Monday, December 12, 2011

Axis2 - Sandesha Reliable messaging Implementation

As the adoption curve for Web services continues to evolve, merely alleviating the distributed communication headaches of heterogeneous platforms will not be enough for many projects. Even though interoperability figures at the top of list for most people considering Web services, distributed systems pose many thorny issues that can leave interoperability as an unrealized goal. In the following paragraphs, we will take a look at how Web services tackles one of these distributed technology concerns: Reliability.
Reliability is a critical concern especially among applications involving financially sensitive data, having a Web service broker information on behalf of a weather forecast is not the same as one providing stock market orders. The former can tolerate a network failure and newly issued requests without major impact, but if the latter does not have the necessary provisions to deal with these effects it can have severe consequences. To this end, there is one particular Web service specification under the auspices of OASIS that tackles reliability issues: WS-ReliableMessaging .
WS-ReliableMessaging, like any other Web service specification, poses the characteristic known as composability, which allows you to mix and match SOAP specific behaviors on an as needed basis. In this manner, any SOAP-based application you may already have can reap the benefits of this reliability layer simply by incorporating additional SOAP header information, thus enforcing any of the rules available in WS-ReliableMessaging, such as:
  • Guaranteed delivery at least once - the sent message must be delivered at the receiver or else a notification of potential delivery failure is given to the sender
  • Duplicate elimination - delivery at most once, duplicates are detected and eliminated by the receiver
  • Guaranteed message ordering - messages are delivered in the order sent
While WS-ReliableMessaging provides the protocol -- based on SOAP -- to transfer reliability data over the wire, such a payload, in one manner or another, has to be interpreted or processed by a higher level stack to determine if a reliable communication has been executed. In WS-ReliableMessaging's case, this higher level stack refers to a specific environment which will be capable of such evaluation, this could either be an ESB or a Web Services framework like PHP/PEAR or Java/Axis.
Where this takes us is that, even though services built with any WS-ReliableMessaging implementation should be capable of interacting seamlessly with one other, in order to use such information, there will surely be a learning curve unique to a particular Web services stack. One such case is the WS-ReliableMessaging implementation produced by the Apache Software Foundation named Sandesha which is closely pegged to the Axis framework, a Java Web services stack produced by the same foundation.
We will now take a look at Sandesha and see how it leverages the Axis framework to create reliable Web services. Bear in mind we won't delve into specific details, so you are advised to consult Sandesha's documentation to see how it plugs-in with the Axis architecture or, of course, Axis documentation if you are unfamiliar with the framework.
Our scenario consists of a Web service client which requires a reliable request to a stock quoting system. Listing 1.1 illustrates how our client uses Sandesha/Axis for such a task.
Listing 1.1 : Web Service Client using Sandesha/Axis for WS-ReliableMessaging
import org.apache.axis.client.Service;
import org.apache.axis.client.Call;
import org.apache.axis.encoding.XMLType;

import org.apache.sandesha.Constants;
import org.apache.sandesha.SandeshaContext;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

public class StockQuoteClient {

   private static String targetURL = 
        "http://acmestockquote.com/axis/services/StockQuote";

   public static Double stockQuote(String symbol) {
        Double priceObject = new Double(0.0); 
 try {

         Service service = new Service();
  Call call = (Call) service.createCall();
  SandeshaContext ctx = new SandeshaContext();
     ctx.initCall(call,targetURL,
 "urn:wsrm:stockQuotePrice",Constants.ClientProperties.IN_OUT);
 call.setOperationName(
       new QName("acmestockquote.com", "stockQuotePrice"));
 call.addParameter(
       "Text", XMLType.XSD_STRING, ParameterMode.IN);
 call.addParameter(
       "Seq", XMLType.XSD_STRING, ParameterMode.IN);
 call.setReturnType(
       org.apache.axis.encoding.XMLType.XSD_DOUBLE);
  ctx.setLastMessage(call);
 priceObject = (Double) 
  call.invoke(new Object[]{"StockQuote",symbol});
        ctx.endSequence();
 } catch (Exception e) { 
            e.printStackTrace();
 }
        return priceObject; 
   }
   
    public static void main(String[] args) {

        StockQuoteClient.stockQuote("SLB"); 
 StockQuoteClient.stockQuote("BCA"); 
 StockQuoteClient.stockQuote("SNY"); 
    }
}
The stockQuote method contains the bulk of our business logic. First off, you will notice the use of the Service and Call classes, each of these object instances would normally be used by any Web service client based on Java Axis, but in this particular case, both are interleaved with the SandeshaContext class which is it what grants us our reliability layer.
The SandeshaContext is used to maintain state on the interactions taking place between client and server. That is the reason why the Call method invocations are nested between ctx.initCall and ctx.endSequence, which represent Sandesha's delimiters for initiating and terminating a reliable process, in case the actual Call methods generate an error that is undetectable by standard Web services operation -- such as guaranteed delivery or duplicate requests - Sandesha can determine by its context such an outcome.
In this listing, you can also observe the use of the namespace urn:wsrm:stockQuotePrice within the ctx.initCall method. This represents the additional SOAP header information added to the client request that has to be acknowledged by the Web service provider in order to fulfill the reliability loop. In Axis/Sandesha's case, while the combination does provide extensive support for building service providers capable of interpreting WS-ReliableMessaging clients, it would go beyond the scope of this article to explore such details. However, you should note that the Axis/Sandesha framework has been successfully tested to interoperate with WS-ReliableMessaging enabled clients and servers produced on different Web services stacks, such as those produced by IBM, Microsoft and Systinet.
With this we conclude our overview of Sandesha and WS-ReliableMessaging. Having exposed how to leverage Web services with reliability features, you are now in a position to consider complementing other enterprise messaging technologies such as JMS (Java Messaging Service) -- which until recently provided the only viable alternative to reliable distributed communication -- and use WS-ReliableMessaging to offer this same reliability level, but with the inherent benefits of platform independent Web services.

No comments:

Post a Comment