Monday, March 12, 2012

A Generic Pass-Through Route to solve a variety of Integration Challenges

Have you have ever needed to write a proxy (pass-through) route? This scenario applies to situations where you receive an HTTP request from a client, and simply need to redirect that HTTP request to another back-end server, returning the response from back end to the original client.

You might want to add some custom processing  or transformation to the message (or not) before sending to the back end service. Camel makes it easy to add such custom processing. I’ve seen cases where the simple ability to log and provide a “point of record” was enough to warrant the use of a pass-through route.  Another use for a pass-through would be to “fix” a request message  (so that it contains expected payload) before sending it on to the server – or manipulating a response into a suitable format for the client.  You can imagine a pass-through route that doesn’t touch requests coming from newer clients, but that can update requests (on the fly) that come from legacy clients so that those messages adhere to newer version, and eliminate need to maintain older back end server. 

So now that we’ve established the usefulness of a pass-through pattern – I will show you an easy way to implement this pattern. Apache Camel makes it very easy to write a route that implements the pass-through pattern. Here I will descried the steps of to create such a pass-through route is just a matter of minutes. You can create a new FUSE Project using the FUSE IDE. You can download FUSE IDE from here:

Once installed, FUSE IDE will allow you to easily create any type of route.

Below is the spring configuration that implements the proxy route.



<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:camel="http://camel.apache.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       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">



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

              <route>

                     <from uri="jetty:http://0.0.0.0:5012/proxy/incoming" />

                     <to uri="log:com.fusesource.proxytest?level=DEBUG&amp;showAll=true&amp;multiline=true&amp;showBody=true" />

                     <removeHeaders pattern="CamelHttp*"/>

                     <removeHeader headerName="Host"/>

       

                     <to uri="jetty:http://localhostt:3000/myservice/send" />

              </route>

       </camelContext>



</beans>

From the example, you can see the incoming component is the camel jetty. The Outgoing is also camel jetty.

The reason for the “removeHeaders” is basically to remove all the CamelHttp* headers that get populated by the incoming camel jetty consumer. Because certain headers get automatically populated and retained as the exchange passes through the route, the existence of these headers could potentially confuse and impact the behavior of the outgoing camel jetty producer. When certain headers are not removed, The outgoing jetty producer component (that sends requests to back end) gets confused, potentially over-riding the value configured for destination URL,  and you can end up with unexpected value for actual endpoint destination URL used by consumer component. Take care with these CamelHttp* headers and my advice is remove them in routes that go from jetty consumer to  jetty producer.  The basic idea is explained here:


You may be tempted to use the Camel HTTP component (camel-http) rather than 'jetty' for calling the back end in your pass-through route. The 'jetty' producer component has better performance under load, so it is almost always the right choice for this pattern.

The Jetty HTTP client endpoint uses the Jetty library to implement a HTTP client. In particular, the Jetty HTTP client features support for HttpClient thread pool and non-blocking request/response.  See more info on benefits of the Camel 'jetty' producer component in the FUSE documentation for writing a pass-through route .

I’m attaching a working example. If you want to play with working code - you can download it from here.
The the following sub-projects:
proxytest - A maven project that implements the route. To build run 'mvn install'. To run the route in standalone mode you can type 'mvn camel:run'.

mockservice - A simple mock server that mimics a real back end service. Your pass-through route can use this to redirect requests to in the absence of a real back end service. To build type 'mvn install'. To run the mock service in standalone mode you can type 'mvn camel:run'.

Included, is a sample SOAP UI client project (see proxytest\proxy-test-soapui-project.xml) that you can import into SOAP UI, and use to send HTTP request into the route. The route will receive the request on port 5012, redirect to the mock service listening on port 3000. The mock service will simply echo back the request. The route will then return the response back to the original SOAP UI client.  You can use SOAP UI to perform load tests on your new proxy service!

Wednesday, June 29, 2011

Camel Integration with Oracle WebLogic JMS

This post is similar to a previous post Camel Integration with WebSphere MQ. However, this time I will describe my experience with implementing a Camel route that integrates with WebLogic JMS. The Camel route runs inside Servicemix as an OSGI bundle. I used the Enterprise version of Servicemix from FuseSource available here:
http://fusesource.com/downloads/

