This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git
The following commit(s) were added to refs/heads/main by this push: new 570f8bd91ce CAMEL-17993 Add tests in camel-ftp-starter (#550) 570f8bd91ce is described below commit 570f8bd91cead1cb4caecf2ef4ceebd58a314096 Author: JiriOndrusek <ondrusek.j...@gmail.com> AuthorDate: Mon May 2 20:40:26 2022 +0200 CAMEL-17993 Add tests in camel-ftp-starter (#550) --- components-starter/camel-ftp-starter/pom.xml | 47 +++++ .../camel-ftp-starter/src/test/data/bar.xml | 20 +++ .../camel-ftp-starter/src/test/data/foo.xml | 20 +++ .../src/test/data/ftpbinarytest/logo.jpeg | Bin 0 -> 10249 bytes .../src/test/data/ftpbinarytest/logo1.jpeg | Bin 0 -> 10249 bytes .../src/test/data/ftpbinarytest/logo2.png | Bin 0 -> 93934 bytes .../src/test/data/ftpbinarytest/logo3.jpeg | Bin 0 -> 5488717 bytes .../file/remote/springboot/AbstractBaseFtp.java | 97 +++++++++++ .../file/remote/springboot/ftp/BaseFtp.java | 33 ++++ .../remote/springboot/ftp/FromFtpFilterTest.java | 105 +++++++++++ .../ftp/FromFtpMoveFileRecursiveTest.java | 90 ++++++++++ .../springboot/ftp/FromFtpToBinaryFileTest.java | 113 ++++++++++++ .../remote/springboot/ftp/FtpAnonymousTest.java | 82 +++++++++ .../ftp/FtpConsumerMaxMessagesPerPollTest.java | 93 ++++++++++ .../remote/springboot/ftp/FtpEmbeddedService.java | 193 +++++++++++++++++++++ .../springboot/ftp/FtpProducerConcurrentTest.java | 100 +++++++++++ ...FtpSimpleConsumeStreamingStepwiseFalseTest.java | 97 +++++++++++ .../FtpSimpleConsumeStreamingStepwiseTrueTest.java | 58 +++++++ .../remote/springboot/ftp/FtpSoTimeoutTest.java | 119 +++++++++++++ .../remote/springboot/ftps/BaseFtpsClientAuth.java | 18 ++ .../ftps/BaseFtpsImplicitClientAuth.java | 18 ++ .../FileToFtpsImplicitSSLWithClientAuthTest.java | 80 +++++++++ ...leToFtpsWithCustomTrustStorePropertiesTest.java | 79 +++++++++ .../springboot/ftps/FtpsEmbeddedService.java | 101 +++++++++++ .../ftps/FtpsImplicitEmbeddedService.java | 101 +++++++++++ .../file/remote/springboot/ftps/FtpsTest.java | 78 +++++++++ .../file/remote/springboot/sftp/BaseSftp.java | 36 ++++ .../sftp/SftpConsumerLocalWorkDirectoryTest.java | 127 ++++++++++++++ .../springboot/sftp/SftpEmbeddedService.java | 174 +++++++++++++++++++ .../sftp/SftpKeyExchangeProtocolsTest.java | 140 +++++++++++++++ .../springboot/sftp/SftpSetOperationsTest.java | 56 ++++++ .../sftp/SftpSimpleProduceThroughProxyTest.java | 147 ++++++++++++++++ .../springboot/sftp/SftpUseListFalseTest.java | 90 ++++++++++ .../src/test/resources/hostkey.pem | 15 ++ .../src/test/resources/readme.txt | 1 + .../src/test/resources/server.jks | Bin 0 -> 2421 bytes 36 files changed, 2528 insertions(+) diff --git a/components-starter/camel-ftp-starter/pom.xml b/components-starter/camel-ftp-starter/pom.xml index c93e589ac81..a8b22c895b1 100644 --- a/components-starter/camel-ftp-starter/pom.xml +++ b/components-starter/camel-ftp-starter/pom.xml @@ -39,6 +39,53 @@ <artifactId>camel-ftp</artifactId> <version>${camel-version}</version> </dependency> + <dependency> + <groupId>org.apache.ftpserver</groupId> + <artifactId>ftpserver-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.ftpserver</groupId> + <artifactId>ftplet-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-infra-ftp</artifactId> + <version>${camel-version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <!-- for testing sftp --> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-sftp</artifactId> + <version>${sshd-version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-scp</artifactId> + <version>${sshd-version}</version> + <scope>test</scope> + </dependency> + <!-- for testing sftp through http proxy --> + <dependency> + <groupId>org.littleshoot</groupId> + <artifactId>littleproxy</artifactId> + <version>1.1.2</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </exclusion> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </exclusion> + </exclusions> + </dependency> <!--START OF GENERATED CODE--> <dependency> <groupId>org.apache.camel.springboot</groupId> diff --git a/components-starter/camel-ftp-starter/src/test/data/bar.xml b/components-starter/camel-ftp-starter/src/test/data/bar.xml new file mode 100644 index 00000000000..4c768881014 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/data/bar.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<hello>bar</hello> diff --git a/components-starter/camel-ftp-starter/src/test/data/foo.xml b/components-starter/camel-ftp-starter/src/test/data/foo.xml new file mode 100644 index 00000000000..ce3c19fd1db --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/data/foo.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<hello>foo</hello> diff --git a/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo.jpeg b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo.jpeg new file mode 100644 index 00000000000..b635017d1e2 Binary files /dev/null and b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo.jpeg differ diff --git a/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo1.jpeg b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo1.jpeg new file mode 100644 index 00000000000..b635017d1e2 Binary files /dev/null and b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo1.jpeg differ diff --git a/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo2.png b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo2.png new file mode 100644 index 00000000000..5389aa856f4 Binary files /dev/null and b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo2.png differ diff --git a/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo3.jpeg b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo3.jpeg new file mode 100644 index 00000000000..d8884435da9 Binary files /dev/null and b/components-starter/camel-ftp-starter/src/test/data/ftpbinarytest/logo3.jpeg differ diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/AbstractBaseFtp.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/AbstractBaseFtp.java new file mode 100644 index 00000000000..cdae4306210 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/AbstractBaseFtp.java @@ -0,0 +1,97 @@ +package org.apache.camel.component.file.remote.springboot; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.apache.camel.language.simple.SimpleLanguage.simple; + +public abstract class AbstractBaseFtp { + protected static final String AUTH_VALUE_SSL = "SSLv3"; + protected static final String AUTH_VALUE_TLS = "TLSv1.2"; + + @Autowired + protected CamelContext context; + + @Autowired + protected ProducerTemplate template; + + protected abstract int getPort(); + + protected void assertMockEndpointsSatisfied() throws InterruptedException { + MockEndpoint.assertIsSatisfied(this.context); + } + + protected void sendFile(String url, Object body, String fileName) { + template.sendBodyAndHeader(url, body, Exchange.FILE_NAME, simple(fileName)); + } + + protected static void assertFileExists(String filename) { + File file = new File(filename); + Assertions.assertTrue(file.exists(), "File " + filename + " should exist"); + Assertions.assertTrue(file.isFile(), "File " + filename + " should be a file"); + } + + protected static void assertFileNotExists(Path file) { + Assertions.assertFalse(Files.exists(file, new LinkOption[0]), "File " + file + " should not exist"); + } + + protected static void assertFileExists(Path file, String content) throws IOException { + Assertions.assertTrue(Files.exists(file, new LinkOption[0]), "File " + file + " should exist"); + Assertions.assertTrue(Files.isRegularFile(file, new LinkOption[0]), "File " + file + " should be a file"); + Assertions.assertEquals(content, new String(Files.readAllBytes(file)), "File " + file + " has unexpected content"); + } + + + protected Path testFile(String dir) { + return this.testDirectory().resolve(dir); + } + + protected Path testDirectory() { + return this.testDirectory(false); + } + + protected Path testDirectory(boolean create) { + Class<?> testClass = this.getClass(); + return testDirectory(testClass, create); + } + + public static Path testDirectory(Class<?> testClass, boolean create) { + Path dir = Paths.get("target", "data", testClass.getSimpleName()); + if (create) { + try { + Files.createDirectories(dir); + } catch (IOException var4) { + throw new IllegalStateException("Unable to create test directory: " + dir, var4); + } + } + + return dir; + } + + protected String fileUri(String query) { + Path var10000 = this.testDirectory(); + return "file:" + var10000 + (query.startsWith("?") ? "" : "/") + query; + } + + + // ************************************* + // Config + // ************************************* + + @Configuration + public static class TestConfiguration { + + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/BaseFtp.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/BaseFtp.java new file mode 100644 index 00000000000..d4654b56e5f --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/BaseFtp.java @@ -0,0 +1,33 @@ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.component.file.remote.springboot.AbstractBaseFtp; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.nio.file.Path; + + +public class BaseFtp extends AbstractBaseFtp { + protected static final String AUTH_VALUE_SSL = "SSLv3"; + protected static final String AUTH_VALUE_TLS = "TLSv1.2"; + + @RegisterExtension + static FtpEmbeddedService service = new FtpEmbeddedService(); + + @Override + protected int getPort() { + return service.getPort(); + } + + protected Path ftpFile(String file) { + return service.getFtpRootDir().resolve(file); + } + + protected String getFtpUrl(String user, String password) { + StringBuilder url = new StringBuilder("ftp://"); + url.append(user == null ? "" : user + "@"); + url.append("localhost:" + service.getPort() + "/"); + url.append(password == null ? "" : "?password=" + password); + return url.toString(); + } + +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpFilterTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpFilterTest.java new file mode 100644 index 00000000000..a8d3be23373 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpFilterTest.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.GenericFile; +import org.apache.camel.component.file.GenericFileFilter; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FromFtpFilterTest.class, + FromFtpFilterTest.TestConfiguration.class + } +) +//Based on FromFtpFilterIT +public class FromFtpFilterTest extends BaseFtp { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + protected String getFtpUrl() { + return "ftp://admin@localhost:" + getPort() + "/filter?password=admin&binary=false&filter=#myFilter"; + } + + @Test + public void testFilterFiles() throws Exception { + mock.expectedMessageCount(0); + + sendFile(getFtpUrl(), "This is a file to be filtered", "skipme.txt"); + + mock.setResultWaitTime(3000); + mock.assertIsSatisfied(); + } + + @Test + public void testFilterFilesWithARegularFile() throws Exception { + mock.expectedMessageCount(1); + mock.expectedBodiesReceived("Hello World"); + + sendFile(getFtpUrl(), "This is a file to be filtered", "skipme.txt"); + + sendFile(getFtpUrl(), "Hello World", "hello.txt"); + + mock.assertIsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from(getFtpUrl()).to("mock:result"); + } + }; + } + + @Bean(value = "myFilter") + public MyFileFilter filter() { + return new MyFileFilter(); + } + } + + // START SNIPPET: e1 + public class MyFileFilter<T> implements GenericFileFilter<T> { + @Override + public boolean accept(GenericFile<T> file) { + // we don't accept any files starting with skip in the name + return !file.getFileName().startsWith("skip"); + } + } + // END SNIPPET: e1 +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpMoveFileRecursiveTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpMoveFileRecursiveTest.java new file mode 100644 index 00000000000..b1da84bb63e --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpMoveFileRecursiveTest.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FromFtpMoveFileRecursiveTest.class, + FromFtpMoveFileRecursiveTest.TestConfiguration.class + } +) +// Based on FromFtpMoveFileRecursiveIT +public class FromFtpMoveFileRecursiveTest extends BaseFtp { + + @EndpointInject("mock:result") + private MockEndpoint result; + + protected String getFtpUrl() { + return "ftp://admin@localhost:" + getPort() + "/movefile?password=admin&recursive=true&binary=false" + + "&move=.done/${file:name}.old&initialDelay=2500&delay=5000"; + } + + @BeforeEach + public void setUp() throws Exception { + prepareFtpServer(); + } + + @Test + public void testPollFileAndShouldBeMoved() throws Exception { + result.expectedBodiesReceivedInAnyOrder("Hello", "Bye", "Goodday"); + result.expectedFileExists(ftpFile("movefile/.done/hello.txt.old")); + result.expectedFileExists(ftpFile("movefile/.done/bye/bye.txt.old")); + result.expectedFileExists(ftpFile("movefile/.done/goodday/goodday.txt.old")); + + result.assertIsSatisfied(); + } + + private void prepareFtpServer() { + sendFile(getFtpUrl(), "Hello", "hello.txt"); + sendFile(getFtpUrl(), "Bye", "bye/bye.txt"); + sendFile(getFtpUrl(), "Goodday", "goodday/goodday.txt"); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from(getFtpUrl()).to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpToBinaryFileTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpToBinaryFileTest.java new file mode 100644 index 00000000000..e2497af049d --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpToBinaryFileTest.java @@ -0,0 +1,113 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.Endpoint; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Producer; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.converter.IOConverter; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FromFtpToBinaryFileTest.class, + FromFtpToBinaryFileTest.TestConfiguration.class + } +) +//Baaed on FromFtpToBinaryFileIT +public class FromFtpToBinaryFileTest extends BaseFtp { + + @EndpointInject("mock:result") + private MockEndpoint resultEndpoint; + + // must user "consumer." prefix on the parameters to the file component + private String getFtpUrl() { + return "ftp://admin@localhost:" + getPort() + "/tmp4/camel?password=admin&binary=true" + + "&delay=5000&recursive=false"; + } + + + @BeforeEach + public void setUp() throws Exception { + prepareFtpServer(); + } + + + @Test + public void testFtpRoute() throws Exception { + resultEndpoint.expectedMessageCount(1); + resultEndpoint.assertIsSatisfied(); + Exchange ex = resultEndpoint.getExchanges().get(0); + byte[] bytes = ex.getIn().getBody(byte[].class); + assertTrue(bytes.length > 10000, "Logo size wrong"); + + // assert the file + File file = testFile("deleteme.jpg").toFile(); + assertTrue(file.exists(), "The binary file should exists"); + assertTrue(file.length() > 10000, "Logo size wrong"); + } + + private void prepareFtpServer() throws Exception { + // prepares the FTP Server by creating a file on the server that we want + // to unit + // test that we can pool and store as a local file + Endpoint endpoint = context.getEndpoint(getFtpUrl()); + Exchange exchange = endpoint.createExchange(); + exchange.getIn().setBody(IOConverter.toFile("src/test/data/ftpbinarytest/logo.jpeg")); + exchange.getIn().setHeader(Exchange.FILE_NAME, "logo.jpeg"); + Producer producer = endpoint.createProducer(); + producer.start(); + producer.process(exchange); + producer.stop(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + String fileUrl = fileUri("?noop=true&fileExist=Override"); + from(getFtpUrl()).setHeader(Exchange.FILE_NAME, constant("deleteme.jpg")).to(fileUrl, "mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpAnonymousTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpAnonymousTest.java new file mode 100644 index 00000000000..eb7f5d52024 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpAnonymousTest.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +/** + * Unit test that ftp consumer for anonymous login + */ +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpAnonymousTest.class, + FtpAnonymousTest.TestConfiguration.class + } +) +//Based on FtpAnonymousIT +public class FtpAnonymousTest extends BaseFtp { + + @EndpointInject("mock:result") + private MockEndpoint result; + + @BeforeEach + public void setUp() throws Exception { + prepareFtpServer(); + } + + @Test + public void testAnonymous() throws Exception { + result.expectedMessageCount(1); + + result.assertIsSatisfied(); + } + + private void prepareFtpServer() { + sendFile(getFtpUrl("admin", "admin"), "Hello World", "hello.xml"); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from(getFtpUrl(null, null)).to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpConsumerMaxMessagesPerPollTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpConsumerMaxMessagesPerPollTest.java new file mode 100644 index 00000000000..64ba3d36b28 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpConsumerMaxMessagesPerPollTest.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpConsumerMaxMessagesPerPollTest.class, + FtpConsumerMaxMessagesPerPollTest.TestConfiguration.class + } +) +//Based on FtpConsumerMaxMessagesPerPollIT +public class FtpConsumerMaxMessagesPerPollTest extends BaseFtp { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + private String getFtpUrl() { + return "ftp://admin@localhost:" + getPort() + "/poll/?password=admin&delay=6000&delete=true&sortBy=file:name&maxMessagesPerPoll=2"; + } + + @BeforeEach + void prepareFtpServer() { + sendFile(getFtpUrl(), "Bye World", "bye.txt"); + sendFile(getFtpUrl(), "Hello World", "hello.txt"); + sendFile(getFtpUrl(), "Godday World", "godday.txt"); + } + + @Test + public void testMaxMessagesPerPoll() throws Exception { + // start route + context.getRouteController().startRoute("foo"); + + mock.expectedBodiesReceived("Bye World", "Godday World"); + mock.setResultWaitTime(4000); + mock.expectedPropertyReceived(Exchange.BATCH_SIZE, 2); + + assertMockEndpointsSatisfied(); + + mock.reset(); + mock.expectedBodiesReceived("Hello World"); + mock.expectedPropertyReceived(Exchange.BATCH_SIZE, 1); + + assertMockEndpointsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from(getFtpUrl()).noAutoStartup().routeId("foo").to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpEmbeddedService.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpEmbeddedService.java new file mode 100644 index 00000000000..8067059363e --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpEmbeddedService.java @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.test.infra.common.services.AbstractTestService; +import org.apache.camel.test.infra.ftp.common.FtpProperties; +import org.apache.camel.test.infra.ftp.services.FtpService; +import org.apache.ftpserver.ConnectionConfigFactory; +import org.apache.ftpserver.FtpServer; +import org.apache.ftpserver.FtpServerFactory; +import org.apache.ftpserver.filesystem.nativefs.NativeFileSystemFactory; +import org.apache.ftpserver.ftplet.FtpException; +import org.apache.ftpserver.ftplet.UserManager; +import org.apache.ftpserver.impl.DefaultFtpServer; +import org.apache.ftpserver.impl.FtpIoSession; +import org.apache.ftpserver.listener.Listener; +import org.apache.ftpserver.listener.ListenerFactory; +import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor; +import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory; +import org.apache.ftpserver.usermanager.impl.BaseUser; +import org.apache.ftpserver.usermanager.impl.WritePermission; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; + +import static org.apache.camel.test.junit5.TestSupport.createCleanDirectory; + +public class FtpEmbeddedService extends AbstractTestService implements FtpService { + protected static final String DEFAULT_LISTENER = "default"; + + private static final Logger LOG = LoggerFactory.getLogger(FtpEmbeddedService.class); + + protected FtpServer ftpServer; + + protected int port; + + protected Path rootDir; + + public FtpEmbeddedService() { + } + + public void setUp() throws Exception { + rootDir = testDirectory().resolve("res/home"); + createCleanDirectory(rootDir); + + FtpServerFactory factory = createFtpServerFactory(); + ftpServer = factory.createServer(); + ftpServer.start(); + + port = ((DefaultFtpServer) ftpServer).getListeners().values().stream() + .map(Listener::getPort).findAny().get(); + } + + private Path testDirectory() { + return Paths.get("target", "ftp", context.getRequiredTestClass().getSimpleName()); + } + + protected void createUser(UserManager userMgr, String name, String password, Path home, boolean writePermission) { + try { + BaseUser user = new BaseUser(); + user.setName(name); + user.setPassword(password); + user.setHomeDirectory(home.toString()); + if (writePermission) { + user.setAuthorities(Collections.singletonList(new WritePermission())); + } + userMgr.save(user); + } catch (FtpException e) { + throw new IllegalStateException("Unable to create FTP user", e); + } + } + + protected FtpServerFactory createFtpServerFactory() { + NativeFileSystemFactory fsf = new NativeFileSystemFactory(); + fsf.setCreateHome(true); + + PropertiesUserManagerFactory pumf = new PropertiesUserManagerFactory(); + pumf.setAdminName("admin"); + pumf.setPasswordEncryptor(new ClearTextPasswordEncryptor()); + pumf.setFile(null); + UserManager userMgr = pumf.createUserManager(); + createUser(userMgr, "admin", "admin", rootDir, true); + createUser(userMgr, "scott", "tiger", rootDir, true); + createUser(userMgr, "dummy", "foo", rootDir, false); + createUser(userMgr, "us@r", "t%st", rootDir, true); + createUser(userMgr, "anonymous", null, rootDir, false); + createUser(userMgr, "joe", "p+%w0&r)d", rootDir, true); + createUser(userMgr, "jane", "%j#7%c6i", rootDir, true); + + ListenerFactory factory = new ListenerFactory(); + factory.setPort(port); + + FtpServerFactory serverFactory = new FtpServerFactory(); + serverFactory.setUserManager(userMgr); + serverFactory.setFileSystem(fsf); + serverFactory.setConnectionConfig(new ConnectionConfigFactory().createConnectionConfig()); + serverFactory.addListener(DEFAULT_LISTENER, factory.createListener()); + + return serverFactory; + } + + public void tearDown() { + try { + if (ftpServer != null) { + ftpServer.stop(); + } + } catch (Exception e) { + // ignore while shutting down as we could be polling during + // shutdown + // and get errors when the ftp server is stopping. This is only + // an issue + // since we host the ftp server embedded in the same jvm for + // unit testing + + LOG.trace("Exception while shutting down: {}", e.getMessage(), e); + } finally { + ftpServer = null; + } + + // if (port != null) { + // port.release(); + // } + } + + public void disconnectAllSessions() { + // stop all listeners + Map<String, Listener> listeners = ((DefaultFtpServer) ftpServer).getListeners(); + for (Listener listener : listeners.values()) { + Set<FtpIoSession> sessions = listener.getActiveSessions(); + for (FtpIoSession session : sessions) { + session.closeNow(); + } + } + } + + @Override + protected void registerProperties(BiConsumer<String, String> store) { + store.accept(FtpProperties.SERVER_HOST, "localhost"); + store.accept(FtpProperties.SERVER_PORT, String.valueOf(getPort())); + store.accept(FtpProperties.ROOT_DIR, rootDir.toString()); + } + + public Path getFtpRootDir() { + return rootDir; + } + + public void suspend() { + ftpServer.suspend(); + } + + public void resume() { + ftpServer.resume(); + port = ((DefaultFtpServer) ftpServer).getListeners().values().stream() + .map(Listener::getPort).findAny().get(); + } + + public int getPort() { + return port; + } + + public int countConnections() { + int count = 0; + + // stop all listeners + Map<String, Listener> listeners = ((DefaultFtpServer) ftpServer).getListeners(); + for (Listener listener : listeners.values()) { + count += listener.getActiveSessions().size(); + } + + return count; + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpProducerConcurrentTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpProducerConcurrentTest.java new file mode 100644 index 00000000000..f35d8a20443 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpProducerConcurrentTest.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpProducerConcurrentTest.class, + FtpProducerConcurrentTest.TestConfiguration.class + } +) +//Based on FtpProducerConcurrentIT +public class FtpProducerConcurrentTest extends BaseFtp { + + @EndpointInject("mock:result") + private MockEndpoint result; + + private String getFtpUrl() { + return "ftp://admin@localhost:" + getPort() + "/concurrent?binary=false&password=admin"; + } + + @Test + public void testNoConcurrentProducers() throws Exception { + doSendMessages(1, 1); + } + + @Test + public void testConcurrentProducers() throws Exception { + doSendMessages(10, 5); + } + + private void doSendMessages(int files, int poolSize) throws Exception { + result.reset(); + result.expectedMessageCount(files); + + ExecutorService executor = Executors.newFixedThreadPool(poolSize); + for (int i = 0; i < files; i++) { + result.expectedFileExists(ftpFile("concurrent/" + i + ".txt")); + + final int index = i; + executor.submit(new Callable<Object>() { + public Object call() { + sendFile("direct:start", "Hello World", index + ".txt"); + return null; + } + }); + } + + assertMockEndpointsSatisfied(); + executor.shutdownNow(); + } + + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start").to(getFtpUrl(), "mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSimpleConsumeStreamingStepwiseFalseTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSimpleConsumeStreamingStepwiseFalseTest.java new file mode 100644 index 00000000000..a83e72597de --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSimpleConsumeStreamingStepwiseFalseTest.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.GenericFile; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpSimpleConsumeStreamingStepwiseFalseTest.class, + FtpSimpleConsumeStreamingStepwiseFalseTest.TestConfiguration.class + } +) +public class FtpSimpleConsumeStreamingStepwiseFalseTest extends BaseFtp { + + @EndpointInject("mock:result") + MockEndpoint mock; + + boolean isStepwise() { + return false; + } + + @Test + public void testFtpSimpleConsumeAbsolute() throws Exception { + String expected = "Hello World"; + + String path = ftpFile("tmp/mytemp").toString(); + template.sendBodyAndHeader("file:" + path, expected, Exchange.FILE_NAME, "hello.txt"); + + configureMock(); + + assertMockEndpointsSatisfied(); + assertMore(mock); + } + + void configureMock() { + mock.expectedMessageCount(1); + mock.expectedHeaderReceived(Exchange.FILE_NAME, "hello.txt"); + } + + void assertMore(MockEndpoint mock) { + GenericFile<?> remoteFile = (GenericFile<?>) mock.getExchanges().get(0).getIn().getBody(); + assertTrue(remoteFile.getBody() instanceof InputStream); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("ftp://localhost:" + getPort() + + "/tmp/mytemp?username=admin&password=admin&delay=10000&disconnect=true&streamDownload=true&stepwise=" + + isStepwise()) + .to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSimpleConsumeStreamingStepwiseTrueTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSimpleConsumeStreamingStepwiseTrueTest.java new file mode 100644 index 00000000000..377a48a66de --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSimpleConsumeStreamingStepwiseTrueTest.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpSimpleConsumeStreamingStepwiseTrueTest.class, + FtpSimpleConsumeStreamingStepwiseTrueTest.TestConfiguration.class + } +) +public class FtpSimpleConsumeStreamingStepwiseTrueTest extends FtpSimpleConsumeStreamingStepwiseFalseTest { + + @Override + boolean isStepwise() { + return true; + } + + @Override + void configureMock() { + mock.expectedMessageCount(0); + } + + @Override + void assertMore(MockEndpoint mock) { + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends FtpSimpleConsumeStreamingStepwiseFalseTest.TestConfiguration { + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSoTimeoutTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSoTimeoutTest.java new file mode 100644 index 00000000000..64e8337bff4 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FtpSoTimeoutTest.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftp; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.apache.commons.net.ftp.FTPClient; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpSoTimeoutTest.class, + FtpSoTimeoutTest.TestConfiguration.class + } +) +//Based on FtpSoTimeoutTest +public class FtpSoTimeoutTest { + + @Autowired + protected CamelContext context; + + @Autowired + protected ProducerTemplate template; + + @AfterEach + public void after() throws IOException { + context.getRegistry().findSingleByType(ServerSocket.class).close(); + } + + @Test + @Timeout(value = 10, unit = TimeUnit.SECONDS) + public void testWithDefaultTimeout() { + assertThrows(CamelExecutionException.class, () -> { + // send exchange to the route using the custom FTPClient (with a + // default timeout) + // the soTimeout triggers in time and test is successful + template.sendBody("direct:with", ""); + }); + } + + @Test + @Timeout(value = 10, unit = TimeUnit.SECONDS) + public void testWithoutDefaultTimeout() { + assertThrows(CamelExecutionException.class, () -> { + // send exchange to the route using the default FTPClient (without a + // default timeout) + // the soTimeout never triggers and test fails after its own timeout + template.sendBody("direct:without", ""); + }); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + + @Bean + public ServerSocket createServerSocket() throws IOException { + return new ServerSocket(0); + } + @Bean + public RouteBuilder routeBuilder(ServerSocket serverSocket) { + + return new RouteBuilder() { + @Override + public void configure() { + from("direct:with").to("ftp://localhost:" + serverSocket.getLocalPort() + + "?ftpClient=#myftpclient&connectTimeout=300&soTimeout=300&reconnectDelay=100"); + + from("direct:without").to("ftp://localhost:" + serverSocket.getLocalPort() + + "?connectTimeout=300&soTimeout=300&reconnectDelay=100"); + } + }; + } + + @Bean(value = "myftpclient") + public FTPClient createFtpClient() { + FTPClient ftpClient = new FTPClient(); + ftpClient.setDefaultTimeout(300); + return ftpClient; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/BaseFtpsClientAuth.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/BaseFtpsClientAuth.java new file mode 100644 index 00000000000..941ad63f2d3 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/BaseFtpsClientAuth.java @@ -0,0 +1,18 @@ +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.component.file.remote.springboot.AbstractBaseFtp; +import org.junit.jupiter.api.extension.RegisterExtension; + + +public class BaseFtpsClientAuth extends AbstractBaseFtp { + protected static final String AUTH_VALUE_SSL = "SSLv3"; + protected static final String AUTH_VALUE_TLS = "TLSv1.2"; + + @RegisterExtension + static FtpsEmbeddedService service = new FtpsEmbeddedService(false, AUTH_VALUE_TLS, true); + + @Override + protected int getPort() { + return service.getPort(); + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/BaseFtpsImplicitClientAuth.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/BaseFtpsImplicitClientAuth.java new file mode 100644 index 00000000000..6406c6cdc4d --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/BaseFtpsImplicitClientAuth.java @@ -0,0 +1,18 @@ +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.component.file.remote.springboot.AbstractBaseFtp; +import org.junit.jupiter.api.extension.RegisterExtension; + + +public class BaseFtpsImplicitClientAuth extends AbstractBaseFtp { + protected static final String AUTH_VALUE_SSL = "SSLv3"; + protected static final String AUTH_VALUE_TLS = "TLSv1.2"; + + @RegisterExtension + static FtpsEmbeddedService service = new FtpsEmbeddedService(true, AUTH_VALUE_TLS, true); + + @Override + protected int getPort() { + return service.getPort(); + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FileToFtpsImplicitSSLWithClientAuthTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FileToFtpsImplicitSSLWithClientAuthTest.java new file mode 100644 index 00000000000..f9a1d2c5b56 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FileToFtpsImplicitSSLWithClientAuthTest.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIf; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FileToFtpsImplicitSSLWithClientAuthTest.class, + FileToFtpsImplicitSSLWithClientAuthTest.TestConfiguration.class + } +) +//Based on FileToFtpsImplicitSSLWithClientAuthIT +public class FileToFtpsImplicitSSLWithClientAuthTest extends BaseFtpsImplicitClientAuth { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + protected String getFtpUrl() { + return "ftps://admin@localhost:" + getPort() + + "/tmp2/camel?password=admin&initialDelay=2000&disableSecureDataChannelDefaults=true" + + "&securityProtocol=TLSv1.2&implicit=true&ftpClient.keyStore.file=./src/test/resources/server.jks&ftpClient.keyStore.type=JKS" + + "&ftpClient.keyStore.algorithm=SunX509&ftpClient.keyStore.password=password&ftpClient.keyStore.keyPassword=password&delete=true"; + } + + @Test + public void testFromFileToFtp() throws Exception { + + mock.expectedMessageCount(2); + + assertMockEndpointsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("file:src/test/data?noop=true").log("Got ${file:name}").to(getFtpUrl()); + + from(getFtpUrl()).to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FileToFtpsWithCustomTrustStorePropertiesTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FileToFtpsWithCustomTrustStorePropertiesTest.java new file mode 100644 index 00000000000..d37ca393898 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FileToFtpsWithCustomTrustStorePropertiesTest.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FileToFtpsWithCustomTrustStorePropertiesTest.class, + FileToFtpsWithCustomTrustStorePropertiesTest.TestConfiguration.class + } +) +//based on FileToFtpsWithCustomTrustStorePropertiesIT +public class FileToFtpsWithCustomTrustStorePropertiesTest extends BaseFtpsClientAuth { + + @EndpointInject("mock:result") + private MockEndpoint result; + + private String getFtpUrl() { + return "ftps://admin@localhost:" + getPort() + + "/tmp2/camel?password=admin&initialDelay=2000&disableSecureDataChannelDefaults=true" + + "&securityProtocol=TLSv1.2&implicit=false&ftpClient.trustStore.file=./src/test/resources/server.jks&ftpClient.trustStore.type=PKCS12" + + "&ftpClient.trustStore.algorithm=SunX509&ftpClient.trustStore.password=password&delete=true"; + + } + + @Test + public void testFromFileToFtp() throws Exception { + + result.expectedMessageCount(2); + + assertMockEndpointsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("file:src/test/data?noop=true").log("Got ${file:name}").to(getFtpUrl()); + + from(getFtpUrl()).to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsEmbeddedService.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsEmbeddedService.java new file mode 100644 index 00000000000..46610e290a4 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsEmbeddedService.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.component.file.remote.springboot.ftp.FtpEmbeddedService; +import org.apache.ftpserver.FtpServerFactory; +import org.apache.ftpserver.listener.ListenerFactory; +import org.apache.ftpserver.ssl.SslConfigurationFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.security.NoSuchAlgorithmException; + +public class FtpsEmbeddedService extends FtpEmbeddedService { + private static final Logger LOG = LoggerFactory.getLogger(FtpsEmbeddedService.class); + private static final File FTPSERVER_KEYSTORE = new File("./src/test/resources/server.jks"); + private static final String FTPSERVER_KEYSTORE_PASSWORD = "password"; + + private boolean useImplicit; + private String authValue; + private boolean clientAuth; + + public FtpsEmbeddedService(boolean useImplicit, String authValue, boolean clientAuth) { + super(); + + this.useImplicit = useImplicit; + this.authValue = authValue; + this.clientAuth = clientAuth; + } + + @Override + protected FtpServerFactory createFtpServerFactory() { + FtpServerFactory serverFactory = super.createFtpServerFactory(); + + ListenerFactory listenerFactory = new ListenerFactory(serverFactory.getListener(DEFAULT_LISTENER)); + listenerFactory.setPort(port); + listenerFactory.setImplicitSsl(useImplicit); + listenerFactory.setSslConfiguration(createSslConfiguration().createSslConfiguration()); + + serverFactory.addListener(DEFAULT_LISTENER, listenerFactory.createListener()); + + return serverFactory; + } + + protected SslConfigurationFactory createSslConfiguration() { + // comment in, if you have trouble with SSL + System.setProperty("javax.net.debug", "all"); + + SslConfigurationFactory sslConfigFactory = new SslConfigurationFactory(); + sslConfigFactory.setSslProtocol(authValue); + + sslConfigFactory.setKeystoreFile(FTPSERVER_KEYSTORE); + sslConfigFactory.setKeystoreType("PKCS12"); + sslConfigFactory.setKeystorePassword(FTPSERVER_KEYSTORE_PASSWORD); + sslConfigFactory.setKeyPassword(FTPSERVER_KEYSTORE_PASSWORD); + + sslConfigFactory.setClientAuthentication(authValue); + + if (clientAuth) { + sslConfigFactory.setTruststoreFile(FTPSERVER_KEYSTORE); + sslConfigFactory.setTruststoreType("PKCS12"); + sslConfigFactory.setTruststorePassword(FTPSERVER_KEYSTORE_PASSWORD); + } + + return sslConfigFactory; + } + + public static boolean hasRequiredAlgorithms() { + LOG.info("Checking if the system has the required algorithms for the test execution"); + try { + KeyManagerFactory.getInstance("SunX509"); + TrustManagerFactory.getInstance("SunX509"); + + return true; + } catch (NoSuchAlgorithmException e) { + String name = System.getProperty("os.name"); + String message = e.getMessage(); + + LOG.warn("SunX509 is not available on this platform [{}] Testing is skipped! Real cause: {}", name, message, e); + return false; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsImplicitEmbeddedService.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsImplicitEmbeddedService.java new file mode 100644 index 00000000000..bcd1674776b --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsImplicitEmbeddedService.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.component.file.remote.springboot.ftp.FtpEmbeddedService; +import org.apache.ftpserver.FtpServerFactory; +import org.apache.ftpserver.listener.ListenerFactory; +import org.apache.ftpserver.ssl.SslConfigurationFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.security.NoSuchAlgorithmException; + +public class FtpsImplicitEmbeddedService extends FtpEmbeddedService { + private static final Logger LOG = LoggerFactory.getLogger(FtpsImplicitEmbeddedService.class); + private static final File FTPSERVER_KEYSTORE = new File("./src/test/resources/server.jks"); + private static final String FTPSERVER_KEYSTORE_PASSWORD = "password"; + + private boolean useImplicit; + private String authValue; + private boolean clientAuth; + + public FtpsImplicitEmbeddedService(boolean useImplicit, String authValue, boolean clientAuth) { + super(); + + this.useImplicit = useImplicit; + this.authValue = authValue; + this.clientAuth = clientAuth; + } + + @Override + protected FtpServerFactory createFtpServerFactory() { + FtpServerFactory serverFactory = super.createFtpServerFactory(); + + ListenerFactory listenerFactory = new ListenerFactory(serverFactory.getListener(DEFAULT_LISTENER)); + listenerFactory.setPort(port); + listenerFactory.setImplicitSsl(useImplicit); + listenerFactory.setSslConfiguration(createSslConfiguration().createSslConfiguration()); + + serverFactory.addListener(DEFAULT_LISTENER, listenerFactory.createListener()); + + return serverFactory; + } + + protected SslConfigurationFactory createSslConfiguration() { + // comment in, if you have trouble with SSL + System.setProperty("javax.net.debug", "all"); + + SslConfigurationFactory sslConfigFactory = new SslConfigurationFactory(); + sslConfigFactory.setSslProtocol(authValue); + + sslConfigFactory.setKeystoreFile(FTPSERVER_KEYSTORE); + sslConfigFactory.setKeystoreType("PKCS12"); + sslConfigFactory.setKeystorePassword(FTPSERVER_KEYSTORE_PASSWORD); + sslConfigFactory.setKeyPassword(FTPSERVER_KEYSTORE_PASSWORD); + + sslConfigFactory.setClientAuthentication(authValue); + + if (clientAuth) { + sslConfigFactory.setTruststoreFile(FTPSERVER_KEYSTORE); + sslConfigFactory.setTruststoreType("PKCS12"); + sslConfigFactory.setTruststorePassword(FTPSERVER_KEYSTORE_PASSWORD); + } + + return sslConfigFactory; + } + + public static boolean hasRequiredAlgorithms() { + LOG.info("Checking if the system has the required algorithms for the test execution"); + try { + KeyManagerFactory.getInstance("SunX509"); + TrustManagerFactory.getInstance("SunX509"); + + return true; + } catch (NoSuchAlgorithmException e) { + String name = System.getProperty("os.name"); + String message = e.getMessage(); + + LOG.warn("SunX509 is not available on this platform [{}] Testing is skipped! Real cause: {}", name, message, e); + return false; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsTest.java new file mode 100644 index 00000000000..96cfb9df580 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftps/FtpsTest.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.ftps; + +import org.apache.camel.EndpointInject; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + FtpsTest.class, + FtpsTest.TestConfiguration.class + } +) +//based on FileToFtpsWithCustomTrustStorePropertiesIT +public class FtpsTest extends BaseFtpsClientAuth { + + @EndpointInject("mock:result") + private MockEndpoint result; + + private String getFtpUrl() { + return "ftps://admin@localhost:" + getPort() + + "/tmp1/camel?password=admin&initialDelay=2000&disableSecureDataChannelDefaults=true" + + "&securityProtocol=TLSv1.2&implicit=false"; + + } + + @Test + public void testFromFileToFtp() throws Exception { + + result.expectedMessageCount(2); + + assertMockEndpointsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("file:src/test/data?noop=true").log("Got ${file:name}").to(getFtpUrl()); + + from(getFtpUrl()).to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/BaseSftp.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/BaseSftp.java new file mode 100644 index 00000000000..884a8028eea --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/BaseSftp.java @@ -0,0 +1,36 @@ +package org.apache.camel.component.file.remote.springboot.sftp; + +import org.apache.camel.component.file.remote.springboot.AbstractBaseFtp; +import org.apache.camel.component.file.remote.springboot.ftp.FtpEmbeddedService; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.nio.file.Path; + + +public class BaseSftp extends AbstractBaseFtp { + + @RegisterExtension + static SftpEmbeddedService service = new SftpEmbeddedService(); + + @Override + protected int getPort() { + return service.getPort(); + } + + protected String getRootDir() { + return service.getFtpRootDir().toString(); + } + + protected Path ftpFile(String file) { + return service.getFtpRootDir().resolve(file); + } + + protected String getFtpUrl(String user, String password) { + StringBuilder url = new StringBuilder("ftp://"); + url.append(user == null ? "" : user + "@"); + url.append("localhost:" + service.getPort() + "/"); + url.append(password == null ? "" : "?password=" + password); + return url.toString(); + } + +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpConsumerLocalWorkDirectoryTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpConsumerLocalWorkDirectoryTest.java new file mode 100644 index 00000000000..23e7ba6f14a --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpConsumerLocalWorkDirectoryTest.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.sftp; + +import org.apache.camel.Endpoint; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.builder.NotifyBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.apache.camel.util.FileUtil; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + SftpConsumerLocalWorkDirectoryTest.class, + SftpConsumerLocalWorkDirectoryTest.TestConfiguration.class + } +) +//Based on SftpConsumerLocalWorkDirectoryIT +public class SftpConsumerLocalWorkDirectoryTest extends BaseSftp { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + protected String getFtpUrl() { + return "sftp://localhost:" + getPort() + "/" + getRootDir() + "/?password=admin" + + "&localWorkDirectory=" + ftpFile("lwd") + + "&noop=true"; + } + + @BeforeEach + public void setUp() throws Exception { + prepareFtpServer(); + } + + private void prepareFtpServer() throws Exception { + // prepares the FTP Server by creating a file on the server that we want + // to unit test that we can pool + Endpoint endpoint = context.getEndpoint(getFtpUrl()); + Exchange exchange = endpoint.createExchange(); + exchange.getIn().setBody("Hello World"); + exchange.getIn().setHeader(Exchange.FILE_NAME, "hello.txt"); + Producer producer = endpoint.createProducer(); + producer.start(); + producer.process(exchange); + producer.stop(); + } + + @Test + public void testLocalWorkDirectory() throws Exception { + NotifyBuilder notify = new NotifyBuilder(context).whenDone(1).create(); + + mock.expectedBodiesReceived("Hello World"); + mock.expectedMessageCount(1); + + context.getRouteController().startRoute("myRoute"); + + assertMockEndpointsSatisfied(); + + assertMockEndpointsSatisfied(); + assertTrue(notify.matchesWaitTime()); + + // and the out file should exists + assertFileExists(ftpFile("out/hello.txt"), "Hello World"); + + // now the lwd file should be deleted + assertFileNotExists(ftpFile("lwd/hello.txt")); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from(getFtpUrl()).routeId("myRoute").noAutoStartup().process(new Processor() { + public void process(Exchange exchange) { + File body = exchange.getIn().getBody(File.class); + assertNotNull(body); + assertTrue(body.exists(), "Local work file should exists"); + assertEquals(FileUtil.normalizePath(ftpFile("lwd/hello.txt").toString()), body.getPath()); + } + }).to("mock:result", "file:" + ftpFile("out")); + } + }; + } + } + +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpEmbeddedService.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpEmbeddedService.java new file mode 100644 index 00000000000..2f9d3c24f00 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpEmbeddedService.java @@ -0,0 +1,174 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.camel.component.file.remote.springboot.sftp; + +import org.apache.camel.test.infra.common.services.AbstractTestService; +import org.apache.camel.test.infra.ftp.common.FtpProperties; +import org.apache.camel.test.infra.ftp.services.FtpService; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; +import org.apache.sshd.common.keyprovider.FileKeyPairProvider; +import org.apache.sshd.common.session.helpers.AbstractSession; +import org.apache.sshd.common.signature.BuiltinSignatures; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.scp.server.ScpCommandFactory; +import org.apache.sshd.server.SshServer; +import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator; +import org.apache.sshd.sftp.server.SftpSubsystemFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.function.BiConsumer; + +public class SftpEmbeddedService extends AbstractTestService implements FtpService { + private static final Logger LOG = LoggerFactory.getLogger(SftpEmbeddedService.class); + private static final String KNOWN_HOSTS = "[localhost]:%d ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDdfIWeSV4o68dRrKS" + + "zFd/Bk51E65UTmmSrmW0O1ohtzi6HzsDPjXgCtlTt3FqTcfFfI92IlTr4JWqC9UK1QT1ZTeng0MkPQmv68hDANHbt5CpETZHjW5q4OOgWhV" + + "vj5IyOC2NZHtKlJBkdsMAa15ouOOJLzBvAvbqOR/yUROsEiQ=="; + + protected SshServer sshd; + protected final boolean rootDirMode; + protected int port; + + private Path rootDir; + private Path knownHosts; + + public SftpEmbeddedService() { + this(false); + } + + public SftpEmbeddedService(boolean rootDirMode) { + this.rootDirMode = rootDirMode; + } + + public void setUp() throws Exception { + rootDir = testDirectory().resolve("res/home"); + knownHosts = testDirectory().resolve("user-home/.ssh/known_hosts"); + Files.createDirectories(knownHosts.getParent()); + Files.write(knownHosts, buildKnownHosts()); + setUpServer(); + } + + private Path testDirectory() { + return Paths.get("target", "ftp", context.getRequiredTestClass().getSimpleName()); + } + + public void setUpServer() throws Exception { + sshd = SshServer.setUpDefaultServer(); + sshd.setPort(port); + sshd.setKeyPairProvider(new FileKeyPairProvider(Paths.get("src/test/resources/hostkey.pem"))); + sshd.setSubsystemFactories(Collections.singletonList(new SftpSubsystemFactory())); + sshd.setCommandFactory(new ScpCommandFactory()); + sshd.setPasswordAuthenticator((username, password, session) -> true); + sshd.setPublickeyAuthenticator(getPublickeyAuthenticator()); + + if (rootDirMode) { + sshd.setFileSystemFactory(new VirtualFileSystemFactory(testDirectory().resolve("res").toAbsolutePath())); + } + List<NamedFactory<Signature>> signatureFactories = sshd.getSignatureFactories(); + signatureFactories.clear(); + // use only one, quite strong signature algorithms for 3 kinds of keys - RSA, EC, EDDSA + signatureFactories.add(BuiltinSignatures.rsaSHA512); + signatureFactories.add(BuiltinSignatures.nistp521); + signatureFactories.add(BuiltinSignatures.ed25519); + sshd.setSignatureFactories(signatureFactories); + sshd.start(); + + port = ((InetSocketAddress) sshd.getBoundAddresses().iterator().next()).getPort(); + } + + protected PublickeyAuthenticator getPublickeyAuthenticator() { + return (username, key, session) -> true; + } + + public void tearDown() { + tearDownServer(); + } + + public void tearDownServer() { + try { + // stop asap as we may hang forever + if (sshd != null) { + sshd.stop(true); + } + } catch (Exception e) { + // ignore while shutting down as we could be polling during + // shutdown + // and get errors when the ftp server is stopping. This is only + // an issue + // since we host the ftp server embedded in the same jvm for + // unit testing + LOG.trace("Exception while shutting down: {}", e.getMessage(), e); + } finally { + sshd = null; + } + } + + // disconnect all existing SSH sessions to test reconnect functionality + public void disconnectAllSessions() throws IOException { + List<AbstractSession> sessions = sshd.getActiveSessions(); + for (AbstractSession session : sessions) { + session.disconnect(4, "dummy"); + } + } + + public byte[] buildKnownHosts() { + return String.format(KNOWN_HOSTS, port).getBytes(); + } + + public String getKnownHostsFile() { + return knownHosts.toString(); + } + + public Path getFtpRootDir() { + return rootDir; + } + + @Override + protected void registerProperties(BiConsumer<String, String> store) { + store.accept(FtpProperties.SERVER_HOST, "localhost"); + store.accept(FtpProperties.SERVER_PORT, String.valueOf(port)); + store.accept(FtpProperties.ROOT_DIR, rootDir.toString()); + } + + public int getPort() { + return port; + } + + public static boolean hasRequiredAlgorithms() { + try { + FileKeyPairProvider provider = new FileKeyPairProvider(Paths.get("src/test/resources/hostkey.pem")); + + provider.loadKeys(null); + return true; + } catch (Exception e) { + String name = System.getProperty("os.name"); + String message = e.getMessage(); + + LOG.warn("SunX509 is not available on this platform [{}] Testing is skipped! Real cause: {}", name, message, e); + return false; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpKeyExchangeProtocolsTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpKeyExchangeProtocolsTest.java new file mode 100644 index 00000000000..b52c5588f4c --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpKeyExchangeProtocolsTest.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.sftp; + +import com.jcraft.jsch.JSch; +import org.apache.camel.CamelExecutionException; +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.component.file.remote.springboot.ftp.FtpAnonymousTest; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Isolated; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +import java.util.ArrayList; +import java.util.List; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + SftpKeyExchangeProtocolsTest.class, + SftpKeyExchangeProtocolsTest.TestConfiguration.class + } +) +//Based on SftpKeyExchangeProtocolsIT +@Isolated +public class SftpKeyExchangeProtocolsTest extends BaseSftp { + + @EndpointInject("mock:result") + private MockEndpoint result; + + private static String kex; + + @BeforeAll + public static void beforeTests() { + kex = JSch.getConfig("kex"); + } + + @AfterAll + public static void afterTests() { + // restore after test + JSch.setConfig("kex", kex); + } + + protected String getFtpUrl() { + return "sftp://admin@localhost:" + getPort() + "/" + getRootDir() + "/keyExchangeProtocols/?password=admin" + + "&noop=true"; + } + + @Test + public void testNonExistingKey() { + Throwable exception = Assertions.assertThrows(CamelExecutionException.class, + () -> template + .sendBodyAndHeader("sftp://admin@localhost:" + getPort() + "/" + getRootDir() + "}/keyExchangeProtocols?" + + "password=admin" + + "&keyExchangeProtocols=nonExistingKeyExchange", + "a", Exchange.FILE_NAME, + "a.txt")); + + final List<String> errorMessages = new ArrayList<>(); + while (exception.getCause() != null) { + errorMessages.add(exception.getCause().getMessage()); + exception = exception.getCause(); + } + + MatcherAssert.assertThat(errorMessages, Matchers.hasItem("Algorithm negotiation fail")); + } + + @Test + public void testSingleKey() throws Exception { + result.expectedMessageCount(1); + + template.sendBodyAndHeader("sftp://admin@localhost:" + getPort() + "/" + getRootDir() + "/keyExchangeProtocols" + + "?password=admin" + + "&keyExchangeProtocols=ecdh-sha2-nistp384", + "a", Exchange.FILE_NAME, + "a.txt"); + + result.assertIsSatisfied(); + } + + @Test + public void testMultipleKey() throws Exception { + result.expectedMessageCount(1); + + template.sendBodyAndHeader("sftp://admin@localhost:" + getPort() + "/" + getRootDir() + "/keyExchangeProtocols" + + "?password=admin" + + "&keyExchangeProtocols=ecdh-sha2-nistp384,diffie-hellman-group-exchange-sha256,nonExistingKey", + "a", Exchange.FILE_NAME, + "a.txt"); + + result.assertIsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from(getFtpUrl()).routeId("myRoute").to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpSetOperationsTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpSetOperationsTest.java new file mode 100644 index 00000000000..52cb86a5449 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpSetOperationsTest.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.sftp; + +import org.apache.camel.Exchange; +import org.apache.camel.component.file.remote.SftpEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIf; +import org.springframework.boot.test.context.SpringBootTest; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + SftpSetOperationsTest.class + } +) +//Based on SftpSetOperationsTest +public class SftpSetOperationsTest extends BaseSftp { + + @Test + public void testSftpSetOperations() { + String preferredAuthentications = "password,publickey"; + String uri = "sftp://localhost:" + getPort() + "/" + getRootDir() + + "?username=admin&password=admin&ciphers=aes256-ctr" + "&preferredAuthentications=password,publickey"; + template.sendBodyAndHeader(uri, "Hello World", Exchange.FILE_NAME, "hello.txt"); + + // test setting the cipher doesn't interfere with message payload + File file = ftpFile("hello.txt").toFile(); + assertTrue(file.exists(), "File should exist: " + file); + assertEquals("Hello World", context.getTypeConverter().convertTo(String.class, file)); + + // did we actually set the preferredAuthentications + SftpEndpoint endpoint = context.getEndpoint(uri, SftpEndpoint.class); + assertEquals(preferredAuthentications, endpoint.getConfiguration().getPreferredAuthentications()); + } +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpSimpleProduceThroughProxyTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpSimpleProduceThroughProxyTest.java new file mode 100644 index 00000000000..1bb356978a9 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpSimpleProduceThroughProxyTest.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.sftp; + +import com.jcraft.jsch.ProxyHTTP; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.littleshoot.proxy.HttpProxyServer; +import org.littleshoot.proxy.ProxyAuthenticator; +import org.littleshoot.proxy.impl.DefaultHttpProxyServer; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DirtiesContext +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + SftpSimpleProduceThroughProxyTest.class, + SftpSimpleProduceThroughProxyTest.TestConfiguration.class + } +) +//Based on SftpSimpleProduceThroughProxyIT +public class SftpSimpleProduceThroughProxyTest extends BaseSftp { + + private static HttpProxyServer proxyServer; + private static final int proxyPort = AvailablePortFinder.getNextAvailable(); + + @BeforeAll + public static void setupProxy() { + proxyServer = DefaultHttpProxyServer.bootstrap() + .withPort(proxyPort) + .withProxyAuthenticator(new ProxyAuthenticator() { + @Override + public boolean authenticate(String userName, String password) { + return "user".equals(userName) && "password".equals(password); + } + + @Override + public String getRealm() { + return "myrealm"; + } + }).start(); + } + + @AfterAll + public static void cleanup() { + proxyServer.stop(); + } + + @Test + public void testSftpSimpleProduceThroughProxy() { + template.sendBodyAndHeader( + "sftp://localhost:" + getPort() + "/" + getRootDir() + + "?username=admin&password=admin&proxy=#proxy", + "Hello World", Exchange.FILE_NAME, + "hello.txt"); + + File file = ftpFile("hello.txt").toFile(); + assertTrue(file.exists(), "File should exist: " + file); + assertEquals("Hello World", context.getTypeConverter().convertTo(String.class, file)); + } + + @Test + public void testSftpSimpleSubPathProduceThroughProxy() { + template.sendBodyAndHeader( + "sftp://localhost:" + getPort() + "/" + getRootDir() + + "/mysub?username=admin&password=admin&proxy=#proxy", + "Bye World", Exchange.FILE_NAME, + "bye.txt"); + + File file = ftpFile("mysub/bye.txt").toFile(); + assertTrue(file.exists(), "File should exist: " + file); + assertEquals("Bye World", context.getTypeConverter().convertTo(String.class, file)); + } + + @Test + public void testSftpSimpleTwoSubPathProduceThroughProxy() { + template.sendBodyAndHeader("sftp://localhost:" + getPort() + "/" + getRootDir() + + "/mysub/myother?username=admin&password=admin&proxy=#proxy", + "Farewell World", + Exchange.FILE_NAME, "farewell.txt"); + + File file = ftpFile("mysub/myother/farewell.txt").toFile(); + assertTrue(file.exists(), "File should exist: " + file); + assertEquals("Farewell World", context.getTypeConverter().convertTo(String.class, file)); + } + + + + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("direct:one").to("sftp://localhost:" + getPort() + "/" + getRootDir() + + "?username=admin&password=admin&proxy=#proxy"); + } + }; + } + + @Bean(value = "proxy") + public ProxyHTTP createProxy() { + + final ProxyHTTP proxyHTTP = new ProxyHTTP("localhost", proxyPort); + proxyHTTP.setUserPasswd("user", "password"); + return proxyHTTP; + } + } + +} diff --git a/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpUseListFalseTest.java b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpUseListFalseTest.java new file mode 100644 index 00000000000..e754d0cc096 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/sftp/SftpUseListFalseTest.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.file.remote.springboot.sftp; + +import org.apache.camel.EndpointInject; +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.file.remote.springboot.ftp.BaseFtp; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.apache.camel.util.FileUtil; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledIf; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.File; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@CamelSpringBootTest +@SpringBootTest( + classes = { + CamelAutoConfiguration.class, + SftpUseListFalseTest.class, + SftpUseListFalseTest.TestConfiguration.class + } +) +//Based on SftpUseListFalseIT +public class SftpUseListFalseTest extends BaseSftp { + + @EndpointInject("mock:result") + private MockEndpoint mock; + + @Test + public void testSftpUseListFalse() throws Exception { + String expected = "Hello World"; + + // create file using regular file + template.sendBodyAndHeader("file://" + service.getFtpRootDir(), expected, Exchange.FILE_NAME, "report.txt"); + + mock.expectedMessageCount(1); + mock.expectedHeaderReceived(Exchange.FILE_NAME, "report.txt"); + mock.expectedBodiesReceived(expected); + + context.getRouteController().startRoute("foo"); + + assertMockEndpointsSatisfied(); + } + + // ************************************* + // Config + // ************************************* + + @Configuration + public class TestConfiguration extends BaseFtp.TestConfiguration { + @Bean + public RouteBuilder routeBuilder() { + + return new RouteBuilder() { + @Override + public void configure() { + from("sftp://localhost:" + getPort() + "/" + getRootDir() + + "?username=admin&password=admin&delay=10000&disconnect=true&stepwise=false&useList=false&fileName=report.txt&delete=true") + .routeId("foo").noAutoStartup() + .to("mock:result"); + } + }; + } + } +} diff --git a/components-starter/camel-ftp-starter/src/test/resources/hostkey.pem b/components-starter/camel-ftp-starter/src/test/resources/hostkey.pem new file mode 100644 index 00000000000..9b215f45bb4 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/resources/hostkey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDdfIWeSV4o68dRrKSzFd/Bk51E65UTmmSrmW0O1ohtzi6HzsDP +jXgCtlTt3FqTcfFfI92IlTr4JWqC9UK1QT1ZTeng0MkPQmv68hDANHbt5CpETZHj +W5q4OOgWhVvj5IyOC2NZHtKlJBkdsMAa15ouOOJLzBvAvbqOR/yUROsEiQIDAQAB +AoGBANG3JDW6NoP8rF/zXoeLgLCj+tfVUPSczhGFVrQkAk4mWfyRkhN0WlwHFOec +K89MpkV1ij/XPVzU4MNbQ2yod1KiDylzvweYv+EaEhASCmYNs6LS03punml42SL9 +97tOmWfVJXxlQoLiY6jHPU97vTc65k8gL+gmmrpchsW0aqmZAkEA/c8zfmKvY37T +cxcLLwzwsqqH7g2KZGTf9aRmx2ebdW+QKviJJhbdluDgl1TNNFj5vCLznFDRHiqJ +wq0wkZ39cwJBAN9l5v3kdXj21UrurNPdlV0n2GZBt2vblooQC37XHF97r2zM7Ou+ +Lg6MyfJClyguhWL9dxnGbf3btQ0l3KDstxMCQCRaiEqjAfIjWVATzeNIXDWLHXso +b1kf5cA+cwY+vdKdTy4IeUR+Y/DXdvPWDqpf0C11aCVMohdLCn5a5ikFUycCQDhV +K/BuAallJNfmY7JxN87r00fF3ojWMJnT/fIYMFFrkQrwifXQWTDWE76BSDibsosJ +u1TGksnm8zrDh2UVC/0CQFrHTiSl/3DHvWAbOJawGKg46cnlDcAhSyV8Frs8/dlP +7YGG3eqkw++lsghqmFO6mRUTKsBmiiB2wgLGhL5pyYY= +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/components-starter/camel-ftp-starter/src/test/resources/readme.txt b/components-starter/camel-ftp-starter/src/test/resources/readme.txt new file mode 100644 index 00000000000..2af7c47bcf7 --- /dev/null +++ b/components-starter/camel-ftp-starter/src/test/resources/readme.txt @@ -0,0 +1 @@ +server.jks is copied from camel-quarkus/integration-tests/ftp/src/test/resources/server.jks \ No newline at end of file diff --git a/components-starter/camel-ftp-starter/src/test/resources/server.jks b/components-starter/camel-ftp-starter/src/test/resources/server.jks new file mode 100644 index 00000000000..80637220890 Binary files /dev/null and b/components-starter/camel-ftp-starter/src/test/resources/server.jks differ