Enterprise Java

Getting started with Apache Camel

In a previous blog-post we got to know about enterprise integration patterns (EIPs). Now in this post we will look into Apache Camel framework that realizes those patterns.
 
 
 
 
 
 
 
 

About Camel:

Apache Camel is an open source project which is almost 5 years old and has a large community of users. At the heart of the framework is an engine which does the job of mediation and routes messages from one system to another. At the periphery it has got a plethora of components that allows interfacing with systems using various protocols (e.g. FTP(s), RPC, Webservices, HTTP, JMS, REST etc). Also it provides easy to understand domain specific language in Java, Spring and Scala.

Now let’s get started with Apache camel. We will set up a project using maven, add dependencies for required camel libraries and write our example using both Java and Spring DSL.

Consider a system that accepts two types of orders; widget and gadgets. The orders arrive on a JMS queue and are specified in XML format. The gadget inventory polls a file directory for incoming orders while the widget inventory listens on a queue. We run XPath on all arriving orders and figure out whether they belong to the widget or gadget inventory. Our use case is depicted by the following diagram:

To get started, just open a command line window in a directory and type mvn archetype:generate

"c:\myprojects>mvn archetype:generate

assuming we have versions maven 2+ and jdk 1.6 in our path, also to run this example we need an activemq broker.

We will add the following dependencies in pom

org.apache.camel : camel-core : 2.10.1
- Lib containing Camel engine

org.apache.camel : camel-ftp : 2.10.1
- Camel's ftp component

org.apache.activemq : activemq-camel : 5.6.0
org.apache.activemq : activemq-pool : 5.6.0
- Libs required to integrate camel with activemq

log4j : log4j : 1.2.16
org.slf4j : slf4j-log4j12 : 1.6.4
- Libs for logging

Complete pom.xml is pasted on this gist entry.

Now lets code our camel route that shall poll a JMS queue, apply XPath to figure out whether the order is for gadget inventory or widget inventory and subsequently route it to FTP directory or a JMS queue.

Orders arriving in our system are having the below structure

<xml version="1.0" encoding="UTF-8"> 
 <order>
 <product>gadget</product>
 <lineitems>
  <item>cdplayer</item>
  <qty>2</qty>
 </lineitems>
 <lineitems>
  <item>ipod-nano</item>
  <qty>1</qty>
 </lineitems>
</order>

Value of product element specifies whether is of gadget or it is a widget order. So applying below XPath on the orders shall let us decide where to route this message./order/product =’gadget’ then forward to an FTP directory else forward to a queue.

Now lets code the route, in order to do so one needs to extend the RouteBuilder (org.apache.camel.builder.RouteBuilder) class and override it’s configure method. We will name our class as JavaDSLMain and put the following code in its configure method:

from("activemq:queue:NewOrders?brokerURL=tcp://192.168.64.144:61616")
      .choice().when(xpath("/order/product = 'gadget'"))
  .to("activemq:queue:GadgetOrders?brokerURL=tcp://192.168.64.144:61616")
      .otherwise()
        .to("ftp://192.168.101.3/camel-demo?username=admin&password=admin&binary=true");

Having done that, now lets analyze the above route. Keywords above form the Camel EIP DSL; the intent of this route is summarized as follows :

from : this says that get messages from an endpoint i.e consume, in our case this happens to be a queue.
choice : this is a predicate, here we apply a simple rule.
xpath: this says apply an xpath to the current message, the outcome of the xpath is a boolean.
to : this tells camel to place the message at an endpoint i.e. produce.

Each of this keyword may take some parameters to work. For example the from takes the endpoint parameter from which to consume messages, in our case it is a queue on a JMS (activemq) broker.

Notice that Camel automatically does type conversion for you, in the above route the message object is converted to a DOM before applying the XPath.

We will also put the main method in this class itself to quickly test this up. Inside the main method we need to instantiate a Camel context which shall host this route and on starting the context, Camel shall set up the route and start listening on the NewOrders queue.

The code that goes in the main method is as follows :

CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new JavaDSLMain());
camelContext.start();
/* wait indefinitely */
Object obj = new Object();
synchronized (obj) {
obj.wait();
}

View this gist entry to get the complete code listing.

Another way to use Camel is with Spring, Camel routes goes into spring application context file. Instead of writing Java code all we use is XML to quickly define the routes. For doing this we need to import Camel namespaces in Spring context file and using
an IDE such as Spring tool suite one can quickly build & write integration applications.

Check this gist entry for the Spring application context demonstrating a Camel route.Place this context file inside META-INF/spring folder i.e in our maven project it goes under /src/main/resources/META-INF/spring folder.

At the top we have imported Camel’s Spring namespace which allows defining Camel route inside Spring’s application context , additionally in our pom file we need to add dependency to include Spring bean’s that takes care of recognizing and instantiating Camel engine inside Spring. Add below to include the Camel support for Spring.

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>2.10.1</version>
 </dependency>

Camel provides a helper class (org.apache.camel.spring.Main) that scans for all Spring application context files kept under
META-INF/spring folder kept under classpath. Check this gist entry showing the required code.
With this example we have realized the Content Based Router pattern that inspects content of the message for routing decisions.
 

Reference: Getting started with Apache Camel from our JCG partner Abhishek Jain at the NS.Infra blog.

Abhishek Jain

Abhishek is a lead software engineer with Impetus Technologies, pioneered in outsource product development. He has technical expertise in designing and implementing solutions around distributed application, database technologies, middle-ware technologies and SaaS platform.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
swati
swati
11 years ago

Thanks Abhishek, this article is really illuminating.

kaushik
kaushik
10 years ago

Very nice article. Good for complete novice like me to start with

Dave
Dave
9 years ago

Doesn’t your code in the DSL do the opposite of what the diagram says it should? The diagram says gadgets go to the FTP service, the code says that they go to the Active MQ endpoint as far as I can tell.

Apart from that, it’s a nice intro

Sudheer
Sudheer
9 years ago
Reply to  Dave

I also got into same confusion.

Sunil Kale
Sunil Kale
8 years ago

Hi guys,
I want to transfer file from server or any other remote machine to my local machine using apche camel file transfer API. So please help me ASAP. How to access is using IP or any other method.

P Rod
P Rod
7 years ago

Do you have any examples of how you would test this route using CamelTestSupport?

Back to top button