This use-case was developed to show how to achieve interoperability with WebLogic.
You can download the example code here,

You can extract this file and, using Eclipse, import as an "existing Maven project". You will need to have the M2Eclipse plugin installed.
Overview
The following diagram shows what is happening in the use case created to demonstrate interoperability with WebLogic.







The use case consists of a Camel route (deployed inside Servicemix) that receives an HTTP message from an external client. The arrival of the HTTP message triggers the route. The route is pretty simple. It simply takes the payload of the HTTP message and drops it onto a WebLogic message queue.

The HTTP message received (that triggers the route) is a two-way (request/response.) The message exchange pattern (MEP) for any route is generally determined by the first (consumer) endpoint in a route. Therefore the MEP for this particular route is request/response.

In this route, the JMS producer is responsible for placing the message on the pre-configured WebLogic JMS queue. Because the route is request/response, the JMS producer will by default wait on a response to arrive on the response queue. This response queue is determined by whatever queue name is set in the outgoing JMS message’s JMSReplyTo header. The JMSReplyTo header is a standard-based JMS message header that indicates which address (queue) the JMS consumer that receives the message, should reply to.

In some cases the replyTo queue could be a temporary queue set up (per-message) by Camel on the fly to listen for reply (dynamic replyTo). In other cases, the replyTo queue will be a well-known location (static replyTo.) In the current use-case the replyTo queue is a well-known (static) location. This follows a pattern common to many JMS applications.

To make it easy to test, this example creates a secondary route inside WebLogicRoute.java. that serves as a “mock” server. This route listens on the “test” queue and transforms the message (simply writes request to response) and places response on the replyTo queue.
Implementation
The following shows the Camel code for this route.

from("jetty:http://0.0.0.0:8888/placeorder")
.to(“wmq:queue:test?replyTo=testResponse&useMessageIDAsCorrelationID=true");


The code simply listens for incoming HTTP messages (via the camel Jetty component) and forwards the payload to a WebLogic queue specified by “wmq:queue:test”. (Note the “wmq:” refers to the bean ID of JMSComponent in the Spring configuration file.) The route sets the value of the “JMSreplyTo” header using an option on the outgoing queue URI. Thus the route, after sending to the “test” queue, will wait on a response on the queue specified in the ‘replyTo’ option. In this case the route will listen for a response on “testResponse”. Camel will by default use a message selector to identify the response message, searching for the response message that has a corrrelationId that matching the messageId of the original message. In this way, Camel handles the message correlation for you without additional code. The response then gets converted and sent back to the original client via HTTP.
A secondary route exist merely to “mock” a server and will receive requests and post replies. Typically this will be done by an external process but for our purposes this “mock” service makes the route self-contained and easier to test. Additionally, this secondary route shows just how easy it is to pull messages off a queue, process them, and post replies. The code for this secondary “mock” service is shown below:

// This can be used to "Mock" Server
from(“wmq:queue:test?useMessageIDAsCorrelationID=true")        
        .to("myTransform");

Should you decide to use an external Service to pull requests off the “test” queue you can simply comment out this secondary route.
Spring Configuration
The Spring configuration for WebLogic, used in this example route is shown below:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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">

    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <routeBuilder ref="weblogicRoute"/>
    </camelContext>

    <bean id="weblogicRoute" class="com.fusesource.example.camel.WebLogicRoute">
         <!-- This is the "request" queue -->
        <property name="requestQueue" value="test"/>
         <!-- This is the "response" queue -->   
        <property name="responseQueue" value="testResponse"/>
    </bean>

         <bean id="myTransform" class="com.fusesource.example.camel.MyTransform"/>

        <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
            <property name="environment">
                <props>
                    <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
                    <prop key="java.naming.provider.url">t3://localhost:7001</prop>
                    <prop key="java.naming.security.principal">weblogic</prop>
                    <prop key="java.naming.security.credentials">password1</prop>
                </props>
            </property>
        </bean>

        <bean id="jndiFactoryBean" class="org.springframework.jndi.JndiObjectFactoryBean">
            <property name="jndiName" value="jms/connectionFactory"/>
            <property name="jndiTemplate" ref="jndiTemplate"/>
            <property name="lookupOnStartup" value="false"/>
            <property name="proxyInterface" value="javax.jms.ConnectionFactory"/>
        </bean>

        <bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
            <property name="jndiTemplate" ref="jndiTemplate"/>
        </bean>

          <bean id="jmsConfiguration" class="org.apache.camel.component.jms.JmsConfiguration">
            <property name="connectionFactory" ref="jndiFactoryBean"/>
            <property name="destinationResolver" ref="jndiDestinationResolver"/>
        </bean>

        <bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
               <property name="configuration" ref="jmsConfiguration" />
        </bean>

</beans>

WebLogic Setup
As a JMS broker, WebLogic is somewhat picky about how things are set up. You are responsible for setting up a server, a domain, a jms module, a subdeployment and a connection factory and a queue.
1)     Set up a server for the following t3://localhost:7001.
2)     Set up a connection factory and give jms/connectionFactory as its JNDI name.
3)     Set up a queue and give “test” as its JNDI name.
4)     Set up a queue and give “testResponse” as its jndi name.
5)     Make sure Admin Server for the Domain you just created is up before starting the example Camel route.
A good reference guide for setting up these things inside WebLogic using Oracle Admin Server Console is the following reference:
Making WebLogic Dependency (JAR) available to Maven

When implementing a Camel solution to interoperate with WebLogic MQ, there is a required WebLogic JMS specific client library needed. For the purpose of this example, this library was obtained from an installation of Oracle WebLogic Server 11g for Windows.
The specific WebLogic library required at run-time is “wlthint3client.jar”.
To install the library into your local Maven repo, and thus available to Maven build (and Servicemix), go to your WebLogic installation directory and install wlthint3client using appropriate Maven command. (Note: this library has been included for your convenience in the \lib folder of this example.)
For example, if you have installed WebLogic in  c:\Oracle, the command to install the weblogic client jar into your local maven repo would look like this:
mvn -e install:install-file -Dfile=C:\Oracle\Middleware\wlserver_10.3\server\lib\wlthint3client.jar -DgroupId=weblogic -DartifactId=weblogic -Dversion=10.3 -Dpackaging=jar
Once the libraries are added to the local Maven repository as shown above, then the ‘pom.xml’ file for the given project can include the dependencies, using the groupId, artifactId, and version in order to identify the dependency to Maven. Maven should then be able to find the dependency in the local repo and use it when running the unit test.
    <dependency>
            <groupId>weblogic</groupId>
            <artifactId>weblogic</artifactId>
            <version>10.3</version>
    </dependency>
Note: We do not instantiate weblogic JMS objects in code, rather they are injected via Spring XML. So there is no compile-time requirement for the Weblogic JAR. The requirement for this dependency to be specified comes only when the unit test is run. We’ll talk more about how to make this JAR available when running the bundle inside Servicemix in the next section.
Building the example
First make sure you have built the example and installed into local maven repo:
mvn clean install
This will build the bundle (place the resulting jar into the /target folder), install the bundle into the local Maven respository, and run the JUnit test.
If the build and unit test succeeds you are ready to install the bundle into Servicemix.
As an alternative to running this route in Servicemix, you can also run the camel route in standalone mode (thanks to the camel-maven-plugin in the pom) by typing
mvn camel:run
You can see the routing rules by looking at the java code in the src/main/java directory and the Spring XML configuration lives in src/main/resources/META-INF/spring
Making WebLogic JMS client library Available inside Servicemix (Runtime)

