How to use Object method of com.consol.citrus.ftp.server.FtpServer class

Best Citrus code snippet using com.consol.citrus.ftp.server.FtpServer.Object

Source:WebHookToFtp_IT.java Github

copy

Full Screen

1/*2 * Copyright (C) 2016 Red Hat, Inc.3 *4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 * http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16package io.syndesis.test.itest.ftp;17import java.io.File;18import java.io.IOException;19import java.nio.file.Path;20import com.consol.citrus.actions.AbstractTestAction;21import com.consol.citrus.annotations.CitrusResource;22import com.consol.citrus.annotations.CitrusTest;23import com.consol.citrus.context.TestContext;24import com.consol.citrus.dsl.endpoint.CitrusEndpoints;25import com.consol.citrus.dsl.runner.TestRunner;26import com.consol.citrus.exceptions.CitrusRuntimeException;27import com.consol.citrus.ftp.message.FtpMessage;28import com.consol.citrus.http.client.HttpClient;29import com.consol.citrus.message.DefaultMessage;30import com.consol.citrus.util.FileUtils;31import com.consol.citrus.validation.json.JsonMessageValidationContext;32import com.consol.citrus.validation.json.JsonTextMessageValidator;33import io.syndesis.test.SyndesisTestEnvironment;34import io.syndesis.test.container.integration.SyndesisIntegrationRuntimeContainer;35import org.apache.commons.net.ftp.FTPCmd;36import org.apache.ftpserver.DataConnectionConfiguration;37import org.apache.ftpserver.DataConnectionConfigurationFactory;38import org.junit.Assert;39import org.junit.ClassRule;40import org.junit.Test;41import org.springframework.beans.factory.annotation.Autowired;42import org.springframework.context.annotation.Bean;43import org.springframework.context.annotation.Configuration;44import org.springframework.http.HttpStatus;45import org.springframework.test.annotation.DirtiesContext;46import org.springframework.test.context.ContextConfiguration;47import org.testcontainers.containers.GenericContainer;48/**49 * @author Christoph Deppisch50 */51@ContextConfiguration(classes = WebHookToFtp_IT.EndpointConfig.class)52@DirtiesContext53public class WebHookToFtp_IT extends FtpTestSupport {54 @Autowired55 private HttpClient webHookClient;56 /**57 * Integration receives a WebHook trigger with contact information as Json object. The contact is transformed to a csv like58 * comma delimited String and pushed to Ftp server as new file.59 */60 @ClassRule61 public static SyndesisIntegrationRuntimeContainer integrationContainer = new SyndesisIntegrationRuntimeContainer.Builder()62 .name("webhook-to-ftp")63 .fromExport(WebHookToFtp_IT.class.getResource("WebhookToFtp-export"))64 .customize("$..configuredProperties.contextPath", "contact")65 .customize("$..configuredProperties.directoryName", "public")66 .customize("$..configuredProperties.host", GenericContainer.INTERNAL_HOST_HOSTNAME)67 .customize("$..configuredProperties.port", FTP_TEST_SERVER_PORT)68 .build()69 .withExposedPorts(SyndesisTestEnvironment.getServerPort());70 @Test71 @CitrusTest72 public void testWebHookToFtp(@CitrusResource TestRunner runner) {73 runner.variable("first_name", "Joanne");74 runner.variable("company", "Red Hat");75 runner.variable("email", "joanne@syndesis.org");76 runner.http(builder -> builder.client(webHookClient)77 .send()78 .post()79 .fork(true)80 .payload("{\"first_name\":\"${first_name}\",\"company\":\"${company}\",\"mail\":\"${email}\"}"));81 runner.receive(receiveMessageBuilder -> receiveMessageBuilder82 .endpoint(ftpTestServer)83 .message(FtpMessage.command(FTPCmd.STOR).arguments("tmp_contacts.csv")));84 runner.send(sendMessageBuilder -> sendMessageBuilder85 .endpoint(ftpTestServer)86 .message(FtpMessage.success()));87 runner.receive(receiveMessageBuilder -> receiveMessageBuilder88 .endpoint(ftpTestServer)89 .message(FtpMessage.command(FTPCmd.RNFR).arguments("public/tmp_contacts.csv")));90 runner.send(sendMessageBuilder -> sendMessageBuilder91 .endpoint(ftpTestServer)92 .message(FtpMessage.success()));93 runner.http(builder -> builder.client(webHookClient)94 .receive()95 .response(HttpStatus.NO_CONTENT));96 runner.run(new VerifyFtpUploadTestAction());97 }98 @Configuration99 public static class EndpointConfig {100 @Bean101 public HttpClient webHookClient() {102 return CitrusEndpoints.http().client()103 .requestUrl(String.format("http://localhost:%s/webhook/contact", integrationContainer.getServerPort()))104 .build();105 }106 @Bean107 public DataConnectionConfiguration dataConnectionConfiguration() {108 DataConnectionConfigurationFactory dataConnectionFactory = new DataConnectionConfigurationFactory();109 dataConnectionFactory.setPassiveExternalAddress(integrationContainer.getInternalHostIp());110 dataConnectionFactory.setPassivePorts(String.valueOf(PASSIVE_PORT));111 return dataConnectionFactory.createDataConnectionConfiguration();112 }113 }114 /*115 * Helper test action ready the uploaded ftp file from user home directory and verifies116 * the content with Json message validator.117 */118 private static class VerifyFtpUploadTestAction extends AbstractTestAction {119 private static final String UPLOAD_FILENAME = "contacts.csv";120 @Override121 public void doExecute(TestContext testContext) {122 Path publicUserDir = getFtpUserHome().resolve("public");123 Assert.assertTrue( "Missing ftp user home directory", publicUserDir.toFile().exists());124 File ftpUploadFile = publicUserDir.resolve(UPLOAD_FILENAME).toFile();125 Assert.assertTrue(String.format("Missing ftp upload file '%s'", UPLOAD_FILENAME), ftpUploadFile.exists());126 try {127 JsonTextMessageValidator validator = new JsonTextMessageValidator();128 validator.validateMessage(new DefaultMessage(FileUtils.readToString(ftpUploadFile)),129 new DefaultMessage("{\"message\" : \"${first_name},${company},${email}\"}"),130 testContext,131 new JsonMessageValidationContext());132 } catch (IOException e) {133 throw new CitrusRuntimeException(String.format("Failed to verify ftp upload file '%s'", UPLOAD_FILENAME), e);134 }135 }136 }137}...

