When you first began to work with Axis2, you probably used Axis2 code generation tools to create either Java or C stubs to invoke or create Web services. But when you need more control or more advanced capabilities, you will have to look into the internals of Axis2. MessageContext is part of the information model within Axis2, which is also referred to as the context hierachy.
Axis2 groups information at various levels, depending on the level of access needed. For example, information related to a given runtime message is grouped within message context. Likewise, within Axis2, we have a hierarchy of groups, and each group contains sub-groups related to the context hierarchy. Take a look at the context hierarchy figure given in Axis2 architecture guide. In that figure you can see two parallel hierarchies. One contains static information for Axis2, which is most likely loaded from configuration files. The other, which we are interested in, contains the runtime information for Axis2. Let's take a closer look at the context hierarchy and the information contained within it.
The Axis2 information model is stable across different versions already released. Other than minor changes, it should be the same since Axis2 1.0.
Table of Contents
- What is Inside Axis2 Context Hierarchy
- The Hierarchy
Figure 1 : Axis2 Runtime Context Hierarchy
Figure 1 shows the runtime context hierarchy within Axis2. Let's look at what each one of these encapsulates.
MessageContext creates an object for every message, regardless of whether it is from the client or server, processed within Axis2. First, the transport-related information is fed into the object, followed by the object model. This message context is then passed into each handler that is registered to process this type of message. Since the Axis2 information processing model is stateless, the context hierarchy is the only place that can be used to store state. Additionally, if the context information is relevant to this particular message being processed, it should be stored within message context.
If a certain handler needs to pass information to handlers down the line (to be invoked), or if the Axis2 engine itself needs to pass information to the handlers (to be invoked), then most of the time this information will be kept inside the message context. For example, when we receive a message with WS-Addressing headers, we will be using WS-Addressing handlers to process it. After that, those handlers will store the relevant information extracted from the WS-Addressing headers in the message context. When Axis2 engine wants to know who sends the message or the identification of the message (which were encapsulated inside WS-Addressing headers), it can always find those information within the message context.
At the same time, Axis2 engine or any other handler can set the WS-Addressing version to be used, within the message context. When we are sending out messages, with WS-Addressing enabled, WS-Addressing handlers will see the requested WS-Addressing version to be used and will act accordingly.
Message Context is the container for lots of other information too. If you set properties, using either the client API or within the service implementation class, all this information will be kept inside the message context. The relevant processing units within Axis2 extract these information and customize their functionality.
There can be multiple message contexts objects available at a given time within Axis2. For example, if you are trying to send out a response to a received message, you will have access to both the request message context and also to the response message context. But Axis2 will keep a pointer to the current message context object which will always be the message context you are processing right now. In the above case, the current message context will be response message context. You can get access to the current message context by using MessageContext.getCurrentMessageContext() method.
The main thing to understand is that the message context is the way to store information relevant to a given message. When the processing of the message is complete, it will be attached to Operation Context.
Operation context is the runtime representation of an operation; it is the direct map to the operation that is being invoked by a given message. OperationContext, within Axis2, holds the messages to a given operation. For example, if you invoke an IN-OUT operation, the OperationContext created for this invocation will hold both the IN message context and the OUT message context. The main task of the operation context is the management of message exchange patterns related to the corresponding operation.
An instance of ServiceContext is created for each invocation of a service. This ServiceContext holds all the operation contexts that are created, invoking the operations within that service. If you need to maintain state across multiple operations within the same service, then the ServiceContext is the best place to hold them.
One piece of important information we can get from an instance of ServiceContext is the EPR of that service. This is the URL you should use to access this service.
This is a cool feature within Axis2 that will help you to group different services together and maintain states among them. You need to define a service group during the deployment, using services.xml file. If you invoke the services within the defined service group context, Axis2 will create a common context for those services and share it across the services in that group. For example, you can create a service group, with an authentication service within it. If the clients are first expected to authenticate themselves, then all the other services can internally check with this authentication service, and then proceed with their processing.
If you need more information about this, please refer to the service group context example provided within Axis2 release.
This can be considered as the highest level context. Every Axis2 engine will have one configuration context associated with it. At the same time, you can run two Axis2 engines sharing the same Configuration context. Configuration context will have all the information required for the proper execution of Axis2 engine. If you need to maintain state across all the services and operations within the same Axis2 engine, this is the best place to save them. One common way to use configuration context is to share database connection pools, if you have multiple services accessing the same database.
Configuration context also maintains the active collection of service group contexts and operation contexts within it. Whenever a new message arrives, Axis2 engine will try to map that message into one of the existing service groups or operation contexts. (Service groups are mapped using a custom Id used within Axis2 and operation contexts are mapped using the message id.) If the message does not map to an existing group or context, Axis2 will create a new one.
Recently cluster management support was added to Axis2. The initiation of cluster management also happens inside the Configuration context.
Figure 1 shows the context hierarchy within Axis2. According to that, the lower level context considers the higher-level context to be the parent. For example, the parent of message context is operation context. When we go up in the context hierarchy the level detail and scope widens.
All these contexts have a way to store properties within them. You can set any object to this property object and assign a key to it for later retrieval. When you store a property within a higher level context, it is also accessible from any of the lower level contexts. For example, if you store a property in the configuration context, that property can be accessed from any of the other contexts.
In this tutorial we examined the different contexts available within Axis2 and gave a brief introduction to the information contained within each. The runtime context hierarchy within Axis2 plays a key role in the state management of Axis2. This is an important information model, as Axis2 is stateless and has a primary concern with control of execution. Axis2 stores and retrieves properties from the context hierarchy for all the customizations required within it.
Eran Chinthaka, WS PMC Member/Member-Apache Software Foundation, (FirstName).(LastName)@gmail.com