2007/01/29
29 Jan, 2007

Different Ways of Creating a ConfigurationContext in Axis2

  • Deepal Jayasingha
  • - WSO2

Introduction

Axis2, Apache Web services processing framework can be used in various ways. One can use Axis2 as a client to invoke a service, or one can use Axis2 as a standalone Web service server to host Web services. Also one can use Axis2 inside a J2EE Application server to host Web services. In addition to those, there can be many other different applications of Axis2. Irrespective of the application, Axis2 requires configuration data to start and run. The configuration data that we need to start an instance of Axis2 is called "ConfigurationContext".

ConfigurationContext can be considered as an in-memory database which keeps both static and dynamic data. When we closely look at the Axis2 architecture we can easily identify two data hierarchies, first one is called "description hierarchy" while the second is called "context hierarchy". Description hierarchy keeps all the static data (meta data) which is specified using various deployment descriptors (axis2.xml , module.xml and services.xml). The top most component of the description hierarchy is called AxisConfiguration and the hierarchy consist of several other components as listed below;

  • AxisConfiguration
  • AxisServiceGroup
  • AxisService
  • AxisOperation
  • AxisMessage
  • AxisModule

On the other hand, as mentioned before, the context hierarchy keeps the runtime data or the dynamic data. For example, data that requires to manage various kind of sessions. Similar to the description hierarchy, context hierarchy also contains number of components, and ConfigurationContext is the top most component of the context hierarchy.

  • ConfigurationContext
  • ServiceGroupContext
  • ServiceContext
  • OperationContext
  • MessageContext

Even though there are two hierarchies, both have very strong relationships as shown in Figure 1. By looking at at the figure we can easily understand that ConfigurationContext keeps AxisConfiguration inside it. So ConfigurationContext is the one that has the complete Axis2 system, both static and dynamic data. The important thing to remember here is that we will not have a complete context hierarchy until we get the first request. In the meantime we do not have complete description hierarchy until we deploy the first service. There are four main ways of creating an instance of ConfigurationContext as listed below;

Context Hierachy

Figure 1 : Context & Description Hierarchy

There are four main ways of creating an instance of ConfigurationContext as listed below;

  1. Creating empty (default) ConfigurationContext
  2. Creating ConfigurationContext from a file system
  3. Creating ConfigurationContext using a URL
  4. Creating ConfigurationContext using custom AxisConfigurator

In addition to those four main options, there are many sub-options as well. We will be learning about them as we go through this document. For the user's convenience, and also to reduce the number of mistakes, there is a factory called "ConfigurationContextFactory" to create ConfigurationContext. The factory has four methods to create ConfigurationContext for the above mentioned methods.

Creating Empty ConfigurationContext

There may be instances where we need to have full control on filling and creating two hierarchies. In such a situation creating ConfigurationContext this way will be a good candidate. When we create empty ConfigurationContext it contains empty AxisConfiguration as well, and that AxisConfiguration dose not have any services or modules (not any transports as well). But once we create ConfigurationContext in this manner we can add services and modules as we wish and also add transport senders and transport receivers the way we want. There are two ways through which we can create empty ConfigurationContext. This is shown below;

Option 1 : Using ConfigurationContextFactoy

ConfigurationContext myConfigContext = 
ConfigurationContextFactory.createEmptyConfigurationContext();

Option 2 : Create everything manually

AxisConfiguration axisConfig = new AxisConfiguration();
ConfigurationContext myConfigContext = new ConfigurationContext(axisConfig);

Creating ConfigurationContext From a File System

This is the most commonly used method to create a ConfigurationContext and this has a number of sub option as well. When we create a ConfigurationContext this way, the corresponding AxisConfiguration has bare minimum of set of transports, handler chains etc to run Axis2. Depending on the sub-options we use AxisConfiguration vary one to another.

