Playing around with Apache Camel

Originally posted @ gratiartis.org on May 12th 2011.

I have been playing around with Apache Camel for a couple of projects recently, and so far I’m very impressed. Camel is one of a number of frameworks that seem to have sprung up over the past few years in response to the book Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf. It attempts to provide mechanisms to support all the patterns described in the book. And it does so very well, from what I have experienced so far. So I thought I would mention a couple of things I have done with it.

A simple content-based router

The problem I was trying to solve was that a legacy application was designed to listen to a WebSphere MQ queue, which would contain requests for a variety of operations. A new application had been developed to handle a subset of these operations. I couldn’t have both applications listening to the same queue, so I needed to divert particular operation request messages to a separate new queue.

I needed to put together a simple content-based router that would inspect the header of each incoming message and route the message to a different destination depending on the operation name. I was able to implement this by defining a route which used XPath to select an endpoint based on XML attributes. This could be done in the Camel context XML file and the project contained no code outside this file.


<camelContext xmlns="http://camel.apache.org/schema/spring"&gt;
<route>
<from uri="webspheremq:ANY.OPERATION.REQUEST" />
<choice>
<when>
<xpath>/REQUEST/HEADER[@OperationName='Old.Request']</xpath>
<to uri="activemq:OLD.REQUEST" />
</when>
<when>
<xpath>/REQUEST/HEADER[@OperationName='New.Request']</xpath>
<to uri="activemq:NEW.REQUEST" />
</when>
<otherwise>
<to uri="activemq:DEAD.LETTER.QUEUE" />
</otherwise>
</choice>
</route>
</camelContext>

A CSV to XML transform

Here, I was dealing with integrating two off the shelf applications, the aim being to facilitating exporting a document and meta data from one system and importing it into the other. When exporting a document from the first application, a CSV would be generated in a directory on the filesystem. The other application provided an import adapter, which required an XML trigger file. I needed a small application to follow the following steps:

  1. Listen for CSV files being dropped in a directory on the filesystem.
  2. Split the CSV up into separate requests for each document being exported.
  3. Generate an XML trigger file for each request.
  4. Drop the XML trigger file into a directory ready for import by the downstream system.

As well as providing middleware messaging adapters, Camel also supports defining endpoints that are directories on the filesystem, so it can automatically create a listener for a directory. To deal with the first two steps, I made use of opencsv to parse the CSV, but as I soon discovered, Camel also provided CSV unmarshallers.

I extended the Camel RouteBuilder and using the fluent DSL for Java, defined my routes and created a Splitter class that would take the unmarshalled CSV and output a list of messages to an internal queue., this looked a bit like the following. I then defined a route to pick the individual metadata messages off the internal queue and use a Processor to generate XML in the required format.


from("C:/router/export/csv/")
.unmarshal().csv()
.split().method("org.gratiartis.router.Splitter", "split")
.to("jms:DOCUMENT.METADATA.QUEUE");
from("jms:DOCUMENT.METADATA.QUEUE")
.processRef("org.gratiartis.router.Processor")
.to("C:/router/out/xml/");

Further reading

Camel is very comprehensive and is also one of the best documented projects out there. I keep trying to implement something myself and then finding that there’s already something that will do the job for me.

These are probably the best starting points for info on any particular integration pattern:

http://camel.apache.org/enterprise-integration-patterns.html
http://camel.apache.org/architecture.html

And this was one of the better tutorial introductions to it:

http://architects.dzone.com/articles/apache-camel-integration

If Camel sounds good, you should also take a look at Spring Integration. It’s another framework based on the patterns in the Enterprise Integration Patterns book, but has that Spring tendency towards implementation through bean annotations. But you don’t have to pick one or the other; the Camel project has developed the camel-spring-integration library to provide a bridge from Camel components to Spring Integration endpoints:http://camel.apache.org/springintegration.html

Leave a comment

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