Getting started with Camel 4

This article introduces you to the latest major version of Apache Camel framework highlighting some noteworthy new features and updates available in Camel 4.

Camel 4 Highlights

In Camel 4, the primary focus revolves around several key advancements:

  • The migration from javax to jakarta APIs, aligned with the Java EE 10 standard, is a pivotal aspect. This upgrade facilitates compatibility with modern runtimes like Spring Boot 3 and Quarkus 3.
  • Camel 4 mandates Java 17 as the minimum requirement, with plans to support Java 21 in the subsequent LTS release by year-end.
  • Another significant aspect of Camel 4 is performance optimization. Internal enhancements to the Camel routing engine and framework have significantly improved overall performance.
  • Notably, the integration of Camel 4 with Spring Boot 3 showcases advancements in the Camel Spring Boot project. The usage of Spring Boot’s embedded HTTP server directly enhances performance, deviating from Servlet APIs previously employed.

A Camel 4 example

You can kick-start a Camel 4 application with any of the available Camel Maven archetypes . For example, if you want to bootstrap a new Camel 4 application using the Main Java archetype:

mvn archetype:generate \
  -DarchetypeGroupId=org.apache.camel.archetypes \
  -DarchetypeArtifactId=camel-archetype-java \
  -DarchetypeVersion=4.3.0

Then, we will import the Camel 4 example in a IDE and so that we can customize it.

Customize the Camel 4 example

Firstly, replace the default Camel Route with something a bit more interesting:

public class MyRouteBuilder extends RouteBuilder {

    public void configure() {
        from("direct:beanToJson")
                .marshal().json(JsonLibrary.Jackson)
                .log("${prettyBody}");
    }
}

This Camel Route will marshal a Java Class into JSON using Jackson Library and produce the output in the log. Notice the usage of ${prettyBody} which is a construct available of Camel 4 to pretty print JSON. To know more about this topic, we recommend reading this article: How to pretty print JSON in Java

Then, to be able to marshall your Beans, you will need to add the following dependency to your project:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-jackson</artifactId>
</dependency>

Next, add a Java Class or Record which will be marshalled into JSON:

public record Person(String name, int age) {}

Finally, we will modify the Main Camel Class to include a ProducerTemplate that will send a Person Record to the Route:

public class MainApp {

    public static void main(String... args) throws Exception {
       
        Main main = new Main();

        main.configure().addRoutesBuilder(new MyRouteBuilder());
        main.start();
        CamelContext context = main.getCamelContext();
        
        ProducerTemplate producerTemplate = context.createProducerTemplate();

        Person person = new Person("Alice", 30);

        // Sending the Person object to the route
        producerTemplate.sendBody("direct:beanToJson", person);

        Thread.sleep(2000); // Sleep to allow time for the route to process
     
        main.run(args);
    }  
}

Running the Camel 4 Route

You can run the main Class from your IDE or from the command line as follows:

mvn camel:run

From the Console output, expect to see the output of the Person Class transformed in a JSON as follows:

camel 4 step-by-step guide tutorial

As you can see, the Route prints on the Console the Person Record in JSON format.

Camel Main noteworthy features

This example is a basic overview of the Camel Main framework which allows several advanced features. For example, you can add a listener to the Main Class to capture the beginning and the stop of a Camel Route. For example:

    main.addMainListener(new MyListener());
    
    ....
    
      public static class MyListener extends MainListenerSupport {

        @Override
        public void afterStart(BaseMainSupport main) {
            System.out.println("Main Camel Route started!");
        }

        @Override
        public void beforeStop(BaseMainSupport main) {
            System.out.println("Main Camel Route stopped!");
        }
    }

Let’s see another example: here is how you can bind a Bean in the Camel Main context. For example, here we are binding the Bean MyBean as foo in the Main Context:

main.bind("mybean", new MyBean());

Then, you can refer to the Bean in any of your Camel Routes. For example:

     private static class MyRouteBuilder extends RouteBuilder {
        @Override
        public void configure() throws Exception {
            from("timer:foo?delay={{millisecs}}")                    
                    .bean("mybean");
        }
    }
     
       public static class MyBean {

        public void echo() {
            System.out.println("You called MyBean");
        }
    }

How to set Properties in your Camel main Route

Finally, we will mention something more about the properties you can use in a Camel Main Route. Out of the box, you will be able to inject properties in your Route which are present in the file application.properties.

For example, if you set the greeting properties in resources/application.properties you will be able to use it in your Route with:

log("{{greeting}}");

You can use it as well in your Beans by Injecting the Property as follows:

@Value("${greeting}")
private String greeting;

On the other hand, if you want to use a different file as source of properties, then you can set the Property Placeholder location as follows:

main.setPropertyPlaceholderLocations("example.properties");

The following option sets a global option for the Camel Main application. Global options are available to all routes in the application.

main.configure().withGlobalOption("myglobal", "value")   

You can also set Property as follows, however the difference is that you will not be able to modify them once you set them:

main.addInitialProperty("camel.variable.global:greeting", "Random number");

Lastly, to set Properties for a specific component, you can use the addProperty method as in the following example which sets a Property for the SEDA component:

main.addProperty("camel.component.seda.defaultQueueFactory.counter", "123");

Conclusion

This article was a walk through some key features of Apache Camel 4 using as example the Camel Main framework. We encourage to migrate to this new Camel Release before the planned End of Life of Camel 3.22 which is set to December 2024

Source code for this article: https://github.com/fmarchioni/masterspringboot/tree/master/camel/camel4/camel4-main

Found the article helpful? if so please follow us on Socials
Twitter Icon       Facebook Icon       LinkedIn Icon       Mastodon Icon