Thursday, December 25, 2008

WSO2 WSAS 3.0-beta2 Released

WSO2 WSAS 3.0-beta2 is now available for public review.
WSO2 WSAS is the enterprise version of widely used Axis2. WSO2 WSAS users the Axis2 and related other projects (Rampart, Sandesha2) to provide the Soap Stack functionality. It is shipped with a well tested version of these components (eg. Axis2 with some bug fixed version of Axis2 1.4.1) while supporting essential monitoring and administrative functionality. It supports scalability and high availability for web services with an improved and well tested clustering implementation.
Based on WSO2 Carbon platform since version 3.0, It lets users even to add WSO2 ESB which is based on synapse and WSO2 Mashup functionalities with a minimal effort.

Sunday, November 30, 2008

Low cost IT solutions

With the global economic crisis a lot of companies find it difficult to mange their IT budgets with the commercial proprietary software products. Most of these companies find Open source software products as a solution for there problem.
This article named as Open source lets developers speed SOA development despite economic slowdown
describes how the company called concur have build there SOA solution using WSO2 open source products.

Axis2 service Invocations

Axis2 client API provides a comprehensive set of ways to access a web service. In fact there are four ways depending on the following two properties.

1.Synchronous/Asynchronous invocations – whether client thread wait until response comes or not
2.Single/Dual Channel invocations. - whether the response comes on the back channel or a separate channel initiated by the server.

Now lets see each and every method separately.

1.Synchronous Single channel
In this way the client side invocation thread blocks until the response message comes. If the transport is Http it can be seen that the response comes at the back channel with Http status 200 ok. By default Axis2 works on the single channel mode. Therefore following method does the job. Note that this method returns the response.
serviceClient.sendReceive(getTestOMElement())

2.Asynchronous Single channel
Unlike in the earlier way this kind of invocation returns the client thread immediately. User should register a callback to get the response. But response comes in the back channel as in the earlier case. Following code can be used for this kind of invocation.

AxisCallback axisCallback = new AxisCallback() {
public void onMessage(MessageContext msgContext) {
System.out.println("Got the message ==> " + msgContext.getEnvelope().getBody().getFirstElement());
}

public void onFault(MessageContext msgContext) {

}

public void onError(Exception e) {
System.out.println("Received an error ...");
}

public void onComplete() {

}
};
serviceClient.sendReceiveNonBlocking(getTestOMElement(), axisCallback);


3.Synchronous Dual channel mode
The only difference of this invocation compare to others is that the invocation happens using two different http channels. This type of invocation can only be done using Addressing. i.e both client and service should have addressing enabled. Before sending the request Axis2 client starts a Simple Http server at client side and set the Endpoint reference address of this server to the reply-To addressing header. The request channel receives a Http 202 Accepted header. Server reads the reply-to header from the request and starts a new channel to the reply-to header address. Here is the code for this.
serviceClient.engageModule("addressing")
serviceClient.getOptions().setUseSeparateListener(true);
serviceClient.sendReceive(getTestOMElement());


The useSeparateListener attribute is used to specify this dual channel mode.

4.Asynchronous Dual channel mode
This is the complete asynchronous invocation method. Client immediately returns the thread and response message receive in a separate channel. This kind of access can be made by adding the addressing engaging and useSeperateListner code for the second type of invocation.

AxisCallback axisCallback = new AxisCallback() {
public void onMessage(MessageContext msgContext) {
System.out.println("Got the message ==> " + msgContext.getEnvelope().getBody().getFirstElement());
}

public void onFault(MessageContext msgContext) {

}

public void onError(Exception e) {
e.printStackTrace();
System.out.println("Received an error ...");
}

public void onComplete() {

}
};
serviceClient.engageModule("addressing")
serviceClient.getOptions().setUseSeparateListener(true);
serviceClient.sendReceiveNonBlocking(getTestOMElement(), axisCallback);

Thursday, November 13, 2008

Getting java runtime stack trace

In most of the time finding java runtime stack trace is useful in debugging. The common practice is to run the application in debug mode and find the stack trace.
Here is a way I found to print the stack trace within the java code it self without running in debug mode. I found this in JavaUtils class of the Axis2 kernel.

public static String callStackToString() {
return stackToString(new RuntimeException());
}

public static String stackToString(Throwable e) {
java.io.StringWriter sw = new java.io.StringWriter();
java.io.BufferedWriter bw = new java.io.BufferedWriter(sw);
java.io.PrintWriter pw = new java.io.PrintWriter(bw);
e.printStackTrace(pw);
pw.close();
String text = sw.getBuffer().toString();
// Jump past the throwable
text = text.substring(text.indexOf("at"));
text = replace(text, "at ", "DEBUG_FRAME = ");
return text;
}

Wednesday, November 5, 2008

Accessing Axis2 Information at Client and Service

