Friday, September 26, 2008

How to get a thread dump of WSO2 Servers

I will explain in terms of the product WSO2 ESB.
When WSO2 ESB server is running, find the process ID by using the following command

 ps -ef | grep wso2esb

Once you find the process ID, use the following command and then you will get a thread dump on the WSO2 ESB console

kill -3 [ProcessID_of_WSO2ESB]

Also, you can get the thread dump to a text file by giving a command as follows

jstack $PID > thread_dump.txt

Wednesday, September 24, 2008

Setting up WSO2 ESB in a clustered environment

I will briefly describe how one can easily set up WSO2 ESB in a clustered environment.

Prerequisites
Download the latest version of WSO2 ESB and extract to a folder of your choice. (I will refer to the two WSO2 ESB instances as cluster1 and cluster2)
NOTE: I will be having both the WSO2 ESB instances on my local machine.

Step 1
Out of the two WSO2 ESB instances, select one and edit the default ports. (cluster2)
a) axis2.xml ($ESB_HOME/webapp/WEB-INF/classes/conf)
- To enable clustering uncomment the following of both ESB instances
<cluster class="org.apache.axis2.clustering.tribes.TribesClusterManager">

<parameter name="AvoidInitiation">false</parameter>
<parameter name="domain">wso2esb.domain</parameter>
...
...
</cluster>

- Change the HTTP and HTTPS ports specified in the axis2.xml of cluster2 (E.g.:- HTTP - 8281 , HTTPS - 8244)

b) tomcat.properties of cluster2 should also be changed as follows ($ESB_HOME/tomcat/config)
Change the Admin console port given in the tomcat.properties file (E.g.:- 9443)

Step 2
Edit the ./wso2esb.sh file of both the instances (cluster1 and cluster2) and add the following
-Daxis2.local.ip.address=<Your_IP>

Step 3
Now you are all ready to start the two WSO2 ESB instances in the clustered environment

Thursday, September 18, 2008

Reliable message exchange with WSO2 ESB - Invoking WS-RM Service using nonWS-RM one-way client

Invoking a WS-RM enabled service using a one-way client where WS-RM is not enabled

Reliable messaging allows messages to be delivered reliably between applications in the presence of system, or network failures. I will breifly describe how reliable messaging is made possible with WSO2 ESB along with some samples. Step by step information will be provided on how to configure WSO2 ESB to handle the exchanging of messages between WS-Reliable Messaging (WS-RM) enabled services and clients.

To start off with, you will need to download and install WSO2 ESB on your machine. (Refer https://wso2.org/project/esb/java/1.7.1/docs/installationguide.html on how to download and install WSO2 ESB). From this point onwards the location where WSO2 ESB is installed will be refered to as ESB_HOME.


Step 1 - Creating and deploying a WS-RM enabled service.

The implementation class should be created as follows.

package org.wso2.esb.services;

public class RMService {
public void Ping(String x){
System.out.println("Received Ping request");
}
}

Then create a services.xml file as follows

<service name="RMService">
<description>This service is created to add two numbers.</description>
<parameter name="ServiceClass" locked="false">org.wso2.esb.services.RMService</parameter>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2006/01/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2006/01/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<module ref="Mercury"/>
</service>

Place the above services.xml file in a directory named META-INF. Compile the RMService class and get the compiled class, bundle it with the META-INF file and create an .aar file. For testing purposes we will be using the SimpleAxisServer which comes with the WSO2 ESB package so deploy the services. Therefore drop the created archive file in ESB_HOME/samples/axis2Server/repository/services. (To check if the service has been deployed successfully access http://localhost:9000/soap)


Step 2 - Creating the WSO2 ESB Configuration

Start the WSO2 ESB server located at ESB_HOME/bin and access the WSO2 ESB Admin console through https://localhost:9444/esb/

Inorder for the non-WS-RM client to communicate with the WS-RM enabled service the folling configuration should be used. Log in to the WSO2 ESB admin console (username - admin, password - admin) and create the following configuration.


<definitions xmlns="http://ws.apache.org/ns/synapse">
<proxy name="RMProxy" transports="http" startOnLoad="true" statistics="enable">
<target>
<inSequence>
<RMSequence single="true" version="1.0"/>
<send>
<endpoint>
<address uri="http://localhost:9000/soap/RMService">
<enableAddressing/>
<enableRM/>
</address>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<enableRM/>
</proxy>
</definitions>

Step 3 - Generating Stubs

Inorder for the client to successfully execute we need to generate stubs. This can easily be done through WSO2 WSAS. (Refer http://charithaka.blogspot.com/2008/02/securing-axis2wsas-web-services-with.html Step 3). For ease of use I will be providing a generated jar file which works with the below client code. You can download it from here
Make sure to add jars in ESB_HOME/lib and the above downloaded client stub jar to your class path in order to compile the client.

Step 4 - Create a non-WS-RM Client

The next step would be create a client to invoke the WS-RM enabled service as follows. The below client supports only SOAP11 messages. For you to try out SOAP12 messages you can use the client
OneWayAnnonSOAP12Client.

public class OneWayAnnonSOAP11Client {
public static void main(String[] args)throws AxisFault {
ConfigurationContext cc = ConfigurationContextFactory.createConfigurationContextFromFileSystem("/home/rmScenario/client_repo","/home/rmScenario/client-repo/axis2.xml");
OMElement payload = createPayLoad();

ServiceClient serviceclient = new ServiceClient(cc, null);

Options opts = new Options();
opts.setTo(new EndpointReference("http://localhost:8280/soap/RMProxy"));
opts.setAction("urn:Ping");

serviceclient.setOptions(opts);

try {
serviceclient.fireAndForget(payload);
} catch (RemoteException e) {
e.printStackTrace();
}

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public static OMElement createPayLoad(){
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://service.esb.wso2.org", "ns");
OMElement method = fac.createOMElement("Ping", omNs);
OMElement value = fac.createOMElement("ping", omNs);
value.addChild(fac.createOMText(method, "pong"));
method.addChild(value);
return method;
}
}

You can access the entire client code from here.

Before you execute the client, make sure you have copied the Mercury.mar (make sure that the mar file is inside a folder named 'module') and axis2.xml to the specified locations above.

Step 5 - Starting the Simple Axis2 Server

Go to the ESB_HOME/samples/axis2Server and start the simple axis2server
E.g.:- sh ./axis2Server.sh

Step 6 - Executing the client

Now you are all set to execute the client. To see whether the messages are being sent properly you can send them through TCPMon.