Example: Apache Camel with Blueprint

Here we present a fully-working Apache Camel Blueprint project. It provides example code for building routes, creating beans, and deploying to ServiceMix with Blueprint.

Blueprint

In short, Blueprint is much like Spring. Really, its a lot like Spring, but with slight differences. The Blueprint Container specification was created by the OSGi Alliance (using Eclipse Gemini Blueprint as the reference implementation) to provide applications with a better separation of modules, the ability to dynamically add, remove, and update modules in a running system, the ability to deploy multiple versions of a module simultaneously (and have clients automatically bind to the appropriate one), and a dynamic service model. Blueprint is heavily influenced by Spring, and therefore it implements many Spring features, although it is more geared towards OSGi applications.

The Blueprint file is written in XML and is usually contained in the OSGI-INF/blueprint/ directory, which is it's default location. This directory will get packaged with the resulting JAR file, and OSGi containers like ServiceMix will look there by default to check for one or more Blueprint files. This doesn't seem to be documented very well anywhere, but keep in mind that Blueprint files aren't required to be packaged inside of a JAR file. They can be standalone files that get loaded in to an OSGi container (i.e. dropped in to the deploy/ directory of ServiceMix) by themselves. This can be extremely handy for reconfiguring routes on the fly.

The Code

Here, we'll show you how to create a simple, deployable Camel route using a mix of Blueprint (for route specification) and Java (for message processing). The project directory is structured as follows:

stackabuse-example-blueprint/
    pom.xml
    src/
        main/
            java/
                com.stackabuse.example.WeatherProcessor.java
            resources/
                OSGI-INF/
                    blueprint/
                        blueprint-example.xml
        test/

Using Maven for OSGi bundles is very convenient, mostly because of the provided maven-bundle-plugin created by the Apache Felix project. This plugin, given some configurations in the pom.xml file, will generate your MANIFEST.MF file for you using BND, saving a lot of headaches.

The blueprint-example.xml file contains our Camel route definitions in XML, which is capable of the same level of detail as the Java domain specific language (DSL). The contents look like this:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
            http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
            http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/blueprint/jaxws.xsd
            http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
           ">

  <bean id="weatherProcessor" class="com.stackabuse.example.WeatherProcessor" />

  <camelContext xmlns="http://camel.apache.org/schema/blueprint">

    <route>
      <from uri="timer:fetch?period=3600s&amp;delay=5s" />
      <to uri="direct:trigger" />
    </route>

    <route>
      <from uri="direct:trigger" />
      <to uri="weather:foo?location=Omaha,United States&amp;period=7 days&amp;units=IMPERIAL" />
      <process ref="weatherProcessor" />
      <to uri="log:com.stackabuse.example?level=DEBUG" />
      <to uri="file:/Users/scott/Desktop/weather?fileName=omaha.txt" />
    </route>

  </camelContext>

</blueprint>

All Blueprint files start with the <blueprint> tag and usually contain the <camelContext> tag to specify Camel routes. In this example, our route is triggered by a simple timer every hour (3600 seconds), in which it will then fetch the 7 day forecast for Omaha, NE USA and save the result in to a file on the desktop. Before the data is saved, it gets routed through a processor, which is defined as Java bean before the <camelContext> tag starts. This bean, which is shown below, implements the org.apache.camel.Processor interface and extracts only the data we want from the returned JSON weather data. It parses the JSON and returns a string of the form "[date]: [temperature] Celsius" to be saved to the file.

On Apache Camel's website, just about every Camel component page provides examples in both Java and Blueprint, making route development just as easy, if not easier, in Blueprint. I've found it difficult to find many examples of Blueprint code out there, despite it's popularity, so if you ever have doubts about Blueprint's capabilities, just assume whatever works in Spring will work in Blueprint, plus the extra Camel-specific features/schemas.

Using the Code

If you'd like to try this out yourself, you can download the code below. To run it, you must have Apache Maven and Apache ServiceMix installed. Build the project by navigating to the stackabuse-example-blueprint directory, executing mvn package, and finally, placing the resulting JAR file in ServiceMix's deploy/ directory. Since the resulting JAR is an OSGi bundle, it won't contain it's dependencies like you may expect. You'll need to place the following dependencies in the deploy/ folder as well:

  • org.apache.felix.eventadmin-1.3.2.jar
  • camel-weather-2.12.3.jar
  • camel-core-osgi-2.12.3.jar
  • org.osgi.core-1.0.0.jar
  • json-20140107.jar

You should be able to find all of these JARs in your local Maven repository (~/.m2/) after building the project with Maven.

And finally, to run the bundle, start ServiceMix by either executing servicemix or start from the [ServiceMix Home Dir]/bin. Within a few seconds, you should see a weather/ directory appear on the desktop containing a file with the next day weather forecast for Omaha.

Resources