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)