http://www.developer.com/

Back to article

Axis2 Session Management


July 18, 2006

Web services are in high demand and a large number of players have entered the web service arena. As a result of this, users are looking for more and more features, and they are trying to do everything by using Web services. By design, Web services are said to be stateless. There was no notion of managing sessions in the Web service world, but now this has changed and users cannot develop an advanced application without managing state. A good example would be banking applications where you log in into the system, withdraw money, and log, out.

If we try to map that into a Web service:

  • First, the user logs in into your account (invoking a login method)
  • The user withdraws money (invoking some operation on his account)
  • The user logs out (completing the transaction).

You easily can understand that the three operations stated above are interrelated, and the same user does all three invocations. So, it means that someone needs to keep track of the user, and another has to keep track of the user data throughout methods invocation. This implies the need for session management.

When it comes to advanced applications, we have to break the rules; otherwise, no one can implement real Web applications. As a result, even though Web services are stateless by nature, upi need to add a layer above it to provide session management.

The Stateless Nature of Axis2

One of the good design principles of Axis2 is that it keeps logic and states separately, so none of its components are needed to maintain session and they don't maintain sessions. In Axis2 handlers, transports and even AxisEngine are said to be stateless; therefore, there is no difference between having multiple instances or one instance of them.

As a best practice, a handler or transport should not keep any instance variable (if it is likely to be changed), because that breaks the stateless nature of Axis2. So, if the handler or transport wants to act in a stateful manner, the correct way is to store the state and Axis2 state hierarchy and use it whenever necessary, rather than keeping instance variable.

Types of sessions in Axis2

As mentioned above, an enterprise web service cannot sustain itself unless the session concept burns into Web service engines. In other words, it is wrong to say that each and every SOAP web service engine should maintain sessions because you can have services that do not require maintaining sessions. A good example could be a Google search service and a Google spell checker service.

Managing sessions directly causes an increase of the memory footprint and to slow down performance, but you need to have a compromise: whether or not you support the session and provide state full service development. Axis2 is meant to be an enterprise Web service engine, so it has to support session management.

When sessions are considered, there can be different types of sessions as well, and the lifetime of the session may vary from one to another. Some sessions last a few seconds whereas others last the system lifetime. Axis2 architecture has been designed to support four types of sessions. There are a few differences from one to another; hopefully you can develop any kind of Web service by using the following four types of session scope.

  • Request
  • SOAPSession
  • Application
  • Transport

Axis2 context hierarchy

It is useful to understand the types of contexts in Axis2 before discussing types of session in depth. As mentioned above, Axis2 keeps logic and states separately, so contextS are there to store the states. There are five types of contexts in Axis2:

  • ConfigurationContext: The runtime representation of THE whole system, to start Axis2 system you need to have A configuration context. The lifetime of configuration context will be the lifetime of the system, so if you store some state (a property) it will last forever (until system shutdown).
  • ServiceGroupContext: In Axis2, you can deploy multiple services together as a service group. At runtime, there will be one or more service group contexts (depending on the session scope of the group) to keep states of the group throughout the session.
  • ServiceContext: Will represent the runtime of one service; the context lifetime will be 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 context represents the lifetime of a MEP (Message Exchange Patterns). The lifetime of the operation context is usually less than the lifetime of the service context.
  • 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, the best way is to store them in message context. One operation context may have many message contexts.

Irrespective of the session scope, when the session start up and when it finishes, Axis2 will notify the service implementation class, but you have to add two additional methods to your service implementation class.

public void init(ServiceContext serviceContext) {
}

public void destroy(ServiceContext serviceContext) {
}

In addition to that, whenever a service receives a request, it will notify by passing the corresponding OperationContext as an argument. So, if the service wants to access an incoming message's context or an incoming SOAPMessage, he can do that by just adding the following method to the service implementation class; this method will be called before the actual method is called.

public void setOperationContext(OperationContext operationContext) {
}

Request session scope

Request session scope is the default session in Axis2. When you deploy a service without knowing anything about session management, your service will be deployed in the requested session scope. The lifetime of this session is limited to the method invocation's lifetime, or the request processing time. So, when you deploy a service in request scope, you don't have a way to manage session; it is the same as though you don't have a session at all.

Once you deploy a service in request session scope for each and every invocation service, the implementation class will be created. Say you have deploy a service called "foo" in request scope; if a client invokes the service 10 times, there will be 10 instances of the service implementation class. If you want to specify the scope explicitly, you still can do that by adding a scope attribute to the service element in services.xml as follows:

<service name="foo" scope=" request">
</service>

Even if you deploy a service in a request scope, there are many ways of managing sessions in Axis2. One way is to store the state in Axis2' global runtime (configuration context) and retrieve it whenever necessary.

SOAP Session Scope