Most of the people get used to implement web services either using POJO or generated services with wsdl using wsdl2java tool. The preferred way to generate the client code is again to use wsdl2java tool with service wsdl. In other words people preferred to use data bound java classes.
But sometimes they need to get inside information even at the Client and service level. Axis2 internally keep XML data as an Axiom object. It uses the context hierarchy in processing data. For each message Axis2 creates a message context which is bound to an Operation Context. Normally an Operation Context can have one or two message contexts depending on the Operation MEP (message exchange pattern). Therefore if there is a way to get access to Message Context or Operation Context all these details can be retrieved by using them.

At server side.
At the server side message context can be accessed like this,
MessageContext messageContext = MessageContext.getCurrentMessageContext();

once get the message context then any thing can be access from that
messageContext.getEnvelope(); // getting soap envelop
messageContext.getProperties(); // getting all the properties these inclued properties set by transports as well
messageContext.getOperationContext(); // accessing operation context
messageContext.getAxisOperation(); // axis operation information
messageContext.getAxisService(); // axis servier information

At the client side.
At the client side operation context can be accessed like this,
OperationContext operationContext = stub._getServiceClient().getLastOperationContext();
MessageContext outMessageContext = operationContext.getMessageContext(WSDL2Constants.MESSAGE_LABEL_OUT);
MessageContext inMessageContext = operationContext.getMessageContext(WSDL2Constants.MESSAGE_LABEL_IN);

Once got the message context other can be accessed as given above.

Monday, November 3, 2008

Minimal jars to run Apache Axis2

Apache Axis2 distributions comes with number of jars which are used in various services. Out of these 60 jar files there are only a few needs for some applications. Actually the minimum set of jars depends on the service type to be used.

Here is a list of jars required to Deploy a service created by using wsdl2java tool using ADB databinding. This jars set is taken from Axis2 1.4.1 release.

axis2-kernel-1.4.1.jar
commons-logging-1.1.1.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
wstx-asl-3.2.4.jar
wsdl4j-1.6.2.jar
XmlSchema-1.4.2.jar
axiom-impl-1.2.7.jar
axiom-dom-1.2.7.jar
axiom-api-1.2.7.jar
backport-util-concurrent-3.1.jar
neethi-2.0.4.jar
commons-httpclient-3.1.jar
activation-1.1.jar
commons-fileupload-1.2.jar
woden-api-1.0M8.jar
woden-impl-dom-1.0M8.jar
httpcore-4.0-beta1.jar
axis2-adb-1.4.1.jar
commons-codec-1.3.jar

For additional binding corresponding runtime jars for that binding is required. (i.e for xmlbeans-2.3.0.jar)

Wednesday, October 15, 2008

How Axis2 Engine works

Axis2 Engine is one of the most important parts of Axis2 message processing. Axis2 Engine is responsible for invoking the Phases (Phase is a collection of handlers) which are supposed to invoke for a given message context object. Once Axis2 Engine invokes a Phase, then the Phase invokes the handlers for that phase in a similar a manner. Axis2 Engine uses currentHandlerIndex variable which is stored in messageContext to keep a track of executed phases.
Axis2 supports mainly two flows of message processing, namely Out flow and In flow. To support these two flows Axis2 has two methods called send() and receive() respectively.
Before calling to the send() method, Axis2 assume that the AxisService and AxisOperation has already been set to the messageContext. Normally Axis2 client calls the send() method. Therefore at the send() method it creates the handler chain by getting the Operation specific handler chain and global handler chain. Then it invokes the each phase as mentioned earlier.
Unlike in the send() method, when calling to the receive() method most of the time by the transport receiver, both AxisOperation and AxisService has not been found in the messageContext. Therefore at the receive method first it invoke the Global phases or Inflow chain which is stored in the AxisConfiguration. The main idea of this global phases is to dispatch the message (i.e. finding the AxisService and AxisOperation according to the parameters of the messageContext). Distpatch phase is the last phase of this chain. After Dispatch phase AxisService and AxisOperation should have been found. This is checked at the checkPostConditions method of the DispatchPhase class. If the dispatch information is found handler chain is populated with the operation specific handlers and continue the execution. Otherwise it throws an exception.

Monday, September 29, 2008

Using WS-commons mail transport with Axis2

Axis2 and Synapse (an ESB which uses Axis2) were using separate set of codes for transports while keeping them in Axis2 and Synapse code repositories. Recently we moved then into a common place under the ws_commons project called transports. As a result of this now Axis2 uses the mail transport which was originally there with the Synapse and have removed its own mail transport.
Compared to earlier Axis2 mail transport Synapse mail transport configure a mail box parameters per service and do not use ?x-service-path to specify the service.

I recently had some tests with this transport and here is how this mail transport can be used with Axis2 for inonly and inout message operations.

First here is how to use it with a in only operation.
For in only operations we need to set the mail message receiver at the server (for service) and sender at the client. To configure the mail message receiver at server side first it is required to declare the Mail transport receiver at the Axis2 xml file and it should be looked like this,

<transportReceiver name="mailto" class="org.apache.axis2.transport.mail.MailTransportListener">

</transportReceiver>



Note that there are no parameters specified here as in with the previous Axis2 mail transports. then where we specify them? it should be done at services.xml as entry per service.

