Showing posts with label jms. Show all posts
Showing posts with label jms. Show all posts

Saturday, October 22, 2011

JMS Proxy Services with Fail-Over Support

Rajika has written a very comprehensive article about setting up WSO2 ESB with JMS in a fail-over scenario.
The concept of fail-over endpoints is integral to WSO2 ESB. The user can define a fail-over endpoint in the ESB which in turns consists of two or more child endpoints. ESB will select one of the child endpoints to be the primary endpoint and will keep forwarding all messages to this primary endpoint. If the ESB detects some error while communicating with the primary endpoint, it will automatically fail-over to one of the available backup endpoints. User can also configure the endpoint error codes upon which to trigger a fail-over, endpoint suspend durations and timeout durations. However this is not what Rajika is talking about in his article. His article is about setting up a JMS proxy service with fail-over support in the ESB .
For an example imagine a situation where you have setup a proxy service to receive messages from a JMS queue. The ESB proxy service polls messages out of the queue and forwards them to a backend application for further processing. Now what if the ESB instance which hosts the above mentioned proxy service happens to fail (say due to a hardware failure). Actually in this case there's both good news and bad news. Good news is that no messages will get lost due to the persistent behavior of JMS messaging. If some messages were in flight within the ESB when the failure occurred those messages might get lost. But even that can be avoided by using something like JTA. The bad news however is that the backend application will not receive further requests to be processed. So as far as your overall system is concerned, your applications and services will stay idle while messages keep piling up on the JMS queue.
Rajika discusses a possible architecture to avoid such system downtime by having a backup proxy service (ideally deployed in a separate ESB instance) which listens on the same JMS queue. The backup proxy will be disabled by default to prevent contention between the two proxy services. His architecture also utilizes a scheduled task deployed on the backup ESB which sends periodic heartbeats to the other ESB node. If the backup ESB detects that the primary ESB instance is not responding, it will activate the backup proxy service which will start polling for JMS messages and resume operations in the system.
This is actually fairly simple to implement in WSO2 ESB and can be even further customized to suit the exact enterprise requirements. All the source code and relevant configurations are provided in the article itself.

Monday, April 12, 2010

WSO2 ESB Tips & Tricks 04: Troubleshooting JMS

WSO2 ESB works really well with JMS. The JMS transport adapter used by WSO2 ESB comes from the Apache Axis2 project and it makes use of JNDI to connect to various JMS brokers. Therefore WSO2 ESB can work with pretty much any JMS broker that offers JNDI support. The product ships with sample configurations for Apache ActiveMQ integration, but it can be easily modified for integration with a JMS broker like IBM MQ or SwiftMQ.
Enabling JMS in WSO2 ESB is a simple 2-step process.
  1. Deploy the JMS client libraries to the repository/components/lib directory (these libraries will be used by the ESB to connect to the JMS broker)
  2. Enable JMS transport receiver and the sender by modifying the axis2.xml file or using the management console
