Sunday, July 15, 2012


Understanding WS-Addressing in Apache Axis2

The WS-Addressing specification has become an integral part of any WS stack. Most Web services stacks support WS-Addressing by default, and some have even integrated it into the core of their engines. Apache Axis2, a pioneer in providing WS-Addressing specification support, has proven to be a success with WS-Addressing through various interoperability sessions. 
Eran Chinthaka
Software Engineer
WSO2 Inc.
chinthaka's picture
Apache Axis supports the two widely used versions of WS-Addressing Specifications, namely: WS-Addressing Final and Submission.

Applies To

Apache Axis2/Java1.2

Introduction

The Axis2 release comes with an implementation of the WS-Addressing Final and Submission versions [1]. These implementations have been tested in numerous interoperability sessions in the past, and have been part of Axis2 since the inception of Axis2.
Axis2 uses a similar addressing model internally as proposed in the WS-Addressing final specification. The model is meant to capture addressing information, in general, to a "bag" within its engine. These properties can also be populated by transport processors, service authors, etc. This makes Axis2 work smoothly even if the WS-Addressing implementation is disabled at runtime for legacy reasons.
First let's look at how addressing processing works inside Axis2.

How Axis2 Processes WS-Addressing Headers

The main task of the Axis2 engine is to process incoming and outgoing SOAP messages. When it receives or sends SOAP messages, it creates an instance of MessageContext to keep track of all the information related to that message. This MessageContext includes the SOAP message just received or about to be sent, and might also reference the other SOAP messages related to this message exchange pattern [2].
The message context also encapsulates various meta-data about the message and also some information relevant to the processing of the message. The MessageContext object also has properties that capture addressing related properties like where this message came from, the destination URL, etc., This information is independent from WS-Addressing specification details. This information is mostly captured from the specific transport receivers. For example, if the transport used is HTTP, then the HTTP transport listener (either AxisServlet or SimpleHTTPServer) copies the URL, SOAP action (if available), content type header, etc., If you look at this addressing model carefully, you will see that it is almost similar to the WS-Addressing model defined in the specification; yet the model can capture information from the source other than WS-Addressing headers.
All the handlers, control logic and message receivers, (message receivers are responsible for taking care of the respective message exchange pattern in use and to hand over the message to the Web service implementation) extract addressing properties from the message context, irrespective of whether they come from transport, WS-Addressing implementation or any other means. So this bag of properties can be regarded as a WS-Addressing neutral set of properties.
The WS-Addressing implementation comes with every Axis2 release bundled within the Axis2 release itself. This WS-Addressing implementation is a module in Axis2. So you should be able to see addressing-.mar inside the release. If you need to use WS-Addressing, you need to engage the WS-Addressing module. (Please refer to the Axis2 user guide for more information on engaging modules.)
When we engage WS-Addressing to the message path, the WS-Addressing module adds a couple of handlers to the IN path and also to the OUT path of the message processing. The addressing handlers deployed in the IN path, Addressing "IN" Handlers, read WS-Addressing information from the incoming message and populate the above discussed addressing properties. (If there are values already inside some of these properties, WS-Addressing simply overrides them). Addressing "IN" handlers have the capability to detect the WS-Addressing version used inside the SOAP message and process them accordingly.
Likewise, Addressing handlers in the OUT path, take out the addressing properties from the message context and populate the out going SOAP message with them.
This is how the Axis2 engine understands WS-Addressing information within SOAP messages. However, WS-Addressing integration does not end at this point. The Axis2 engine has all the rules defined by WS-Addressing implemented internally. For example, the rules defined to handle SOAP faults, are handled within the proper locations of the Axis2 engine according to the WS-Addressing rules. So you might argue that WS-Addressing is already built into it. What WS-Addressing module provides is just the option of understanding the WS-Addressing header in SOAP messages.
Let's see how you can access WS-Addressing properties. You do not have to worry about accessing the SOAP message to get or set addressing information. The already mentioned property bag within the MessageContext object will have convenient methods that will provide the required functionality. For example, if you need to retrieve the value of the WS-Addressing To header, simply call messageContext.getTo(). Likewise, if you want to change the value of the To header, use messageContext.setTo(EndpointReference). This EndpointReference class resembles the EndpointReference defined within the WS-Addressing specification. You can set the address, set reference parameters, etc., using the EndpointReference class.
Once you engage the WS-Addressing module, the engine will use WS-Addressing within the engine. You are not required to configure anything to make it run. However, there are some configuration options available if you want more control over how it works. Having understood how the WS-Addressing implementation works within Axis2, let's see how we can tweak some of the processing of addressing handlers within Axis2.