The weblogic client library needs to be installed into FUSE ESB (Servicemix) making it available at run time. Assuming you have run the 'mvn install:install-file' command to install the weblogic library into the local maven repository, you should now be able to install the library into Servicemix by pointing Servicemix to the proper location in the local maven repo (using the'wrap:' and 'mvn:' prefix.
From the Servicemix command-line console type:
osgi:install wrap:mvn:weblogic/weblogic/10.3\$Bundle-SymbolicName=weblogic&Bundle-Version=10.3
Once the dependent runtime Weblogic client JAR file is installed in Servicemix, you can install the WebLogic example route into Servicemix.
Installing the Route
You have 3 options for installing the bundle. Choose one of the following techniques.
1) Install as feature
The pom file does the necessary work to create a feature file representing the bundle. This feature file is installed alongside the bundle into the local maven repository. You can add the feature descriptor to the set of feature descriptors that Servicemix knows about by issuing the following command:
features:addurl  mvn:com.fusesource.examples/camel-weblogic-osgi/1.0.0/xml/features
You can then install the "camel-weblogic-osgi" feature by running the following:
features:install  camel-weblogic-osgi
2) Install as a bundle
Before doing this make sure the dependent runtime features have been installed:
features:install camel-jms
features:install camel-jetty
osgi:install wrap:mvn:weblogic/weblogic/10.3\$Bundle-SymbolicName=weblogic&Bundle-Version=10.3
Once above dependencies are successfully installed into Servicemix, you can install the example route into servicemix using the following from the servicemix command console:
osgi:install -s mvn:com.fusesource.examples/camel-weblogic-osgi/1.0.0
3) Copy JAR into hotdeploy directory
Before doing this make sure the dependent features specified in option 2 above “Install as a bundle” have been installed. Once these dependencies are successfully installed into Servicemix, you can install the example route while Servicemix is running, drop the file target\camel-weblogic-osgi-1.0.0.jar into the \deploy directory of your Servicemix installation.
Logging and Troubleshooting
Make sure there is no other route listening for request on port 8888.
To enable logging for this example type:
log:set DEBUG  com.fusesource.example.camel
With logging set to DEBUG for 'com.fusesource.example.camel', search the log for "Message body =" (see the debug statements in MyTransform.java).
For an even higher level of logging (logging Camel specifics)
log:set DEBUG org.apache.camel
See logs in <servicemix_home>\data\logs\servicemix.log
Testing the Route
To trigger the route you can perform an HTTP POST at the URL "http://localhost:8888/placeorder", sending in any valid XML as the content of the message. SOAPUI is a good (free) tool for sending test HTTP requests.
The route will take the content of the incoming HTTP post and put it on the appropriate queue (as specified in the "camel-context.xml".)
Typically, the process that is listening on this queue is external to the route. It is expected that the process will pick up the message and place a response on the designated response queue (copying messageId into correlationId) per JMS request/reply convention. If this pattern is followed by the external process, then Camel will be able to receive the response on expected queue and correlate it with the request.

Tuesday, November 30, 2010

Camel Integration with WebSphere MQ

This post will describe my experience with implementing a Camel route that integrates with WebSphere MQ. The Camel route runs inside Servicemix as an OSGI bundle. I used the Enterprise version of Servicemix from FuseSource available here:
http://fusesource.com/downloads/

This use-case was developed to show how to achieve interoperability with WebSphere MQ.
You can download the example code here .

You can extract this file and, using Eclipse, import as an "existing Maven project". You will need to have the M2Eclipse plugin installed.

Overview
The following diagram shows what is happening in the use case created to demonstrate interoperability with WebSphere MQ









The use case consists of a Camel route (deployed inside Servicemix) that receives an HTTP message from an external client. The arrival of the HTTP message triggers the route. The route is pretty simple. It simply takes the payload of the HTTP message and drops it onto a Websphere MQ queue.

The HTTP message received (that triggers the route) is a two-way (request/response.) The message exchange pattern (MEP) for any route is generally determined by the first (consumer) endpoint in a route. Therefore the MEP for this particular route is request/response.

In this route, the JMS producer is responsible for placing the message on the pre-configured MQ queue. Because the route is request/response, the JMS producer will by default wait on a response to arrive on the response queue. This response queue is determined by whatever queue name is set in the outgoing JMS message’s JMSReplyTo header. The JMSReplyTo header is a standard-based JMS message header that indicates which address (queue) the JMS consumer that receives the message, should reply to.

In some cases the replyTo queue could be a temporary queue set up (per-message) by Camel on the fly to listen for reply (dynamic replyTo). In other cases, the replyTo queue will be a well-known location (static replyTo.) In the current use-case the replyTo queue is a well-known (static) location. This follows a pattern common to many JMS applications.