Having followed the above mentioned process you can start creating JMS endpoints to forward messages and JMS proxy services to receive messages. However while implementing certain JMS related scenarios you might run into some error conditions. The rest of this blog post focuses on a couple of such commonly encountered problems and how to get rid of them, once and for all.
CNF? NCDF?
If you ever run into any ClassNotFoundExceptions or NoClassDefFoundExceptions while using JMS support in WSO2 ESB, chances are you haven’t deployed all the required client libraries. Please inspect what you have copied into repository/components/lib directory and make sure the required class is available in one of the deployed jars.
Also note that WSO2 ESB ships with geronimo-jms library which contains the javax.jms packages. Therefore you do not have to deploy them again.
HTTP Header Conversion Problem
When forwarding HTTP traffic to a JMS queue using WSO2 ESB, you might at times run into an error similar to the one given below.
ERROR JMSSender Error creating a JMS message from the axis message context
javax.jms.MessageFormatException: MQJMS1058: Invalid message property name: Content-Type
This exception is thrown by the JMS client libraries used to connect with your JMS broker and the problem is specific to the JMS broker being used. I have encountered this issue mostly with IBM Websphere MQ, but I guess there might be other broker implementations that may display the same issue. So here’s what happens….
The incoming HTTP message contains a bunch of HTTP headers that contain the ‘-‘ character. Some notable examples are ‘Content-length’ header and the ‘Transfer-encoding’ header. When ESB attempts to forward the message over JMS it sets the headers of the incoming message to the outgoing JMS message as JMS properties. According to the JMS spec the ‘-‘ character is prohibited in JMS property names. Some JMS brokers like ActiveMQ do not strictly check for this and hence they won’t complain. But certain other brokers will throw exceptions similar to the one shown above.
Even though the problem sounds very complex and tricky the solution is almost trivial. We just need to get rid of the troublemaking HTTP headers from the message before it is delivered over JMS. You can make use of the property mediator as follows to achieve this:
<property action="remove" name="Content-Length" scope="transport">
<property action="remove" name="Accept-Encoding" scope="transport">
<property action="remove" name="User-Agent" scope="transport">
<property action="remove" name="Content-Type" scope="transport">
JMS Property Data Type Mismatch
Sometimes when the ESB attempts to forwards a message over JMS, the client libraries may complain, saying that the data type of a particular message property is invalid. You may often run into this problem if you are using the property mediator to manipulate property values set on the message. This is because certain implementations of JMS, have restrictions on data types of properties. The property mediator always sets property values as strings.
To overcome this problem you will have to revise your mediation sequences and avoid manipulating property values which should contain non-string values. If you must set a non-string property value you will have to write a simple custom mediator to get the job done. Starting from WSO2 ESB 3.0 (scheduled to go out this month), the property mediator is type aware. Therefore to get rid of this problem you can set properties with specific data types. For an example if you want to set a property named foo with the integer value 12345 use the property mediator as follows:
<property name="foo" value="12345" type="INTEGER" scope="transport/">
If you leave the type attribute out the property value will be set as a string.
Too Many Threads? Out of Memory?
With certain JMS brokers WSO2 ESB tends to spawn new worker threads indefinitely until it runs out of memory and crashes. I have observed this behavior with SwiftMQ. This problem is caused by a bug in the underlying Axis2 engine and there is a simple workaround to the problem. In your mediation sequence engage the property mediator as follows:
<property action="remove" name="transportNonBlocking" scope="axis2">
This will prevent the ESB from creating new worker threads unlimitedly and everything will be back to normal. Note that you can always use a JMX client like jconsole to monitor the active threads and memory consumption of the ESB.

Sunday, December 13, 2009

WSO2 ESB Tips & Tricks 03: Transport Switching

Back to WSO2 ESB Tips and Tricks!
Today we are going to see how to implement a transport switching scenario with WSO2 ESB. WSO2 ESB supports receiving and sending messages over following transport and application layer protocols.
  • HTTP/HTTPS
  • Mail protocols (POP3, IMAP, SMTP)
  • JMS / AMQP
  • VFS (Virtual File System)
  • FIX (Financial Information eXchange)
  • TCP
  • UDP
With WSO2 ESB having support for such a wide range of transports, it is easy to implement a scenario which involves receiving messages over one protocol and forwarding them over another. As an example I’m going to explain how to receive messages over HTTP and forward them over JMS, using Apache Active MQ as the JMS provider. Looking at how most system integrators use WSO2 ESB it seems this is one of the most common use cases for ESB products.
The first thing we have to do is enable the JMS transport sender in the ESB. By default only the HTTP and HTTPS transports are enabled in the ESB configuration. But configuring and enabling other transports is a trivial task. Transports can be enabled by uncommenting the corresponding entries in the axis2.xml file or by using the ESB management console.
First, shutdown the ESB if it is already running. Then we need to deploy the Active MQ JMS client libraries into the ESB runtime. Download and extract an Apache Active MQ binary distribution (I prefer v5.2). Copy the following jar files from the Active MQ lib directory to the ESB_HOME/repository/components/lib directory.
  • geronimo-j2ee_management.jar
  • activemq-core.jar
