ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


Web Services Messaging with Apache Axis2: Concepts and Techniques

by Srinath Perera, Ajith Ranabahu
07/27/2005

Until recently, web service interactions were solely synchronous and request-response in nature. However, it soon became clear that the synchronous request-response type of interaction is a very small subset of messaging scenarios. Messaging is very important in constructing loosely coupled systems, and as a result, this limitation is critical. Web service specifications, such as WS-addressing and WSDL, have incorporated the concepts of messaging, and lay the foundation to cover a wider range of messaging scenarios. The Apache Axis2 architecture assumes neither one message exchange pattern, nor synchronous/asynchronous behavior. This article explains messaging concepts and how Axis2 can be used to implement several well-known messaging scenarios.

A Brief Introduction to Messaging

Throughout the history of computing, one of the greatest challenges has been in distributed computing: when the resources are distributed, interprocess communication becomes quite difficult. Researchers are still looking for better solutions. Interestingly, almost all of the solutions for the problem of distributing computer power emerge from two conceptual bases: remote procedure calls (RPC) and messaging.

Unquestionably, using RPCs is the more popular technique among developers, partly due to its resemblance to using local procedure calls. It has an air of familiarity for programmers, and creates a natural tendency towards using RPC style in a distributed system. Messaging, on the other hand, is not remarkably popular, and quite a few developers are likely to raise their eyebrows if it is mentioned. Nevertheless, messaging provides certain advantages over RPC systems in certain scenarios.

The fundamental differences between RPC and messaging frameworks are as follows.

Web Service Messaging

Web services are defined based on XML messaging, and the following three parameters describe a given web service's messaging interaction.

  1. Message exchange pattern
  2. Synchronous and asynchronous client API
  3. One-way/two-way behavior of the transport

Related Reading

Java Web Services in a Nutshell
By Kim Topley

In the most abstract form, web service messaging is based on sending and receiving messages. A given message is sent by one party, and received by a another. The messages might be related to each other, and it is important to identify the most common use cases among those related groups of messages; such message groups are defined as message exchange patterns, or MEPs.

A service requester's behavior in the transient period between two related messages defines the synchronous/asynchronous behavior in the client API. In the synchronous case, invocation at the client API would block, and wait until the related message arrives at the destination. In the non-blocking case, the client invocation continues without blocking, and when a related message arrives, it is correlated with earlier messages.

Transports are categorized as one-way or two-way, based on simplex or duplex behavior. Transports like SMTP and JMS are one-way transports, and are non-blocking in nature. On the other hand, transports like HTTP and TCP are two-way, and the related message may travel back in the return channel. Actually, in web service messaging, two-way transports may be used as a one-way transports, but in such cases, they can be effectively treated as one-way.

Message Exchange Patterns

According to the W3C recommendation, a message exchange pattern is a template that establishes a pattern for the exchange of messages between two communicating parties. A MEP identifies a common grouping of related messages. The MEPs are defined based on the service requester and service provider, and it is important to note that the MEPs are named based on message characteristics in the service provider, for the sake of clarity. All of the names can be understood by replacing the in with request and out with response.

For an example, let us consider two well-known MEPs.

  1. In-only/"fire and forget:" The service requester sends a message to the service provider and does not expect any related message.
  2. In-out/"request response:" The service requester sends a message to the service provider and expects a response.

The concept of MEPs is still evolving, and the number of patterns is unlimited, so web service middleware implementations are compelled to implement only a few chosen MEPs. "Fire and forget" and "request-response" are the ones that are used explicitly, and most other patterns can be constructed using these two.

Synchronous/Asynchronous Behavior of the Client API

Synchronous/asynchronous (or blocking/nonblocking) behavior is based on the thread that handles the web service invocation. A synchronous service will block, and wait for related messages to arrive. On the other hand, an asynchronous invocation will just return, and waiting for related messages will be done by a different thread that runs in the background.

Both approaches have strong use cases. Consider a bank transaction that needs a number of messages to fly back and forth: the bank transaction is sequential by nature, as results are required to arrive before execution goes to the next step, so synchronously waiting for the results make sense. On the other hand, consider a flight reservation program that needs to collect data from many sources, and match based on the results. In this case, the asynchronous approach would work, since the program can submit all of the requests and work on the data as they arrive. Considering network latency, the asynchronous approach would yield much better results.

