Bridging Between JMS and RabbitMQ (AMQP) Using Spring Integration
Join the DZone community and get the full member experience.
Join For FreeAn old customer recently asked me if I had a solution for how to
integrate between their existing JMS infrastructure on Websphere MQ with
RabbitMQ.
Although I know that RabbitMQ has the shovel plugin
which can bridge between Rabbit instances I've yet not found a good
plugin for JMS <-> AMQP forwarding.
The first thing that came
to my mind was to utilize a Spring Integration mediation as SI has
excellent support for both JMS and Rabbit.
Curious as I am I
started a PoC and this is the result. It takes messages of a JMS queue
and forwards to an AMQP exchange that is bound to a queue the consumer
application is supposed to listen to. I used an external HornetQ
instance in JBoss 6.1 as the JMS Provider, but I am 100% secure that the
same setup would work for Websphere MQ as they both implement JMS.
Be
aware that I've done no performance tweaking or QoS setup yet as this
is just a proof-of-concept. For a real setup you'd probably have to
think about delivery guarantees versus performance and etc...
The code will be available at a GitHub repository near you soon..
SpringContext in XML:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:int-jms="http://www.springframework.org/schema/integration/jms" xmlns:int="http://www.springframework.org/schema/integration" xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp-2.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.1.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <beans:bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <beans:property name="environment"> <beans:props> <beans:prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</beans:prop> <beans:prop key="java.naming.provider.url">jnp://localhost:1099</beans:prop> <beans:prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</beans:prop> </beans:props> </beans:property> </beans:bean> <beans:bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <beans:property name="jndiTemplate"> <beans:ref bean="jndiTemplate"/> </beans:property> <beans:property name="jndiName"> <beans:value>ConnectionFactory</beans:value> </beans:property> </beans:bean> <!-- Channels and adapters for SI --> <int-jms:message-driven-channel-adapter connection-factory="jmsQueueConnectionFactory" destination-name="myJmsQueue" channel="rabbitChannel"/> <channel id="rabbitChannel"/> <int-amqp:outbound-channel-adapter channel="rabbitChannel" exchange-name="fromJmsExchange" amqp-template="rabbitTemplate"/> <!-- Connectivity to Rabbit --> <rabbit:template id="rabbitTemplate" connection-factory="cf"/> <rabbit:connection-factory id="cf" host="localhost"/> <!-- Rabbit entities, to be created at context startup --> <rabbit:admin connection-factory="cf"/> <rabbit:queue name="fromJMS"/> <rabbit:direct-exchange name="fromJmsExchange"> <rabbit:bindings> <rabbit:binding queue="fromJMS"/> </rabbit:bindings> </rabbit:direct-exchange> </beans:beans>
Maven POM:
<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>org.rl</groupId> <artifactId>si.jmstorabbit</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>si.jmstorabbit</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <hornet.version>2.2.5.Final</hornet.version> <spring.integration.version>2.1.0.RELEASE</spring.integration.version> </properties> <repositories> <repository> <id>springsource-release</id> <url>http://repository.springsource.com/maven/bundles/release</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>springsource-external</id> <url>http://repository.springsource.com/maven/bundles/external</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <dependencies> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-core</artifactId> <version>${spring.integration.version}</version> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-file</artifactId> <version>${spring.integration.version}</version> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-amqp</artifactId> <version>${spring.integration.version}</version> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-jms</artifactId> <version>${spring.integration.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.0.7.RELEASE</version> </dependency> <dependency> <groupId>jboss</groupId> <artifactId>jnp-client</artifactId> <version>4.2.2.GA</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>jboss</groupId> <artifactId>jboss-common-client</artifactId> <version>3.2.3</version> </dependency> <dependency> <groupId>org.jboss.netty</groupId> <artifactId>netty</artifactId> <version>3.2.7.Final</version> </dependency> <dependency> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> <version>1.1</version> </dependency> </dependencies> </project>
Published at DZone with permission of Billy Sjöberg, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments