Apache Axis2 is a leading open source software that provides the basis for the web services stack and supports both SOAP ( Simple Object Access Protocol) and REST (Representational State Transfer). In addition to that, it acts as the foundation for building complete web services stack with Apache Rampart, Rahas,Sandesha2 and Kandula2 providing support for all key web services specification.
Axis2 has flexible and scalable architecture compared to its predecessor Axis and it provides lot of support for extending its core functionality. Axis2 consists of pluggable modules, systems, event listeners and pluggable transport framework with very useful extension points. One such a great feature of Axis2 is transport independence. It doesn’t depend on any specific transport and its up to the user to select best transport to meet his requirements.
In this article, I’m not going to explain about what is Axis2 and all its features, instead I’m going to show you my attempt to write a new transport for Axis2 based on the Stomp protocol. Before reading the rest of the article, I recommend you to get an idea about the Axis2 architecture.
Role of a Message Broker in SOAP message delivery
If you need to send a SOAP message to Axis2, there are many ways to transport the SOAP message into the Axis engine. The most standard and flexible way is SOAP over HTTP. But when it comes to the reliability of the transport, it fails. After submitting the SOAP message, HTTP has no guarantee about its delivery. When we consider mission critical systems with zero down times, HTTP may not be the proper transportation option.
Message Oriented Middleware(MOM) can be helpful in such situations. They are often called ‘Message Brokers’ and they provide asynchronous message delivery between heterogeneous systems. Message brokers decouple the senders of messages from the consumers of the messages. The senders and consumers of the messages are completely independent and know nothing about each other.
The key feature of a broker is reliable messaging. With reliable messaging, broker is responsible for delivering messages one and only once for its subscriber. Message level security, Transaction support, message persistence and scalability are other noteworthy features of a message broker.
JMS(Java Messaging Service) provides rich set of Java API to communicate with any JMS compliant message broker. So developers found that SOAP over JMS is a better alternative to SOAP over HTTP, when it comes to reliability and guaranteed delivery.
But the problem was JMS is only for Java. In order to communicate with message brokers, open standard protocols such as AMQP and Stomp were defined and they can be used with any language.
What is Stomp?
Stomp is a very simple protocol to communicate with any Stomp supported message broker. Currently Apache ActiveMQ has a very good support for Stomp including SSL, Non blocking IO (NIO) and message persistence.
Unlike JMS(Java Messaging Service), Stomp has a wire format so that it can be implemented by any language with very little effort. So Stomp already has clients with scripting languages such as Ruby, PHP and Python.
Anatomy of the Stomp transport for Axis2
Before reading this section, I assume you may have a good understanding about the Axis2 architecture.
As I mentioned earlier, Axis2 is independent of underlying transport mechanism. You can create any kind of transport as your wish and plug it into the Axis core. That is a one such a great flexibility in Axis2 architecture.
In order to give you 10,000 feet view of my Stomp transport, just look at the figure below.
As the figure depicts, two queues are used as message destinations. They can be two separate queues in the same broker or two separate queues in different brokers. Selection is up to you. This architecture resembles the JMS point-to-point messaging paradigm.
Let me show you how web service client invokes a web service hosted in Axis2 using SOAP over Stomp.
- User application needs to make a SOAP request and it delegates the responsibility to Axis Client API with necessary data.
- AxisEngine creates the MessageContext object and pass it to he StompSender.
- StompSender creates a Stomp message and populates it with Stomp specific information and data extracted from the MessageContext. Body of the message contains the SOAP Request.
- StompSender places that Stomp message in inbound queue.
- In the server side, StompListener is subscribed to the inbound queue and it will receive the Stomp message when it is placed on the queue.
- StompListener dispatches the stomp message and extracts the SOAP request and starts building the MessageContext.
- After building the MessageContext, StompListener passes it to the Axis Engine to be processed.
- AxisEngine sends the processed MessageContext into StompSender and it starts building a Stomp message using the data extracted from MessageContext.
- Server side StompSender places the Stomp message in reply queue.
- Client side StompListener is subscribed to the reply queue it will receive the Stomp message.
-  and  steps are repeated in the client side. Once the reply message is processed, it will be passed back to the user application.
Classes involved in the Stomp transport
Stomp transport consist of following classes.
This is the listening interface for the incoming Stomp messages. This class implements the TransportListener interface and takes the responsibility of constructing StompConnection objects according to the axis2.xml file. Each constructed StompConnection object is assigned with an instance of new StompPacketListener. This happens only once when ListenerManager calls the init() method of the StompListener.
- StompConnectionThis class abstracts the connection information that are useful to establish a connection with a message broker. Examples are host,port, login credentials and destination names. Usually these information are obtained through ConfigurationContext object and StompListener takes the responsibility of extracting them from ConfigurationContext and populating new StompConnections.
- StompPacketListenerThis is the actual dispatcher of a Stomp message. After calling the init() method of the StompListener, several StompConnections may exist and each one is assigned with their own StompPacketListener. StompPacketListener objects subscribes to the Inbound queue or Reply queue, depending on the situation. (If client side, then reply queue. Else they subscribe to the inbound queue).
according to the above figure, same worker thread pool is shared between all StompPacketListener instances. Whenever Stomp packet is received, StompPacketListener pick up a worker thread from worker pool and delegates the dispatching process to that thread.
This is the opponent to the StompListener. This class is responsible for extracting information from MessageContext and populating a new stomp message. Also it delivers the message to the inbound or reply queue, depending on the situation.
This class merely contains the data that is received with a Stomp packet.
This class consists of utility methods.
Constants that are related to this transport are defined here. This includes the transport name and several service parameters.
Third party libraries used
I used Gozirra Java client for Stomp to make communications with the message broker. But its too simple and lack of good design features. So I’ll be writing my own Stomp client to use with this transport in near future.
Up to this point, I’ve implemented all the classes I mentioned and code is now in testing phase and I appreciate your comments on this.
I’ll make another post about how to build this transport with Axis2 source and configurations for axis2.xml.
So stay tuned…