Also this would be a good time to start the Active MQ broker.
Now start the ESB. The underlying Carbon platform will detect the newly deployed jar files and automagically convert them into OSGi bundles on the fly. Once the server has started go to the ESB_HOME/repository/components/dropins directory and do a file listing. You will see a set of OSGi bundles created out of the jar files you deployed.
Now that the server is up and running login to the management console as an admin. Click on ‘Transports’ under ‘Manage’ on the left navigation bar. A list of available transport receivers and senders will be displayed.

Select the ‘Enable’ option for the JMS sender. Click on ‘Enable’ to start the JMS transport sender. Once started, you can further configure the transport by specifying various parameters. But for this demonstration we can go ahead with the default settings (ie no parameters).

If you prefer to enable the JMS sender the old school way open up the axis2.xml file in the conf directory and uncomment the following entry before starting the ESB.
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>
Having enabled the JMS sender, we should now create a proxy service which will accept messages over HTTP and send them to a JMS endpoint. Click on ‘Add’ under ‘Proxy Services’ to start the proxy service creation wizard. On the first step simply specify a suitable name for the service (eg: JMSBridge) and click on ‘Next’.

On the second step of the wizard, create an anonymous in-sequence consisting of a property mediator. Configure the property mediator to set the ‘OUT_ONLY’ property to the value ‘true’. Save the in-sequence and create an anonymous endpoint for the proxy service. Specify the following JMS EPR as the target address. This EPR points to a dynamic queue named ‘SimpleStockQuoteService’ in Apache Active MQ broker.
jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue
In this scenario we will be doing a one-way invocation using the sample client application. In other words, the client sends a message to the ESB but does not expect a response in return. So the ESB should not expect a response from the backend JMS service either. We indicate this to the ESB by setting the OUT_ONLY property in the in-sequence of the proxy service. ESB will not register any call backs for messages containing the OUT_ONLY property thus no response would be expected.
Having specified the in-sequence and the target endpoint click on ‘Next’ to proceed to the third step of the wizard. Leave the out-sequence and the fault-sequence settings unchanged and simply click on ‘Finish’ to save and exit the wizard. A new proxy service will be deployed on the ESB at this point.
If you prefer to create the above proxy using the ESB configuration language you can use the XML snippet given below.
<syn:proxy name="JMSBridge" transports="https http" startOnLoad="true" trace="disable">
<syn:target>
<syn:endpoint>
<syn:address uri="jms:/SimpleStockQuoteService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue"/>
</syn:endpoint>
<syn:inSequence>
<syn:property name="OUT_ONLY" value="true" scope="default"/>
</syn:inSequence>
</syn:target>
</syn:proxy>
On the management console, click on the ‘Synapse’ link under ‘Configure’ and add the above XML as a child of the top level ‘definitions’ element. Click ‘Update’ to apply the changes.
Now we are all set to run the scenario. Deploy the SimpleStockQuoteService into the sample Axis2 server. Open up the axis2.xml file for the sample Axis2 server and enable the JMS transport receiver in it. This file can be found at samples/axis2Server/repository/conf directory. To enable the JMS listener uncomment the following XML fragment.
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
......
</transportReceiver>
Finally start the sample Axis2 server. Since we have enabled the JMS receiver for the sample server, the SimpleStockQuote service will be exposed over JMS and the server will start listening on a JMS queue named ‘SimpleStockQuoteService’. When you haven’t specified a queue name in the service configuration, the Axis2 JMS transport will by default listen on a queue with the same name as the service. To explicitly specify the queue name for a service one must set the transport.jms.Destination parameter as a service parameter (ie in the services.xml file).
Finally go to samples/axisClient and run the following command to send a one-way message to the ESB proxy service over HTTP. (Here we invoke the in-only placeOrder operation on the backend service)
ant stockquote –Daddurl=http://localhost:8280/services/JMSBridge –Dmode=placeorder
The ESB will take the message and forward it over JMS to the queue named ‘SimpleStockQuoteService’. The sample Axis2 server which is currently listening on this queue will pick up the message and process it. Note the following log entry in the Axis2 server log when it takes the message from the JMS queue.
Sun Dec 13 16:15:39 IST 2009 samples.services.SimpleStockQuoteService  :: Accepted order for : 5789 stocks of IBM at $ 89.61765128551305
So there you have it. The proxy service abstraction in WSO2 ESB makes it extremely simple to perform protocol conversions and route messages back and forth. I suggest you also have a look at the set of transport switching samples that come with WSO2 ESB distribution. We got samples covering all the major protocols and even some of the domain specific transports like FIX and AMQP.
In my next post, I will focus on common problems that most developers encounter while implementing transport switching scenarios involving JMS and possible solutions to such pitfalls.

