Camel with Spring Boot example | Masterspringboot

This short tutorial will show you how to create a simple Camel with Spring Boot example application with a minimal test case in no time.

The simplest way to bootstrap a Camel application is to use one of its Maven archetypes. When using Spring Boot application, the recommended archetype is camel-archetype-spring-boot:

mvn archetype:generate                   \   
-DarchetypeGroupId=org.apache.camel.archetypes  \   
-DarchetypeArtifactId=camel-archetype-spring-boot   \   
-DarchetypeVersion=3.7.0             \   
-DgroupId=com.sample                  \   
-DartifactId=camel-spring-boot 

The following Spring Boot project will be created:

You can also import the Spring Boot project in your favourite IDE, for example in IntelliJ by choosing “Import Project” and pointing to the Camel Spring Boot project.

camel spring boot hello world

Let’s check out project class. The Spring Boot Main class is MySpringBootApplication which simply starts our application:

@SpringBootApplication
public class MySpringBootApplication {
  public static void main(String[] args) {
    SpringApplication.run(MySpringBootApplication.class, args);
  }
}

Next, the Router class MySpringBootRouter. Please note this class contains the @Component annotation to make Camel auto detect this route when starting:

@Component
public class MySpringBootRouter extends RouteBuilder {
  @Override
  public void configure() {
    from("timer:hello?period={{timer.period}}")
        .routeId("hello")
        .transform()
        .method("myBean", "saySomething")
        .filter(simple("${body} contains 'foo'"))
        .to("log:foo")
        .end()
        .to("stream:out");
  }
}

This Route has a Timer component in it which fires according to the “timer.period” (defined in application.properties). Each time the Timer is fired, the Bean registered under the context “myBean” will be invoked through its method “saySomething”. A Sample filter is included to fetch and log messages whose body contains ‘foo’.

Let’s check the Transformation done by the Bean “myBean”:

@Component("myBean")
public class MySpringBean {
  @Value("${greeting}")
  private String say;

  public String saySomething() {
    return say.toUpperCase();
  }
}

In the method saySomething we have changed the default example to transform the text to uppercase.

The Test class included in the project is in charge to intercept the Camel Route and replace the consumer with a direct consumer.

@SpringBootTest @CamelSpringBootTest public class MySpringBootApplicationTest {
  @Autowired private CamelContext camelContext;
  @Autowired private ProducerTemplate producerTemplate;
  @Test public void test() throws Exception {
      MockEndpoint mock = camelContext.getEndpoint("mock:stream:out", MockEndpoint.class);
      AdviceWith.adviceWith(camelContext, "hello",
        // intercepting an exchange on route
        r -> {
          // replacing consumer with direct component

          r.replaceFromWith("direct:start"); // mocking producer 					r.mockEndpoints("stream*"); 				} 		);  		

          // setting expectations 		

          mock.expectedMessageCount(1);mock.expectedBodiesReceived("HELLO WORLD");

          // invoking consumer 		

          producerTemplate.sendBody("direct:start", null);

          // asserting mock is satisfied 		

          mock.assertIsSatisfied();
        }
      }

Please note we have set to upper case the expected value of the “Hello World” message.

Within the application.properties there are several default message properties. For the scope of this example, the following properties can be adjusted:

# what to say greeting = Hello World  # how often to trigger the timer timer.period = 2000

You can run the application with:

mvn install spring-boot:run 

You should see that the “HELLO WORLD” message is printed on the Camel spring Boot console:

2021-02-21 18:12:28.138  INFO 6030 --- [           main] com.sample.MySpringBootApplication       : Started MySpringBootApplication in 1.991 seconds (JVM running for 2.311) HELLO WORLD HELLO WORLD

Making the Hello World Camel Spring Boot interactive

Let’s spice a bit our example using some cool features of Spring Boot. As an example, we will add a REST Controller to produce the greeting message:

@RestController
public class MyRestController {
  @Autowired private ProducerTemplate template;

  @RequestMapping("/hello")
  public String sayHello(@RequestParam(defaultValue = "frank") String name) {
    return template.requestBody("direct:sayHello", name).toString();
  }
}

As you can see, we are using the direct Component which is the abstract way to initialize a Route from a ProducerTemplate object. In a nutshell, the ProducerTemplate will fire the synchronous call to “direct:sayHello” passing as parameter the value for “name” contained in the HTTP request. If no request object has been added, the default value of ‘frank’ will be used.

In order to use this example, we will replace the timer component with “direct:sayHello“:

@Component
public class MySpringBootRouter extends RouteBuilder {
  @Override
  public void configure() {
    from("direct:sayHello")
        .routeId("hello")
        .transform()
        .method("myBean", "saySomething")
        .filter(simple("${body} contains 'foo'"))
        .to("log:foo")
        .end()
        .to("stream:out");
  }
}

That’s it. Adjust the Test class accordingly. (You can check the full source code below).

You can run the application with:

mvn install spring-boot:run 

You can test it as follows:

curl http://localhost:8080/hello?name=Jack JACK 

We have just covered two basic examples of Camel applications built using Spring Boot.

Source code for the Camel Spring Boot demo: https://github.com/fmarchioni/masterspringboot/tree/master/camel/camel-helloworld-spring