Introduction to Apache Camel

Introduction to Apache Camel

Enterprise Integration Patterns

Patterns can provide guidance by documenting the kind of experience that usually lives only in architects' heads: they are accepted solutions to recurring problems within a given context. Patterns also provide a vocabulary for developers to efficiently describe their solution.This is a general definition of a pattern. In enterprises we have a large number of applications, some are custom built while others may be third party and these need to be integrated together to work together and share information in-order to solve a business use case. The integration of such applications might pose some problems which can be efficiently and effectively solved using patterns combined under the category called Enterprise Integration Patterns (EIP).

What is Camel?

Camel is an integration framework that helps us in easy integration of our projects/ applications. At its core it is a routing engine or more precisely a routing engine builder. Camel project was started in early 2007 and now is a mature open source project, available under the liberal Apache 2 license, with a strong community.Camel is called a routing-engine builder as it allows us to define our own rules for routing, decide which source to accept messages from and where to route these messages(destination).Out of the box, Camel comes with support for more than 280 protocols and data types.

Camel supports most of the Enterprise Integration Patterns from the excellent book by Gregor Hohpe and Bobby Woolf.

In the sections below we will discuss Camel's message model, architecture and concepts followed by a code example.

Camel Message Model

  1. Message - The fundamental entity containing the data being carried and routed in Camel. Messages flow in one direction, from a sender to a receiver.Message is composed of a unique identifier, Header, an optional Attachment and Body.The identifier can be set by the creator of message if not will be created by camel.Headers are values associated with the message, such as sender identifiers, hints about content encoding, authentication information, and so on.Body has the message content and attachments are used mostly in case of mails.
  2. Exchange - Messages are encapsulated in exchange before routing.An exchange also provides support for the various types of interactions between systems, also known as message exchange patterns (MEPs). MEPs are used to differentiate between one-way and request-response messaging styles. This MEP can take one of the two values : - a) InOnly - A one-way message (also known as an event message). b) InOut - A request-response message. An exchange has a unique id, MEP thats set to one of the above two patterns, Exception to hold info about any exception that occurred while routing, Properties Similar to message headers, but they last for the duration of the entire exchange, they are used to contain global-level information, whereas message headers are specific to a particular message.
Camel Exchange with In and Out messages

Camel Architecture

No alt text provided for this image
  1. Camel Context - We can think of it like a box that keeps all the camels runtime components together.
  2. Routing Engine - Camel's Routing engine moves the messages around under the hood, its not evidently visible to the developer but is there doing all the work.
  3. Routes - Routes are the core camel abstraction. Each has an id that is used to uniquely identify a route for logging, debugging purposes. Each route is tied to an input endpoint to serve as an input source of messages. Routes provided for easy decoupling of client/server and producer consumer applications and also let us bind preprocessing and transformation of messages. For example the below code snippet has two routes defined.
  4. DSL - DSL stands for domain specific language that is used define routes. It is used to wire the endpoints and processors together. It can be a in xml or Java having terms named after the EIP terms. The example below is a java code snippet.
  5. Components - Camel supports more than 80 components that can be file component, http component, jms (java messaging system) etc. Component name are used in the URI of the endpoints. For example the timer and log components in the snippet below.We can even create our own components.
  6. Endpoint - Endpoint URIs are used in the routes. Each endpoint is composed to a schema, context path and options. Schema is used to select the component from the factory. For example timer:myTimer?period=5000 is an endpoint used in the route code snippet below. It has a schema timer that tells that timer component is to be used, context myTimer is the name of the timer and option period is used to trigger the timer after a delay of 5000 ms.
  7. Processors - Each exchange passes through processors, these are able to create, use or modify an incoming exchange. We can even create our own custom processors. Each route is like a graph and these processors are like nodes of that graph, where one node is connected to another. The output of one processor can be made input of another. For example transform() used is a processor used for inline message transformation.
//route
from("timer:myTimer?period=5000")
        .routeId("2")
        .transform().constant("checking")
        .log("running 1")
        .to("direct:myEnd");

//Another route
from("direct:myEnd")
        .routeId("3")
        .to("log:myLog")
        .end();

Producer

Camel producer refers to an abstraction that is able to create and send messages to an endpoint. Producer will create an exchange and add the message to that exchange and then send it to the relevant endpoint. Post that the message will be routed as defined by the route that is created with the endpoint as from.