Full Screen

Full Screen

Source:EndpointModelConverterTest.java Github

copy

Full Screen

...64 * @author Christoph Deppisch65 */66public class EndpointModelConverterTest {67 @Test(dataProvider = "converterData")68 public void testConvert(ModelConverter modelConverter, Object target, Endpoint source, String endpointType) throws Exception {69 Object result = modelConverter.convert(source);70 Assert.assertEquals(result.getClass(), target.getClass());71 String snippet = modelConverter.getJavaConfig(target);72 Assert.assertTrue(snippet.contains(endpointType), snippet);73 }74 @DataProvider75 public Object[][] converterData() {76 return new Object[][] {77 new Object[] {new JmsEndpointModelConverter(), new JmsEndpointModel(), new JmsEndpoint(), "jms().asynchronous()"},78 new Object[] {new ChannelEndpointModelConverter(), new ChannelEndpointModel(), new ChannelEndpoint(), "channel()"},79 new Object[] {new CamelEndpointModelConverter(), new CamelEndpointModel(), new CamelEndpoint(), "camel()"},80 new Object[] {new VertxEndpointModelConverter(), new VertxEndpointModel(), new VertxEndpoint(), "vertx()"},81 new Object[] {new HttpClientModelConverter(), new HttpClientModel(), new HttpClient(), "http().client()"},82 new Object[] {new HttpServerModelConverter(), new HttpServerModel(), new HttpServer(), "http().server()"},83 new Object[] {new WebServiceClientModelConverter(), new WebServiceClientModel(), new WebServiceClient(), "soap().client()"},84 new Object[] {new WebServiceServerModelConverter(), new WebServiceServerModel(), new WebServiceServer(), "soap().server()"},85 new Object[] {new WebSocketClientModelConverter(), new WebSocketClientModel(), new WebServiceClient(), "websocket().client()"},86 new Object[] {new WebSocketServerModelConverter(), new WebSocketServerModel(), new WebSocketServer(), "websocket().server()"},87 new Object[] {new FtpClientModelConverter(), new FtpClientModel(), new FtpClient(), "ftp().client()"},88 new Object[] {new FtpServerModelConverter(), new FtpServerModel(), new FtpServer(), "ftp().server()"},89 new Object[] {new JdbcServerModelConverter(), new JdbcServerModel(), new JdbcServer(), "jdbc().server()"},90 new Object[] {new SshClientModelConverter(), new SshClientModel(), new SshClient(), "ssh().client()"},91 new Object[] {new SshServerModelConverter(), new SshServerModel(), new SshServer(), "ssh().server()"},92 new Object[] {new RmiClientModelConverter(), new RmiClientModel(), new RmiClient(), "rmi().client()"},93 new Object[] {new RmiServerModelConverter(), new RmiServerModel(), new RmiServer(), "rmi().server()"},94 new Object[] {new JmxClientModelConverter(), new JmxClientModel(), new JmxClient(), "jmx().client()"},95 new Object[] {new JmxServerModelConverter(), new JmxServerModel(), new JmxServer(), "jmx().server()"},96 new Object[] {new MailClientModelConverter(), new MailClientModel(), new MailClient(), "mail().client()"},97 new Object[] {new MailServerModelConverter(), new MailServerModel(), new MailServer(), "mail().server()"}98 };99 }100}...