<service name="TestInService">
<description>Test In Service</description>
<parameter name="transport.mail.Address">mail address to listen</parameter>
<parameter name="transport.mail.Protocol">pop3</parameter>
<parameter name="transport.PollInterval">2</parameter>
<parameter name="mail.pop3.host">pop3 mail account</parameter>
<parameter name="mail.pop3.user">username</parameter>
<parameter name="mail.pop3.password">password</parameter>
<messageReceivers>
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="com.test.transports.service.TestInOnlyMessageReceiver"/>
</messageReceivers>
<operation name="TestInOperation" mep="http://www.w3.org/ns/wsdl/in-only">
<actionMapping>urn:TestInOperation</actionMapping>
</operation>
</service>

These are the only steps to follow to mail transport at server side.
At the client side we need to first declare a mail sender.

<transportSender name="mailto"
class="org.apache.axis2.transport.mail.MailTransportSender">
<parameter name="mail.smtp.from">from address this is added to from header</parameter>
<parameter name="mail.smtp.user">user name</parameter>
<parameter name="mail.smtp.password">password</parameter>
<parameter name="mail.smtp.host">smtp host</parameter>
</transportSender>

Sender configuration is almost similar to earlier Axis2 sender configuration. Now we can use this code to send the message using mail transport.


ConfigurationContext configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
AXIS2_REPOSITORY_LOCATION, AXIS2_CLIENT_CONFIG_FILE);
ServiceClient serviceClient = new ServiceClient(configurationContext, null);
serviceClient.setTargetEPR(new EndpointReference("mailto:test@wso2.com"));
serviceClient.getOptions().setAction("urn:TestInOperation");
serviceClient.fireAndForget(getTestOMElement("org"));


Note here that it is enough to specify the email address of the server. Since there is a particular receiver for this service, it will pick the message from there.

Now lets see how we can use mail transport for an inout operation. The smtp transport does not have an implicit back channel. Therefore response should come as a separate mail message. The request message will go to the server as in the inonly scenario. So now lets see how to configure to receive the response message.
First a mail sender should be configured at the Axis2 xml in the server side as given above. So that the server can send the response using this transport sender. Server picks the sending address either using WSA reply to header if given or SMTP reply to header.
To configure the receiver at the client side first we need to add the mail transport receiver at the client Axis2 xml file as given above. Then the there is a question of how to set the other parameters since there is no any services.xml file at the client side. Actually mail transport receiver gets these parameters from the Axis2 service and hence we can set them at the client code itself like this.

ConfigurationContext configurationContext =
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
AXIS2_REPOSITORY_LOCATION, AXIS2_CLIENT_CONFIG_FILE);
ServiceClient serviceClient = new ServiceClient(configurationContext, null);
serviceClient.setTargetEPR(new EndpointReference("mailto:oiositest2@wso2.com"));
serviceClient.getOptions().setAction("urn:TestInOutOperation");

// these two lines are needed only if it is required to use addressing
serviceClient.getOptions().setUseSeparateListener(true);
serviceClient.engageModule("addressing");

serviceClient.getAxisService().addParameter("transport.mail.Address","test@wso2.com");
serviceClient.getAxisService().addParameter("transport.mail.Protocol","pop3");
serviceClient.getAxisService().addParameter("transport.PollInterval","2");
serviceClient.getAxisService().addParameter("mail.pop3.host","pop 3 address");
serviceClient.getAxisService().addParameter("mail.pop3.user","username");
serviceClient.getAxisService().addParameter("mail.pop3.password",”password");

OMElement result = serviceClient.sendReceive(getTestOMElement("org"));
System.out.println("Result ==> " + result);

There will be a separate listener for the given mail address and that receives the response.

Tuesday, September 16, 2008

Running WSO2 WSAS on WebLogic

WSO2 WSAS can be used not only as a standalone application but also as an web application for a servlet container. Many people find latter very useful since that let them run the WSO2 WSAS within their favorite Servlet Container along with the other applications.

I recently had some experiments with the WebLogic server using the 10 Minute Guide to Installing WSO2 WSAS on WebLogic Tutorial written by Afkham Azzez. Every thing worked fine in the installation process.

Then I tried to do more experiments with some WSO2 Mercury samples. By doing this I found that the response messages are not serialized properly. Further looking into that I found when running on Weblogic Axiom uses the underline stax implementation of the WebLogic and that causes some problems of serializing the namespaces and namespace prefixes.

This made me surprised since Axiom supposed to work with any stax implementation. Then I looked into the Axiom serialization logic and found that it works on two different ways.

  1. For some stax implementations it first writes the prefix for a new namespace

  2. For some stax implementations it writes the prefix after start Element

For wstx (default for Axis2) and sun stax implementations it works on the later mode and that has done by specifying these names at the serializing logic. I specified the weblogic also as a later mode implementation and that made every thing worked fine.

I have made these changes already to Axiom and any one having problems working in weblogic can try with Axiom nightly builds.