Consumer

Consumers receive the messages, wrapped in exchange, sent by the producer. The consumer can be async receiver or event driven which listens to a particular messaging channel for example a queue. Consumer can be a synchronous receiver or polling consumer that keeps on polling for new messages after consumer the prior one.

Lets understand Camel with Spring boot using a code example

We can use the Spring initializr to generate a project whose pom looks like this

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.6.2</version>
      <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.aneshka.camel</groupId>
   <artifactId>camelDemo</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>camelDemo</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>org.apache.camel.springboot</groupId>
         <artifactId>camel-spring-boot-starter</artifactId>
         <version>3.14.0</version>
      </dependency>
      <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-parent</artifactId>
         <version>3.14.0</version>
         <type>pom</type>
         <scope>import</scope>
      </dependency>

      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
      </plugins>
   </build>

</project>

 

Spring boot gets a SpringBootCamelContext auto configured which we are using in the example below.

Also the Camel route can be defined as below. Annotating with Component makes the route discoverable by the spring boot camel context. Here we have defined a custom endpoint called start and it simply logs the message body as well as exchange pattern as sent by the producer.

@Component
public class CamelRouter extends RouteBuilder {

    @Override
    public void configure() {
        from("direct:start")
                .routeId("1")
                .log("${body}")
                .log("${exchange.getPattern()}")
                .end();
    }

}

Spring boot also gets a DefaultProducerTemplate which can be easily injected and used as shown below.

@SpringBootApplication
public class CamelDemoApplication {

   private static ProducerTemplate producerTemplate;

   @Autowired
   public CamelDemoApplication(ProducerTemplate producerTemplate) {
      this.producerTemplate = producerTemplate;
   }

   public static void main(String[] args) {

      SpringApplication.run(CamelDemoApplication.class, args);
      // sending to custom endpoint creating exchange and setting message
      producerTemplate.send("direct:start", ExchangePattern.InOnly, exchange -> exchange.getIn().setBody("Hello World"));

   }

This code sends a message wrapped in the InOnly exchange to our custom endpoint which has a route defined wherein we log the message body and the exchange type.

Output of the code looks like this

No alt text provided for this image

Camel makes it easy to integrate the applications at enterprise level. The use of DSL makes glueing of code easy and keeps developer focused on glueing components rather than focusing on how it happens under the hood.

Sources of knowledge

  • https://camel.apache.org/manual/book-getting-started.html
  • https://camel.apache.org/components/3.14.x/eips/enterprise-integration-patterns.html
  • https://www.enterpriseintegrationpatterns.com/toc.html

To view or add a comment, sign in

More articles by Aneshka Goyal

  • Event Driven Architecture - Evolution and Flavours

    What is Software Architecture? “Software Architecture” refers to the fundamental organisation of a software system…

  • Introduction to Agent To Agent (A2A) Protocol

    What is A2A? The Agent2Agent (A2A) Protocol is an open standard developed by Google and donated to the Linux Foundation…

  • Introduction to AgenticAI

    What is Agentic AI? Agentic AI refers to artificial intelligence systems that act autonomously, making decisions and…

    2 Comments
  • Introduction to SSO with OIDC

    What is SSO? SSO stands for single sign on. Here we sign in once and as users are able to access a set of applications…

  • Introduction to Apache Cassandra

    What is Apache Cassandra? Apache Cassandra is an open source NoSQL distributed database. It delivers on availability…

    2 Comments
  • Introduction to GraphQL Federation - Netflix DGS and Apollo Gateway

    What is GraphQL? GraphQL is a query language for our API, and a server-side runtime for executing queries using a type…

  • Introduction to Distributed Tracing

    What is Distributed Tracing? The word tracing is to trace the request as it flows through the system. Since modern…

    2 Comments
  • Introduction to Service Discovery

    What is Service Discovery? Service Discovery as the name suggests allows us to know or discover where each instance of…

  • Introduction to Micro frontend

    What is Micro frontend? The term “micro frontends” debuted in the 2016 ThoughtWorks Technology Radar guide. At its…

    2 Comments
  • Introduction to Pub-Sub and Streams with Redis&SpringBoot

    Publish/Subscribe Problem: Let's say we have synchronous messaging between two components of our system called as…

    2 Comments

Others also viewed

Explore content categories