Saturday, September 12, 2009

Enterprise Messaging with Synapse, WSO2 ESB and WebSphere MQ

I've been recently playing a lot with Apache Synapse, WSO2 ESB and IBM WebShpere MQ (WMQ). My intention was to use WMQ as a JMS provider for Synapse and WSO2 ESB. IBM WebSphere MQ being a very popular and matured messaging solution, I figured that getting Synapse and WSO2 ESB to work with WMQ and document the integration process would really help the IBM, Apache and WSO2 communities. Originally I anticipated this application integration to be a very comlpex and tedious task. But for much of my delight, it turned out to be a very easy and simple process in the end. What was little complicated was to get WMQ properly installed and get its JMS features configured. But the integration with Synapse and WSO2 ESB was indeed a piece of cake.
So here I'm going to list the steps hat one should follow to get WMQ integrated with Synapse or WSO2 ESB. Start by downloading the required software. Binary distributions of Apache Synapse and WSO2 ESB can be downloaded from their respective websites. A trial version of the IBM WMQ V7.0 can be downloaded from here. In addition to these application you will also require Java 5 or higher along with Apache ANT to run some of the samples described here.
Installing Apache Synapse or WSO2 ESB doesn't require any additional steps. You simply need to extract the downloaded archives and that's all. However WMQ installation is not so easy. It is a fairly long and time consuming process which requires carefulness and patience. Anyway the installation process is well documented and so it shouldn't be a problem. For your convenience I'm describing the WMQ installation procedure for Linux here. The necessary commands to be executed at each step are given in italic font.

Installing WMQ
1. Create an empty directory and extract the downloaded WMQ archive into it
2. Add a new user group called 'mqm' to the system
groupadd mqm
3. Add a new user called 'mqm' to the system. Add the user to the 'mqm' group. Set the user's home directory to /var/mqm
useradd -d /var/mqm -g mqm mqm
4. Create the directory /var/mqm and change its owner to mqm
mkdir /var/mqm
chown mqm:mqm mqm
5. Create the directory /opt/mqm
mkdir /opt/mqm
6. Create another directory anywhere on the disk and set a symlink to it from /opt/mqm
mkdir /home/hiranya/mqm
ln -s /home/hiranya/mqm /opt/mqm
7. Install libstdc++5 library on the system (using Synaptic or apt-get on Debian/Ubuntu systems) if not already installed
8. As root go to the directory where WMQ is extracted and run the license display script
./mqlicense.sh
9. Install the MQ runtime and the server using rpm
rpm -ivh MQSeriesRuntime-7.0.0-0.i386.rpm MQSeriesServer-7.0.0-0.i386.rpm --nodeps
10. Install the MQ samples
rpm -ivh MQSeriesSamples-7.0.0-0.i386.rpm --nodeps
11. Install the MQ client
rpm -ivh MQSeriesClient-7.0.0-0.i386.rpm --nodeps
That wasn't too bad, was it? Now it's time to verify the installation. Here's what you got to do.

