Introduction

Apache Camel is a Spring based Integration Framework which implements the Enterprise Integration Patterns with powerful Bean Integration.

Camel lets you create the Enterprise Integration Patterns to implement routing and mediation rules in either a Java based Domain Specific Language (or Fluent API), via Spring based Xml Configuration files or via the Scala DSL. This means you get smart completion of routing rules in your IDE whether in your Java, Scala or XML editor.

Apache Camel uses URIs so that it can easily work directly with any kind of Transport or messaging model such as HTTP, ActiveMQ, JMS, JBI, SCA, MINA or CXF Bus API together with working with pluggable Data Format options. Apache Camel is a small library which has minimal dependencies for easy embedding in any Java application.

Apache Camel can be used as a routing and mediation engine for the following projects:

  • Apache ActiveMQ which is the most popular and powerful open source message broker
  • Apache CXF which is a smart web services suite (JAX-WS)
  • Apache MINA a networking framework
  • Apache ServiceMix which is the most popular and powerful distributed open source ESB and JBI container

So don't get the hump, try Camel today!

Getting Started with Apache Camel

The Enterprise Integration Patterns (EIP) book

The purpose of a "patterns" book is not to advocate new techniques that the authors have invented, but rather to document existing best practices within a particular field. By doing this, the authors of a patterns book hope to spread knowledge of best practices and promote a vocabulary for discussing architectural designs.
One of the most famous patterns books is Design Patterns: Elements of Reusable Object-oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides. Some people refer to this as the "gang of four" book, partly to distinguish this book from other books that use "Design Patterns" in their titles and, perhaps, partly because they cannot remember the names of all four authors.
Since the publication of Design Patterns, many other patterns books, of varying quality, have been written. One famous patterns book is called Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions by Gregor Hohpe and Bobby Woolfe. It is common for people to refer to this book as EIP, which is an acronym of its title. As the subtitle of EIP suggests, the book focusses on design patterns for asynchronous messaging systems. The book discusses 65 patterns. Each pattern is given a textual name and most are also given a graphical symbol. The graphical symbols are intended to be used in architectural diagrams.

The Camel project

