How Apache Axis2 Finds the Operation and Service a Message is Destined To
Submitted on June 18, 2006 - 07:12. Story : Project :
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.
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.
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.1What is the information available to identify the service and the operation?
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>
| Information | Example Value |
|---|---|
| HTTP request uri | /axis2/services/EchoXMLService/echoOMElement |
| SOAPAction | action="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> |
| Information | Dispatcher Name |
|---|---|
| HTTP request uri | org.apache.axis2.engine.RequestURIBasedDispatcher |
| SOAPAction | org.apache.axis2.engine.SOAPActionBasedDispatcher |
| QName of the first child of SOAP Body element | org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher |
| If WS-Addressing is enabled the address of To EPR (Endpoint Reference) and Action element | org.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 1POST /axis2/services/EchoXMLService HTTP/1.1Here 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
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>
POST /other/proxy/url HTTP/1.1Here 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.
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>
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">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).
<!-- 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>
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>"
Resources
Author
Eran Chinthaka, Senior Software Engineer, WSO2 Inc. chinthaka @ wso2 (2 votes)
»
- Login or register to post comments
- Printer friendly version
- 11780 reads
Tag Cloud
Apache Rampart
Apache Synapse
Axis2
Axis2
Axis2/C
Axis2/C
Rampart/C
WSF/C
data services
ESB
ESB
WSAS/Java
Synapse/Java
Axis2/Java
Sandesha2/Java
Rampart/Java
AXIOM/Java
ESB/Java
Mashup Server
Mule
OpenID
open source
PHP
WSF/PHP
POJO
Proxy Services
Rampart
rampart
Registry
REST
Sandesha2
security
SOA
soap
Spring
Synapse
Synapse
Training
webinar
Web Services
WS-Security
WSAS
WSAS
wsdl
wsf
WSF/C
WSF/PHP
WSO2
WSO2 Registry
WSO2 WSF/PHP











Service with parameter
Hi,
i know this is already beyond the hello world sample but may i ask how to implement a service which asks for a parameter then returns a value. Lets say i have a function public String getAlias(String firstName)... how do i go about in services.xml?... how do i call it through rest?
any response would be appreciated =)
thanks
- ayessa
Service with parameter
Hi,
i know this is already beyond the hello world sample but may i ask how to implement a service which asks for a parameter then returns a value. Lets say i have a function public String getAlias(String firstName)... how do i go about in services.xml?... how do i call it through rest?
any response would be appreciated =)
thanks
- ayessa
Service with parameter
Hi,
i know this is already beyond the hello world sample but may i ask how to implement a service which asks for a parameter then returns a value. Lets say i have a function public String getAlias(String firstName)... how do i go about in services.xml?... how do i call it through rest?
any response would be appreciated =)
thanks
- ayessa