In this type of ConfigurationContext, creating Axis2 most of the time relies on a particular location in the file system and that is considered as the "repository". The repository is a directory in the file system which has two sub-directories called "modules" and "services". We can put modules (quality of services like WS-Addressing , WS-Reliable Messaging) into modules sub-directory and Web services into services sub-directory. Repository concept is very convenient in server side but not that useful in the client side, since at the client side we do not have idea of services. In addition to that, file system based ConfigurationContext is the one which can have hot-deployment and hot-update features.

When we want to create ConfigurationContext in this manner we have two parameters listed below of whose behaviors need to be configured-both or either can have valid locations or we can just use NULL values.

  • Location of the repository
  • Location of axis2.xml

So depending on the above two parameters we can have four sub-options as well. There are few ways to specify those parameters when we create ConfigurationContext.

Option 1 : Create ConfigurationContext by using both the parameters as NULL

This is the most commonly used technique in the client side to create a ConfigurationContext. Since both the parameters are NULL we do not have the repository concept in this case. We can use ConfigurationContextFactoy to create ConfigurationContext as follows;

ConfigurationContext myConfigContext = 
ConfigurationContextFactory.createConfigurationContextFromFileSystem(null , null)

When we create ConfigurationContext in this manner, the corresponding AxisConfiguration is created using default axis2.xml which we can find in Axis2 distribution jar file. That particular axis2.xml has all the parameters, transports and handler chains to start up an Axis2 system. We can use the created ConfigurationContext not only in the client side, but also in the server side as well, as we can later add services to created AxisConfiguration programmatically.

Even though we do not have a repository in this case, we have an option to add modules (module mar files) in to the classpath and engage them whenever we want. It should be mentioned here that the idea of classpath is somewhat different. Here the classpath is the location where we have our axis2 jar files. So if we want to have quality of services with this type of ConfigurationContext (we would specially want in the client side ) then we can put modules or mar files into the classpath.

In this particular case we have neither service hot-deployment nor service hot-update since we do not have a repository.

Option 2 : Creating a ConfigurationContext using a valid repository location and default axis2.xml

In this case we can use ConfigurationContextFactor as follows;

ConfigurationContext myConfigContext = 
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"location of the repository" , null)

Here, location of the repository should be an absolute path. In this case AxisConfiguration will be created using default axis2.xml, and services and modules will be created and loaded from the repository.

One thing to note here is that when we create ConfigurationContext in this manner, Axis2 will not load modules from the classpath. So if we want any quality of service, then we need to put those modules into the modules directory.

Option 3 : Creating a ConfigurationContext with custom axis2.xml and null repository

In this case we can use ConfigurationContextFactory to create ConfigurationContext as follows ;

ConfigurationContext myConfigContext = 
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"" , "location of axis2.xml")

Location of axis2.xml should be an absolute file path to our custom axis2.xml. Once we create ConfigurationContext in this manner, corresponding AxisConfiguration will be created using our axis2.xml.

When we use this option we have an additional way to specify the repository location (not passing method arguments) by adding the following parameter into our axis2.xml.

<parameter name="repository"> location of the repository </parameter>

Once we specify the above parameter in our axis2.xml, then services and modules will be loaded from that location. When we specify this parameter we loose the luxury of loading modules from classpath.

Option 4 : Creating ConfigurationContext using both valid parameters

Once we have a repository, just as we need to use our own axis2.xml, we can use ConfigurationContextFactoy to create a ConfigurationContext as follows;

ConfigurationContext myConfigContext = 
ConfigurationContextFactory.createConfigurationContextFromFileSystem(
"location of the repository" , "location of axis2.xml")

In this case both the location should be absolute file path. When we create ConfigurationContext in the manner, corresponding AxisConfiguration is created using axis2.xml we specify and it uses our repository to load services and modules.

Option 5 : Use Java VM (Virtual Machine) parameters to specify repository location and axis2.xml location.