Camel (http://activemq.apache.org/camel/) is an open-source, Java-based project that is a part of the Apache ActiveMQ project. Camel provides a class library that, according to its documentation, can be used to implement 31 design patterns in the EIP book. I am not sure why the Camel documentation discusses only 31 of the 65 EIP design patterns. Perhaps this is due to incomplete documentation. Or perhaps it means that the Camel project, which is less than 1 year old at the time of writing, is not yet as feature rich as the EIP book.
Because Camel implements many of the design patterns in the EIP book, it would be a good idea for people who work with Camel to read the EIP book.

Online documentation for Camel

The Camel project was started in early 2007. At the time of writing, the Camel project is too young for there to be published books available on how to use Camel. Instead, the only source of documentation seems to the documentation page on the Apache Camel website.

Problems with Camel's online documentation

Currently, the online documentation for the Apache Camel project suffers from two problems. First, the documentation is incomplete. Second, there is no clearly specified reading order to the documentation. For example, there is no table of contents. Instead, documentation is fragmented over a collection of 60+ web pages, and hypertext links haphazardly tie these web pages to each other. This documentation might suffice as reference material for people already familiar with Camel but it does not qualify as a tutorial for beginners.
The problems with the documentation are unlikely to be due to, say, its author(s) lacking writing ability. Rather, it is more likely that the problems are due to the author(s) lack of time. I expect Camel's documentation will improve over time. I am writing this overview of Camel to partially counter some of the problems that currently afflict the Camel documentation. In particular, this document aims to serve as a (so far, incomplete) "beginner's guide to Camel". As such, this document tries to complement, rather than compete with, the online Camel documentation.

A useful tip for navigating the online documentation

There is one useful hint I can provide for reading the online Camel documentation. Each documentation page has a logo at the top, and immediately underneath this is a think reddish bar that contains some hypertext links. The Hypertext links on left side of this reddish bar indicate your position in documentation. For example, If you are on the "Languages" documentation page then the left-hand side of the reddish bar contains the following links.

Apache Camel > Documentation > Architecture > Languages

As you might expect, clicking on "Apache Camel" takes you back to the home page of the Apache Camel project, and clicking on "Documentation" takes you to the main documentation page. You can interpret the "Architeture" and "Languages" buttons as indicating you are in the "Languages" section of the "Architecture" chapter. Doing this gives you at least some sense of where you are within the documentation. If you are patient then you can spend a few hours clicking on all the hypertext links you can find in the documentation pages, bookmark each page with a hierarchical name (for example, you might bookmark the above page with the name "Camel – Arch – Languages") and then you can use your bookmarks to serve as a primitive table of contents for the online Camel documentation.

Online Javadoc documentation

The Apache Camel website provides Javadoc documentation. It is important to note that the Javadoc documentation is spread over several independent Javadoc hierarchies rather than being all contained in a single Javadoc hierarchy. In particular, there is one Javadoc hierarchy for the core APIs of Camel, and a separate Javadoc hierarchy for each communications technology supported by Camel. For example, if you will be using Camel with ActiveMQ and FTP then you need to look at the Javadoc hierarchies for the core API, ActiveMQ API and FTP API.

Concepts and terminology fundamental to Camel

I said in Section 3.1 ("Problems with Camel's online documentation") that the online Camel documentation does not provide a tutorial for beginners. Because of this, in this section I try to explain some of the concepts and terminology that are fundamental to Camel. This section is not a complete Camel tutorial, but it is a first step in that direction.

Endpoint

The term endpoint is often used when talking about inter-process communication. For example, in client-server communication, the client is one endpoint and the server is the other endpoint. Depending on the context, an endpoint might refer to an address, such as a host:port pair for TCP-based communication, or it might refer to a software entity that is contactable at that address. For example, if somebody uses "www.example.com:80" as an example of an endpoint, they might be referring to the actual port at that host name (that is, an address), or they might be referring to the web server (that is, software contactable at that address). Often, the distinction between the address and software contactable at that address is not an important one.
Some middleware technologies make it possible for several software entities to be contactable at the same physical address. For example, CORBA is an object-oriented, remote-procedure-call (RPC) middleware standard. If a CORBA server process contains several objects then a client can communicate with any of these objects at the same physical address (host:port), but a client communicates with a particular object via that object's logical address (called an IOR in CORBA terminology), which consists of the physical address (host:port) plus an id that uniquely identifies the object within its server process. (An IOR contains some additional information that is not relevant to this present discussion.) When talking about CORBA, some people may use the term "endpoint" to refer to a CORBA server's physical address, while other people may use the term to refer to the logical address of a single CORBA object, and other people still might use the term to refer to any of the following:

  • The physical address (host:port) of the CORBA server process
  • The logical address (host:port plus id) of a CORBA object.
  • The CORBA server process (a relatively heavyweight software entity)
  • A CORBA object (a lightweight software entity)
    Because of this, you can see that the term endpoint is ambiguous in at least two ways. First, it is ambiguous because it might refer to an address or to a software entity contactable at that address. Second, it is ambiguous in the granularity of what it refers to: a heavyweight versus lightweight software entity, or physical address versus logical address. It is useful to understand that different people use the term endpoint in slightly different (and hence ambiguous) ways because Camel's usage of this term might be different to whatever meaning you had previously associated with the term.
    Camel provides out-of-the-box support for endpoints implemented with many different communication technologies. Here are some examples of the Camel-supported endpoint technologies.
  • A JMS queue.
  • A web service.
  • A file. A file may sound like an unlikely type of endpoint, until you realize that in some systems one application might write information to a file and, later, another application might read that file.
  • An FTP server.
  • An email address. A client can send a message to an email address, and a server can read an incoming message from a mail server.
  • A POJO (plain old Java object).
    In a Camel-based application, you create (Camel wrappers around) some endpoints and connect these endpoints with routes, which I will discuss later in Section 4.8 ("Routes, RouteBuilders and Java DSL"). Camel defines a Java interface called Endpoint. Each Camel-supported endpoint has a class that implements this Endpoint interface. As I discussed in Section 3.3 ("Online Javadoc documentation"), Camel provides a separate Javadoc hierarchy for each communications technology supported by Camel. Because of this, you will find documentation on, say, the JmsEndpoint class in the JMS Javadoc hierarchy, while documentation for, say, the FtpEndpoint class is in the FTP Javadoc hierarchy.

CamelContext

A CamelContext object represents the Camel runtime system. You typically have one CamelContext object in an application. A typical application executes the following steps.

  1. Create a CamelContext object.
  2. Add endpoints – and possibly Components, which are discussed in Section 4.5 ("Components") – to the CamelContext object.
  3. Add routes to the CamelContext object to connect the endpoints.
  4. Invoke the start() operation on the CamelContext object. This starts Camel-internal threads that are used to process the sending, receiving and processing of messages in the endpoints.
  5. Eventually invoke the stop() operation on the CamelContext object. Doing this gracefully stops all the endpoints and Camel-internal threads.
    Note that the CamelContext.start() operation does not block indefinitely. Rather, it starts threads internal to each Component and Endpoint and then start() returns. Conversely, CamelContext.stop() waits for all the threads internal to each Endpoint and Component to terminate and then stop() returns.
    If you neglect to call CamelContext.start() in your application then messages will not be processed because internal threads will not have been created.
    If you neglect to call CamelContext.stop() before terminating your application then the application may terminate in an inconsistent state. If you neglect to call CamelContext.stop() in a JUnit test then the test may fail due to messages not having had a chance to be fully processed.

CamelTemplate

Camel used to have a class called CamelClient, but this was renamed to be CamelTemplate to be similar to a naming convention used in some other open-source projects, such as the TransactionTemplate and JmsTemplate classes in Spring.
The CamelTemplate class is a thin wrapper around the CamelContext class. It has methods that send a Message or Exchange – both discussed in Section 4.6 ("Message and Exchange")) – to an Endpoint – discussed in Section 4.1 ("Endpoint"). This provides a way to enter messages into source endpoints, so that the messages will move along routes – discussed in Section 4.8 ("Routes, RouteBuilders and Java DSL") – to destination endpoints.

The Meaning of URL, URI, URN and IRI