The synchronous invocations are simple: the invocations wait for the related messages to arrive, and can be coded like any local procedure call. But the correlation of the asynchronous messages is complex, and the client has to work to handle the complexities. Still, there are cases where doing extra work to handle the complexity can be justified.

Behavior of the Transport Layer

The behavior of the transport layer is a critical factor that decides how web service messaging takes place. Transports are categorized as one-way or two-way, according to their behavior.

One-way transports reduce the complexity of web service messaging, as the related message must come from a separate channel. On the other hand, if the transport is two-way, messaging has a choice of using transport as one-way or two way. For an example, when the transport is HTTP, the related message may come from the return path of the HTTP connection, or the web service provider might write HTTP 200 to indicate that there is no response coming on the same connection, in which case the response is sent over a separate HTTP connection.

The Role of Web Service Addressing

Web service addressing (also called WS-addressing) lays the framework for the information exchange between different parties that takes place in a web service interaction. The following five parameters define an interaction.

  1. Message exchange pattern
  2. Transport with which the service can be accessed
  3. Transport used by the related messages
  4. Behavior of the transport
  5. Synchronous/asynchronous behavior of the client API

The service provider declares the first two, and the client is free to define the other parameters. The client-level synchronous/asynchronous behavior is completely transparent to the service provider, and the client uses WS-addressing to explain the web service messaging.

Among many other constructs, WS-addressing defines four headers: To, ReplyTo, RelatesTo, FaultTo, and a special address that is called the Anonymous address. When a service provider receives a SOAP message, it finds the target service based on the To address and invokes the service. The results, if there are any, are sent to the ReplyTo address, and any error is sent to the FaultTo address. If any of the above headers are not specified or have the value Anonymous, the result is sent via the return path of a two-way transport (since Anonymous always resolves to the return path of a two-way transport).

Transports, together with WS-addressing, define a mechanism to find interrelated messages. Messages are related either because they share the same transport channel, or because they all share common information that links them to each other. The RelateTo header of the web service addressing provides precisely this relationship.

The following table shows different values of the addressing headers for a few well-defined message interactions.

MEP Sync/Async Transport Behavior Message To ReplyTo RelatesTo
In-Only NA One-way IN Optional Optional NA
In-Out Sync One IN Optional Anonymous NA
OUT Anonymous Optional IN-Message
In-Out Async One IN Optional Anonymous NA
OUT Anonymous Optional IN-Message
In-Out Async two IN Required Required NA
OUT Required Optional IN-Message

Axis2 Client API Concepts

The Axis2 client API handles In-Only and In-Out MEPs with all messaging combinations discussed in the last section. The space of the MEPs are unlimited; as a result, Axis2 is compelled to provide a core that can support any message exchange pattern, but provides API support only for the two most widely used patterns: In-Only and In-Out. There are two ways to implement more complex patterns: combine In-Out and In-Only patterns to achieve the desired pattern, or write a new implementation for the desired pattern. As Axis2 provides support for any MEP in the core level, implementing either is fairly straightforward. The In-Only and In-Out MEPs are supported with the two classes InOnlyMEPClient and InOutMEPClient, described in the next two sections.

In-Only MEP Support: InOnlyMEPClient

The InOnlyMEPClient class provides support for fire-and-forget messaging, and treats all transport types as one-way transports. The real difference between InOnlyMEPClient and InOutMEPClient is that the addressing parameters are not locked in the former, and addressing parameters are controlled by Axis2 in the latter. As the addressing parameters can be controlled, the InOnlyMEPClient can be used as the messaging API, and used as the building block to build more complex message interactions on top of it.

In-Out MEP Support: InOutMEPClient

InOutMEPClient and the Call class that extends the InOutMEPClient provide the API for request-response messaging. Axis2 takes care of the complete operation, and all of the addressing properties except the To address are under the control of the Axis2.

Users can configure InOutMEPClient to behave differently using the following four parameters:

  1. Sender transport
  2. Listener transport
  3. Use separate listener
  4. Use blocking

The client API currently provides support for HTTP and SMTP transports. The following matrix shows the possible combinations for these parameters and how they combine to provide different effects.

Messaging interaction Sender transport Listener transport Use separate Listener Blocking
Sync/One Channel HTTP HTTP FALSE TRUE
Async/One Channel HTTP HTTP FALSE FALSE
Async/Two Channel HTTP HTTP TRUE FALSE
SMTP SMTP TRUE FALSE
Sync/Two Channel HTTP HTTP TRUE TRUE
SMTP SMTP TRUE TRUE

