For this tutorial and the following ones, I am going to use a Fuse instance on a Lubuntu Linux box. My IDE is Eclipse Luna and the build system is Apache Maven v. 3.5.2. Eclipse is actually running on Java 8 but it does not matter since I’m going to run all the builds from a terminal.
Let’s see how we can implement and deploy a simple Camel route in JBoss Fuse. We start by defining our requirements that, in this case, are going to be very trivial: we want to read messages from a queue, process them and the write them back to another queue. The processing step is going to be simple too: we will just log the message body.
First of all, we need two queues. Start Fuse and reach the console (see the previous post). In the menu bar, click on “ActiveMQ”. Then click on “+Create” on the submenu, select “queue” in the radio buttons group, type the appropriate name in the text box (I’m choosing “source-queue”) and finally click the “Create Queue” button (see pictures below). Repeat the process and create a “sink-queue” queue, it will be our destination queue. Later, we will be going to need to queue a message in the source queue through the web panel. In order to be able to do that, we have to set the username and password. In the web console, go to the drop down menu in the top right corner (where your username appears). Select “preferences”. Go to the “ActiveMQ” tab and insert your administrative username and password. The settings are automatically saved. Now that we have the infrastructure ready, let’s switch to the development side.
If you are going to develop projects for Fuse, Maven is the way to go. The default way you install new components in Fuse, is by telling it to get the artifacts from a Maven repository. For this tutorial I assume that you are quite familiar and comfortable with Maven and that you have a working installation of Maven on your system.
We can create the initial skeleton of the project starting from a Maven archetype. Open a Terminal and type:
mvn archetype:generate
choose the archetype named camel-archetype-blueprint (in my case is the number 449) and complete the process. Here is a dump of my terminal:
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 510: 449
Choose org.apache.camel.archetypes:camel-archetype-blueprint version:
1: 2.8.0
[...]
42: 2.14.1
Choose a number: 42: 42
Downloading: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.jar
Downloaded: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.jar (17 KB at 14.1 KB/sec)
Downloading: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.pom
Downloaded: https://repo.maven.apache.org/maven2/org/apache/camel/archetypes/camel-archetype-blueprint/2.14.1/camel-archetype-blueprint-2.14.1.pom (3 KB at 10.9 KB/sec)
Define value for property 'groupId': : org.merka
Define value for property 'artifactId': : fuse-demo-blueprint
Define value for property 'version': 1.0-SNAPSHOT: : 1.0
Define value for property 'package': org.merka: : org.merka.demo
[INFO] Using property: camel-version = 2.14.1
[INFO] Using property: log4j-version = 1.2.17
[INFO] Using property: maven-bundle-plugin-version = 2.3.7
[INFO] Using property: maven-compiler-plugin-version = 2.5.1
[INFO] Using property: maven-resources-plugin-version = 2.6
[INFO] Using property: slf4j-version = 1.7.7
Confirm properties configuration:
groupId: org.merka
artifactId: fuse-demo-blueprint
version: 1.0
package: org.merka.demo
camel-version: 2.14.1
log4j-version: 1.2.17
maven-bundle-plugin-version: 2.3.7
maven-compiler-plugin-version: 2.5.1
maven-resources-plugin-version: 2.6
slf4j-version: 1.7.7
Y: : Y
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: camel-archetype-blueprint:2.14.1
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.merka
[INFO] Parameter: artifactId, Value: fuse-demo-blueprint
[INFO] Parameter: version, Value: 1.0
[INFO] Parameter: package, Value: org.merka.demo
[INFO] Parameter: packageInPathFormat, Value: org/merka/demo
[INFO] Parameter: maven-bundle-plugin-version, Value: 2.3.7
[INFO] Parameter: maven-resources-plugin-version, Value: 2.6
[INFO] Parameter: groupId, Value: org.merka
[INFO] Parameter: maven-compiler-plugin-version, Value: 2.5.1
[INFO] Parameter: slf4j-version, Value: 1.7.7
[INFO] Parameter: version, Value: 1.0
[INFO] Parameter: log4j-version, Value: 1.2.17
[INFO] Parameter: camel-version, Value: 2.14.1
[INFO] Parameter: package, Value: org.merka.demo
[INFO] Parameter: artifactId, Value: fuse-demo-blueprint
[INFO] project created from Archetype in dir: /home/merka/workspace/fuse-demo-blueprint
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:20 min
[INFO] Finished at: 2014-12-23T20:29:24+01:00
[INFO] Final Memory: 13M/60M
[INFO] ------------------------------------------------------------------------
Now we can import the project in our IDE of choice and open it. Just to be sure that everything is OK, run a first build with the command mvn -DskipTests=true clean package from the shell and wait for the required dependencies to be downloaded.
The archetype project comes with a couple of “hello world” files that you can completely ignore at this point: they only serves as an example. It’s actually better if you delete all the hello-world-related stuff, unit test included. Open the blueprint.xml file in the folder OSGI-INF/blueprint and comment out the existing route. You should also delete the “helloBean” definition. The file should 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"
xmlns:camel="http://camel.apache.org/schema/blueprint"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<camelContext id="blueprintContext" trace="false" xmlns="http://camel.apache.org/schema/blueprint">
<!-- <route id="timerToLog"> -->
<!-- <from uri="timer:foo?period=5000"/> -->
<!-- <setBody> -->
<!-- <method ref="helloBean" method="hello"/> -->
<!-- </setBody> -->
<!-- <log message="The message contains ${body}"/> -->
<!-- <to uri="mock:result"/> -->
<!-- </route> -->
</camelContext>
</blueprint>
Before the camelContext element, add the following bean definition: it provides Camel with the credentials to access the ActiveMQ Broker:
<!-- connect to the local ActiveMQ broker -->
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616" />
<property name="userName" value="merka" />
<property name="password" value="merka" />
</bean>
Then, add the following snippet inside the camelContext element. It defines a route that satisfies our requirements:
<route id="queue2queue">
<from uri="activemq:source-queue"></from>
<log message="the message body is: ${body}" loggingLevel="INFO"></log>
<to uri="activemq:sink-queue"></to>
</route>
It is quite readable. The from element defines a consumer endpoint: it will read messages from the queue named source-queue (that we have just created), as soon as they are available. The message body is logged, thanks to the log element, and then it is written to sink-queue.
Build the project with Maven (mvn clean install). This puts the artifact in the local Maven repository, thus making it available to Fuse. To install the artifact in Fuse, go to the Karaf prompt and type
osgi:install mvn:org.merka/fuse-demo-blueprint/1.0
With this command you tell Karaf to search for the artifact with the given groupId/artifactId/version. If found, it answers with the id of the installed osgi bundle:
JBossFuse:karaf@root> osgi:install mvn:org.merka/fuse-demo-blueprint/1.0
Bundle ID: 251
You can see all the installed components typing list. Start the bundle with the commnand start <bundle-id>. Check the log for possible errors with log:display or log:tail. If no errors are found, go to the web console and manually send a message into the source-queue queue. The message is immediately consumed from the queue, the message body appears in the log and a brand new message is sent to sink-queue.