Bridging MSMQ with JMS using FUSE-ESB4

This is a small tutorial showing how to create an OSGi based project to be deployed into FUSE-ESB4.
In particular, using a real use case, I'd like to show how to use some tools that accelerate the building of OSGi based applications ready to be deployed into FUSE-ESB4.

I'm assuming a basic knowledge of FUSE-MediationRouter and Maven.

For this tutorial we need a Windows machine since we are going to use a Camel component which uses a native library for accessing the MSMQ broker.

This is the list of the tools we are going to use:

  • Maven
  • pax-construct, this is a nice collection of scripts that allows to create maven based projects specially tailored for OSGi
  • MSMQ, we assume that you have MSMQ up and running on your machine
  • FUSE-ESB4, install the product with the installer that you can find here

Now that we have all the needed tools ready, let's start:

  1. First, we have to download and install the camel-msmq component from the Progress open source subversion repository, https://projects.open.iona.com/projects/svn/iona/camel/trunk/components/camel-msmq, so please, using any svn client you like check out the source code and after reading the provided README file do a mvn install.
  2. Now go in the FUSE-ESB4 installation directory and type: bin\servicemix.bat this will start the container together with the console shell.
  3. From the console shell we have to install two OSGi bundles needed for our example, so in the console type:
    • osgi install -s mvn:org.apache.camel/camel-jms/1.4.4.0-fuse
    • osgi install -s mvn:org.apache.camel/camel-msmq/1.x-fuse-SNAPSHOT
      The two commands above installed the jms and the msmqm camel components to be used for implementing the bridge.
  4. Now we are ready to build our Camel based JMS to MSMQ bridge. I suggest you to put the directory where the pax-construct scripts reside in your command PATH, then start to type:
    • pax-create-project -g com.progress.ps.fuse.demos -a camel-spring-osgi-jms-msmsq-bridge
    • cd camel-spring-osgi-jms-msmsq-bridge
    • pax-add-repository -i open.iona.m2 -u http://repo.open.iona.com/maven2
    • pax-add-repository -i open.iona.m2-snapshot -u http://repo.open.iona.com/maven2-snapshot
    • pax-create-bundle -p com.progress.ps.fuse.demos.jms_msmq_bridge.routes -n jms-msmq-bridge-routes

What we did so far, it was to create a parent maven project, camel-spring-osgi-jms-msmsq-bridge, we added the Progress open source maven repositories and, finally, we created a maven project jms-msmq-bridge-routes where we are going to define the routes.

The pax-create-bundle creates a maven project which uses the maven-bundle-plugin for packaging the application in a bundle.