The idea of this method is to pass JVM parameters when starting Axis2, so Axis2 will use them appropriately to create ConfigurationContext. In the meantime we can use a combination of JVM parameters and method arguments (arguments in ConfigurationContextFactory ) to create a ConfigurationContext. As an example we can pass a null argument to the repository location and valid axis2.xml location in the method call, and provide repository location as a JVM parameter. If we give both method argument and JVM parameters, then the precedence will be given to the method argument. If the method argument is null, then it will try to read the following JVM parameters.

  • JVM parameter for repository location is "axis2.repo"
  • JVM parameter for axis2.xml is "axis2.xml"

For example, when we run the program, we can pass them as below;

> java MyApp -Daxis2.xml="location of axis2.xml"

Creating ConfigurationContext using a URL

When we want Axis2 to run on a clustering environment where multiple replicas share the same configurations, creating ConfigurationContext from a URL is very useful. We can host our axis2.xml in one location and point all the replicas to that particular location to load axis2.xml. Not only axis2.xml, but we can also have a repository in a remote machine. So each and every replica in the cluster can share the same axis2.xml and the same repository.

In this particular scenario, the structure of repository is aberrant, we cannot only just have two sub-directories, but also each needs to list out what is in there. So services directory should contain a text file called "services.list" including all the services aar files in it, while modules directory should contain a file called "modules.list" including all the module mar file in the directory.

For example, if the services directory has foo.aar and bar.aar then services.list file should look like below;

foo.aar
bar.aar

Similarly if the modules directory contains module call abc.mar and xyz.mar then modules.list file will look like;

abc.mar
xyz.mar

To create a ConfigurationContext in the manner we can use ConfigurationContextFactory as follows;

ConfigurationContext myConfigContext = 
ConfigurationContextFactory.createConfigurationContextFromURIs(
"https://xyz.com/axis2/axis2.xml" , "https://xyz.com/axis2repo")

In this case either or both method parameters can be null;

  • If axis2.xml is null, then the default axis2.xml file will be used as axis2.xml
  • If repository location is null, then modules will be loaded from the classpath
  • If the repository location argument is null and if we specify the repository location in axis2.xml, then that location will be used as the repository location.

One thing to note here is that when we create ConfigurationContext in this manner, we cannot use any of the JVM parameters and we do not have any hot-deployment or hot-update features.

Creating ConfigurationContext using Custom AxisConfigurator

When we want to have full control on how to create AxisConfiguration, how to load modules and how to load services, we can implement our own AxisConfigurator and use that to create the ConfigurationContext. Actually, Axis2 itself uses the same technique to create ConfigurationContext;

  • In the case of file system based ConfigurationContext creation it uses FileSystemConfigurator
  • In the case of URL based ConfigurationContext creation it uses URLBasedAxisConfigurator and
  • When we deploy axis2 in a web application server it uses WarBasedAxisConfigurator

So when we want to create a ConfigurationContext using a database or any other means, we can write our own AxisConfigurator and pass that to ConfigurationContextFactory to create a ConfigurationContext as follows;

ConfigurationContext myConfigCtx = 
ConfigurationContextFactory.createConfigurationContext(
MyAxisConfigurator);

AxisConfigurator is an interface with the following method, so when we want to have our own way of deployment mechanism for Axis2 we can implement those methods and use that to create ConfigurationContext.

 AxisConfiguration getAxisConfiguration() throws AxisFault;
void loadServices();
void engageGlobalModules() throws AxisFault;

Conclusion

We discussed a number of available ways to create a ConfigurationContext. Depending on our application we can choose the best option that satisfies our goals. Considering all those available methods to achieve better flexibility and more control, AxisConfigurator mechanism is a good candidate to create a ConfigurationContext from a database or some similar mechanism.

Author

Deepal Jayasinghe,Senior Software Engineer, WSO2 Inc. deepal at wso2 dot com

 

About Author

  • Deepal Jayasingha
  • WSO2 Inc.