Tweaking Addressing Processing

There are some properties you can set, using the API you are dealing with, to change the behavior of addressing handlers. If you are writing a client, use either ServiceClient API or your stub API. If you are a service author, then you need to set these properties to the message context. The following items use examples to demonstrate how these properties can be set using Options API. Let's see what these properties are and what they change.

DISABLE_ADDRESSING_FOR_OUT_MESSAGES

When you send out SOAP messages and if WS-Addressing is engaged, then it always sends out WS-Addressing headers inside the SOAP messages. There can be times you might not wish to include WS-Addressing headers only for a selected set of outgoing messages. For example, if you have a legacy Web service implementation, you can use Axis2 to process WS-Addressing headers and forward the message without those headers. In that case, what you have to do is to set DISABLE_ADDRESSING_FOR_OUT_MESSAGES to the message context or to the Options object that you have.
 options.setProperty(DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.TRUE);

WS_ADDRESSING_VERSION

As mentioned earlier, Axis2 supports two addressing versions. Namely: Final and Submission versions [1] . You can use any of these versions within Axis2. The WS_ADDRESSING_VERSION property can be used to inform the Axis2 engine about the addressing version that you are interested in using. For example, if you want to use the WS-Addressing submission version, set WS_ADDRESSING_VERSION to org.apache.axis2.addressing.AddressingConstants.Submission.WSA_NAMESPACE.
If you want to use WS-Addressing final version then set it to org.apache.axis2.addressing.AddressingConstants.Final.WSA_NAMESPACE
 options.setProperty(WS_ADDRESSING_VERSION, org.apache.axis2.addressing.AddressingConstants.Final.WSA_NAMESPACE);

INCLUDE_OPTIONAL_HEADERS

The WS-Addressing specification defines a set of EPRs to be included inside the SOAP message if WS-Addressing is enabled. Some of these headers are optional. For example, the destination URL (To address) and the action parameters are required while the others are optional. The Axis2 WS-Addressing implementation adds only the required headers by default, if WS-Addressing is engaged. If you want to include the optional headers as well, then you need to set the INCLUDE_OPTIONAL_HEADERS property to ask Axis2 to include those headers also.
 options.setProperty(INCLUDE_OPTIONAL_HEADERS, Boolean.TRUE);

REPLACE_ADDRESSING_HEADERS

As I mentioned earlier, WS-Addressing Out Handlers are responsible for taking out addressing information from the message context and putting them into the outgoing SOAP message. There can be situations where the outgoing message might already have addressing headers. For example, if the current Axis2 node is just an intermediary or a message mediation node, then it will be passing the same message to the outgoing path as well. Therefore, the outgoing message has addressing headers in it by the time it comes to the addressing out handler. The nodes tend to remove any existing headers, and then add the new headers. If we add the same headers twice then it might not be correct. If the REPLACE_ADDRESSING_HEADERS property is set to True, then the addressing handlers will remove any existing headers if present, before adding the new ones.
 options.setProperty(REPLACE_ADDRESSING_HEADERS, Boolean.TRUE);

ADDR_VALIDATE_ACTION

Axis2 finds the service and the operation a SOAP message is destined to within the dispatch phase. (Refer to the article How Apache Axis2 Finds the Operation and Service a Message is Destined to [3] to know more about how dispatching works.) If Axis2 cannot find the operation a message is destined to, then the user should be notified about this. If WS-Addressing is engaged, then the WS-Addressing specification is defined to throw an ActionNotSupported Fault to the user. However, sometimes, users might need to suppress this behaviour (there are scenarios for this in the Apache Synapse project). Setting ADDR_VALIDATE_ACTION to False will suppress Addressing handlers from sending the ActionNotSupported fault to the user.
 options.setProperty(ADDR_VALIDATE_ACTION, Boolean.TRUE);

Summary

WS-Addressing is a key specification in today's Web services stacks. With the popularity and wide spread adoption of asynchronous invocations, the importance of WS-Addressing has increased. This article illustrated how this important specification is implemented within the pioneering open source Web services engine in Apache Axis2. The parameter configuration section also described how you can gain control to some extent over this process.

References

  1. WS-Addressing Specifications : Final Submission
  2. Understanding Message Exchange Patterns
  3. How Apache Axis2 Finds the Operation and Service a Message is Destined To

No comments: