Hi,
thank you very much for your feedback. Type test-jar helped to include the test
classes. I tried to replicate some test fro camel-spring-boot but I think I
miss some important part to the puzzle. This is my test class derived from
https://github.com/apache/camel-spring-boot/blob/main/components-starter/camel-ftp-starter/src/test/java/org/apache/camel/component/file/remote/springboot/ftp/FromFtpToBinaryFileTest.java
I have just included the parent classes to make it compact.
@DirtiesContext
@CamelSpringBootTest
@SpringBootTest(classes = {CamelAutoConfiguration.class, Process1E2ETest.class,
Process1E2ETest.TestConfiguration.class})
// Baaed on FromFtpToBinaryFileIT
public class Process1E2ETest {
@RegisterExtension
static FtpEmbeddedService service = new FtpEmbeddedService();
@Autowired
protected CamelContext context;
@Autowired
protected ProducerTemplate template;
@EndpointInject("mock:result")
private MockEndpoint resultEndpoint;
protected static void assertFileExists(String filename) {
File file = new File(filename);
assertTrue(file.exists(), "File " + filename + " should exist");
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 {
assertTrue(Files.exists(file, new LinkOption[0]), "File " + file + "
should exist");
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");
}
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;
}
// 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(new
File("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();
}
protected int getPort() {
System.out.println("Port:" + service.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();
}
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, new
SimpleExpression(fileName));
}
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);
}
protected String fileUri(String query) {
Path var10000 = this.testDirectory();
return "file:" + var10000 + (query.startsWith("?") ? "" : "/") + query;
}
// *************************************
// Config
// *************************************
@Configuration
public class TestConfiguration {
@Bean
public RouteBuilder routeBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
String fileUrl = fileUri("?noop=true&fileExist=Override");
// <--- BREAKPOIINT
from(getFtpUrl()).setHeader(Exchange.FILE_NAME,
constant("deleteme.jpg"))
.to(fileUrl,
"mock:result");
}
};
}
}
}
The trouble is - if put breakpoint in the method configure() within the
ReouteBuilder bean, the FTP is not yet initialized and service.getPort() is 0
How can I force FTP to be initialized before the RouteBuilder bean is loaded?
Regards
Jiři
________________________________
Od: Federico Mariani <[email protected]>
Odesláno: Úterý, 3. červen 2025 13:31
Komu: [email protected] <[email protected]>
Předmět: Re: Camel Test Infrastructure FTP
Hi,
Did you import in your pom.xml *camel-test-infra-ftp *with type* test-jar? *The
test jar contains both main and test classes
https://github.com/apache/camel-spring-boot/blob/main/components-starter/camel-ftp-starter/pom.xml#L54-L60
Moreover, in *camel-spring-boot* repository there are some tests that use
*camel-test-infra-ftp*
https://github.com/apache/camel-spring-boot/tree/main/components-starter/camel-ftp-starter/src/test.
Maybe you can find something interesting there.
Regards,
Federico
Il giorno mar 3 giu 2025 alle ore 12:24 <[email protected]> ha scritto:
> Hello,
>
> I would like to use Camel Infrastructure for my Spring Boot Camel
> End-to-End tests.
>
> II have spent quite some time investigating how it works. Unfortunately
> the documentation is very limited and I was not able to find any examples
> either.
>
> I started with a very simple scenario -> one route from FTP to file. After
> couple of hours I was able to come to following test that works.
>
> @SpringBootTest
> @Import({ FtpServiceTestConfig.class, Process1TestRoutes.class})
> @TestPropertySource("classpath:application-e2e.yaml")
> @TestInstance(TestInstance.Lifecycle.PER_CLASS)
> @ActiveProfiles("e2e")
> public class Process1E2ETest {
> @Autowired
> CamelContext camelContext;
>
> @RegisterExtension
> static FtpService ftpService =
> FtpServiceFactory.createEmbeddedService();
>
> @Test
> void shouldTransferFileFromInputToOutput() throws Exception {
>
> // Create the route after FTP server is initialized
> camelContext.addRoutes(new RouteBuilder() {
> @Override
> public void configure() {
> from("ftp://" + ftpService.hostname() + ":" +
> ftpService.port() + "/" + ftpService.directoryName()
> + "?username=" + ftpService.username()
> + "&password=" + ftpService.password()
> + "&delete=true&delay=1000")
> .to("file:target/out")
> .log("Received: ${file:name}");
> }
> });
>
> // Ensure target directory exists
> Files.createDirectories(Path.of("target/out"));
>
> // Create input file in the correct FTP directory
> Path ftpRootDir = ftpService.getFtpRootDir();
> Path ftpInputDir = ftpRootDir.resolve(ftpService.directoryName());
> Files.createDirectories(ftpInputDir);
> Path inputFile = ftpInputDir.resolve("test.txt");
> Files.writeString(inputFile, "Hello from test",
> StandardOpenOption.CREATE);
>
> System.out.println("Created file at: " +
> inputFile.toAbsolutePath());
>
> // Wait longer for Camel route to process the file
> Thread.sleep(5000);
>
> Path outputFile = Path.of("target/out/test.txt");
> assertTrue(Files.exists(outputFile), "Output file should exist at
> " + outputFile.toAbsolutePath());
> String content = Files.readString(outputFile);
> assertEquals("Hello from test", content);
> }
> }
>
> I had to copy FtpService and FtpServiceFactory with their dependencies
> from Camel Github Repository (
> https://github.com/apache/camel/tree/camel-4.12.x/test-infra/camel-test-infra-ftp/src/test/java/org/apache/camel/test/infra/ftp/services)
> as they are not included in maven dependency jar. I am using Apache Camel
> 4.12.0
>
> I do not like the solution much as it creates the route only inside the
> test that is kind of ugly. If I try to create it in @TestConfiguration or
> even @BeforeAll the troube is that the FTP server is not initalized yet and
> ftpService.port() is 0 at that time.
>
> Can anyone explain me how it is meant to be used and/or provide some
> example?
>
> Regards
>
> Jiří
>