Implementation
The following shows the Camel code for this route.


from("jetty:http://0.0.0.0:8888/placeorder")

.to(targetUri + "?replyTo=SYSTEM.SOAP.RESPONSE.QUEUE");


The code simply listens for incoming HTTP messages (via the camel Jetty component) and forwards the payload to a Websphere MQ queue. The route sets the value of the “JMSreplyTo” header using an option on the outgoing targetUri. Thus the route, after sending to the targetUri queue, will wait on a response on the queue specified in the ‘replyTo’ option. In this case the route will listen for a response on “SYSTEM.SOAP.RESPONSE.QUEUE”. Camel will by default use a message selector to identify the response message, searching for the response message that has a corrrelationId that matching the messageId of the original message. In this way, Camel handles the message correlation for you without additional code. The response then gets converted and sent back to the original client via HTTP.

The Spring configuration for WebSphere MQ, used in above use case is shown below:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   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">

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <routeBuilder ref="mqRoute"/>
</camelContext>

<bean id="mqRoute" class="com.fusesource.camel.MqRoute">
    <!-- This is the "request" queue -->
     <property name="outgoingQueue" value="outgoingPayments"/>
     <!-- This is the "response" queue -->
    <property name="incomingQueue" value="incomingPayments"/>

</bean>

  <bean id="myTransform" class="com.fusesource.camel.MyTransform"/>


<bean id="wmq" class="org.apache.camel.component.jms.JmsComponent">
  <property name="connectionFactory">
    <bean class="com.ibm.mq.jms.MQConnectionFactory">
        <property name="transportType" value="1"/>
        <property name="hostName" value="localhost"/>
        <property name="port" value="1414"/>
        <property name="queueManager" value="QM_TEST"/>
    </bean>
  </property>
</bean>

</beans>
Building the example
First make sure you have built the example and installed into local maven repo:

mvn install -DskipTests=true


You can see the routing rules by looking at the java code in the src/main/java directory. The Spring XML configuration lives in src/main/resources/META-INF/spring/camel-context.xml

WebSphere MQ Dependencies
When implementing a Camel solution to interoperate with WebSphere MQ, there is a required set of IBM-specific libraries needed. For the purpose of this POC, these libraries were obtained by downloading a WebSphere MQ v. 7.0.1.3 trial for Windows.

Making Dependency Available to Runtime
A set of MQ libraries are required to be installed into FUSE ESB (Servicemix) making them available at run time. This set of dependent runtime JARs is provided as part of a MQ installation. The libraries, and the folder from and MQ installation where they can be found is shown below:

%MQ_INSTALL_DIR%\java\lib\OSGI
\com.ibm.mq.osgi.directip_7.0.1.3.jar
\com.ibm.msg.client.osgi.commonservices.j2se_7.0.1.3.jar
\com.ibm.msg.client.osgi.jms.prereq_7.0.1.3.jar
\com.ibm.msg.client.osgi.jms_7.0.1.3.jar
\com.ibm.msg.client.osgi.nls_7.0.1.3.jar
\com.ibm.msg.client.osgi.wmq.nls_7.0.1.3.jar
\com.ibm.msg.client.osgi.wmq.prereq_7.0.1.3.jar
\com.ibm.msg.client.osgi.wmq_7.0.1.3.jar
These JARs packaged as standard OSGI libraries by IBM and therefore recognizable and deployable into any standard OSGI container. These libraries can be deployed into Servicemix easily using the following commands:

osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.jms.prereq_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.jms_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.wmq.prereq_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.wmq_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.nls_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.commonservices.j2se_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.mq.osgi.directip_7.0.1.3.jar
osgi:install -s file:C:/Progra~1/IBM/WebSph~1/java/lib/OSGi/com.ibm.msg.client.osgi.wmq.nls_7.0.1.3.jar
All but the last bundle are deployed with the ‘-s’ option (meaning to auto-start the bundle). The last bundle above is a bundle “fragment” so no start is required.

