WSO2Con 2013 CFP Banner

How Apache Axis2 Finds the Operation and Service a Message is Destined To

Discuss this article on Stack Overflow
By Eran Chinthaka
  • 18 Jun, 2006
  • Level: 
  • Reads: 72420
When you are running Apache Axis2/Java as a Web services server, your server must be having a lot of services, and each service has one or more operations associated with it. And for each of these operations you might be getting hundreds of incoming messages. But have you ever wandered how Axis2/Java finds the correct operation and the service a message is destined to? This is what we call dispatching in technical jargon. Let's see how this is done by taking a deeper look in to Apache Axis2/Java internals.
chinthaka's picture
Eran Chinthaka
Software Engineer
WSO2 Inc.

What is the Information Available for Identification?

First, let's see what information is available to find the correct operation. Let me show you a typical http request. We will limit the scope of this tutorial to http requests as other transport protocols do it the same way.
POST /axis2/services/EchoXMLService/echoOMElement HTTP/1.1
User-Agent: Axis2
Host: 127.0.0.1
Content-Type: application/soap+xml; charset=UTF-8;action="EchoOMElement";
.....................

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://127.0.0.1:5556/axis2/services/EchoXMLService/echoOMElement</wsa:To>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>urn:uuid:AD147449058471C81E11506120248601</wsa:MessageID>
<wsa:Action>urn:EchoOMElement</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<ns1:echoOMElement xmlns:ns1="http://org.apache.axis2/xsd">
<ns1:myValue>Isaac Asimov, The Foundation Trilogy</ns1:myValue>
</ns1:echoOMElement>
</soapenv:Body>
</soapenv:Envelope>
What is the information available to identify the service and the operation?
InformationExample Value
HTTP request uri/axis2/services/EchoXMLService/echoOMElement
SOAPActionaction="EchoOMElement"
QName of the first child of SOAP Body element<ns1:echoOMElement xmlns:ns1="http://org.apache.axis2/xsd">
If WS-Addressing is enabled the address of To EPR (Endpoint Reference) and Action element <wsa:To>http://127.0.0.1:5556/axis2/services/EchoXMLService/echoOMElement</ wsa:To>
<wsa:Action>urn:EchoOMElement</wsa:Action>
This is the exact information we use inside Axis2 in order to find the proper destination. The four "dispatchers" inside Axis2 takes care of each and every piece of information mentioned above.
InformationDispatcher Name
HTTP request uriorg.apache.axis2.engine.RequestURIBasedDispatcher
SOAPActionorg.apache.axis2.engine.SOAPActionBasedDispatcher
QName of the first child of SOAP Body elementorg.apache.axis2.engine.SOAPMessageBodyBasedDispatcher
If WS-Addressing is enabled the address of To EPR (Endpoint Reference) and Action elementorg.apache.axis2.engine.AddressingBasedDispatcher

How Does These Dispatchers Work?

All the dispatchers first try to find the service with the information it has. They do this if the dispatchers invoked before it had not found a service. If the service is already found, the findService method of the dispatcher will just pass through. Then it tries to find an operation within the service, if a service is found by then. Again, the dispatcher will do this only if other dispatchers invoked prior to it had not found an operation. Likewise, all the dispatchers put a collaborative effort in doing this. This will enable one dispatcher to find a service and another dipatcher to later find the operation. For example, RequestURIBasedDispatcher could find the service, but it has no information to find the operation. Then RequestURIBasedDispatcher will set the service it found to the message context (message context is used to keep the run time information of each and every message received by the engine). The other dispatchers extract the service information from the message context and try to find an operation.

What Does Each Dispatcher Do?