Examples

The following code samples show how to do several well-defined interactions with Apache Axis2. The user may configure Axis2 to switch between different interactions by simply switching the properties in the client API. The client API of Axis2 supports only XML-level messaging, and OMElement represents a chunk of XML.

Invoking One-Way Messaging

The one-way MEP is simple in that there is exactly one way it can behave, as there is only one message that goes back and forth. The messages are treated asynchronously and the transport is one-way.

Request-Response Messaging

There are four ways a request-response message can behave:

  1. In-Out synchronous with two-way transport
  2. In-Out asynchronous with two-way transport
  3. In-Out synchronous with one-way transport
  4. In-Out asynchronous with one-way transport

The following code samples show how these cases can be addressed with Axis2. Pay attention to how the four properties of the client API are used.

  1. In-Out synchronous, HTTP as two-way transports
    
    OMElement payload = .... 
    Call call = new Call();
    call.setTo(
            new EndpointReference(AddressingConstants.WSA_TO,
                    "HTTP://...));
    call.setTransportInfo(Constants.TRANSPORT_HTTP, 
           Constants.TRANSPORT_HTTP, false);
    OMElement result =
            (OMElement) call.invokeBlocking(
            operationName.getLocalPart(), payload);
    
    

    Here, the SOAP messages travel through the same HTTP connection. The addressing properties are not specified, so they will be defaulted to Anonymous at the server side. The client API will block until the response message arrives.

  1. In-Out asynchronous, HTTP using HTTP as two-way transports
    
    //this is the payload goes on the body of SOAP message 
    OMElement payload = .... 
    Call call = new Call();
    call.setTo(
            new EndpointReference(AddressingConstants.WSA_TO,
                    "HTTP://...));
    call.setTransportInfo(Constants.TRANSPORT_HTTP,
                  Constants.TRANSPORT_HTTP, false);
    
    Callback callback = new Callback() {
        public void onComplete(AsyncResult result) {
            //what user can do to result
        }
        public void reportError(Exception e) {
           //on error
        }
    };
    call.invokeNonBlocking(operationName.getLocalPart(),
           payload, callback);
    
    

    As before, the SOAP messages travel through the same HTTP connection and the invocation does not require addressing. The client API will not block and the callback will be executed once the response message arrives.

  2. In-Out, asynchronous HTTP as one-way transport
    
    OMElement payload = .... 
    Call call = new Call();
    call.setTo(
            new EndpointReference(AddressingConstants.WSA_TO,
                    "HTTP://...));
    call.setTransportInfo(Constants.TRANSPORT_HTTP,
        Constants.TRANSPORT_HTTP, true);
    Callback callback = new Callback() {
            public void onComplete(AsyncResult result) {
            ....
            }
    
            public void reportError(Exception e) {
            ...
            }
    };
    call.engageModule(new Qname("addressing"));
    call.invokeNonBlocking(operationName.getLocalPart(), method, callback);
    
    

    In this case, the SOAP messages travel through two HTTP connections, addressing is mandatory, and the presence of the ReplyTo header instructs the server to send the response in a separate channel. The client does not block, and when the response message arrives, the callback is invoked.

  3. In-Out, synchronous HTTP as one-way transport
    
    OMElement payload = .... 
    Call call = new Call();
    call.setTo(
    new EndpointReference(AddressingConstants.WSA_TO,
            "HTTP://...));
    call.setTransportInfo(Constants.TRANSPORT_HTTP,
        Constants.TRANSPORT_HTTP, true);
    OMElement result =
            (OMElement) call.invokeBlocking(
               operationName.getLocalPart(), payload);
    
    

    This uses a "In-Out, asynchronous HTTP as one-way transport" type of invocation under the curtain, but the invocation blocks until the result arrives in the second connection, and execution returns with the result.

Summary

In summary, the behavior of web service messaging is based on three parameters: the message exchange pattern, the synchronous/asynchronous behavior of the client, and the behavior of the transport. Axis2 is built on a core that is not bound to any type of MEP, yet provides client API support for the most widely used MEPs: one-way and request-response. The article explains the concepts behind the Axis2 messaging support and how the client API is used.

Resources

Srinath Perera is a principal architect for Apache Axis2.

Ajith Ranabahu is a committer for the Apache Axis2 project and has been working on web-service-based projects for the past three years.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.