Refactor infinispan test (#81)

diff --git a/infinispan/README.adoc b/infinispan/README.adoc
index 776b52f..25021b5 100644
--- a/infinispan/README.adoc
+++ b/infinispan/README.adoc
@@ -5,7 +5,7 @@
 This example demonstrates how you can use Camel-Infinispan Starter component. The example is really simple: put a key/value pair in a remote cache and get the same key.
 This example starts an Infinispan server with Infinispan Docker Image, so it can run OOTB.
 
-=== Build
+=== Build and test
 
 You can build this example using:
 
@@ -13,6 +13,10 @@
 
 === Run
 
+Start Infinispan container in a separate terminal:
+
+    $ docker run --rm -e USER=admin -e PASS=password -p 11222:11222 -v $PWD/src/test/resources:/user-config/ quay.io/infinispan/server:13.0.5.Final-1 -c /user-config/infinispan.xml
+
 You can run this example using:
 
     $ mvn spring-boot:run
diff --git a/infinispan/pom.xml b/infinispan/pom.xml
index c3f61e3..ee6a717 100644
--- a/infinispan/pom.xml
+++ b/infinispan/pom.xml
@@ -84,6 +84,11 @@
             <version>${camel-version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-test-spring-junit5</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/Application.java b/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/Application.java
index be1a151..19a6993 100644
--- a/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/Application.java
+++ b/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/Application.java
@@ -16,46 +16,29 @@
  */
 package org.apache.camel.example.springboot.infinispan;
 
-import java.util.Properties;
-import java.util.function.Consumer;
-
-import com.github.dockerjava.api.command.CreateContainerCmd;
-import com.github.dockerjava.api.model.ExposedPort;
-import com.github.dockerjava.api.model.PortBinding;
-import com.github.dockerjava.api.model.Ports;
-
 import org.apache.camel.component.infinispan.remote.InfinispanRemoteComponent;
 import org.apache.camel.component.infinispan.remote.InfinispanRemoteConfiguration;
+
 import org.infinispan.client.hotrod.RemoteCacheManager;
 import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.testcontainers.containers.BindMode;
-import org.testcontainers.containers.GenericContainer;
-import org.testcontainers.containers.output.OutputFrame;
-import org.testcontainers.containers.output.Slf4jLogConsumer;
-import org.testcontainers.containers.wait.strategy.Wait;
 import org.testcontainers.shaded.org.apache.commons.lang.SystemUtils;
 
+import java.util.Properties;
+
 
 // CHECKSTYLE:OFF
 @SpringBootApplication
 public class Application {
-    
-    
+
     private static final Logger LOG = LoggerFactory.getLogger(Application.class);
-    
-    private static final String CONTAINER_IMAGE = "quay.io/infinispan/server:13.0.5.Final-1";
-    private static final String CONTAINER_NAME = "infinispan";
-    private static final String DEFAULT_USERNAME = "admin";
-    private static final String DEFAULT_PASSWORD = "password";
-    private static final int CONTAINER_PORT = 11222;
-    
-    private GenericContainer<?> container;
+
     /**
      * Main method to start the application.
      */
@@ -63,32 +46,19 @@
         SpringApplication.run(Application.class, args);
     }
     
-    
-    
     @Configuration
+    @ConfigurationProperties(prefix = "infinispan")
     public class InfinispanConfiguration {
 
-        private void initContainer() {
-            LOG.info("start infinispan docker container");
-            Consumer<CreateContainerCmd> cmd = e -> {
-                e.getHostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(CONTAINER_PORT),
-                                                   new ExposedPort(CONTAINER_PORT)));
+        private String host;
+        
+        private Integer port;
 
-            };
-            final Logger containerLog = LoggerFactory.getLogger("container." + CONTAINER_NAME);
-            final Consumer<OutputFrame> logConsumer = new Slf4jLogConsumer(containerLog);
+        private String username;
 
-            container = new GenericContainer<>(CONTAINER_IMAGE).withNetworkAliases(CONTAINER_NAME)
-                .withEnv("USER", DEFAULT_USERNAME).withEnv("PASS", DEFAULT_PASSWORD)
-                .withLogConsumer(logConsumer)
-                .withClasspathResourceMapping("infinispan.xml", "/user-config/infinispan.xml",
-                                              BindMode.READ_ONLY)
-                .withCommand("-c", "/user-config/infinispan.xml").withExposedPorts(CONTAINER_PORT)
-                .withCreateContainerCmdModifier(cmd).waitingFor(Wait.forListeningPort())
-                .waitingFor(Wait.forLogMessage(".*Infinispan.*Server.*started.*", 1));
-            container.start();
+        private String password;
 
-        }
+        private String serverName;
 
         protected ConfigurationBuilder getConfiguration() {
             ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
@@ -96,11 +66,11 @@
             clientBuilder.forceReturnValues(true);
 
 
-            clientBuilder.addServer().host("localhost").port(CONTAINER_PORT);
+            clientBuilder.addServer().host(getHost()).port(getPort());
 
             // add security info
-            clientBuilder.security().authentication().username(DEFAULT_USERNAME).password(DEFAULT_PASSWORD)
-                .serverName("infinispan").saslMechanism("DIGEST-MD5").realm("default");
+            clientBuilder.security().authentication().username(getUsername()).password(getPassword())
+                .serverName(getServerName()).saslMechanism("DIGEST-MD5").realm("default");
             if (SystemUtils.IS_OS_MAC) {
                 Properties properties = new Properties();
                 properties.put("infinispan.client.hotrod.client_intelligence", "BASIC");
@@ -112,11 +82,10 @@
 
         @Bean(name = "infinispanRemoteComponent")
         public InfinispanRemoteComponent infinispanRemoteComponent() {
-            initContainer();
             InfinispanRemoteConfiguration infinispanRemoteConfiguration = new InfinispanRemoteConfiguration();
-            infinispanRemoteConfiguration.setHosts("localhost" + ":" + CONTAINER_PORT);
-            infinispanRemoteConfiguration.setUsername(DEFAULT_USERNAME);
-            infinispanRemoteConfiguration.setPassword(DEFAULT_PASSWORD);
+            infinispanRemoteConfiguration.setHosts(getHost() + ":" + getPort());
+            infinispanRemoteConfiguration.setUsername(getUsername());
+            infinispanRemoteConfiguration.setPassword(getPassword());
 
             RemoteCacheManager cacheContainer = new RemoteCacheManager(getConfiguration().build());
             infinispanRemoteConfiguration.setCacheContainer(cacheContainer);
@@ -125,6 +94,46 @@
             component.setConfiguration(infinispanRemoteConfiguration);
             return component;
         }
+
+        public String getHost() {
+            return host;
+        }
+
+        public void setHost(final String host) {
+            this.host = host;
+        }
+
+        public Integer getPort() {
+            return port;
+        }
+
+        public void setPort(final Integer port) {
+            this.port = port;
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public void setUsername(final String username) {
+            this.username = username;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+
+        public void setPassword(final String password) {
+            this.password = password;
+        }
+
+        public String getServerName() {
+            return serverName;
+        }
+
+        public void setServerName(final String serverName) {
+            this.serverName = serverName;
+        }
     }
 
 }
diff --git a/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/CamelInfinispanRoute.java b/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/CamelInfinispanRoute.java
index b4c82c5..04cb79b 100644
--- a/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/CamelInfinispanRoute.java
+++ b/infinispan/src/main/java/org/apache/camel/example/springboot/infinispan/CamelInfinispanRoute.java
@@ -19,6 +19,7 @@
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.infinispan.InfinispanConstants;
 import org.apache.camel.component.infinispan.InfinispanOperation;
+
 import org.springframework.stereotype.Component;
 
 /**
@@ -29,7 +30,11 @@
 
     @Override
     public void configure() throws Exception {
+
         from("timer://foo?period=10000&repeatCount=1")
+        .to("direct:put-cache");
+
+        from("direct:put-cache")
         .setHeader(InfinispanConstants.OPERATION).constant(InfinispanOperation.PUT)
         .setHeader(InfinispanConstants.KEY).constant("1")
         .setHeader(InfinispanConstants.VALUE).constant("test")
diff --git a/infinispan/src/main/resources/application.properties b/infinispan/src/main/resources/application.properties
index e7198c6..b5bdda2 100644
--- a/infinispan/src/main/resources/application.properties
+++ b/infinispan/src/main/resources/application.properties
@@ -17,5 +17,9 @@
 
 camel.springboot.name=Infinispan
 camel.springboot.main-run-controller=true
-camel.component.infinispan.hosts=localhost:11222
+infinispan.host=localhost
+infinispan.port=11222
+infinispan.username=admin
+infinispan.password=password
+infinispan.server-name=infinispan
 
diff --git a/infinispan/src/test/java/org/apache/camel/example/springboot/infinispan/ApplicationTest.java b/infinispan/src/test/java/org/apache/camel/example/springboot/infinispan/ApplicationTest.java
new file mode 100644
index 0000000..321f129
--- /dev/null
+++ b/infinispan/src/test/java/org/apache/camel/example/springboot/infinispan/ApplicationTest.java
@@ -0,0 +1,88 @@
+package org.apache.camel.example.springboot.infinispan;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.output.OutputFrame;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+import org.testcontainers.containers.wait.strategy.Wait;
+
+import com.github.dockerjava.api.command.CreateContainerCmd;
+import com.github.dockerjava.api.model.ExposedPort;
+import com.github.dockerjava.api.model.PortBinding;
+import com.github.dockerjava.api.model.Ports;
+
+import java.util.function.Consumer;
+
+@CamelSpringBootTest
+@SpringBootTest(classes = Application.class)
+final class ApplicationTest {
+
+	private static final Logger LOG = LoggerFactory.getLogger(ApplicationTest.class);
+
+	private static final String CONTAINER_IMAGE = "quay.io/infinispan/server:13.0.5.Final-1";
+
+	private static GenericContainer<?> container;
+
+	@Autowired
+	private ProducerTemplate producerTemplate;
+
+	@Autowired
+	private CamelContext camelContext;
+
+	private static String host = "localhost";
+
+	private static Integer port = 11222;
+
+	private static String name = "infinispan";
+
+	private static String username = "admin";
+
+	private static String password = "password";
+
+	private ApplicationTest() {
+	}
+
+	@BeforeAll
+	public static void initContainer() {
+		LOG.info("start infinispan docker container");
+		final Consumer<CreateContainerCmd> cmd = e -> {
+			e.getHostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(port),
+					new ExposedPort(port)));
+
+		};
+		final Logger containerLog = LoggerFactory.getLogger("container." + name);
+		final Consumer<OutputFrame> logConsumer = new Slf4jLogConsumer(containerLog);
+
+		container = new GenericContainer<>(CONTAINER_IMAGE).withNetworkAliases(name)
+				.withEnv("USER", username).withEnv("PASS", password)
+				.withLogConsumer(logConsumer)
+				.withClasspathResourceMapping("infinispan.xml", "/user-config/infinispan.xml",
+						BindMode.READ_ONLY)
+				.withCommand("-c", "/user-config/infinispan.xml").withExposedPorts(port)
+				.withCreateContainerCmdModifier(cmd).waitingFor(Wait.forListeningPort())
+				.waitingFor(Wait.forLogMessage(".*Infinispan.*Server.*started.*", 1));
+		container.start();
+	}
+
+	@Test
+	public void shouldPopulateCache() throws Exception {
+		final MockEndpoint mock = camelContext.getEndpoint("mock:result", MockEndpoint.class);
+		mock.expectedMessageCount(1);
+		producerTemplate.sendBody("direct:test", null);
+		mock.assertIsSatisfied();
+		Assertions.assertEquals("test", mock.getExchanges().get(0).getIn().getBody(String.class));
+	}
+}
diff --git a/infinispan/src/test/java/org/apache/camel/example/springboot/infinispan/TestRoute.java b/infinispan/src/test/java/org/apache/camel/example/springboot/infinispan/TestRoute.java
new file mode 100644
index 0000000..7b55cbc
--- /dev/null
+++ b/infinispan/src/test/java/org/apache/camel/example/springboot/infinispan/TestRoute.java
@@ -0,0 +1,15 @@
+package org.apache.camel.example.springboot.infinispan;
+
+import org.apache.camel.builder.RouteBuilder;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestRoute extends RouteBuilder {
+	@Override
+	public void configure() throws Exception {
+		from("direct:test")
+				.to("direct:put-cache")
+				.to("mock:result");
+	}
+}
diff --git a/infinispan/src/main/resources/infinispan.xml b/infinispan/src/test/resources/infinispan.xml
similarity index 100%
rename from infinispan/src/main/resources/infinispan.xml
rename to infinispan/src/test/resources/infinispan.xml