This documentation explains the design of axis-Mora.
The basic axis architecture of Handler model has not changed in Axis-Mora.There is a request flow and a response flow and each of them has their own handlers.
1) The processing of the SOAP request can be described as follows.
On the first call, the Axis engine is initialized. It reads the WSDD file, creates deployment object and initializes the HandlerPool. (The DOM is used to parsing at this level).
2) TransportListener listens the HTTP request and passes the service name using SOAP action. It also passes input stream and output stream to the Axis engine.
3) Axis engine creates MessageContext object (Which acts as a mediator that takes care of the interaction between the components). MessageContext parses the Envelope and Headers using DeserializationContext and stores it in itself (i.e. MessageContext). The body is parsed to the Wrapper. (The data is parsed only when they are needed. For this parsing we use XMLPullParser).
4) Request Handlers process the MessageContext . Handlers are supposed to deal with the Headers only. If they are using the body (e.g.:-encryption) they should write it back to the stream.
5) Then the provider (This is actually a minimal one, most of logic passed to the Wrapper) locates the wrapper and invokes the service. The result is set to the MessageContext as a result object.
6) Response Handlers process the MessageContext.
7) When the MessageContext comes back to the AxisEngine, engine calls the serialize() method to write the response back.
There is one axis engine in the system. It has WSDDDeployment and HandlerPool objects. As all the requests are served as a call on the engine. The concurrency has been taken care of. Axis engine will call the handlers in the right order. In case of error SOAPFault is set and the Handlers invoked so far driven back on onFault().
We are using the XMLPullParser for the deserialization.
Serialization subsystem of axis has not been changed. Serialization of axis has been completely reused in axis-Mora. The serialization is done by the means of calling the output(SerializationContext) method of the SOAPEnvelope of axis. Serializing process can be briefly explained as below.
Note:- But you have to make sure the object value of the SOAPHeaderElement and SOAPBodyElement should be such that the SerializationContext can find serializers for the values at the type mapping.
Registering the Serializers can be done by adding the Seralizers which can serialize a instance of Result, and HeaderElementContent. The serializer is added to the default type mapping. Used value is enabled by adding to default type mapping and edit the DefaultTypeMappingImpl **this is used in the implementation **
Add the Serializer as a default type mapping
TypeMappingRegistry reg = new TypeMappingRegistryImpl();
javax.xml.rpc.encoding.TypeMapping t =
reg.getOrMakeTypeMapping("www.opensurce.lk/axismora/encoding");
sc.getTypeMapping().register(Result.class,Constants.SOAP_RESULT,
new ResultSerializerFactory(),null);
t.register(Parameter.class,Constants.SOAP_RESULT,new resultSerializerFactory(),null);
Before going on to the wrapper part let’s see what is the state of the request now. The request SOAP message is accessed up to the body level. The rest i.e. SOAP body will be accessed by the wrapper. The SOAP body is parsed into the wrapper class. Here wrapper deserializes the body, gets the parameters and calls the web service. When the web service returns the result, the wrapper sets it into the message data.
Consider a web service named Ws with a method name foo which returns a complex type X and accepts a complex type Y as an argument. Then there will be a wrapper class for the web service Ws named as WsService(For every service’s wrapper’s name will be the service name with the appended name “Service”).
For the service named Ws the wrapper will be named WsService. This class extends the BasicHandler which have the method invoke( MessageContext msgcontext) . In fact BasicHandler implements the Handler API, which has one method - invoke(MessageContext msgcontext).
For each method in the web service wrapper contains a private method. This private method has the same method-name as the corresponding method of the webservice.
e.g.: In this case the private method wiil be "private foo(msgcontext)". This method will get the parameters for the actual method by deserializing the body and call the actual method with giving these parameters.
invoke(MessageContext msg)- This will be called by the AxisEngine, just like any other handler. Code inside the invoke method looks up the method name and it calls the private method that with the name ( refer the above diagram).
After calling the method, the returned result is set it in to the MessageContext.Deserialization of the SOAPBody is done at the wrapper. Wrapper is written with the complete awareness of the web service. Hence after finding out the method name the wrapper knows what is there in the SOAPBody. For example in the above example when the wrapper finds out the method name is “foo” it knows that the SOAPBody contains the object of the complex type – X. Therefore the deserialize methods are called at the private method corresponding to the web service.
Deserialization of simple types are in-built. For complex types the wrapper calls the method - deserialize(MessageContext msgData) of the complex type, i.e. each complex type object must have a method called deserialize(MessageContext msgData) where the deserialization occurs. After the deserialize(MessageContext msgData) method of the complex object is called values will be set to the complex type object.Wrapper class then will call the actual web service method with parsing the expected parameters. Then the result will be set it to the MessageContext.
For example the private method in the wrapper corresponding to webservice ::
private foo(MessageContext msg){
X . deserialize(msgdata)
Result r = ws.foo(x);
msgdata.setResult(r);
}
The serialization part of the result will be done by calling the serialize method of the particular complex type object. This calling is done by the AxisEngine , when it wants to serialize the particular result in the response soap body.
We have discussed so far that the wrapper and type objects are responsible for deserializing the body part of the SOAP Request. For doing it, MessageContext interface provides the following methods.
If the error occurs at the wrapper level then the SOAPFault is set in to the MessageContext and wrapper discard the accessing.
Here we have built in type classes for eight simple types and String classes.
We provide a wrapper generator tool for creating the wrapper classes, type classes and web services. This is done by reading the wsdl file. So the burden of the deserialization and serialization is taken care of generator.
Major advantage of the wrapper is, we throw away the reflexion part of the axis and instead of it we uses the wrapper concept. So it gives up the runtime mapping ,the performance is remarkable compare to the axis.
All the types’ providers are treats equally by the architecture. The wrapper will take care of actual behavior. E.g. to have EJB deployed it should we wrapped by the Wrapper in suitable scope.
This is the logically the same as in the existing architecture. The WSDDDeployment class is rewritten using the logics of the existing WSDDDeployment as to match with the expected interfaces.
Class.forname() we are there. Loading the classes are done by the Handler Pool not in the org.apache.axis.deployement.wsdd.
Use the AxisFault for wrap the exception.