Enabling JMS transport for Axis2 services

This post explains how you could enable JMS transport for Axis2 services deployed on WSAS.

WSO2 WSAS is an enterprise ready Web services engine powered by Apache Axis2.

It is a lightweight, high performing platform for Service Oriented Architectures, enabling business logic and applications. Bringing together a number of Apache Web services projects, WSO2 WSAS provides a secure, transactional and reliable runtime for deploying and managing Web services

Once you start WSAS with [WSAS_HOME]\bin\startup.bat and hit the url https://localhost:9443 you can login with admin/admin.

Click the menu item 'services' and you'll find the set of available services.

Click on the 'echo' service and then the 'Manage Transports' - you can find that only http and https transports are available.

Let's see how we can configure JMS for the 'echo' service.

You can find axis2.xml inside [WSAS_HOME]\conf - edit it to uncomment the following.

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

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

<parameter name="default">
<parameter name="java.naming.factory.initial">
org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url">
tcp://localhost:61616</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName">
QueueConnectionFactory</parameter>
</parameter>
</transportReceiver>


<transportSender name="jms"
class="org.apache.axis2.transport.jms.JMSSender"/>
The above configuration defines three connection factories.

The JMS transport receiver configuration allows you to define the default connection factory (named as "default") for use by Axis2 services using the JMS transport. This connection factory would be used by any service which does not explicitly specify a connection factory name in its services.xml.

In case your service needs a different connection factory,other than the 'default' one - that needs to be mentioned in the services.xml.

<parameter name="transport.jms.ConnectionFactory" locked="true">myTopicConnectionFactory</parameter>
Now you need to run a message broker. You can download ActiveMQ 5.2 from here.

Copy the file activemq-all-5.2.0.jar from [ACTIVEMQ_HOME] to [WSAS_HOME]\lib.

All set - now restart the WSAS.

If you view transports available for 'echo' service through WSAS admin console [as you did previously], you'll find JMS is now available.

Also in the 'echo' service page you may notice that there are three endpoints available under 'Endpoint References' - what we'll be using for the 'echo' service client is the 'jms' endpoint.

One thing to notice here is a service on an Axis2 instance is deployed on all started transports by default, unless a list of transports are specified in its services.xml.

In case your service only to be deployed on JMS, you should specify it in the services.xml

<transports>
<transport>jms</transport>
</transports>
All set - let's move to the client.

Make sure you have the actievemq-all-5.2.0.jar in the client classpath and jms transport being enabled in client.axis2.xml.

package org.apache.ws.axis2;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;

public class Client {

/**
* @param args
* @throws AxisFault
*/
public static void main(String[] args) throws AxisFault {

ConfigurationContext context = null;
ServiceClient client = null;
Options options = null;
OMElement response = null;

context = ConfigurationContextFactory.createConfigurationContextFromFileSystem("repo",
"repo/conf/client.axis2.xml");
client = new ServiceClient(context, null);
options = new Options();
options.setAction("urn:echoString");
options
.setTo(new EndpointReference(
"jms:/echo?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory"
+ "&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&java.naming.provider.url=tcp://localhost:61616"));

client.setOptions(options);
response = client.sendReceive(getPayload("hi"));
System.out.println(response.getFirstChildWithName(new QName("return")).getText());
}

private static OMElement getPayload(String value) {
OMFactory factory = null;
OMNamespace ns = null;
OMElement elem = null;
OMElement childElem = null;

factory = OMAbstractFactory.getOMFactory();
ns = factory.createOMNamespace("http://echo.services.wsas.wso2.org", "ns1");
elem = factory.createOMElement("echoString", ns);
childElem = factory.createOMElement("param0", null);
childElem.setText(value);
elem.addChild(childElem);
return elem;
}

}