Apache Camel -Spring boot

Pardhu Guttikonda
4 min readMar 29, 2022

Apache Camel for interaction between services.

Definition :- Apache Camel is an Open Source integration framework which provides Enterprise Integration Patterns. Easily integrate various systems consuming or producing data.

Photo by Kaleidico on Unsplash

🎯 Prerequisites:

  • Understanding of java and spring framework
  • Docker need to be installed OR ActiveMQ need to be installed in the local machine.

How we can pass messages between two spring services?

  • Sender service will be sending the message in queues to ActiveMQ.
  • Receiver will be reading the message from ActiveMQ.
    Note:- during the process of sending data, we can process and transform the data. Also, we can send data in asynchrony manner.

👉 Dependencies for Both sender and Receiver :

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-activemq-starter</artifactId>
<version>3.15.0</version>
</dependency>

Also in the application.properties file, add the broker URL of ActiveMQ

-------------------sender---------------------
spring.activemq.broker-url=tcp://localhost:61616
server.port=8000
--------------------receiver------------------
spring.activemq.broker-url=tcp://localhost:61616
server.port=8080

Now lets pull ActiveMQ to our local machine using docker

docker run -p 61616:61616 -p 8161:8161 rmohr/activemq

UI for ActiveMQ will be running on port 8161, Where we can see the number of services connected to ActiveMQ also the running queue of messages.

Photo by AbsolutVision on Unsplash

🛰 Sending message to ActiveMQ at sender service

💡Working:

  • In this example, we are using direct:pardhu-active-mq to send the message to ActiveMQ on post request to a rest API.(“pardhu-active-mq” unique string to identify the route).
  • We wrote a Data Model which contains name and message. Received on Post, request to sender service.
  • We have to convert the POJO class to JSON string, and then we have to send it to the ActiveMQ. (Because Our Data Models can not be identified in the received site).
  • We can verify our message in the ActiveMQ UI, which will be running on the port 8161.

Register camel Route:

  • Camel Router are registered as Components which extends org. Apache.camel.builder.RouteBuilder and Override configure method.
  • Also, we are using a bean to convert the class Object to JSON String.
import com.service1.camel1.DemoBeans;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CamelRouters extends RouteBuilder {

@Autowired
DemoBeans demoBeans;

public static final String route = "direct:pardhu-active-mq";

@Override
public void configure() throws Exception {
from(route)
.bean(demoBeans,"toJSON")
.log("${body}")
.to("activemq:pardhu-demo");
}
}

DemoBean:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.camel.Exchange;
import org.springframework.stereotype.Component;

@Component
public class DemoBeans {
public String toJSON(Exchange exchange) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(exchange.getMessage().getBody());
}
}

RestController to trigger sending data

  • We have to create an Exchange with message body.
  • Pass the exchange to producerTemplate, where as route is nothing but “direct:pardhu-active-mq” unique string.
import static com.service1.camel1.camelrouter.CamelRouters.route;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.service1.camel1.model.DemoModel;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.ExchangeBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@org.springframework.web.bind.annotation.RestController
public class RestController {

@Autowired
private ProducerTemplate producerTemplate;

@Autowired
private CamelContext camelContext;

@PostMapping("/send")
public ResponseEntity<?> sendMessage(@RequestBody DemoModel message) throws JsonProcessingException {
Exchange exchange = ExchangeBuilder.anExchange(camelContext).withBody(message).build();
producerTemplate.asyncSend(route,exchange);
return ResponseEntity.ok("Done");
}
}

DemoModel Data Model

import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import lombok.Data;

@Data
public class DemoModel implements Serializable {
@JsonProperty("name")
String name;
@JsonProperty("message")
String message;
}

After running the Sender service successfully.
Send a POST Request to http://localhost:8000/send with the following data Object.

JSON Object

Verify the message in ActiveMQ (http://localhost:8161)

Username , password = admin, admin

Queues
  • Also we can see all the consumers of that particular route named pardhu-demo.
Photo by Claudio Schwarz on Unsplash

🚀 Receiver can get the messages in Queue

Working:

  • Here we will just receive the message Queue from the route named pardhu-demo and print them.

Receiver Camel Builder

  • Message from Queue will be processed and printed in the castToModel Bean.
import com.service2.camel2.CastToModel;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CamelRouter extends RouteBuilder {

@Autowired
CastToModel castToModel;

@Override
public void configure() throws Exception{
from("activemq:pardhu-demo")
.process(castToModel);
}
}

CastToModel Bean

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.service2.camel2.model.DemoModel;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.springframework.stereotype.Component;

@Component
public class CastToModel implements Processor {
public void process(Exchange exchange) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
DemoModel demo = mapper.readValue(exchange.getMessage().getBody().toString(),DemoModel.class);
System.out.println(demo.toString());
}
}

Code available at :-> GitHub

Thank you..!

--

--