Getting Started
This document will guide you through the fundamentals of the Apache Camel Core. At the end of it you will have a basic understanding of integrating systems, have learned some of the most important concepts of the project, and will be able to create and run your first project.
The Enterprise Integration Patterns (E.I.P.) book
Books about design patterns document the existing best practices within a particular field. The authors of these books hope to spread knowledge of best practices and to promote a vocabulary for discussing architectural designs.
A famous book about design patterns is the Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions written by Gregor Hohpe and Bobby Wolf. The E.I.P. book, as it is known, describes 65 design patterns for asynchronous messaging systems. The book gives each of them a name and an image - intended to be used in architectural diagrams.
The Apache Camel Core project
The Apache Camel Core is an open-source, Java-based project that helps users to implement many of the design patterns described in the E.I.P. book. As such, we suggest that our users have a copy of the E.I.P. book as one of their references.
Supporting Documentation
Online documentation for Camel
The links on the right-side allow easy navigation between different topics within a guide. Our documentation tries to cover the topics for both novice and experienced users. However, experienced users may want to skip the subjects they are familiar with.
Over the years, our community has written books, articles and tutorials about Apache Camel. Our community has presented Apache Camel in many videos and talks.
Some notable references from material developed from members, which may provide significant help for new users include:
-
The Camel in Action 2nd edition book, presently serving as the Camel bible, has a free chapter one, which is highly recommended to read to get more familiar with Camel.
-
The Fundamentals of Apache Camel training by Michael Hoffman.
We strongly recommend that our users explore the pages above for additional material that suits their needs.
Online Javadoc documentation
Our API documentation in Javadoc format is available on javadoc.io.
The Javadoc API that are the most relevant for Camel end users are in the following components (JARs):
Creating your first project
We’ll start this guide by creating a simple integration. You need to have Apache Maven and a JDK version 11 or greater installed on your system.
We strongly recommend you use an LTS version of Java (i.e., 11 or 17). We regularly test Camel in our continuous integration (CI) environment using Java’s LTS versions. |
Generating the project
You will use one of the various Maven archetypes provided by Camel to create your first project. An archetype is a template for a project. In other words: Camel Core provides templates you can use to create projects.
Run this command to create your first Camel Core project:
mvn archetype:generate -B -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-java -DarchetypeVersion=3.18.4 -Dpackage=org.apache.camel.learn -DgroupId=org.apache.camel.learn -DartifactId=first-camel-integration -Dversion=1.0.0-SNAPSHOT
If you have never used archetypes before, the command looks lengthy. We’ll explain the relevant arguments:
-
-DarchetypeArtifactId
: this is the ID of the archetype to use (i.e., which of the templates from Camel Core to use -camel-archetype-java
in this case) -
-DarchetypeVersion
: this is the version of the archetype to use. It is also the same version of Camel to use for the example. We are using3.18.4
in this example. -
-Dpackage
: the package name for the project you are creating. We’ll useorg.apache.camel.learn
in all this guide. -
-DgroupId
: the group ID for the project you are creating. We’ll useorg.apache.camel.learn
in all this guide. -
-DartifactId
: the artifact name for the project you are creating. -
-Dversion
: the version for your project.
later we will describe other ways to generate a Camel project. |
Building and running the project
You can run the following command to build the project:
mvn clean package
To run the project you can run the following command:
mvn camel:run -Dcamel.main.durationMaxMessages=2
After you run the command above, you should have the following messages:
...
[che.camel.learn.MainApp.main()] MainSupport INFO Apache Camel (Main) 3.18.4 is starting
[che.camel.learn.MainApp.main()] BaseMainSupport INFO Auto-configuration summary
[che.camel.learn.MainApp.main()] BaseMainSupport INFO [JVM System Property] camel.main.durationMaxMessages=2
[che.camel.learn.MainApp.main()] XPathBuilder INFO Created default XPathFactory com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl@33cc7a16
[che.camel.learn.MainApp.main()] FileEndpoint INFO Endpoint is configured with noop=true so forcing endpoint to be idempotent as well
[che.camel.learn.MainApp.main()] FileEndpoint INFO Using default memory based idempotent repository with cache max size: 1000
[che.camel.learn.MainApp.main()] AbstractCamelContext INFO Apache Camel 3.18.4 (camel-1) is starting
[che.camel.learn.MainApp.main()] AbstractCamelContext INFO Routes startup (started:1)
[che.camel.learn.MainApp.main()] AbstractCamelContext INFO Started route1 (file://src/data)
[che.camel.learn.MainApp.main()] AbstractCamelContext INFO Apache Camel 3.18.4 (camel-1) started in 89ms (build:12ms init:68ms start:9ms JVM-uptime:1s)
[che.camel.learn.MainApp.main()] MainSupport INFO Waiting until complete: Duration max 2 messages processed
[1) thread #1 - file://src/data] route1 INFO Other message
[1) thread #1 - file://src/data] route1 INFO UK message
[1) thread #1 - file://src/data] MainLifecycleStrategy INFO Duration max messages triggering shutdown of the JVM
[ CamelMainShutdownCamelContext] AbstractCamelContext INFO Apache Camel 3.18.4 (camel-1) is shutting down (timeout:45s)
[ CamelMainShutdownCamelContext] AbstractCamelContext INFO Routes stopped (stopped:1)
[ CamelMainShutdownCamelContext] AbstractCamelContext INFO Stopped route1 (file://src/data)
[ CamelMainShutdownCamelContext] AbstractCamelContext INFO Apache Camel 3.18.4 (camel-1) shutdown in 7ms (uptime:1s JVM-uptime:2s)
[che.camel.learn.MainApp.main()] MainSupport INFO Apache Camel (Main) 3.18.4 shutdown
If you can see an output like that on your terminal, it means the integration has run well.
The integration you have just run consumed two files and copied them to a directory based on their contents. You can check it out yourself but looking at the target/messages
directory within the project:
find target/messages
You should have the following files:
target/messages target/messages/others target/messages/others/message2.xml target/messages/uk target/messages/uk/message1.xml
Use the Windows Explorer or the Windows equivalent of the |
Understanding the project
The integration you created implements a pattern (E.I.P.) called Content Based Router. The Camel implementation of this pattern allows you to implement logic that route messages based on their content.
More specifically, this integration looks at the content of the XML files in the src/data
directory. If the content of the element city
is London, then it moves the file to the directory target/messages/uk
. Otherwise, it moves the file to the directory target/messages/others
.
To create the integration that performs this task, this code configures a route that connects a source endpoint represented by the address file:src/data?noop=true
to two other endpoints represented by the addresses file:target/messages/uk
and file:target/messages/others
.
Do not worry if you feel overwhelmed by the technical jargon. In the next sections we will explain what each of these are and why they are important for Camel-based integrations.
Endpoint
When we talk about inter-process communication, such as client/server or microservices, we often use the term endpoint to refer to a software entity. In this context, a characteristic of an endpoint is that it is contactable at an address. The address may itself convey additional characteristics of an endpoint. For instance, the address host:port
conveys both the port and network name of a TCP-based communication endpoint.
The distinction between the address and the software contactable at that address is often not important.
in the past, other technologies (such as CORBA) used the terminology endpoint in ways that could appear ambiguous. To prevent any confusion, we clarify that Camel uses it solely in the way we have described above. |
Camel provides out-of-the-box support for endpoints implemented with many communication technologies. Here are some examples of the 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).
Routes
In a Camel-based application, you create routes. A route is used to connect a source endpoint to a destination endpoint.
Other projects in the integration, microservices and middleware space use the terms source and sink for the source and destination endpoints. The Camel Core project does not use this terminology. |
A route describes the step-by-step movement of a Message
from a source endpoint, through arbitrary types of decision-making routines (such as filters and routers) to a destination endpoint (if any).
At this point, you might want to use an IDE to open the project and view the files. |
In the project you created, there should be 2 source files located in the directory src/main/java/org/apache/camel/learn
:
-
MainApp.java
: contains the code for configuring and launching the application. -
MyRouteBuilder.java
: contains the code for the route.
The code for the route should be:
public class MyRouteBuilder extends RouteBuilder {
public void configure() {
from("file:src/data?noop=true")
.choice()
.when(xpath("/person/city = 'London'"))
.log("UK message")
.to("file:target/messages/uk")
.otherwise()
.log("Other message")
.to("file:target/messages/others");
}
}
We will elaborate on the nature and the role of a route within the Camel Core project in later parts of this guide. For now, let’s focus on the two most important aspects of the route that we created:
-
It extends the
RouteBuilder
, which is the base class for creating routes in Camel. -
It uses the
configure
method to describe the step-by-step movement of the data from the source to the destination.
Route Configuration
In this route configuration, we are connecting the source endpoint represented by the address file:src/data?noop=true
to two other endpoints represented by the addresses file:target/messages/uk
and file:target/messages/others
. In Camel, Uniform Resource Identifiers (URIs) represent the addresses of the endpoints. These URIs convey additional information that is very important for the route and your integration:
-
The component that is used to consume and/or produce data.
-
A resource identifier.
-
The options for the component.
The Meaning of URL, URI and URN
Some Camel methods take a parameter that is a URI string. People usually know that a URI is "something like a URL" but do not always understand the relationship between URI and an URL or its relationship with other acronyms such as IRI and URN.
Most people are familiar with URLs (uniform resource locators), such as http://…
, ftp://…
, \mailto:…:
. A URL specifies the location of a resource.
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 (i.e.:, a book, person, or piece of equipment). By itself, a URN does not specify the location of the resource.
A URI (uniform resource identifier) is a URL or a URN.
The Endpoint Address
In Camel, the URIs that represent the addresses of the endpoints take the following format:
component:resource[?options]
The scheme part of the URI represents the component used to consume or produce data. Camel contains more than 300 components that allow your application to communicate with many systems, protocols, and applications.
These are some examples of valid URIs for Camel: jms:queue:order
, kafka:myTopic?groupId=KafkaConsumerFullIT
, direct:result
. By looking at these URIs we can identify that they are using the jms
, kafka
, and the direct
component.
Every component has its own specific set of features, constraints, and requirements that we must observe when working with them. Camel exposes them through the resource
and options
. What this means varies according to the component we are working with. For instance, in the file component, the resource is a directory; in the Kafka component, the resource is the topic; etc.
Route Configuration and EIPs
The integration you created implements a pattern (E.I.P.) called Content Based Router.
Camel usually exposes these patterns via a Java Domain-Specific Language (Java DSL). You can use the methods from the Java DSL in the route to implement the patterns. For instance, the integration you created contained the following code snippet:
// ...
.choice()
.when(xpath("/person/city = 'London'"))
.log("UK message")
.to("file:target/messages/uk")
.otherwise()
.log("Other message")
.to("file:target/messages/others");
// ...
The code above implements the Content Based Router by evaluating (when()
) a predicate that tests if the body of the message matches an xpath expression (xpath("/person/city = 'London'")
). If true
, then the destination endpoint for the message should be file:target/messages/uk
. Otherwise, the destination endpoint should be file:target/messages/others
.
Camel supports most of the Enterprise Integration Patterns from the excellent book by Gregor Hohpe and Bobby Woolf.
Adding Routes and Running the Application
Before executing a route, it needs to be configured and added to the CamelContext.
The MainApp.java
file contains the code that performs these steps:
public class MainApp {
public static void main(String... args) throws Exception {
Main main = new Main();
main.configure().addRoutesBuilder(new MyRouteBuilder());
main.run(args);
}
}
We start by creating a Main component that we configure to include the route (main.configure().addRoutesBuilder(new MyRouteBuilder());
). Then we start the execution of the main application by running it with the run
method that will create the CamelContext and execute the integration in the foreground until we terminate it (i.e., with Ctrl + C
).
You don’t interact directly with the CamelContext in this example, but it is a fundamental part of Camel. We will talk about it in the next section.
Concepts and terminology fundamental to Camel
In this section, we explain additional Camel concepts and features.
CamelContext
The CamelContext is the runtime system, which holds together all the fundamental concepts we have presented so far (routes, endpoints, components, etc).
This context object represents the Camel runtime system. Typically, you have one CamelContext instance in an application.
You did not manipulate the CamelContext in the sample application you created, because the Main component managed it for you. As your integration grows more complex, you will eventually need to manipulate it. A typical application executes the following steps:
-
Create the context object.
-
Add endpoints and, possibly, components, which we will discuss in the Section ("Components").
-
Add routes to the context object to connect the endpoints.
-
Invoke the
start()
operation on the context object. This operation starts the Camel internal threads that process the sending, receiving, and processing of messages in the endpoints. -
Eventually invoke the
stop()
operation on the context object. Doing this, gracefully stops all the endpoints and Camel-internal threads.
the |
If you neglect to call CamelContext.start()
in your application, Camel will not process the messages because internal threads will not have been created.
If you neglect to call CamelContext.stop()
before terminating your application, it may terminate in an inconsistent state. If you neglect to call CamelContext.stop()
in a JUnit test, it may fail because the messages did not have a chance to be fully processed.
our documentation contains an in-depth overview of the CamelContext if you want to learn more about it. |
Components
Components are another fundamental building block of Apache Camel and are used to connect routes to a wide variety of external systems and services. Camel comes with a large number of built-in components that provide connectivity to a wide range of technologies and protocols, such as HTTP, JMS, file, and many others. You can also create a custom components if the built-in components do not meet your needs.
Typically, Camel-based applications shouldn’t need to interact directly with a component. However, there are some circumstances where manipulating the component may be beneficial for the performance, operation, or scalability of the application. Our documentation contains an in-depth overview of the Component if you want to learn more about it, including important details necessary to write your own.
Message and Exchange
The Message
interface provides an abstraction for a single message, such as a request, reply or exception message.
The public API of the Message
interface provides getters and setters methods. You can use them to access the message id, body and individual header fields of a message.
The Exchange
interface provides an abstraction for an exchange of messages. An exchange of messages is a request message and its corresponding reply or exception message. In Camel, the request, reply and exception messages are called in, out and fault messages.
Processor
A processor is used to implement consumers of message exchanges or to implement a Message Translator, and other use-cases.
When writing routes, you may use processors to execute more complex logic on the exchanges. For example:
public void process(Exchange exchange) {
final String body = exchange.getMessage().getBody(String.class);
System.out.println(“Updated body: “ + body.replace(“city”, “county”));
// ... more code here
}
public void configure() {
from(“file:src/data?noop=true”)
.process(this::process);
}
The code for the processor must comply with the Processor
interface. This interface represents a class that processes a message. We show the signature of this interface below:
package org.apache.camel;
public interface Processor {
void process(Exchange exchange) throws Exception;
}
the parameter to the |
An application-level developer might also want to implement the Processor
interface with a class that executes some business logic.
our documentation contains an in-depth overview of the Processor. |
Built-in processors
Many classes in the Camel library implement the Processor
interface in a way that provides support for the design patterns in the E.I.P. 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. -
The
FilterProcessor
class which discards messages that do not satisfy a stated predicate (that is, condition).
Routes, RouteBuilders and Java DSL
Camel provides three ways for an application developer to specify routes:
-
Using XML.
-
Using YAML.
-
Using the Java Domain-specific Language (DSL).
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. Our 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 you can use in a way that looks almost like a DSL, except that it has a bit of Java syntactic baggage.
our documentation contains an in-depth overview of the Java DSL. |
Continue Learning about Camel
Now that you have learned the basics of Camel, you can refer to the Working With Camel Core for a list of guides that can help you increase your understanding about Camel.
You can also refer to the Reference Documentation to get access to the links with documentation for all of Camel’s components, EIPs, DSLs and more.