RequestURIBasedDispatcher - It will get the request URI and tries to find the operation. First, it will remove the /axis2/services part from the URI. (Remember, "/axis2/services" can also be changed support your desired pattern). Then Axis2 takes rest of the URIs ("EchoXMLService/echoOMElement"), tries to search for a service which has the name "EchoXMLService". If found, it tries to find an operation named "echoOMElement" within the found service. SOAPActionBasedDispatcher - This dispatcher can only find the relevant operation, if another dispatcher is invoked before it had found a service, this will check for a operation "echoOMElement" within the service it gets from the message context. SOAPMessageBodyBasedDispatcher - This will get the QName of the first child of the SOAP body element and search through Axis2 configuration for a service and an operation. AddressingBasedDispatcher - This dispatcher will work only if WS-Addressing header are on the SOAP envelope and Addressing module is engaged. This will search for a service and operation, just like the RequestURIBasedDispatcher, except that it gets the information from the WS-Addressing header in the message. This will use the value of <wsa:To> to find the service and the value of <wsa:Action> to find the operation. One particular message may not contain all the information listed above, but must have least amount of information to identify the operation. And as I mentioned earlier, it can be a combination of two dispatchers that will ultimately find the service and operation. Let's check out some samples in oder to further understand how this works with different SOAP messages. Let's assume we have EchoXMLService deployed and it has echoOMElement as an operation. Example 1
POST /axis2/services/EchoXMLService HTTP/1.1
User-Agent: Axis2
Host: 127.0.0.1
Content-Type: application/soap+xml; charset=UTF-8;action="EchoOMElement";
......................

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header />
<soapenv:Body>
<ns1:echo xmlns:ns1="http://org.apache.axis2/xsd">
<ns1:myValue>Isaac Asimov, The Foundation Trilogy</ns1:myValue>
</ns1:echo>
</soapenv:Body>
</soapenv:Envelope>
Here the RequestURIBasedDispatcher will find the service, but it has no information to find the operation. It will set the EchoXMLService in to message context as the service and pass through. Once SOAPActionBasedDispatcher gets its chance, it will first see that some one had found a service. Then having seen that, the operation has not been found, it tries to search for a operation from the SOAP action that it has received within the EchoXMLService. Example 2
POST /other/proxy/url HTTP/1.1
User-Agent: Axis2
Host: 127.0.0.1
Content-Type: application/soap+xml; charset=UTF-8;action="";
.....................

<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://127.0.0.1:5556/axis2/services/EchoXMLService</wsa:To>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:MessageID>urn:uuid:AD147449058471C81E11506120248601</wsa:MessageID>
<wsa:Action>urn:EchoOMElement</wsa:Action>
</soapenv:Header>
<soapenv:Body>
<ns1:echoOMElement xmlns:ns1="http://org.apache.axis2/xsd">

<ns1:myValue>Isaac Asimov, The Foundation Trilogy</ns1:myValue>
</ns1:echoOMElement>
</soapenv:Body>
</soapenv:Envelope>
Here we are trying to send this SOAP message to a proxy and thus the http request URI can not be used to find either the service or the operation. At the same time the SOAP action is empty. But the user had send WS-Addressing headers and Addressing module is engaged in the receiving end. As you can see, value of <wsa:To> and <wsa:Action> headers can be used to find the correct service and the operation, without other information Successfulness of dispatching depends on the proper order of dispatchers in the execution chain. Now lets see how these can be ordered.

How Can I Change The Order and The Number Of Dispatchers?

Dispatchers can be ordered in any way an administrator prefers. And he can decide which dispatchers to be included for dispatching and to remove rest of the dispatchers. To do this, simply edit the <phaseOrder> element found within axis2.xml. Here is a sample section from the default axis2.xml
<phaseOrder type="inflow">
<!-- System pre defined phases -->
<phase name="Transport">
<handler name="RequestURIBasedDispatcher"
class="org.apache.axis2.engine.RequestURIBasedDispatcher">
<order phase="Dispatch"/>
</handler>
<handler name="SOAPActionBasedDispatcher"
class="org.apache.axis2.engine.SOAPActionBasedDispatcher">
<order phase="Dispatch"/>
</handler>
</phase>
.........................
.........................
<phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase">
<handler name="AddressingBasedDispatcher"
class="org.apache.axis2.engine.AddressingBasedDispatcher">
<order phase="Dispatch"/>
</handler>

<handler name="SOAPMessageBodyBasedDispatcher"
class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher">
<order phase="Dispatch"/>
</handler>
................
................
</phase>
...............................
...............................
</phaseOrder>
As you can see our dispatchers are put in to different phases of the IN pipe (Phase is a section of Axis2 engine's execution path. Please refer to Apache Axis2 Architecture guide for more information about Phases).

What if Axis2 Engine cannot Find a Service and an Operation For a Message?

If Axis2 engine cannot find a service and an operation for a message, it immediately fails, sending a fault to the sender.
  • If service not found - "Service Not found EPR is <the epr it had received>"
  • If service found but not an operation- "Operation Not found EPR is <the epr it had received> and WSA Action = <the operation name it had received>"
So when you see these errors next time, you know what to do.

Resources

Author

Eran Chinthaka, Senior Software Engineer, WSO2 Inc. chinthaka @ wso2
WSO2Con 2014 USA