Verifying the Installation
1. Login as user mqm (ssh mqm@localhost)
2. Create a new queue manager
crtmqm -q venus.queue.manager
3. Start the queue manager
strmqm
4. Start MQSC program (a new shell will appear - without a prompt)
runmqsc
5. Define a local queue in the MQSC shell
define qlocal (orange.queue)
6. Terminate MQSC
end
7. Go to /opt/mqm/samp/bin and run the amqsput sample program to place a message on to the queue
./amqsput ORANGE.QUEUE
8. The above command should be followed up by some sample message text of your choice and a blank line
9. Run the following command to pull the message back from the queue
./amqsget ORANGE.QUEUE
10. So far so good! We got the server properly installed. Now on to the client!
11. Create a new queue manager
crtmqm -q saturn.queue.manager
12. Start the queue manager
strmqm
13. Start MQSC
runmqsc
14. Create a new queue
define qlocal (queue1)
15. Create a connection channel to the queue
define channel (channel1) chltype (svrconn) trptype (tcp) mcauser ('mqm')
16. Create a listener (specify a port)
define listener (listener1) trptype (tcp) control (qmgr) port (8585)
17. Start the listener
start listener (listener1)
18. Terminate MQSC
end
19. Create a system environment variable to point to the channel created above
export MQSERVER='CHANNEL1/TCP/localhost(8585)'
20. Go to /opt/mqm/samp/bin and run the amqsputc to place a message in the queue (using the client API)
./amqputc QUEUE1 saturn.queue.manager
21. Now run amqsgetc to receive the message
./amqgetc QUEUE1 saturn.queue.manager
22. Excellent! We got the client installed properly too :)
Now that we got WMQ installed let's try to get its JMS features enabled.

Setting Up JMS
1. Install WMQ classes for JMS
rpm -ivh MQSeriesJava-7.0.0-0.i386.rpm --nodeps
2. Start MQSC (This will start mqsc for the last created queue manager - saturn.queue.manager)
runmqsc
3. Define a JMS channel for the queue manager
define channel(java.channel) chltype(svrconn) trptypr(tcp)
4. Define a listener
define listener(listener.tcp) trptype(tcp) port(1414)
5. Start the listener
start listener(listener.tcp)
6. Setup the classpath variable and the MQ_JAVA_LIB_PATH to run the IVT programt
export CLASSPATH=/opt/mqm/java/lib/com.ibm.mqjms.jar:/opt/mqm/samp/jms/
export MQ_JAVA_LIB_PATH=/opt/mqm/java/lib
7. Go to /opt/mqm/java/bin and invoke the IVT sample program
./IVTRun -nojndi
./IVTRun -nojndi -client -m saturn.queue.manager -host localhost -channel JAVA.CHANNEL
8. If the IVT program can recieve and send JMS messages we are done! Now let's proceed to enabling JNDI support
9. Go to the /opt/mqm/java/bin directory and open the JMSAdmin.config file. Edit the PROVIDER_URL property to point to an empty directory of your choice on the file system. This directory will be used the JNDI provider source (eg: /var/mqm/jndi). If the specified directory does not exist in the file system create it.
10. Run the IVTSetup tool to create the default set of JNDI bindings
./IVTSetup
11. Now run the IVTRun tool as follows
./IVTRun -url "file:/var/mqm/jndi" -icf com.sun.jndi.fscontext.RefFSContextFactory
12. By now we have enabled and verified JNDI support. Let's use the JMSAdmin tool to make some modifications in the JNDI bindings
13. Fireoff /opt/java/bin/JMSAdmin and run the following commands:
ALTER QCF(ivtQCF) TRANSPORT(CLIENT)
ALTER QCF(ivtQCF) QMGR(saturn.queue.manager)
14. Run the IVTRun tool again as mentioned in step 11. This time messages will be sent to the saturn queue manager.
Now we are all set. It's time to get WMQ integrated with Synapse and WSO2 ESB. Let's start with Apache Synapse.

Synapse Integration
Follow the steps given below as the user 'mqm'. Trying to run Synapse as a different user caused some JMS security exceptions.
1. Copy the following jar files from /opt/mqm/java/lib to SYNAPSE_HOME/lib
  • com.ibm.mqjms.jar
  • fscontext.jar
  • providerutil.jar
  • com.ibm.mq.jmqi.jar
  • dhbcore.jar
2. Enable the JMS listener in the axis2.xml. Configure the default connection factory as follows.
<parameter name="default">
<parameter name="java.naming.factory.initial">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url">file:/var/mqm/jndi</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName">ivtQCF</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.Destination">ivtQ</parameter>
</parameter>
Note that we are using the JNDI configuration used by the IVT sample program. We are using the same queue connection factory and the JMS queue to define the default connection factory.

3. Create the following proxy service in the synapse.xml (this is a simplified version of sample 250)
<proxy name="JMSProxy" transports="jms">
<target>
<inSequence>
<log level="full"/>
<drop/>
</inSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
</proxy>
4. Start Synapse - go to SYNAPSE_HOME/bin and run ./synapse.sh
5. Go to SYNAPSE_HOME/samples/axis2Client/src/samples/userguide and open the GenericJMSClient.java source file. Make the following changes in the code.
  • Set the jms_dest property default value to "ivtQ" (line 45)
  • Set the java.naming.provider.url to "file:/var/mqm/jndi" (line 82)
  • Set the java.naming.factory.initial to "com.sun.jndi.fscontext.RefFSContextFactory" (line 85)
  • Set the lookup key to "ivtQCF" (line 89)
6. Now from the SYNAPSE_HOME/samples/axis2Client directory run the following command to run the JMS client application which will send messages to the ivtQ.
ant jmsclient -Djms_type=pox -Djms_payload=IBM

7. At this point Synapse will pick the messages from the queue and log them on the console.

WSO2 ESB 2.1 Integration
Follow the steps given below as user 'mqm'
1. Copy the Websphere MQ client jars (mentioned above under Synapse Integration) to ESB_HOME/repository/components/lib
2. Enable the JMS listener in axis2.xml and configure the default JMS connection factory as follows
<parameter name="default">              
<parameter name="java.naming.factory.initial" >com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" >file:/var/mqm/jndi</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" >ivtQCF</parameter>
<parameter name="transport.jms.ConnectionFactoryType" >queue</parameter>
<parameter name="transport.jms.Destination">BOGUSQ</parameter>
</parameter>
Note that we have specified a queue named 'BOGUSQ' as the default destination. This is because we need to use ivtQ for our proxy service only. If we use 'ivtQ' here all the services deployed in ESB (XKMS, echo, wso2carbon-sts) will start listening on the same queue. You also need to login to JMSAdmin and create the queue named 'BOGUSQ'. In JMSAdmin shell run the following commands.
DEFINE Q(BOGUSQ) QMGR(saturn.queue.manager)
ALTER Q(BOGUSQ) QUEUE(QUEUE1)
If the QUEUE1 does not exist, first login to MQSC and create it.
3. Add the proxy service we used with Synapse to ESB_HOME/conf/synapse.xml
4. Start WSO2 ESB
./wso2server.sh -DuseSynapseXML
5. Use the sample client we used in Synapse to send messages to the queue

Wednesday, July 22, 2009

Integrating Apache ActiveMQ with WSO2 ESB

When going through some of the recent posts in the WSO2 ESB user forum, I got the impression that some folks are having trouble getting Apache ActiveMQ to work with WSO2 ESB. So today I'm going to explain how to integrate Apache ActiveMQ with WSO2 ESB and run one of the JMS sample scenarios.

I will be using WSO2 ESB 2.1 and Apache ActiveMQ 5.2. First download WSO2 ESB 2.1 and Apache ActiveMQ 5.2 from the respective websites if you already haven't done so. Apache ActiveMQ has different distributions for Windows platform and Unix/Linux platform. So remember to download the distribution that matches your target platform. To run the sample scenario described here you will also require Apache ANT. Once you have extracted the downloaded archives to some location in your local disk. Let's refer to WSO2 ESB installation directory as ESB_HOME and ActiveMQ installation directory as AMQ_HOME.

Now we are all set to go.....

First go to AMQ_HOME/bin directory and start the ActiveMQ broker. On Linux you simply have to execute the script named 'activemq'.