From now on we are going to work under the jms-msmq-bridge-routes project directory:

  • add these two dependencies to the pom.xml under jms-msmq-bridge-routes project:
      <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-core</artifactId>
        <version>1.4.4.0-fuse</version>
      </dependency>
      <dependency>
        <groupId>org.apache.camel</groupId>
        <artifactId>camel-msmq</artifactId>
        <version>1.x-fuse-SNAPSHOT</version>
      </dependency>
    
  • remove all the generated classes and add this class:
    package com.progress.ps.fuse.demos.jms_msmq_bridge.routes.internal;
    
    import java.nio.ByteBuffer;
    import org.apache.camel.Exchange;
    import org.apache.camel.Processor;
    import org.apache.camel.builder.RouteBuilder;
    import org.apache.camel.component.msmq.MsmqConstants;
    
    public class MyRouteBuilder extends RouteBuilder {
    	public void configure() throws Exception {
    
    		// From msmq to jms
    		from("timer:myTimerEvent?fixedRate=true&period=200").setBody(
    				constant("Message from msmq to jms")).to(
    				"msmq:DIRECT=OS:localhost\\private$\\msmq-jms");
    
    		from("msmq:DIRECT=OS:localhost\\private$\\msmq-jms").process(
    				new Processor() {
    					public void process(Exchange exc) throws Exception {
    						int size = ((Long) exc.getIn().getHeader(
    								MsmqConstants.BODY_SIZE)).intValue();
    						ByteBuffer buffer = (ByteBuffer) exc.getIn().getBody();
    						exc.getIn().setBody(
    								buffer.asCharBuffer().subSequence(0, size / 2)
    										.toString());
    					}
    				}).to("jms:msmq-jms");
    
    		from("jms:msmq-jms").to("log:msmq-jms");
    
    		// From jms to msmq
    		from("timer:myTimerEvent?fixedRate=true&period=200").setBody(
    				constant("Message from jms to msmq")).to("jms:jms-msmq");
    
    		from("jms:jms-msmq").to("msmq:DIRECT=OS:localhost\\private$\\jms-msmq");
    
    		from("msmq:DIRECT=OS:localhost\\private$\\jms-msmq").process(new Processor() {
    			public void process(Exchange exc) throws Exception {
    				int size = ((Long) exc.getIn().getHeader(
    						MsmqConstants.BODY_SIZE)).intValue();
    				ByteBuffer buffer = (ByteBuffer) exc.getIn().getBody();
    				exc.getIn().setBody(
    						buffer.asCharBuffer().subSequence(0, size / 2)
    								.toString());
    			}
    		}).to("log:jms-msmq");
    	}
    }
    

    In the class above you can see the definition of four routes that simulates the traffic of messages from JMS to MSMQ and vice versa.

  • Create, under MSMQ, two private queues called respectively jms-msmq and msmq-jms.
  • Modify the osgi.bnd file for instructing the maven-bundle-plugin to put the right information in the bundle's manifest:
    #-----------------------------------------------------------------
    # Use this file to add customized Bnd instructions for the bundle
    #-----------------------------------------------------------------
    Import-Package: org.apache.activemq, org.apache.camel, org.apache.camel.builder, org.apache.camel.model, org.apache.camel.component.jms
    
  • Under src/main/resources create a folder META-INF/spring and put there the following xml file, beans.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://activemq.apache.org/camel/schema/osgi"
    	xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
    	xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd
           http://activemq.apache.org/camel/schema/osgi http://activemq.apache.org/camel/schema/osgi/camel-osgi.xsd
           http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd">
    
    	<osgi:camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
    		<package>com.progress.ps.fuse.demos.jms_msmq_bridge.routes.internals</package>
    	</osgi:camelContext>
    
    	<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
    		<property name="connectionFactory">
    			<bean class="org.apache.activemq.ActiveMQConnectionFactory">
    				<property name="brokerURL" value="tcp://localhost:61616" />
    			</bean>
    		</property>
    	</bean>
    
    </beans>
    
  • Now, type mvn install and under the target directory you'll have the bundle jms-msmq-bridge-routes-1.0-SNAPSHOT.jar ready to be deployed
  • Copy the file above into: <fuse-esb install dir>/deploy
  • On the console, if you type: log d you should see something like this:
    16:43:15,533 | INFO  | nerContainer-389 | msmq-jms                         | rg.
    apache.camel.processor.Logger   87 | Exchange[BodyType:String, Body:Message from
     msmq to jms]
    16:43:15,603 | INFO  | pool-28-thread-1 | jms-msmq                         | rg.
    apache.camel.processor.Logger   87 | Exchange[BodyType:String, Body:Message from
     jms to msmq]
    16:43:15,714 | INFO  | nerContainer-390 | msmq-jms                         | rg.
    apache.camel.processor.Logger   87 | Exchange[BodyType:String, Body:Message from
     msmq to jms]
    16:43:15,784 | INFO  | pool-28-thread-1 | jms-msmq                         | rg.
    apache.camel.processor.Logger   87 | Exchange[BodyType:String, Body:Message from
     jms to msmq]
    

    that would mean that the messages are flowing from MSMQ and JMS.
    Using the jconsole you can also check the various information published bu FUSE-ESB4.
    This is a simple example that could be used as a starting point for building something more complex. Pax-construct provides also a pax-wrapper script that creates a maven project for transforming into an OSGi bundle a third party library.
    So, starting from a parent project, using the pax-construct scripts, you can add additional sub-projects for osgi-fying third party libraries and building new bundles, then from the parent project, typing mvn install, you can build your OSGi application together with all its dependencies.

Labels

 
(None)