September 21, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

The Axis2 Transport Framework

  • May 16, 2006
  • By Deepal Jayasinghe
  • Send Email »
  • More Articles »

Apache Axis2 is said to be a well-defined framework for Web services and related components developers. It has a lot of room for extending its main functionality; among them are pluggable modules, systems, even listeners and pluggable transport framework assume to be very useful. One of the most important features in Axis2 is transport independency. Axis2 does not depend on transport and Axis2 is a pure SOAP processing engine. It is the user's responsibility to select transports that match his requirements.

An asynchronous Web service is one of the main considerations in these days of Web service development, and developers are very keen on developing their Web service in an asynchrony manner. Axis2 has inbuilt capability of asynchronous Web service handling; in the meantime, none of the request-response concept has burnt into Axis2. As far as Axis2 is concerned, what it does is either process incoming messages or process outgoing messages and delivers the message to MessageReceiver or to TransportSender. In the case of an incoming message, it is the MessageReceiver; in the case of an outgoing message, it is the TransportSender. Figure 1 shows the graphical view of message processing inside Axis2 and also highlights the location of transport's fit in the flow.

Figure 1: Message processing inside Axis2

Note: The sender is the one that called AxisEngine.send(MessageContext) so it could be either MessageReceiver (if there is any response for the incoming message), or OperationClient (in the case of client side).

Transport Receiver

In the Axis2 world, Transport receiver is the one that calls AxisEngine.receive(MessageContext); in other words, the one that initializes the execution for an incoming message. In the case of a real-time system transport, the receiver is an application server or simply a listener that listens to a specific port.

There are two ways that someone can start a transport listener. The first way is to create an Axis2 system by itself and then start a listener (AxisServlet uses this technique). The second way is start listeners by using ListenerManager API (which will be discussed later in this article).

Irrespective of the way you start listener, it has to keep a reference to ConfigurationContext (which is the run-time representation of the system). When transport receiver receives a message, there are few steps that listener has to carry out:

  1. Create a new messageContext; that will be the placeholder for the incoming SOAP message as well as related properties.
  2. Set the configurationContext reference in messageContext (Transport Listener has a reference to the configuration context).
  3. Extract transport-related information into messageContext (header information, input/output stream, and so forth).
  4. Set the transport prefix into message context (the requirement of this will be discussed later).
  5. Create a SOAPMessage for the incoming message. As a result of AXIOM being the underline message representation, it will not read the entire message into memory until someone asks to do that.
  6. Add the created SOAPMessage into messageContext.
  7. Create a new AxisEngine.
  8. Call axisEngine.receive(messageContext).
Note: If the transport is a two-way transport like HTTP, there is one more step left. Once the transport receiver gets the control back (Java return back), it has to check the message context to determine whether the response is written or not. If it is written, there will be a flag in the message context to indicate that msgCtx.isResponseWritten(). If it is not, it is required to send an HTTP 202 and close the incoming stream.

Transport Sender

As its name implies, Transport sender is the one that sends the request message or simply writes the content to an output stream. To be a valid transport sender, it has to implement a "TransportSender" interface, and that interface extends the Handler interface so Transport sender is actually a handler with two more additional methods.

The simplest API that Axis2 provides to register transport senders is axis2.xml; there you can register the transport sender with the name and parameters (if it is required). As an example, the default HTTP sender in Axis2, CommonsHTTPTransportSender, has registered in axis2.xml as follows.

<transportSender name="http"
                 class="org.apache.axis2.transport.http.
                        CommonsHTTPTransportSender">
   <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
   <parameter name="Transfer-Encoding"
              locked="false">chunked</parameter>
</transportSender>
Note: The name attribute is the name of the transport sender; it should be a unique name. There cannot be two transport senders with the same name, but it is possible to have a transport sender and a transport receiver with the same name. The parameters are to configure the sender; the class attribute represents the implementation class of the TransportSender.

When the transport receiver is compared with the transport sender, transport sender has the lesser job. It has to get the SOAP message from the message context and serialize that into the output stream of the sender. There are no two separate transport senders for server side and client side, but in some cases, the server side transport sender has to act differently than the client side sender. (The same class can be used with slightly different logics.) As a transport sender, the following are the common steps that need to be followed when sending a message.

  1. If the message context has a To (target address) address, open up a connection. (On the client side, the TO address is needed, but on the server side it is not.)
  2. String address = msgContext.getTo().getAddress();
  3. Otherwise, try to find the Outputstream from the message context. (This happens on the server side when the request comes via two-way transport.)
  4. Write a transport-specific header if it has any (in the case of HTTP, HTTP headers such as HTTP version, content type, soapaction, and the like).
  5. Get the corresponding SOAPEnvelope from message context:
  6. SOAPEnvelope env = msgCtx. getEnvelope();
  7. Then, serialize the envelope into the output stream as follows:
  8. SOAPEnvelope envelope   = msgContext.getEnvelope();
    OMElement outputMessage = envelope;
    OMOutputFormat format   = new OMOutputFormat();
    outputMessage.serializeAndConsume(outputstream, format);
    outputstream.flush();
    

Listener Manager

Listener manager is a convenient way of managing transport receivers in a given system. It should be noted that the transport receivers discussed above may or may not be managed by using the listener manager API. The difference is that the receivers or listeners that Listener manager can handle has to implement a "TransportListener" interface, but it is not a must to implement that interface for the above-mentioned transport receivers.

Transport listeners

As discussed above, to be a listener, you must implement a TransportListener interface. It looks like the following:

public interface TransportListener {

   void init(ConfigurationContext axisConf,
             TransportInDescription transprtIn)
      throws AxisFault;

   void start() throws AxisFault;
   void stop() throws AxisFault;
   EndpointReference getEPRForService(String serviceName,
                                      String ip) throws AxisFault;
}
  • init: This method will be called when a transport listener is initialized. As discussed in the transport receiver section, a listener has to keep a reference to configuration context, so the configuration context object will be passed as an argument. TransportInDescription is the corresponding description object for the listener. The description object will contain the name of the transport and parameters specified in axis2.xml for this particular transport.
  • start: Listener manager will call this method when it is asked to start a given transport, so all the transport starting logic should be here. For example, it should contain the starting server socket and the like.
  • stop: To stop the transport, logic required to close the started socket can be written here.
  • getEPRForService :Any service available in the system has a unique address to invoke the service, and if there are multiple transports there will be multiple addresses for a given service. The well-known name for that address is End Point Reference (EPR). From any given transport listener, it should be able to get a unique EPR for a given service. When dynamic WSDL is generated and to set the wsa:ReplyTo addresses, this method will be called. At that point, it is up to the transport receiver to create an EPR for a given service. If the transport is HTTP, the EPR will look like http://myaddress.com/foo/axis2/servives/ServiceName, and in the case of SMTP it will look like ServiceName@foo.myaddress.com. The second method parameter, IP, can be null; if it is null. the transport listener has to find the IP address somehow when it generates an EPR.

There are two ways to register a transport listener into the system. The first way is to add an entry into axis2.xml. The second way is to create TransportListener by hand and add that into Listener Manager. In the case of axis2.xml, you have to add the following XML element into axis2.xml;

<transportSender name="http"
   class="org.apache.axis2.transport.http.CommonsHTTPTransportSender">
   <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter>
   <parameter name="Transfer-Encoding"
              locked="false">chunked</parameter>
</transportSender>

Here, the name of the transport is HTTP and the listener implementation class is CommonsHTTPTransportSender. The corresponding description object has two parameters.

Note: If you want to have proxy support or port a forwarding mechanism when you are using axis2 default transports, the generated EPR can be customized by adding the following parameter into the transport tag. The parameter value should be a valid URL.
<parameter name=" hostname">
   http://myaddress.com/foo/axis2/services
</parameter>




Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel