Logo Computer scientist,
engineer, and educator
• Articles • Articles about computing • Articles about software development • Apache integration software

Implementing an Apache Camel route in an OSGi Java bundle using Maven from the ground up

This article describes how to use Maven to build a simple Camel route in an OSGi bundle, that can be deployed on Apache Karaf. It also explains the function a simple example of a route specified using the OSGi Blueprint XML specification. This article builds on a number of previous articles, which I will assume the reader is familiar with:

The basics of Camel routing are described in Creating an Apache Camel route in Java from the ground up; you should read this first if you have no idea what Camel is. The basics of the OSGi model, and how to install and configure Apache Karaf are dealt with in Creating OSGI bundles and services from the ground up using Apache Karaf. Some of the steps are repeated in this article for convenience, but I won't be repeating the detailed explanation. Configuring Karaf for hosting OSGi bundles containing Camel routes is outlined in Implementing an Apache Karaf route in an OSGi Java bundle from the ground up. Finally, the use of Maven with Camel is covered in Creating an Apache Camel JMS route in Java using Maven, step by step ; you should read this if you have never used Maven, or have no idea what a Maven Archetype is.

Because Maven automates almost the entire process of building and packaging a simple application, it's possible to follow the steps in this article without reading any of the previous ones. However, there would be little educational benefit in doing so.

Because the Maven Archetype automatically creates a simple "Hello, World" Camel route, there is no coding in this article. However, I will explain in outline what the archetype generates and how it works.

The steps in this article have been tested with Karaf 2.3.3 on Fedora Linux. However, because much of the software components are taken implicitly from public repositories, which are constantly being updated, I can't be sure that the version numbers I give are current, or that newer versions will behave in exactly the same way.

Installing and configuration Apache Karaf for Camel support

Obtaining and configuring Karaf for Camel routing support is described in Implementing an Apache Karaf route in an OSGi Java bundle from the ground up. In summary, from the Karaf context the necessary steps are as follows:
karaf@root> features:chooseurl camel 2.12.1
karaf@root> features:install camel
karaf@root> osgi:install -s mvn:org.apache.camel/camel-osgi/1.5.0
Use osgi:list to ensure that all the bundles are in the Active state.

Creating the Maven project

Applying the Maven archetype

Maven has access to an archetype that sets up a project that creates a Camel route specified using an XML file. The XML format is an extension of the Blueprint format specified by the OSGi model. Probably most developers who are coding Camel routes using XML are using the Spring format; the Blueprint format is based on this and is similar, apart from the headers.

The Maven archetype is called camel-archetype-blueprint, and the project skeleton can be created using the following Maven command:

$ mvn archetype:generate \
  -DarchetypeGroupId=org.apache.camel.archetypes \
  -DarchetypeArtifactId=camel-archetype-blueprint \
  -DarchetypeVersion=2.8.0 \
  -DgroupId=net.kevinboone.apacheintegration \
  -DartifactId=camelosgimaventest -Dversion=0.0.0.1
Here the command-line switches beginning with 'archetype' define the idenity of the archetype we need. The remaining switches define and name the software component we are creating. These are abitrary, must be be unique in the Maven repository being used. We will use these identifiers when installing from the Maven repository to the Karaf container.

Examining the sample bundle

We don't need to code anything to deploy and run this simple example, because the archetype generates a "Hello, world" example that is ready to run. Naturally this example would need to be extended in a real project, but as it is it is sufficient for demonstration purposes.

The application is controlled by the blueprint.xml file. The Maven archetype puts this in the directory src/main/resources/OSGI-INF/blueprint, and when the bundle JAR file is built its location will be /OSGI-INF, as specified by OSGi. The blueprint.xml file is parsed when the bundle starts up, and primarily defines JavaBeans and their relationships to one another; it also specifies a set of Camel routes, if the necessary support has been added to the container.

In this example we define on JavaBean:

  <bean id="helloBean" class="net.kevinboone.apacheintegration.HelloBean">
      <property name="say" value="Hi from Camel"/>
  </bean>
The id field is used to refer to an instance of this Java class; the class itself has a package name based on the groupId given creating the project. The property element causes the method setSay() to be executed, with the argument "Hi from Camel. The class HelloBean has only three methods: getSay() and setSay(), as needed to define the property say, and a method hello() which returns a text string based on the value of the say property.

The Camel route is defined as follows:

    <route>
      <from uri="timer:foo?period=5000"/>
      <setBody>
          <method ref="helloBean" method="hello"/>
      </setBody>
      <log message="The message contains ${body}"/>
    </route>
The origin of the route is a timer that ticks once every 5000 msec. The destination of the route is a log operation. When the timer fires, the result of executing HelloBean.hello() is collected into a message body, and that body is passed to the logger.

The other key file generated by the Maven archetype is the project specification pom.xml. I won't reproduce this here, but if you look in this file you should see two interesting elements. First, the dependencies section defines that the project depends on camel-core and camel-blueprint. These artefacts will be pulled from the Maven repository the first time the project is built, and the necessary components added to the compiler class search path. Second there is a plugin section that invokes maven-bundle-plugin. This plug-in allows Maven to package the Java classes and XML files into the structure of an OSGi bundle, and create the bundle manifest. The structure and purpose of the manifest are described in my earlier article Creating OSGI bundles and services from the ground up using Apache Karaf.

Building the bundle

Thanks to the magic of Maven (for better or worse), the project can be built, packaged, and installed in the local Maven repository simply by running
$ mvn install
A local copy of the assembled bundle is generated with the name camelosgimaventest-0.0.0.1.jar (0.0.0.1 being the version number). By default, the local maven repository is in $HOME/.m2, and the JAR file will be placed in a directory whose name is obtained by contatenating the groupId (net.kevinboone.apacheintegration in this case), the artefact ID (camelosgimaventest), the version number. This standardised location will be meaningful to the Maven installer in Karaf.

Deploying the bundle into Karaf

Ultimately, what will get installed in Karaf is the JAR file containing the OSGi bundle. However, there are two ways to do that using the osgi:install command in the Karaf console: we can use a file:// URL and give the filesystem location of the JAR file, or we can use a mvn: URL.

In this case it makes no difference as, in the end, the file will come from the local filesystem. However, in some senses it makes sense to become familiar with the Maven URL syntax, as this works for retrieving bundles from remote repositories as well. So, to install the bundle:

karaf@root> osgi:install -s mvn:net.kevinboone.apacheintegration/camelosgimaventest
The Maven installer knows to look for this Maven artefact in the local repository before checking the public repositories, and the mvn install command will have placed it in the right place in the local repository.

If the bundle is installed successfully, you should see the message it outputs in the Karaf log (data/log/karaf.log) every five seconds.

60 - org.apache.camel.camel-core - 2.12.1 | The message contains Hi from Camel at 2014-05-02 19:27:14

Summary

This article has explained how to build a very simple Camel route using Maven and package it up as an OSGi bundle to deploy on Karaf. Although simple, most of the infrastructure is in place to deploy more complex routes, simply by editing blueprint.xml and adding such Java code as is needed.
Copyright © 1994-2013 Kevin Boone. Updated May 02 2014