As a convenience, an optional step is to install these IBM MQ OSGI bundles into your local maven repo (or to a corporate Nexus repository.) If you do this, you would be able to use the Servicemix "mvn:" prefix with osgi:install (rather than "file:") telling Servicemix to use the local Maven settings to find the bundle and install it into the container. First it tries to find "mvn:" prefixed artifacts in the local Maven repository, it then tries any external configured repository.

Other Dependencies
There are a few features you need to make sure are installed into the Servicemix container prior
to deploying the sample.

features:install camel-jetty
features:install camel-jms
features:install camel-spring

Deploying the sample into Servicemix

Once all the dependent runtime MQ bundles are installed into Servicemix, you can install
the example bundle into Servicemix using the following from the servicemix command console:

osgi:install -s mvn:com.fusesource.examples/camel-mq-osgi/1.1

To enable logging for this example type:
log:set DEBUG com.fusesource.camel
For an even higher level of logging (logging Camel specifics)
log:set DEBUG org.apache.camel

Running outside of Servicemix

As an alternative to running this route in Servicemix, you can also run the camel route
in standalone mode outside of Servicemix using the camel maven plugin (see pom). This allows you to start the route using the "mvn camel:run" command.
When you run example using 'mvn camel:run' the camel-maven-plugin will construct a classpath from any Maven dependencies listed in the POM with scope "compile." So in order for maven to find these runtime dependencies, you will need to install this minimal set of IBM runtime libraries in your local maven repository. Similar to the IBM MQ OSGI runtime libraries, these jars can also be found in a installation of IBM MQ. You can install these JARS into your local maven repo as follows (the following assumes you have installed Websphere MQ version 7.)

mvn install:install-file -Dfile=C:\PROGRA~1\IBM\WEBSPH~1\java\lib\com.ibm.mqjms.jar -DgroupId=com.ibm -DartifactId=com.ibm.mqjms -Dversion=7.0.1.3 -Dpackaging=jar
mvn install:install-file -Dfile=C:\PROGRA~1\IBM\WEBSPH~1\java\lib\dhbcore.jar -DgroupId=com.ibm.mq.dhbcore -DartifactId=dhbcore -Dversion=7.0.1.3 -Dpackaging=jar
mvn install:install-file -Dfile=C:\PROGRA~1\IBM\WEBSPH~1\java\lib\com.ibm.mq.jmqi.jar -DgroupId=com.ibm.mq -DartifactId=com.ibm.mq.jmqi -Dversion=7.0.1.3 -Dpackaging=jar

It was necessary to take special action to install these artifacts into a well-known location (local Maven Repo) and tag the artifacts with appropriate naming scheme. Note the values specified for groupId/artifactIds are very sensitive to typos (this was the cause of some time spent debugging during testing - so be careful.) I took the liberty to define groupId and artifactId for the Maven artifacts associated with these IBM libraries. These names were based on common Maven conventions. It is unknown whether IBM maintains an appropriate public Maven repository that contains such “official” artifacts but none could be found when implementing the POC. If it is determined that such a public repo exists, then this step might be avoided.

Once the libraries are added to the local Maven repository as shown above, then the ‘pom.xml’ file for the given project can include the dependencies, using the groupId, artifactId, and version in order to identify the dependency to Maven. Maven should then be able to find the dependency in the local repo.

As a convenience, an optional step would be to install these jars into your local maven repo (or to a corporate Nexus repository.) In which case you could retrieve the dependencies from there and manually installing the JARS to the local maven repo would not be necessary.
Testing the Route
Whether running inside Servicemix or in standlone mode, the technique for triggering the route will be the same. To trigger the route you can perform an HTTP POST at the URL "http://localhost:8888/placeorder", sending in any valid XML as the content of the message. (I use a simple tool like SOAPUI or CURL to send http requests) The route will take the content of the incoming HTTP post and put it on the appropriate queue (as specified in the "camel-context.xml".)

As a convenience for testing, a secondary "server simulator" route has been added (see "MqRoute.java") that will listen on the outgoing queue. The route that is listening on this queue will pick up the message and place a response on the designated response queue (copying messageId into correlationId) per JMS request/reply convention. The primary route is then able to receive the response on expected queue and correlate it with the request.