Full Screen

Full Screen

Source:FtpServer.java Github

copy

Full Screen

...40 private final FtpEndpointConfiguration endpointConfiguration;41 /** Property file holding ftp user information */42 private Resource userManagerProperties;43 /** Do only start one instance after another so we need a static lock object */44 private static Object serverLock = new Object();45 /**46 * Default constructor using default endpoint configuration.47 */48 public FtpServer() {49 this(new FtpEndpointConfiguration());50 }51 /**52 * Constructor using endpoint configuration.53 * @param endpointConfiguration54 */55 public FtpServer(FtpEndpointConfiguration endpointConfiguration) {56 this.endpointConfiguration = endpointConfiguration;57 }58 @Override...

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1package com.consol.citrus.ftp.server;2import org.apache.ftpserver.FtpServer;3import org.apache.ftpserver.ftplet.FtpException;4import org.apache.ftpserver.ftplet.Ftplet;5import org.apache.ftpserver.ftplet.FtpletContext;6import org.apache.ftpserver.ftplet.FtpletResult;7import org.apache.ftpserver.ftplet.FtpRequest;8import org.apache.ftpserver.ftplet.FtpSession;9import org.apache.ftpserver.ftplet.User;10import org.apache.ftpserver.impl.FtpServerContext;11import org.apache.ftpserver.listener.Listener;12import org.apache.ftpserver.usermanager.UserManager;13import org.springframework.context.ApplicationContext;14import java.io.IOException;15import java.net.ServerSocket;16import java.util.ArrayList;17import java.util.List;18import java.util.Map;19import java.util.concurrent.ConcurrentHashMap;20public class FtpServer {21 private org.apache.ftpserver.FtpServer ftpServer;22 private int port;23 private int portRange;24 private UserManager userManager;25 private List<Listener> listeners = new ArrayList<>();26 private List<Ftplet> ftplets = new ArrayList<>();27 private ApplicationContext applicationContext;28 private FtpServerContext ftpServerContext;29 private Map<String, Object> ftpServerContextObjects = new ConcurrentHashMap<>();30 private FtpletContext ftpServerFtpletContext;31 public FtpServer() {32 this.port = 2121;33 this.portRange = 100;34 }35 public FtpServer(int port, int portRange) {36 this.port = port;37 this.portRange = portRange;38 }39 public void start() {40 if (ftpServer != null) {41 throw new IllegalStateException("

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1package com.consol.citrus.ftp.server;2import java.io.File;3import java.util.ArrayList;4import java.util.List;5import org.apache.ftpserver.ftplet.FtpFile;6import org.apache.ftpserver.ftplet.FtpFileFilter;7import org.apache.ftpserver.ftplet.User;8public class FtpServer extends org.apache.ftpserver.FtpServer {9 private FtpFile rootDirectory;10 public FtpServer(FtpFile rootDirectory) {11 this.rootDirectory = rootDirectory;12 }13 public FtpFile getFileSystemView(User user) throws FtpException {14 return rootDirectory;15 }16 public FtpFile getFileSystemView(User user, String dir) throws FtpException {17 return rootDirectory;18 }19 public static class FtpFileImpl implements FtpFile {20 private File file;21 public FtpFileImpl(File file) {22 this.file = file;23 }24 public boolean isHidden() {25 return file.isHidden();26 }27 public boolean exists() {28 return file.exists();29 }30 public boolean isDirectory() {31 return file.isDirectory();32 }33 public boolean isFile() {34 return file.isFile();35 }36 public String getAbsolutePath() {37 return file.getAbsolutePath();38 }39 public String getName() {40 return file.getName();41 }42 public long getSize() {43 return file.length();44 }45 public boolean delete() {46 return file.delete();47 }48 public boolean move(FtpFile destination) {49 return file.renameTo(new File(destination.getAbsolutePath()));50 }51 public List<FtpFile> listFiles() {52 List<FtpFile> ftpFiles = new ArrayList<FtpFile>();53 for (File file : file.listFiles()) {54 ftpFiles.add(new FtpFileImpl(file));55 }56 return ftpFiles;57 }58 public List<FtpFile> listFiles(FtpFileFilter filter) {59 List<FtpFile> ftpFiles = new ArrayList<FtpFile>();60 for (File file : file.listFiles()) {61 FtpFile ftpFile = new FtpFileImpl(file);62 if (filter.accept(ftpFile)) {

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1package com.consol.citrus.ftp.server;2public class 3 {3 public static void main(String[] args) {4 FtpServer ftpServer = new FtpServer();5 ftpServer.setPort(2222);6 ftpServer.setHost("localhost");7 ftpServer.start();8 ftpServer.stop();9 }10}11package com.consol.citrus.ftp.server;12public class 4 {13 public static void main(String[] args) {14 FtpServer ftpServer = new FtpServer();15 ftpServer.setPort(2222);16 ftpServer.setHost("localhost");17 ftpServer.start();18 ftpServer.stop();19 }20}21package com.consol.citrus.ftp.server;22public class 5 {23 public static void main(String[] args) {24 FtpServer ftpServer = new FtpServer();25 ftpServer.setPort(2222);26 ftpServer.setHost("localhost");27 ftpServer.start();28 ftpServer.stop();29 }30}31package com.consol.citrus.ftp.server;32public class 6 {33 public static void main(String[] args) {34 FtpServer ftpServer = new FtpServer();35 ftpServer.setPort(2222);36 ftpServer.setHost("localhost");37 ftpServer.start();38 ftpServer.stop();39 }40}41package com.consol.citrus.ftp.server;42public class 7 {43 public static void main(String[] args) {44 FtpServer ftpServer = new FtpServer();45 ftpServer.setPort(2222

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1public class FtpServer {2 private org.apache.ftpserver.FtpServer ftpServer;3 private org.apache.ftpserver.listener.ListenerFactory listenerFactory;4 private org.apache.ftpserver.ftplet.UserManager userManager;5 private org.apache.ftpserver.usermanager.impl.BaseUser user;6 private org.apache.ftpserver.ftplet.Authority authority;7 private org.apache.ftpserver.ftplet.Ftplet ftplet;8 private org.apache.ftpserver.ftplet.FtpletResult ftpletResult;9 private org.apache.ftpserver.ftplet.FtpletContext ftpletContext;10 private org.apache.ftpserver.ftplet.FtpRequest ftpRequest;11 private org.apache.ftpserver.ftplet.FtpReply ftpReply;12 private org.apache.ftpserver.ftplet.FtpSession ftpSession;13 private org.apache.ftpserver.ftplet.User user;14 private org.apache.ftpserver.ftplet.FileSystemView fileSystemView;15 private org.apache.ftpserver.ftplet.FileSystemFactory fileSystemFactory;16 private org.apache.ftpserver.ftplet.FileSystemView fileSystemView;17 private org.apache.ftpserver.ftplet.FtpFile ftpFile;18 private org.apache.ftpserver.ftplet.FtpFileFilter ftpFileFilter;19 private org.apache.ftpserver.ftplet.FtpStatistics ftpStatistics;20 private org.apache.ftpserver.ftplet.FtpStatisticsListener ftpStatisticsListener;21 private org.apache.ftpserver.ftplet.FtpStatisticsListener.FtpStatisticsView ftpStatisticsView;22 private org.apache.ftpserver.ftplet.FtpStatisticsListener.FtpStatisticsView.FtpStatisticsViewEntry ftpStatisticsViewEntry;23 private org.apache.ftpserver.ftplet.FtpStatisticsListener.FtpStatisticsView.FtpStatisticsViewEntry.FtpStatisticsViewEntryUser ftpStatisticsViewEntryUser;24 private org.apache.ftpserver.ftplet.FtpStatisticsListener.FtpStatisticsView.FtpStatisticsViewEntry.FtpStatisticsViewEntryUser.FtpStatisticsViewEntryUserSession ftpStatisticsViewEntryUserSession;25 private org.apache.ftpserver.ftplet.FtpStatisticsListener.FtpStatisticsView.FtpStatisticsViewEntry.FtpStatisticsViewEntryUser.FtpStatisticsViewEntryUserSession.FtpStatisticsViewEntryUserSessionTransfer ftpStatisticsViewEntryUserSessionTransfer;26 private org.apache.ftpserver.ftplet.UserManagerFactory userManagerFactory;

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1package com.consol.citrus.ftp.server;2import java.util.List;3import org.apache.ftpserver.ftplet.FtpFile;4public class FtpServer {5 private String name;6 private String host;7 private int port;8 private String user;9 private String password;10 private String homeDirectory;11 private List<FtpFile> files;12 public FtpServer() {13 }14 public FtpServer(String name, String host, int port, String user, String password, String homeDirectory, List<FtpFile> files) {15 this.name = name;16 this.host = host;17 this.port = port;18 this.user = user;19 this.password = password;20 this.homeDirectory = homeDirectory;21 this.files = files;22 }23 public String getName() {24 return this.name;25 }26 public void setName(String name) {27 this.name = name;28 }29 public String getHost() {30 return this.host;31 }32 public void setHost(String host) {33 this.host = host;34 }35 public int getPort() {36 return this.port;37 }38 public void setPort(int port) {39 this.port = port;40 }41 public String getUser() {42 return this.user;43 }44 public void setUser(String user) {45 this.user = user;46 }47 public String getPassword() {48 return this.password;49 }50 public void setPassword(String password) {51 this.password = password;52 }53 public String getHomeDirectory() {54 return this.homeDirectory;55 }56 public void setHomeDirectory(String homeDirectory) {57 this.homeDirectory = homeDirectory;58 }59 public List<FtpFile> getFiles() {60 return this.files;61 }62 public void setFiles(List<FtpFile> files) {63 this.files = files;64 }65 public boolean equals(final Object o) {66 if (o == this) return true;67 if (!(o instanceof FtpServer)) return false;68 final FtpServer other = (FtpServer) o;69 if (!other.canEqual((Object) this)) return false;70 final Object this$name = this.getName();71 final Object other$name = other.getName();72 if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;73 final Object this$host = this.getHost();

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1import org.springframework.context.support.ClassPathXmlApplicationContext;2public class FtpServer {3 public static void main(String[] args) {4 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");5 context.getBean("ftpServer");6 }7}8import org.springframework.context.support.ClassPathXmlApplicationContext;9public class FtpClient {10 public static void main(String[] args) {11 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");12 context.getBean("ftpClient");13 }14}

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1public class 3 {2public static void main(String[] args) {3FtpServer ftpServer = new FtpServer();4ftpServer.stop();5}6}7FtpServer#start()8FtpServer#stop()9FtpServer#isRunning()10FtpServer#isStopped()11FtpServer#isStarting()12FtpServer#isStopping()13FtpServer#isSuspended()14FtpServer#isSuspended()15FtpServer#resume()16FtpServer#suspend()17FtpServer#destroy()18FtpServer#addUser()19FtpServer#removeUser()20FtpServer#getUser()21FtpServer#getUsers()22FtpServer#setUsers()23FtpServer#addUserManager()24FtpServer#removeUserManager()25FtpServer#getUserManager()26FtpServer#getUserManagers()27FtpServer#setUserManagers()28FtpServer#addListener()29FtpServer#removeListener()30FtpServer#getListeners()31FtpServer#setListeners()32FtpServer#setFileSystem()33FtpServer#getFileSystem()34FtpServer#setFileSystemView()35FtpServer#getFileSystemView()36FtpServer#setCommandFactory()37FtpServer#getCommandFactory()38FtpServer#setConnectionConfig()39FtpServer#getConnectionConfig()40FtpServer#setDataConnectionConfiguration()41FtpServer#getDataConnectionConfiguration()42FtpServer#setCommandManagerFactory()43FtpServer#getCommandManagerFactory()44FtpServer#setFtplets()45FtpServer#getFtplets()46FtpServer#setFtpletContainer()47FtpServer#getFtpletContainer()48FtpServer#setFtpletContext()49FtpServer#getFtpletContext()50FtpServer#setConnectionConfig()51FtpServer#getConnectionConfig()52FtpServer#setDataConnectionConfiguration()53FtpServer#getDataConnectionConfiguration()54FtpServer#setCommandFactory()55FtpServer#getCommandFactory()56FtpServer#setCommandManagerFactory()57FtpServer#getCommandManagerFactory()58FtpServer#setFtplets()59FtpServer#getFtplets()60FtpServer#setFtpletContainer()61FtpServer#getFtpletContainer()62FtpServer#setFtpletContext()

Full Screen

Full Screen

Object

Using AI Code Generation

copy

Full Screen

1FtpServer ftpServer = new FtpServer();2ftpServer.setPort(21);3ftpServer.setUser("user");4ftpServer.setPassword("password");5ftpServer.setRootDirectory("ftp");6ftpServer.start();7FtpClient ftpClient = new FtpClient();8ftpClient.setHost("localhost");9ftpClient.setPort(21);10ftpClient.setUser("user");11ftpClient.setPassword("password");12ftpClient.setDefaultDirectory("ftp");13ftpClient.setFileType("binary");14ftpClient.setPassiveMode(true);15ftpClient.setTimeout(5000);16ftpClient.connect();17FtpClient ftpClient = new FtpClient();18ftpClient.setHost("localhost");19ftpClient.setPort(21);20ftpClient.setUser("user");21ftpClient.setPassword("password");22ftpClient.setDefaultDirectory("ftp");23ftpClient.setFileType("binary");24ftpClient.setPassiveMode(true);25ftpClient.setTimeout(5000);26ftpClient.connect();27FtpClient ftpClient = new FtpClient();28ftpClient.setHost("localhost");29ftpClient.setPort(21);30ftpClient.setUser("user");

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful