Showing posts with label JMS. Show all posts
Showing posts with label JMS. Show all posts

Sunday, May 5, 2013

Testing one-way operations which do not return HTTP 202 responses

When you invoke a one-way (in-Only) operation of a web service over HTTP, it responds with HTTP 202 accepted message. Many web service clients such as soapUI or Jmeter waits till they receive a response from the web service.
Waiting for HTTP 202 response is always not desirable since there are situations where you do not even get a 202 response. For example, if you invoke one-way JMS operation, it does not send a reply back to the client.
Look at a scenario similar to the following.

A client sends a message over HTTP to a proxy service in WSO2 ESB. The proxy service places the message in a JMS queue and does not expect a response back. In this case, client does not even get a HTTP 202 response hence it waits and eventually timed out. This prevents you using the tools like soapUI, Apache Jmeter in these scenarios. How can we fix this so that the client always get a HTTP 202 response back?

Let's go through the procedure in detail.

Step 1:

Configure Apache ActiveMQ JMS broker with WSO2 ESB as explained here.

Step 2: 

Create a queue in ActiveMQ. You could access ActiveMQ console application through http://localhost:8161/admin and create a new queue. Name it as "onewaytest".

Step 3: 

Create a simple proxy service in WSO2 ESB as shown below. This proxy service just forwards the incoming SOAP messages into the "onewaytest" JMS queue which we have created in the previous step.

<proxy xmlns="http://ws.apache.org/ns/synapse" name="onewayProxy" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="jms:/onewaytest?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description></description>
</proxy>


Step 4:


Use soapUI (or SOAP/XML-RPC sampler in Apache Jmeter) and send a SOAP request to the above proxy service. You will get "java.net.SocketTimeoutException: Read timed out" in soapUI log. This explains the behavior of HTTP client waiting for HTTP 202 response.

Step 5:


There is an useful property, FORCE_SC_ACCEPTED which can be used inside the inSequence of the proxy service to send HTTP 202 Accepted response back to the client in case of one-way JMS operations.

Add this property to the inSequence of the above proxy service.

<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" />

Step 6:


Re-send a SOAP message to the proxy service using soapUI. You will get a HTTP 202 response.


HTTP/1.1 202 Accepted
Content-Type: text/xml; charset=UTF-8
Date: Sun, 05 May 2013 07:42:27 GMT
Server: WSO2-PassThrough-HTTP
Transfer-Encoding: chunked



Wednesday, September 16, 2009

How to enable JMS in WSO2 WSAS-3.*

WSO2 WSAS provides with a simple and easily configurable UI to enable transports. In this post, we are going to look at how JMS is enabled in WSAS-3.* versions.

Pre-requisites:
----------------
You can use any JMS provider as you preferred. I'm going to use Apache ActiveMQ-5.2.0 for this example.
Download the latest version of WSO2 WSAS from here

Step 1
-------
Suppose you have downloaded WSO2 WSAS-3.* and extracted in to a directory in your file system. Let it be WSAS_HOME

First, we need to start ActiveMQ message broker. Go to ActiveMQ_Install_dir/bin and run activemq.bat
Also, the following ActiveMQ libraries must be copied to WSAS_HOME/repository/components/lib directory
  • activeio-core-3.1-SNAPSHOT.jar (ActiveMQ_Install_dir\lib\optional)
  • activemq-core-5.0.0.jar (ActiveMQ_Install_dir\lib\)
  • geronimo-j2ee-management_1.0_spec-1.0.jar (ActiveMQ_Install_dir\lib\)
  • geronimo-jms_1.1_spec-1.0.jar (ActiveMQ_Install_dir\lib\)
Now, restart WSO2 WSAS

Step 2
-------
Log in to WSAS management console (username=admin, password=admin) and click on Manage --> Transports at the left navigation menu.
You will be directed to the Transport Management page as follows.



Step 3
-------
Locate JMS transport in the above Transport Management page and click on enable next to transportListener
Following page will be shown where you can configure JMS listener according to your JMS provider.



similarly, you can enable JMSSender.

If JMS is configured correctly as in the above steps, you will see the JMS endpoints of your service will be shown in the WSDLs or service dashboard as follows.

Monday, October 6, 2008

SOAP over JMS with Axis2

Axis2 provides a JMS transport implementation which can be used to send SOAP messages over JMS. This post will help you to -
  • Configure JMS transport in Axis2
  • Generate Axis2 client
  • Invoke default version service by sending request SOAP message over JMS
  • Monitoring messages via JConsole
I assume Apache ActiveMQ is used as our JMS implementation. However, you are free to use any other stack.

Pre-requisites
1. Install the latest version of Apache Axis2 binary distribution
2. Install Apache ActiveMQ 5.0.0

Step 1
First, we need to start ActiveMQ message broker. Go to ActiveMQ_Install_dir/bin and run activemq.bat



Step 2
In order to configure the JMSListener in axis2.xml, uncomment the following section.
<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>

Also, uncomment the transport Sender which is in the Transport-outs section of axis2.xml.

<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>

Step3
The following ActiveMQ libraries must be copied to the Axis2 lib directory (AXIS2_HOME/lib).
  • activeio-core-3.1-SNAPSHOT.jar (ActiveMQ_Install_dir\lib\optional)
  • activemq-core-5.0.0.jar (ActiveMQ_Install_dir\lib\)
  • geronimo-j2ee-management_1.0_spec-1.0.jar (ActiveMQ_Install_dir\lib\)
  • geronimo-jms_1.1_spec-1.0.jar (ActiveMQ_Install_dir\lib\)
Step 4
Start Axis2server and go to http://localhost:8080
Then select the default version service.
The WSDL of the Version service will be displayed. You will notice the following port.

<wsdl:port name="VersionJmsSoap11Endpoint" binding="ns:VersionSoap11Binding">
<soap:address location="jms:/Version?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"/>
</wsdl:port>

This implies that the Version service is now exposed over JMS transport as well. Lets write a client and send SOAP requests through JMS.

Step 5

Generate Client stubs with the following command.
AXIS2_HOME/bin/WSDL2Java -uri http://localhost:8070/axis2/services/Version?wsdl -o out -uw

The client stubs will be generated in a directory called "out".

Now, write a client importing the generated stub classes as follows(You can easily create a project in Eclipse using the generated Build.xml)

import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import sample.axisversion.ExceptionException0;
import sample.axisversion.VersionStub;


public class JMSClient {

public static void main(String[] args) throws AxisFault{
ConfigurationContext cc = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null,"D:\\axis2\\axis2-client\\conf\\axis2.xml");
String url = "jms:/Version?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616";
VersionStub stub = new VersionStub(cc,url);

try {
System.out.println(stub.getVersion());
} catch (RemoteException e) {
e.printStackTrace();
} catch (ExceptionException0 e) {
e.printStackTrace();
}
}

}

We need to enable JMS in client side too. Therefore, create a client repository (Just create a directory and copy the axis2.xml in there). Make sure to enable JMS transportReceiver and TransportSender in client's axis2.xml.

Step 6

Run the client. You will get the response back with axis2 version.
Now we need to look at the messages transmitted through JMS channel. Open a command prompt and type 'jconsole' and hit enter.
Connect to ActiveMQ agent.
Click on MBeans and select org.apache.activemq mbean.
Select localhost --> Queue

Run the client few times and note the queue size.