Axis2 Session Management

Archived Content
This article is provided for historical perspective only, and may not reflect current conditions. Please refer to relevant product page for more up-to-date product information and resources.
  • By Deepal Jayasingha
  • 29 Nov, 2008

Web services are inherently stateless, but it can be difficult to implement enterprise-level Web service applications without having support for sessions and session history. In this article, Deepal Jayasinghe presents some common scenarios that necessitate session support, as well as an introduction to the session management capabilities of Axis2.

Table of Contents

Introduction

To understand the need for session support, let us consider the sequence of events associated with a typical banking application:

  • User logs in to online banking site (invoking login method)
  • User transfers money between accounts (invoking some operation on his account)
  • User logout (complete the transaction)

We can easily understand that the three operations stated above are interrelated, and that the same user performs all three invocations.  This means that someone needs to keep track of the user and user data throughout methods invocation, which implies the need for session management. Even with alternative ways of implementing the same application, a way to identify and authenticate users is required.

Stateless Nature of Axis2

One of the key advantages of Axis2 is that it keeps logic and data in separate components.  Users typically have two types of data models, static and runtime. Static data consists of AxisService, ServiceGroup, AxisOperation, AxisConfiguration and others.  The dynamic data hierarchy consists of ConfigurationContext, ServiceGroupContext, ServiceContext, OperationContext and MesasgeContext.

A stateless nature provides better support for concurrency handling as well. In Axis2 Handlers, the MessageReceivers, TransportSenders, TransportReceivers and even AxisEngine are stateless, so they do not keep any state in those classes.  As a result, it does not matter whether we have one instance or a number of instances of the same Handlers.  This also means that when we write handlers, we need to write them in such a way that they do not keep any state.  For example, we cannot consider the following handler implementation as a good approach, as it has a class variable to store the messageContext.  When we deploy Axis2 in a concurrent environment we will definitely have issues.  As a best practice, you should not use any class variables inside your code.


public class InvalidHandler extends AbstractHandler {

//Class varible to keep current MC
private MessageContext currentMessageContext;

public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
currentMessageContext = msgContext;
//We need to write whatever the log we need to have here
return InvocationResponse.CONTINUE;
}
}
Problem: Keep MessageContext as a class variable.

Session Type in Axis2

Within session management, there are different types of sessions.  The lifetime of sessions may vary as well; some sessions last for a few seconds while some others last for the system lifetime.  Axis2 architecture has been designed to support four types of session scopes:

  • Request
  • SOAPSession
  • Application
  • Transport

Before discussing session management further, first we will review Axis2 runtime hierarchy, or dynamic data.  There are five different types of runtime data, also known as contexts, which are listed below:

  • ConfigurationContext: This is the runtime representation of the entire system, which is needed to start the Axis2 system. The lifetime of configuration context will be the lifetime of the system, so if we store some state (a property), it will last until system shutdown.
  • ServiceGroupContext: In Axis2, multiple services can be deployed together as a service group, and the runtime representation of this is called ServiceGroupContext.
  • ServiceContext: This represents the runtime of one service, and the context lifetime is the lifetime of the session. There can be one or many service contexts in the system, depending on the session scope of the corresponding service.
  • OperationContext: This represents the lifetime of a MEP (Message Exchange Pattern).  The lifetime of operation context is normally shorter than the lifetime of the ServiceContext.
  • MessageContext: The lifetime of an incoming message is represented by the message context.  If two handlers in a given execution chain want to share data, then the best way is to store them in message context.  One OperationContext may have one or more MessageContexts.

Session Initialization and Session Destroy

There is always a lifetime management associated with session management.  When writing a session-aware service, you may need to know when a session begins and ends.  Axis2 provides the information on a service implementation class in two ways, through Java reflection or an optional interface.

Java reflection

The service author has to implement the following two methods in his service implementation class if he wants to be notified when the session starts and finishes. At runtime, when a session starts, Axis2 looks to see whether the following methods are in the service implementation class so it can call the right method.


//This method will be called when a session start
public void init(ServiceContext serviceContext) {
// Our code goes here
}

//This method will be called when a session finishes.
public void destroy(ServiceContext serviceContext) {
// Our code goes here
}

Using optional interface

Java reflection is a good user interface because there is a very low probability of making mistakes on method names and method parameters.  Axis2 has an interface called “org.apache.axis2.service.Lifecycle”, which has the same two methods introduced above. If we want to receive a notification when a session starts, we write our service implementation class to implement that particular interface so that Axis2 will automatically call the right method.  We can write our service implementation class as shown below:


public class MyService implements Lifecycle {

public void init(ServiceContext context) throws AxisFault {

}

public void destroy(ServiceContext context) {

}
}

Accessing MessageContext

Just as keeping class variables anywhere in Axis2 is not a good practice, it is also not advised to keep variables inside the service implementation class.  However, we still need a way to access contexts and obtain session-related data when managing sessions.  Once we have MessageContext, we can access almost everything, but we first have to get the current MessageContext inside the service class. In this simple process, we can use Axis2 to set MessageContext into ThreadLocal, and from that we can access the MessageContext.  For example, if we want to access the MessageContext inside the method called “foo”, then we can do that as follows:


public void foo(){
MessageContext messageContext = MessageContext.getCurrentMessageContext();
}

This can be used to access current MessageContext, regardless of the session scope we use.

Conclusion

In this section we examined the nature of Web services as well as the importance of having session management support for enterprise-level applications. In addition, we discussed how Axis2 handles sessions, as well as the correct way to manage sessions in Axis2.  Finally, we explored different types of session as well as lifetime management. In Part 2 of this two-part series, we will take a more detailed look at the four types of sessions.

Author

[Deepal Jayasinghe, Tech lead, WSO2, deepal +AT+ wso2 +dot+ com]

About Author

  • Deepal Jayasingha
  • WSO2 Inc.