tisdag 26 juli 2011

Camel and HornetQ as JMS provider

In my current project we're utilizing JBoss HornetQ as the messaging bus, and I wanted to try out how Camel could connect to it. My intention was to have the HornetQ instance running externally from the Camel application and connect to it. There are a bunch of examples on how to embedd HornetQ 2.2.5 (the release I'm dealing with) inside Spring, but I could'nt find a single one for how to connect to an external instance.

For my own reference I post the working solution here which uses HornetQ's JNDI to lookup the ConnectionFactory as well as a Spring JNDI template.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
<prop key="java.naming.provider.url">jnp://localhost:1099</prop>
<prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</prop>
</props>
</property>
</bean>

<bean id="jmsQueueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate"/>
</property>
<property name="jndiName">
<value>ConnectionFactory</value>
</property>
</bean>

<bean name="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
</bean>

<camel:camelContext id="context1">
<camel:route id="FirstRoute">
<camel:from uri="jms:queue:inputqueue"/>
<camel:log logName="jmsLog" message="Got message from JMS queue:"/>
<camel:to uri="jms:topic:helloworld"/>
</camel:route>
</camel:camelContext>
</beans>


And the Maven POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>camelHornet</groupId>
<artifactId>camelHornet</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<camel.version>2.8.0</camel.version>
<hornet.version>2.2.5.Final</hornet.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-core-client</artifactId>
<version>${hornet.version}</version>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-jms-client</artifactId>
<version>${hornet.version}</version>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-jms</artifactId>
<version>${hornet.version}</version>
</dependency>

<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
<type>jar</type>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.hornetq</groupId>
<artifactId>hornetq-logging</artifactId>
<version>${hornet.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
<version>3.2.3.Final</version>
</dependency>
<dependency>
<groupId>jboss</groupId>
<artifactId>jnp-client</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.0.0.CR1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.camel</groupId>
<artifactId>camel-maven-plugin</artifactId>
<version>${camel.version}</version>
<configuration>
<applicationContextUri>META-INF/context.xml</applicationContextUri>
</configuration>
</plugin>
</plugins>
</build>
</project>

4 kommentarer:

  1. That's a really intressting topic. I had look for how to's but i didn't find anything on google, except yours. Great Job!

    SvaraRadera
  2. Just be wary of the fact that Camel uses Spring's JmsTemplate under the hood for message publishing - unless you're pooling those JMS connections somewhere (perhaps you defined a pooling ConnectionFactory in JNDI?) then you risk creating a Connection, Session and Producer for every message sent. I wrap my HornetQ ConnectionFactory in a Spring CachingConnectionFactory to counteract this problem.

    Craig Leonard

    SvaraRadera
    Svar
    1. You are absolutely right Craig, missing to cache your JMS CF is a very common performance killer. I did not want to clutter the XML config more than necessary however, and this was only a PoC.

      Thanks for the heads up though!

      Radera
  3. Dear Bikky great post!
    If you like you can check the new hornetq book

    www.amazon.com/dp/1849518408/?tag=packtpubli-20

    SvaraRadera