Then you need to copy the following 3 jar files into ESB_HOME/repository/components/lib directory. (With WSO2 ESB 2.1 this is the location where most of the 3rd party dependencies should be deployed)
  • activemq-core-5.2.0.jar
  • geronimo-j2ee-management_1.0_spec-1.0.jar
  • geronimo-jms_1.1_spec-1.1.1.jar
You will find all these jars in AMQ_HOME/lib directory.

Then open up ESB_HOME/conf/axis2.xml file in your favorite text editor and uncomment the JMS listener configuration. JMS listener configuration should look something like this.

<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="myTopicConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">
org.apache.activemq.jndi.ActiveMQInitialContextFactory
</parameter>
<parameter name="java.naming.provider.url" locked="false">
tcp://localhost:61616
</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">
TopicConnectionFactory
</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>
</parameter>

<parameter name="myQueueConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">
org.apache.activemq.jndi.ActiveMQInitialContextFactory
</parameter>
<parameter name="java.naming.provider.url" locked="false">
tcp://localhost:61616
</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">
QueueConnectionFactory
</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>

<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">
org.apache.activemq.jndi.ActiveMQInitialContextFactory
</parameter>
<parameter name="java.naming.provider.url" locked="false">
tcp://localhost:61616
</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">
QueueConnectionFactory
</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
</transportReceiver>
Now go to ESB_HOME/bin and start sample 250 which demonstrates how to receive messages over JMS and forward them over HTTP. To start the sample go to ESB_HOME/bin and run the command ./wso2esb-samples.sh -sn 250 if you are on Unix/Linux or run the command ./wso2esb-samples.bat -sn 250 if you are on Windows. This will bring up WSO2 ESB with sample 250 configuration.

The ESB startup may take some time depending on your system. However note the following lines on the console when it starts up.
INFO - JMSConnectionFactory JMS ConnectionFactory : myTopicConnectionFactory initialized
INFO - JMSConnectionFactory JMS ConnectionFactory : myQueueConnectionFactory initialized
INFO - JMSConnectionFactory JMS ConnectionFactory : default initialized
INFO - JMSListener JMS Transport Receiver/Listener initialized...
This confirms that the JMS transport has successfully started by connecting to the ActiveMQ broker. When the ESB has fully started up you should get a message similar to the following line on the console.
INFO - StartupFinalizerServiceComponent WSO2 Carbon started in 33 sec
Now we are ready to run the sample. Go to ESB_HOME/samples/axis2Server/src/SimpleStockQuoteService and run the command ant to build the sample service and deploy in the sample Axis2 server that comes with WSO2 ESB (This is where you need Apache ANT. So make sure you have properly installed ANT before trying to build the service and proceed any further.). Then switch back to ESB_HOME/samples/axis2Server and start the sample server by running axis2server.sh or axis2server.bat startup script.

Finally to run the sample client head over to ESB_HOME/samples/axis2Client directory and run the following command.
ant jmsclient -Djms_type=pox -Djms_dest=dynamicQueues/StockQuoteProxy -Djms_payload=MSFT
This will send a message to a JMS queue named StockQuoteProxy. The ESB will receive the message from the queue and forward it to the sample Axis2 server over HTTP. When the Axis2 server is done with processing the message it will print the following line on the console.
samples.services.SimpleStockQuoteService  :: Accepted order for : 9351 stocks of MSFT at $ 158.6569470528259
Congratulations! You just got Apache ActiveMQ integrated and working with WSO2 ESB. Now that wasn't too hard, was it? The key thing you have to remember is the way 3rd party dependencies are deployed into WSO2 ESB. In older versions of WSO2 ESB you had to copy the jar files into ESB_HOME/lib. But that does not work with the latest version of WSO2 ESB. The deployment model of WSO2 ESB has slightly changed with the introduction of WSO2 Carbon and Equinox P2 into the ESB.

So that's all about getting ActiveMQ to work with WSO2 ESB. With this knowledge now you may try other JMS related samples that come with WSO2 ESB.