Some Camel methods take a parameter that is a URI string. Many people know that a URI is "something like a URL" but do not properly understand the relationship between URI and URL, or indeed its relationship with other acronyms such as IRI and URN.
Most people are familiar with URLs (uniform resource locators), such as "http://...", "ftp://...", "mailto:...". Put simply, a URL specifies the location of a resource.
A URI (uniform resource identifier) is a URL or a URN. So, to fully understand what URI means, you need to first understand what is a URN.
URN is an acronym for uniform resource name. There are may "unique identifier" schemes in the world, for example, ISBNs (globally unique for books), social security numbers (unique within a country), customer numbers (unique within a company's customers database) and telephone numbers. Each "unique identifier" scheme has its own notation. A URN is a wrapper for different "unique identifier" schemes. The syntax of a URN is "urn:<scheme-name>:<unique-identifier>". A URN uniquely identifies a resource, such as a book, person or piece of equipment. By itself, a URN does not specify the location of the resource. Instead, it is assumed that a registry provides a mapping from a resource's URN to its location. The URN specification does not state what form a registry takes, but it might be a database, a server application, a wall chart or anything else that is convenient. Some hypothetical examples of URNs are "urn:employee:08765245", "urn:customer:uk:3458:hul8" and "urn:foo:0000-0000-9E59-0000-5E-2". The <scheme-name> ("employee", "customer" and "foo" in these examples) part of a URN implicitly defines how to parse and interpret the <unique-identifier> that follows it. An arbitrary URN is meaningless unless: (1) you know the semantics implied by the <scheme-name>, and (2) you have access to the registry appropriate for the <scheme-name>. A registry does not have to be public or globally accessible. For example, "urn:employee:08765245" might be meaningful only within a specific company.
To date, URNs are not (yet) as popular as URLs. For this reason, URI is widely misused as a synonym for URL.
IRI is an acronym for internationalized resource identifier. An IRI is simply an internationalized version of a URI. In particular, a URI can contain letters and digits in the US-ASCII character set, while a IRI can contain those same letters and digits, and also European accented characters, Greek letters, Chinese ideograms and so on.

Components

Component is confusing terminology; EndpointFactory would have been more appropriate because a Component is a factory for creating Endpoint instances. For example, if a Camel-based application uses several JMS queues then the application will create one instance of the JmsComponent class (which implements the Component interface), and then the application invokes the createEndpoint() operation on this JmsComponent object several times. Each invocation of JmsComponent.createEndpoint() creates an instance of the JmsEndpoint class (which implements the Endpoint interface). Actually, application-level code does not invoke Component.createEndpoint() directly. Instead, application-level code normally invokes CamelContext.getEndpoint(); internally, the CamelContext object finds the desired Component object (as I will discuss shortly) and then invokes createEndpoint() on it.
Consider the following code.

myCamelContext.getEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword");

The parameter to getEndpoint() is a URI. The URI prefix (that is, the part before ":") specifies the name of a component. Internally, the CamelContext object maintains a mapping from names of components to Component objects. For the URI given in the above example, the CamelContext object would probably map the pop3 prefix to an instance of the MailComponent class. Then the CamelContext object invokes createEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword") on that MailComponent object. The createEndpoint() operation splits the URI into its component parts and uses these parts to create and configure an Endpoint object.
In the previous paragraph, I mentioned that a CamelContext object maintains a mapping from component names to Component objects. This raises the question of how this map is populated with named Component objects. There are two ways of populating the map. The first way is for application-level code to invoke CamelContext.addComponent(String componentName, Component component). The example below shows a single MailComponent object being registered in the map under 3 different names.

Component mailComponent = new org.apache.camel.component.mail.MailComponent();
myCamelContext.addComponent("pop3", mailComponent);
myCamelContext.addComponent("imap", mailComponent);
myCamelContext.addComponent("smtp", mailComponent);

The second (and preferred) way to populate the map of named Component objects in the CamelContext object is to let the CamelContext object perform lazy initialization. This approach relies on developers following a convention when they write a class that implements the Component interface. I illustrate the convention by an example. Let's assume you write a class called com.example.myproject.FooComponent and you want Camel to automatically recognize this by the name "foo". To do this, you have to write a properties file called "META-INF/services/org/apache/camel/component/foo" (without a ".properties" file extension) that has a single entry in it called class, the value of which is the fully-scoped name of your class. This is shown below.

META-INF/services/org/apache/camel/component/foo
class=com.example.myproject.FooComponent

If you want Camel to also recognize the class by the name "bar" then you write another properties file in the same directory called "bar" that has the same contents. Once you have written the properties file(s), you create a jar file that contains the com.example.myproject.FooComponent class and the properties file(s), and you add this jar file to your CLASSPATH. Then, when application-level code invokes createEndpoint("foo:...") on a CamelContext object, Camel will find the "foo"" properties file on the CLASSPATH, get the value of the class property from that properties file, and use reflection APIs to create an instance of the specified class.
As I said in Section 4.1 ("Endpoint"), Camel provides out-of-the-box support for numerous communication technologies. The out-of-the-box support consists of classes that implement the Component interface plus properties files that enable a CamelContext object to populate its map of named Component objects.
Earlier in this section I gave the following example of calling CamelContext.getEndpoint().

myCamelContext.getEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword");

When I originally gave that example, I said that the parameter to getEndpoint() was a URI. I said that because the online Camel documentation and the Camel source code both claim the parameter is a URI. In reality, the parameter is restricted to being a URL. This is because when Camel extracts the component name from the parameter, it looks for the first ":", which is a simplistic algorithm. To understand why, recall from Section 4.4 ("The Meaning of URL, URI, URN and IRI") that a URI can be a URL or a URN. Now consider the following calls to getEndpoint.

myCamelContext.getEndpoint("pop3:...");
myCamelContext.getEndpoint("jms:...");
myCamelContext.getEndpoint("urn:foo:...");
myCamelContext.getEndpoint("urn:bar:...");

Camel identifies the components in the above example as "pop3", "jms", "urn" and "urn". It would be more useful if the latter components were identified as "urn:foo" and "urn:bar" or, alternatively, as "foo" and "bar" (that is, by skipping over the "urn:" prefix). So, in practice you must identify an endpoint with a URL (a string of the form "<scheme>:...") rather than with a URN (a string of the form "urn:<scheme>:..."). This lack of proper support for URNs means the you should consider the parameter to getEndpoint() as being a URL rather than (as claimed) a URI.

Message and Exchange

The Message interface provides an abstraction for a single message, such as a request, reply or exception message.
There are concrete classes that implement the Message interface for each Camel-supported communications technology. For example, the JmsMessage class provides a JMS-specific implementation of the Message interface. The public API of the Message interface provides get- and set-style methods to access the message id, body and individual header fields of a messge.
The Exchange interface provides an abstraction for an exchange of messages, that is, a request message and its corresponding reply or exception message. In Camel terminology, the request, reply and exception messages are called in, out and fault messages.
There are concrete classes that implement the Exchange interface for each Camel-supported communications technology. For example, the JmsExchange class provides a JMS-specific implementation of the Exchange interface. The public API of the Exchange interface is quite limited. This is intentional, and it is expected that each class that implements this interface will provide its own technology-specific operations.
Application-level programmers rarely access the Exchange interface (or classes that implement it) directly. However, many classes in Camel are generic types that are instantiated on (a class that implements) Exchange. Because of this, the Exchange interface appears a lot in the generic signatures of classes and methods.

Processor

The Processor interface represents a class that processes a message. The signature of this interface is shown below.

Processor
package org.apache.camel;
public interface Processor {
    void process(Exchange exchange) throws Exception;
}

Notice that the parameter to the process() method is an Exchange rather than a Message. This provides flexibility. For example, an implementation of this method initially might call exchange.getIn() to get the input message and process it. If an error occurs during processing then the method can call exchange.setException().
An application-level developer might implement the Processor interface with a class that executes some business logic. However, there are many classes in the Camel library that implement the Processor interface in a way that provides support for a design pattern in the EIP book. For example, ChoiceProcessor implements the message router pattern, that is, it uses a cascading if-then-else statement to route a message from an input queue to one of several output queues. Another example is the FilterProcessor class which discards messages that do not satisfy a stated predicate (that is, condition).

Routes, RouteBuilders and Java DSL

A route is the step-by-step movement of a Message from an input queue, through arbitrary types of decision making (such as filters and routers) to a destination queue (if any). Camel provides two ways for an application developer to specify routes. One way is to specify route information in an XML file. A discussion of that approach is outside the scope of this document. The other way is through what Camel calls a Java DSL (domain-specific language).

Introduction to Java DSL

For many people, the term "domain-specific language" implies a compiler or interpreter that can process an input file containing keywords and syntax specific to a particular domain. This is not the approach taken by Camel. Camel documentation consistently uses the term "Java DSL" instead of "DSL", but this does not entirely avoid potential confusion. The Camel "Java DSL" is a class library that can be used in a way that looks almost like a DSL, except that it has a bit of Java syntactic baggage. You can see this in the example below. Comments afterwards explain some of the constructs used in the example.

Example of Camel's "Java DSL"
RouteBuilder builder = new RouteBuilder() {
    public void configure() {
        from("queue:a").filter(header("foo").isEqualTo("bar")).to("queue:b");
        from("queue:c").choice()
                .when(header("foo").isEqualTo("bar")).to("queue:d")
                .when(header("foo").isEqualTo("cheese")).to("queue:e")
                .otherwise().to("queue:f");
    }
};
CamelContext myCamelContext = new DefaultCamelContext();
myCamelContext.addRoutes(builder);

The first line in the above example creates an object which is an instance of an anonymous subclass of RouteBuilder with the specified configure() method.
The CamelContext.addRoutes(RouterBuilder builder) method invokes builder.setContext(this) – so the RouteBuilder object knows which CamelContext object it is associated with – and then invokes builder.configure(). The body of configure() invokes methods such as from(), filter(), choice(), when(), isEqualTo(), otherwise() and to().
The RouteBuilder.from(String uri) method invokes getEndpoint(uri) on the CamelContext associated with the RouteBuilder object to get the specified Endpoint and then puts a FromBuilder "wrapper" around this Endpoint. The FromBuilder.filter(Predicate predicate) method creates a FilterProcessor object for the Predicate (that is, condition) object built from the header("foo").isEqualTo("bar") expression. In this way, these operations incrementally build up a Route object (with a RouteBuilder wrapper around it) and add it to the CamelContext object associated with the RouteBuilder.

Critique of Java DSL

The online Camel documentation compares Java DSL favourably against the alternative of configuring routes and endpoints in a XML-based Spring configuration file. In particular, Java DSL is less verbose than its XML counterpart. In addition, many integrated development environments (IDEs) provide an auto-completion feature in their editors. This auto-completion feature works with Java DSL, thereby making it easier for developers to write Java DSL.
However, there is another option that the Camel documentation neglects to consider: that of writing a parser that can process DSL stored in, say, an external file. Currently, Camel does not provide such a DSL parser, and I do not know if it is on the "to do" list of the Camel maintainers. I think that a DSL parser would offer a significant benefit over the current Java DSL. In particular, the DSL would have a syntactic definition that could be expressed in a relatively short BNF form. The effort required by a Camel user to learn how to use DSL by reading this BNF would almost certainly be significantly less than the effort currently required to study the API of the RouterBuilder classes.

Architecture

Camel uses a Java based Routing Domain Specific Language (DSL) or an Xml Configuration to configure routing and mediation rules which are added to a CamelContext to implement the various Enterprise Integration Patterns.

At a high level Camel consists of a CamelContext which contains a collection of Component instances. A Component is essentially a factory of Endpoint instances. You can explicitly configure Component instances in Java code or an IoC container like Spring or Guice, or they can be auto-discovered using URIs.

An Endpoint acts rather like a URI or URL in a web application or a Destination in a JMS system; you can communicate with an endpoint; either sending messages to it or consuming messages from it. You can then create a Producer or Consumer on an Endpoint to exchange messages with it.

The DSL makes heavy use of pluggable Languages to create an Expression or Predicate to make a truly powerful DSL which is extensible to the most suitable language depending on your needs. The following languages are supported

Most of these languages is also supported used as Annotation Based Expression Language.

For a full details of the individual languages see the Language Appendix

URIs

Camel makes extensive use of URIs to allow you to refer to endpoints which are lazily created by a Component if you refer to them within Routes

Current Supported URIs

Component / ArtifactId / URI Description
ActiveMQ / activemq-camel
activemq:[topic:]destinationName
For JMS Messaging with Apache ActiveMQ
ActiveMQ Journal / activemq-core
activemq.journal:directory-on-filesystem
Uses ActiveMQ's fast disk journaling implementation to store message bodies in a rolling log file
AMQP / camel-amqp
amqp:[topic:]destinationName
For Messaging with AMQP protocol
Atom / camel-atom
atom:uri
Working with Apache Abdera for atom integration, such as consuming an atom feed.
Bean / camel-core
bean:beanName[?methodName=someMethod]
Uses the Bean Binding to bind message exchanges to beans in the Registry. Is also used for exposing and invoking POJO (Plain Old Java Objects).
CXF / camel-cxf
cxf:address[?serviceClass=...]
Working with Apache CXF for web services integration
DataSet / camel-core
dataset:name
For load & soak testing the DataSet provides a way to create huge numbers of messages for sending to Components or asserting that they are consumed correctly
Direct / camel-core
direct:name
Direct invocation of the consumer from the producer so that single threaded (non-SEDA) in VM invocation is performed
Esper / camel-esper in camel-extra
esper:name
Working with the Esper Library for Event Stream Processing
Event / camel-spring
event://default
spring-event://default
Working with Spring ApplicationEvents
File / camel-core
file://nameOfFileOrDirectory
Sending messages to a file or polling a file or directory
FIX / camel-fix in FUSE
fix://configurationResource
Sends or receives messages using the FIX protocol
Flatpack / camel-flatpack
flatpack:[fixed|delim]:configFile
Processing fixed width or delimited files or messages using the FlatPack library
FTP / camel-ftp
ftp://host[:port]/fileName
Sending and receiving files over FTP
Hibernate / camel-hibernate in camel-extra
hibernate://entityName
For using a database as a queue via the Hibernate library
HL7 / camel-hl7
mina:tcp://hostname[:port]
For working with the HL7 MLLP protocol and the HL7 model using the HAPI library
HTTP / camel-http
http://hostname[:port]
For calling out to external HTTP servers
iBATIS / camel-ibatis
ibatis://sqlOperationName
Performs a query, poll, insert, update or delete in a relational database using Apache iBATIS
IMap / camel-mail
imap://hostname[:port]
Receiving email using IMap
IRC / camel-irc
irc:host[:port]/#room
For IRC communication
JavaSpace / camel-javaspace in FUSE
javaspace:jini://host?spaceName=mySpace?...
Sending and receiving messages through JavaSpace
JBI / servicemix-camel
jbi:serviceName
For JBI integration such as working with Apache ServiceMix
JCR / camel-jcr
jcr://user:password@repository/path/to/node
Storing a message in a JCR (JSR-170) compliant repository like Apache Jackrabbit
JDBC / camel-jdbc
jdbc:dataSourceName?options
For performing JDBC queries and operations
Jetty / camel-jetty
jetty:url
For exposing services over HTTP
JMS / camel-jms
jms:[topic:]destinationName
Working with JMS providers
JPA / camel-jpa
jpa://entityName
For using a database as a queue via the JPA specification for working with OpenJPA, Hibernate or TopLink
JT/400 / camel-jt400
jt400://user:pwd@system/<path_to_dtaq>
For integrating with data queues on an AS/400 (aka System i, IBM i, i5, ...) system
LDAP / camel-ldap
ldap:host[:port]?base=...[&scope=<scope>]
Performing searches on LDAP servers (<scope> must be one of object|onelevel|subtree)
List / camel-core
list:someName
Provdes a simple BrowsableEndpoint which can be useful for testing, visualisation tools or debugging. The exchanges sent to the endpoint are all available to be browsed.
Log / camel-core
log:loggingCategory[?level=ERROR]
Uses Jakarta Commons Logging to log the message exchange to some underlying logging system like log4j
Mail / camel-mail
mail://user-info@host:port
Sending and receiving email
MINA / camel-mina
[tcp|udp|multicast]:host[:port]
Working with Apache MINA
Mock / camel-core
mock:name
For testing routes and mediation rules using mocks
MSMQ / camel-msmq in FUSE
msmq:msmqQueueName
Sending and receiving messages with Microsoft Message Queuing
MSV / camel-msv
msv:someLocalOrRemoteResource
Validates the payload of a message using the MSV Library
Multicast / camel-mina
multicast://host:port
Working with TCP protocols using Apache MINA
Pojo / camel-core
pojo:name
Deprecated. It is now an alias to the Bean component.
POP / camel-mail
pop3://user-info@host:port
Receiving email using POP3 and JavaMail
Quartz / camel-quartz
quartz://groupName/timerName
Provides a scheduled delivery of messages using the Quartz scheduler
Queue / camel-core
queue:name
Deprecated.  It is now an alias to the SEDA component.
Ref / camel-core
ref:name
Component for lookup of existing endpoints bound in the Registry.
RMI / camel-rmi
rmi://host[:port]
Working with RMI
RNC / camel-jing
rnc:/relativeOrAbsoluteUri
Validates the payload of a message using RelaxNG Compact Syntax
RNG / camel-jing
rng:/relativeOrAbsoluteUri
Validates the payload of a message using RelaxNG
SEDA / camel-core
seda:name
Used to deliver messages to a java.util.concurrent.BlockingQueue, useful when creating SEDA style processing pipelines within the same CamelContext
SFTP / camel-ftp
sftp://host[:port]/fileName
Sending and receiving files over SFTP
Smooks / camel-smooks in camel-extra
unmarshal(edi)
For working with EDI parsing using the Smooks library
SMTP / camel-mail
smtp://user-info@host[:port]
Sending email using SMTP and JavaMail
SpringIntegration / camel-spring-integration
spring-integration:defaultChannelName
The bridge component of Camel and Spring Integration
SQL / camel-sql
sql:select * from table where id=#
Performing SQL queries using JDBC
Stream / camel-stream
stream:[in|out|err|file]
Read or write to an input/output/error/file stream rather like unix pipes
StringTemplate / camel-stringtemplate
string-template:someTemplateResource
Generates a response using a String Template
TCP / camel-mina
tcp://host:port
Working with TCP protocols using Apache MINA
Test / camel-spring
test:expectedMessagesEndpointUri
Creates a Mock endpoint which expects to receive all the message bodies that could be polled from the given underlying endpoint
Timer / camel-core
timer://name
A timer endpoint
UDP / camel-mina
udp://host:port
Working with UDP protocols using Apache MINA
Validation / camel-spring
validation:someLocalOrRemoteResource
Validates the payload of a message using XML Schema and JAXP Validation
Velocity / camel-velocity
velocity:someTemplateResource
Generates a response using an Apache Velocity template
VM / camel-core
vm:name
Used to deliver messages to a java.util.concurrent.BlockingQueue, useful when creating SEDA style processing pipelines within the same JVM
XMPP / camel-xmpp
xmpp://host:port/room
Working with XMPP and Jabber
XQuery / camel-saxon
xquery:someXQueryResource
Generates a response using an XQuery template
XSLT / camel-spring
xslt:someTemplateResource
Generates a response using an XSLT template

For a full details of the individual components see the Component Appendix

Enterprise Integration Patterns

Camel supports most of the Enterprise Integration Patterns from the excellent book of the same name by Gregor Hohpe and Bobby Woolf. Its a highly recommended book, particularly for users of Camel.

Pattern Index

There now follows a list of the Enterprise Integration Patterns from the book along with examples of the various patterns using Apache Camel

Messaging Systems

Message Channel How does one application communicate with another using messaging?
Message How can two applications connected by a message channel exchange a piece of information?
Pipes and Filters How can we perform complex processing on a message while maintaining independence and flexibility?
Message Router How can you decouple individual processing steps so that messages can be passed to different filters depending on a set of conditions?
Message Translator How can systems using different data formats communicate with each other using messaging?
Message Endpoint How does an application connect to a messaging channel to send and receive messages?

Messaging Channels

Point to Point Channel How can the caller be sure that exactly one receiver will receive the document or perform the call?
Publish Subscribe Channel How can the sender broadcast an event to all interested receivers?
Dead Letter Channel What will the messaging system do with a message it cannot deliver?
Guaranteed Delivery How can the sender make sure that a message will be delivered, even if the messaging system fails?
Message Bus What is an architecture that enables separate applications to work together, but in a de-coupled fashion such that applications can be easily added or removed without affecting the others?

Message Construction

Correlation Identifier How does a requestor that has received a reply know which request this is the reply for?

Message Routing

Content Based Router How do we handle a situation where the implementation of a single logical function (e.g., inventory check) is spread across multiple physical systems?
Message Filter How can a component avoid receiving uninteresting messages?
Dynamic Router How can you avoid the dependency of the router on all possible destinations while maintaining its efficiency?
Recipient List How do we route a message to a list of dynamically specified recipients?
Splitter How can we process a message if it contains multiple elements, each of which may have to be processed in a different way?
Aggregator How do we combine the results of individual, but related messages so that they can be processed as a whole?
Resequencer How can we get a stream of related but out-of-sequence messages back into the correct order?
Routing Slip How do we route a message consecutively through a series of processing steps when the sequence of steps is not known at design-time and may vary for each message?
Throttler How can I throttle messages to ensure that a specific endpoint does not get overloaded, or we don't exceed an agreed SLA with some external service?
Delayer How can I delay the sending of a message?
Load Balancer How can I balance load across a number of endpoints?
Multicast How can I route a message to a number of endpoints at the same time?
Loop How can I repeat processing a message in a loop?

Message Transformation

Content Enricher How do we communicate with another system if the message originator does not have all the required data items available?
Content Filter How do you simplify dealing with a large message, when you are interested only in a few data items?
Normalizer How do you process messages that are semantically equivalent, but arrive in a different format?

Messaging Endpoints

Messaging Mapper How do you move data between domain objects and the messaging infrastructure while keeping the two independent of each other?
Event Driven Consumer How can an application automatically consume messages as they become available?
Polling Consumer How can an application consume a message when the application is ready?
Competing Consumers How can a messaging client process multiple messages concurrently?
Message Dispatcher How can multiple consumers on a single channel coordinate their message processing?
Selective Consumer How can a message consumer select which messages it wishes to receive?
Durable Subscriber How can a subscriber avoid missing messages while it's not listening for them?
Idempotent Consumer How can a message receiver deal with duplicate messages?
Transactional Client How can a client control its transactions with the messaging system?
Messaging Gateway How do you encapsulate access to the messaging system from the rest of the application?
Service Activator How can an application design a service to be invoked both via various messaging technologies and via non-messaging techniques?

System Management

Wire Tap How do you inspect messages that travel on a point-to-point channel?

For a full breakdown of each pattern see the Book Pattern Appendix

CookBook

This chapter describes various recipes for working with Camel

Bean Integration

Camel supports the integration of beans and POJOs in a number of ways

Bean Binding

Whenever Camel invokes a bean method, either via the Bean component, Spring Remoting or POJO Consuming then the Bean Binding mechanism is used to figure out what method to use (if it is not explicit) and how to bind the Message to the parameters possibly using the Parameter Binding Annotations

Annotations

If a bean is defined in Spring XML or scanned using the Spring 2.5 component scanning mechanism and a <camelContext> is used or a CamelBeanPostProcessor then we process a number of Camel annotations to do various things such as injecting resources or producing, consuming or routing messages.

Spring Remoting

We support a Spring Remoting provider which uses Camel as the underlying transport mechanism. The nice thing about this approach is we can use any of the Camel transport Components to communicate between beans. It also means we can use Content Based Router and the other Enterprise Integration Patterns in between the beans; in particular we can use Message Translator to be able to convert what the on-the-wire messages look like in addition to adding various headers and so forth.

Bean Component

The Bean component supports the creation of a proxy via ProxyHelper to a Java interface; which the implementation just sends a message containing a BeanInvocation to some Camel endpoint.

Then there is a server side implementation which consumes a message and uses the Bean Binding to bind the message to invoke a method passing in its parameters.

When writing software these days, its important to try and decouple as much middleware code from your business logic as possible.

This provides a number of benefits...

  • you can choose the right middleware solution for your deployment and switch at any time
  • you don't have to spend a large amount of time learning the specifics of any particular technology, whether its JMS or JavaSpace or Hibernate or JPA or iBatis whatever

For example if you want to implement some kind of message passing, remoting, reliable load balancing or asynchronous processing in your application we recommend you use Camel annotations to bind your services and business logic to Camel Components which means you can then easily switch between things like

  • in JVM messaging with SEDA
  • using JMS via ActiveMQ or other JMS providers for reliable load balancing, grid or publish and subscribe
  • for low volume, but easier administration since you're probably already using a database you could use
  • use JavaSpace

How to decouple from middleware APIs

The best approach when using remoting is to use Spring Remoting which can then use any messaging or remoting technology under the covers. When using Camel's implementation you can then use any of the Camel Components along with any of the Enterprise Integration Patterns.

Another approach is to bind Java beans to Camel endpoints via the Bean Integration

Visualisation

Camel supports the visualisation of your Enterprise Integration Patterns using the GraphViz DOT files which can either be rendered directly via a suitable GraphViz tool or turned into HTML, PNG or SVG files via the Camel Maven Plugin.

Here is a typical example of the kind of thing we can generate

If you click on the actual generated htmlyou will see that you can navigate from an EIP node to its pattern page, along with getting hover-over tool tips ec.

How to generate

See Camel Dot Maven Goal or the other maven goals Camel Maven Plugin

For OS X users

If you are using OS X then you can open the DOT file using graphviz which will then automatically re-render if it changes, so you end up with a real time graphical representation of the topic and queue hierarchies!

Also if you want to edit the layout a little before adding it to a wiki to distribute to your team, open the DOT file with OmniGraffle then just edit away

Business Activity Monitoring

The Camel BAM module provides a Business Activity Monitoring (BAM) framework for testing business processes across multiple message exchanges on different Endpoint instances.

For example if you have a simple system which you submit Purchase Orders into system A and then receive Invoices from system B, you might want to test that for a specific Purchase Order you receive a matching Invoice from system B within a specific time period.

How Camel BAM Works

What Camel BAM does is use a Correlation Identifier on an input message to determine which Process Instance a message belongs to. The process instance is an entity bean which can maintain state for each Activity (where an activity typically maps to a single endpoint, such as the receipt of Purchase orders, or the receipt of Invoices).

You can then add rules which are fired when a message is received on any activity such as to set time expectations, or to perform real time reconciliation of values across activities etc.

Simple Example

The following example shows how to perform some time based rules on a simple business process of 2 activities A and B (which maps to the Purchase Order and Invoice example above). If you want to experiment with this scenario you could edit the Test Case which defines the activities and rules, then tests that they work.

return new ProcessBuilder(jpaTemplate, transactionTemplate) {
    public void configure() throws Exception {

        // lets define some activities, correlating on an XPath on the message bodies
        ActivityBuilder a = activity("seda:a").name("a")
                .correlate(xpath("/hello/@id"));

        ActivityBuilder b = activity("seda:b").name("b")
                .correlate(xpath("/hello/@id"));

        // now lets add some rules
        b.starts().after(a.completes())
                .expectWithin(seconds(1))
                .errorIfOver(seconds(errorTimeout)).to("mock:overdue");
    }
};

As you can see in the above example, we define two activities first, then we define rules on when we expect the activities on an individual process instance to complete by along with the time at which we should assume there is an error. The ProcessBuilder is-a RouteBuilder and can be added to any CamelContext

Complete Example

For a complete example please see the BAM Example which is part of the standard Camel Examples

Use Cases

In the world of finance a common requirement is tracking financial trades. Often a trader will submit a Front Office Trade which then flows through the Middle Office and Back Office through various systems to settle the trade so that money is exchanged. You may wish to add tests that front and back office trades match up within a time period; if they don't match or a back office trade does not arrive within a required amount of time, you might want to fire off an alarm.

Extract Transform Load (ETL)

The ETL (Extract, Transform, Load) is a mechanism for loading data into systems or databases using some kind of Data Format from a variety of sources; often files then using Pipes and Filters, Message Translator and possible other Enterprise Integration Patterns.

So you could query data from various Camel Components such as File, HTTP or JPA, perform multiple patterns such as Splitter or Message Translator then send the messages to some other Component.

To show how this all fits together, try the ETL Example

Mock Component

Testing of distributed and asynchronous processing is notoriously difficult. The Mock, Test and DataSet endpoints work great with the Spring Testing framework to simplify your unit and integration testing using Enterprise Integration Patterns and Camel's large range of Components together with the powerful Mock and Test testing endpoints.

The Mock component provides a powerful declarative testing mechanism which is similar to jMock in that it allows declarative expectations to be created on any Mock endpoint before a test begins. Then the test is ran which typically fires messages to one or more endpoints and finally the expectations can be asserted in a test case to ensure the system worked as expected.

This allows you to test various things like

  • the correct number of messages are received on each endpoint
  • that the correct payloads are received, in the right order
  • that messages arrive on an endpoint in order, using some Expression to create an order testing function
  • that messages arrive match some kind of Predicate such as that specific headers have certain values, or that parts of the messages match some predicate such as by evaluating an XPath or XQuery Expression

Note that there is also the Test endpoint which is-a Mock endpoint but which also uses a second endpoint to provide the list of expected message bodies and automatically sets up the Mock endpoint assertions. i.e. its a Mock endpoint which automatically sets up its assertions from some sample messages in a File or database for example.

URI format

mock:someName

Where someName can be any string to uniquely identify the endpoint

Simple Example

Here's a simple example of MockEndpoint in use. First the endpoint is resolved on the context. Then we set an expectation, then after the test has run we assert our expectations are met.

MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class);

resultEndpoint.expectedMessageCount(2);

// send some messages
...

// now lets assert that the mock:foo endpoint received 2 messages
resultEndpoint.assertIsSatisfied();

You typically always call the assertIsSatisfied() method to test that the expectations were met after running a test.

Setting expectations

You can see from the javadoc of MockEndpoint the various helper methods you can use to set expectations. The main methods available are as follows

Method Description