How to use Camel extensions in Quarkus

Camel is the open source swiss knife framework for integration, with over 300 components allowing the integration between external systems. In this article we will learn how to use Camel extensions for Quarkus to build powerful Java Integrations.

Using Camel with Quarkus

Firstly, let’s see which extensions you need to develop Camel applications with Quarkus. If you search for “camel” extensions, you will see there are over 200 extensions available:

Then, if you just need the Camel Core functionality, add the camel-quarkus-core extension. On the other hand, if you need specific Camel components, just select them and Camel Core will be included as transitive dependency.

In our example application, we will expose a JSON REST Service through Camel REST Component. Also, we will use JPA for persistence.

quarkus camel extensions

Therefore, include the following set of dependencies:

  • camel-quarkus-rest
  • camel-quarkus-jackson
  • camel-quarkus-direct
  • camel-quarkus-jpa

We will be using H2 Database for persistence therefore we will also include the following extension:

  • quarkus-jdbc-h2

Finally, here is the list build dependencies our application will include:

<dependencyManagement>
	<dependencies>
		<!-- Import BOM -->
		<dependency>
			<groupId>${quarkus.platform.group-id}</groupId>
			<artifactId>${quarkus.platform.artifact-id}</artifactId>
			<version>${quarkus.platform.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		<dependency>
			<groupId>${camel-quarkus.platform.group-id}</groupId>
			<artifactId>${camel-quarkus.platform.artifact-id}</artifactId>
			<version>${camel-quarkus.platform.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

<dependencies>
	<dependency>
		<groupId>org.apache.camel.quarkus</groupId>
		<artifactId>camel-quarkus-jackson</artifactId>
	</dependency>
	<dependency>
		<groupId>org.apache.camel.quarkus</groupId>
		<artifactId>camel-quarkus-rest</artifactId>
	</dependency>
	<dependency>
		<groupId>org.apache.camel.quarkus</groupId>
		<artifactId>camel-quarkus-direct</artifactId>
	</dependency>
	<dependency>
		<groupId>org.apache.camel.quarkus</groupId>
		<artifactId>camel-quarkus-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>io.quarkus</groupId>
		<artifactId>quarkus-jdbc-h2</artifactId>
	</dependency>

</dependencies>

Coding the Camel Quarkus REST Service

Firstly, we will add a Model class that we will persist through JPA and return as REST Resource:

@Entity
@NamedQuery(name = "findAll", query = "SELECT p FROM Person p")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    private String name;
    private String surname;

    // Getter/Setters omitted for brevity
}

Then, we will code a simple Camel Route which exposes a REST DSL Endpoint:

public class Routes extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        restConfiguration().bindingMode(RestBindingMode.json);

        rest("/persons")
                .get()
                .to("direct:getPersons")

                .post()
                .type(Person.class)
                .to("direct:addPerson");

        from("direct:getPersons")
                .to("jpa://com.sample.Person?resultClass=com.sample.Person&namedQuery=findAll")
                .log("Person List: ");

        from("direct:addPerson")
                .to("jpa://com.sample.Person?usePersist=true");

    }
}

The above is a simple example of Camel REST DSL. The Camel Rest DSL is a facade that builds Rest endpoints as consumers for Camel routes. We have exposed the following endpoints:

  • /persons GET: This endpoint returns a list of com.sample.Person through the Camel JPA Component. The Camel JPA Component in turn uses the namedQuery findAll to return the list of com.sample.Person objects
  • /person POST: This endpoint adds a com.sample.Person object through the Camel JPA Component

To decouple the REST Endpoint from the persistence layer, we have added the direct component in the middle.

Finish the application with the application.properties configuration file which contains the Datasource configuration for the persistence:

quarkus.datasource.db-kind=h2
quarkus.datasource.jdbc.url=jdbc:h2:file:../src/main/resources/data/database;AUTO_SERVER=true;DB_CLOSE_DELAY=-1

quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.log.sql=true

Testing the Quarkus application

We are ready to test the application. A simple Test class might be just the following one:

@QuarkusTest
public class RestJsonTest {

    @Test
    public void persons() {

        given()
                .body("{\"name\": \"John\", \"surname\": \"Smith\"}")
                .header("Content-Type", "application/json")
                .when()
                .post("/persons")
                .then()
                .statusCode(200);

        given()
                .when().get("/persons")
                .then()
                .statusCode(200)
                .body(
                        "$.size()", is(1));
    }

}

On the other hand, a manual Test would go like the following one:

curl -X POST http://localhost:8080/persons  -H 'Content-Type: application/json' -d '{"name":"John","surname":"Smith"}'

Next, check the list of Persons:

curl -s http://localhost:8080/persons | jq
[
  {
    "id": 1,
    "name": "John",
    "surname": "Smith"
  }
]

Great! We have just demonstrated how to run Camel extensions in a Quarkus application. You can find the source code for this example on GitHub: https://github.com/fmarchioni/mastertheboss/tree/master/quarkus/camel-demo