SOAP session scope has a slightly longer lifetime than a request session, and deploying a service in a SOAP session is required to change services.xml. Managing a SOAP session requires both the client and service to aware of the sessions; in other words, the client has to send the session-related data if he wants to access the same session and the service has to validate the user by using session-related data.

To manage a SOAP session, a client has to send an addition reference parameter in the SOAP header; it is named the serviceGroupId parameter. The SOAP session provides a way to manage the session not only for a single service invocation but also for multiple services in a service group. As long as you are in the same SOAP session, you can manage service-related data in a service context; if you want to share data across other services in the group, you can use serviceGroupContext.

When you deploy a service in SOAP session and when a client tries to access the service in the first time, Axis2 will generate serviceGroupId and send that to the client as a reference parameter in wsa:ReplyTo, as shown below:

<wsa:ReplyTo>
   <wsa:Address>
      http://www.w3.org/2005/08/addressing/anonymous
   </wsa:Address>
   <wsa:ReferenceParameters>
      <axis2:ServiceGroupId xmlns:axis2=
         "http://ws.apache.org/namespaces/axis2">
            urn:uuid:65E9C56F702A398A8B11513011677354
      </axis2:ServiceGroupId>
   </wsa:ReferenceParameters>
</wsa:ReplyTo>

If the client wants to live in the same session, he has to copy that reference parameter and send it back to the server when he invokes the service the second time. As long as a client sends the valid serviceGroupId, he can use the same session, and the service can maintain the session-related data. Unlike a request session, a SOAP session has a default timeout period, so if the client does not touch the service for 30 seconds, the session will expire, and if the client sends the old serviceGroupId, he will get an AxisFault too.

Managing a SOAP session requires you to engage addressing modules on both the server side and client side. Deploying a service in a SOAP session requires you to change services.xml as follows:

<service name="foo" scope=" soapsession">
</service>

Transport session scope

In the case of a Transport session, Axis2 uses transport-related session management techniques to manage session. As an example, in the case of HTTP, it uses HTTP cookies to manage the session. The lifetime of the session is controlled by the transport, not by Axis2; Axis2 stores the service context and serviceGroupContext in the transport session object so that the service can access those contexts as long as the session lives.

One of the key advantages of the Transport session over other sessions is that you can talk to multiple service groups within one transport session. In a SOAP session, you don't have a way to communicate between two service groups, but with the transport session you have that capability. In this case, the number of service instances created depends on the number of transport sessions created.

Deploying a service in a transport session requires you to change services.xml as follows:

<service name="foo" scope=" transportsession">
</service>

If you are using Axis2 nightly builds or planning to use them the next version, deploying a service in a transport session requires additional changes to axis2.xml. That is mainly to improve the memory usage; otherwise, whether you deploy the service in a transport session or not Axis2 tries to create a session object at the transport level; with these changes, it will not create unnecessary objects. To manage the transport-level session, you need to set the manageTransportSession parameter value to true in axis2.xml:

<parameter name="manageTransportSession"
   locked="false">true</parameter>

Application scope

Application scope has the longest lifetime compared to others; the lifetime of the application session is equal to the lifetime of the system. If you deploy a service in application scope, there will be only one instance of that service and obviously there will be only one service context for that service. In the Axis2 world, if you consider the memory footprint and if you don't want to manage the session, the good candidate is to deploy the service in application scope.

When you deploy a service in application scope, a client does not need to send any additional data to use the same session. To deploy a service in application scope, you need to change axis2.xml as shown below:

<service name="foo" scope=" application">
</service>

Managing the session using the service client

Managing the session on the client side involves bit of a work. As mentioned above, both in a SOAP session and Transport session a client has to send the session-related data if he wants to live in the same session. Maybe he can do that for a SOAP session by coping with required reference parameters, but with a Transport session a user must get access to the transport to copy and send cookies.

To make life easier, Axis2 has the built-in capability of managing sessions in the client session by just setting a flag. Then, depending on the service side session, it will send the corresponding data as long as you use the same service client. So, the main requirement is to use the same service client to invoke the service if you want to live in the same session.

If you want to live in the same session, you can create service client as shown below and re-use the created service client object to invoke the service.

Options options = new Options();
options.setManageSession(true);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);

Once you create the service client as shown above, if the service deploys in a SOAP session it will copy the serviceGroupId and send that from the second invocation onwards. If the server sends the session id, such as HTTP cookies, it will copy that to the service context (on the client side) and send it back to the server when the client invokes the service for a second time.

Summary

The stateless nature is one of the main characteristics of Web services, but it is a limitation for advanced Web services developers. Developing an enterprise-level application using Web services is not easy unless you have a session management layer. Axis2 has four levels of sessions to address enterprises-level Web service development issues.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date