Getting Started with Red Hat build of Apache Camel for Quarkus Red Hat build of Apache Camel 4.8 Getting Started with Red Hat build of Apache Camel for Quarkus

Commands:
cd <directory_name>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.group-id>com.redhat.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.version> <!-- The latest 3.15.x version from https://maven.repository.redhat.com/ga/com/redhat/quarkus/platform/quarkus-bom --> </quarkus.platform.version> <dependency> <groupId>USD{quarkus.platform.group-id}</groupId> <artifactId>USD{quarkus.platform.artifact-id}</artifactId> <version>USD{quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>USD{quarkus.platform.group-id}</groupId> <artifactId>quarkus-camel-bom</artifactId> <version>USD{quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency>
package org.acme.rest.json; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.model.rest.RestBindingMode; /** * Camel route definitions. */ public class Routes extends RouteBuilder { private final Set<Fruit> fruits = Collections.synchronizedSet(new LinkedHashSet<>()); private final Set<Legume> legumes = Collections.synchronizedSet(new LinkedHashSet<>()); public Routes() { /* Let's add some initial fruits */ this.fruits.add(new Fruit("Apple", "Winter fruit")); this.fruits.add(new Fruit("Pineapple", "Tropical fruit")); /* Let's add some initial legumes */ this.legumes.add(new Legume("Carrot", "Root vegetable, usually orange")); this.legumes.add(new Legume("Zucchini", "Summer squash")); } @Override public void configure() throws Exception { restConfiguration().bindingMode(RestBindingMode.json); rest("/fruits") .get() .to("direct:getFruits") .post() .type(Fruit.class) .to("direct:addFruit"); rest("/legumes") .get() .to("direct:getLegumes"); from("direct:getFruits") .setBody().constant(fruits); from("direct:addFruit") .process().body(Fruit.class, fruits::add) .setBody().constant(fruits); from("direct:getLegumes") .setBody().constant(legumes); } }
mvn clean compile quarkus:dev
package org.acme; import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; import org.hamcrest.Matchers; @QuarkusTest public class RoutesTest { @Test public void testFruitsEndpoint() { /* Assert the initial fruit is there */ given() .when().get("/fruits") .then() .statusCode(200) .body( "USD.size()", Matchers.is(1), "name", Matchers.contains("Orange")); /* Add a new fruit */ given() .body("{\"name\": \"Pear\"}") .header("Content-Type", "application/json") .when() .post("/fruits") .then() .statusCode(200); /* Assert that pear was added */ given() .when().get("/fruits") .then() .statusCode(200) .body( "USD.size()", Matchers.is(2), "name", Matchers.contains("Orange", "Pear")); } }
mvn clean test
package org.acme; import io.quarkus.test.junit.NativeImageTest; @NativeImageTest public class NativeRoutesIT extends RoutesTest { // Execute the same tests but in native mode. }
mvn clean verify -Pnative
mvn clean package ls -lh target/quarkus-app -rw-r--r--. 1 user user 238K Oct 11 18:55 quarkus-run.jar
java -jar target/quarkus-app/quarkus-run.jar [io.quarkus] (main) Quarkus started in 1.163s. Listening on: http://[::]:8080
mvn clean package -Pnative ls -lh target -rwxr-xr-x. 1 user user 46M Oct 11 18:57 code-with-quarkus-1.0.0-SNAPSHOT-runner
./target/*-runner [io.quarkus] (main) Quarkus started in 0.013s. Listening on: http://[::]:8080
ps -o rss,command -p USD(pgrep code-with) RSS COMMAND 65852 ./target/code-with-quarkus-1.0.0-SNAPSHOT-runner
import io.quarkus.test.junit.QuarkusTest; import org.junit.jupiter.api.Test; @QuarkusTest class MyTest { @Test public void test() { // Use any suitable code that sends test data to the route and then assert outcomes } }
import io.quarkus.test.junit.QuarkusIntegrationTest; @QuarkusIntegrationTest class MyIT extends MyTest { }
import java.util.Map; import java.util.HashMap; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.wait.strategy.Wait; public class MyTestResource implements QuarkusTestResourceLifecycleManager { private GenericContainer<?> myContainer; @Override public Map<String, String> start() { // Start the needed container(s) myContainer = new GenericContainer(DockerImageName.parse("my/image:1.0.0")) .withExposedPorts(1234) .waitingFor(Wait.forListeningPort()); myContainer.start(); // Pass the configuration to the application under test // You can also pass camel component property names / values to automatically configure Camel components return new HashMap<>() {{ put("my-container.host", container.getHost()); put("my-container.port", "" + container.getMappedPort(1234)); }}; } @Override public void stop() { // Stop the needed container(s) myContainer.stop(); } }
import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @QuarkusTestResource(MyTestResource.class) class MyTest { }
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; import java.util.HashMap; import java.util.Map; import com.github.tomakehurst.wiremock.WireMockServer; import io.quarkus.test.common.QuarkusTestResourceLifecycleManager; public class WireMockTestResource implements QuarkusTestResourceLifecycleManager { private WireMockServer server; @Override public Map<String, String> start() { // Setup & start the server server = new WireMockServer( wireMockConfig().dynamicPort() ); server.start(); // Stub an HTTP endpoint. WireMock also supports a record and playback mode // https://wiremock.org/docs/record-playback/ server.stubFor( get(urlEqualTo("/api/greeting")) .willReturn(aResponse() .withHeader("Content-Type", "application/json") .withBody("{\"message\": \"Hello World\"}"))); // Ensure the camel component API client passes requests through the WireMock proxy Map<String, String> conf = new HashMap<>(); conf.put("camel.component.foo.server-url", server.baseUrl()); return conf; } @Override public void stop() { if (server != null) { server.stop(); } } }
import io.quarkus.test.common.QuarkusTestResource; import io.quarkus.test.junit.QuarkusTest; @QuarkusTest @QuarkusTestResource(WireMockTestResource.class) class MyTest { }
<dependency> <groupId>org.apache.camel.quarkus</groupId> <artifactId>camel-quarkus-junit5</artifactId> <scope>test</scope> </dependency>
@QuarkusTest @TestProfile(SimpleTest.class) //necessary only if "newly created" context is required for the test (worse performance) public class SimpleTest extends CamelQuarkusTestSupport { }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Override protected CamelContext createCamelContext() throws Exception { // Must call super to get a handle on the application scoped CamelContext CamelContext context = super.createCamelContext(); // Apply customizations context.setTracing(true); // Return the modified CamelContext return context; } }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisified(); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start") .transform().simple("Hello USD{body}") .to("mock:result"); } }; } }
@QuarkusTest class MyTestProfile implements QuarkusTestProfile { }
// @TestProfile will trigger the application to be restarted @TestProfile(MyTestProfile.class) @QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { }
public class MyRoutes extends RouteBuilder { @Override public void configure() { from("direct:start") .transform().simple("Hello USD{body}") .to("mock:result"); } }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @Test void testGreeting() { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:start", "World"); mockEndpoint.assertIsSatisified(); } }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BeforeEach public void beforeEach() throws Exception { AdviceWith.adviceWith(this.context, "advisedRoute", route -> { route.replaceFromWith("direct:replaced"); }); } @Override protected RoutesBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").routeId("advisedRoute") .transform().simple("Hello USD{body}") .to("mock:result"); } }; } @Test void testAdvisedRoute() throws Exception { MockEndpoint mockEndpoint = getMockEndpoint("mock:result"); mockEndpoint.expectedBodiesReceived("Hello World"); template.sendBody("direct:replaced", "World"); mockEndpoint.assertIsSatisfied(); } }
public class MyBeanProducers { @Produces @Named("myBean") public MyBean createMyBean() { return new MyBean(); } }
@QuarkusTest class SimpleTest extends CamelQuarkusTestSupport { @BindToRegistry("myBean") MyBean myBean = new MyBean(); }
mvn --version
<?xml version="1.0"?> <settings> <profiles> <profile> <id>extra-repos</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>redhat-ga-repository</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>atlassian</id> <url>https://packages.atlassian.com/maven-external/</url> <name>atlassian external repo</name> <snapshots> <enabled>false</enabled> </snapshots> <releases> <enabled>true</enabled> </releases> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>redhat-ga-repository</id> <url>https://maven.repository.redhat.com/ga</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> <activeProfiles> <activeProfile>extra-repos</activeProfile> </activeProfiles> </settings>
mvn org.apache.maven.plugins:maven-dependency-plugin:3.1.0:go-offline -Dmaven.repo.local=/tmp/my-project
<mirror> <id>all</id> <mirrorOf>*</mirrorOf> <url>http://host:port/path</url> </mirror>
groupId:artifactId:version groupId:artifactId:packaging:version groupId:artifactId:packaging:classifier:version
<project ... > <groupId>org.fusesource.example</groupId> <artifactId>bundle-demo</artifactId> <packaging>bundle</packaging> <version>1.0-SNAPSHOT</version> </project>
<project ... > <dependencies> <dependency> <groupId>org.fusesource.example</groupId> <artifactId>bundle-demo</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>