Deployment Problems in Axis,
Suggestions and Workarounds
Community
Grids Lab,
In this document we
provide an overview of the problems that we encountered while deploying Web
Service specifications within Axis. There are several important capabilities,
pertaining to support for Web specifications, that are currently missing in
Axis (1.2 RC3). We are hoping that these
problems will be resolved in Axis so that Web Service specifications can be
deployed in a less cumbersome fashion than at present.
We first enumerate
problems that we encountered; subsequent sections elaborate the need for
specific features and how (if possible) the lack thereof was circumvented.
1.
Injection of messages: Within Axis currently
only the Clients are allowed to inject messages.
2.
Based on the request-response paradigm: In
Axis every message is considered a request which should have its accompanying
response within a pre-defined period of time.
3.
No ability to gracefully terminate
processing related to a message within the Handler chain associated with a
service.
4.
Handlers cannot initiate messages on their
own.
5.
Static configuration of the handler chain.
6.
Problems with initiating responses.
7.
Problems with corruption of SOAPMessages;
specifically the deviation from the original intended schema-validated XML
document encapsulated within the SOAPMessage and the SOAPMessage itself.
1.
Message Initiation
Message initiation is a
difficult task. Clients are the only entities that are able to initiate
messages as requests. Server-side components either a handler in the
handler-chain or the target service do not have this capability. The only
message initiation is via a request/response mechanism where requests can be
initiated only by the clients. There are several scenarios that indicate the
need for message initiation in the server part.
Consider the case of
Acknowledgements in WS-ReliableMessaging (hereafter WSRM) which requires
message initiation from the WSRM Sink to the Source. The WSRM specification
requires endpoints to comply with the acknowledgement and retransmission
intervals that are exchanged prior to the creation of a Sequence. This implies
that in acknowledgements may be issued several seconds after the receipt of a
message. Furthermore, a single acknowledgement may encapsulate information
pertaining to the receipt of several thousand messages. The limitations within
the request-response paradigm are clear in such scenarios. It is clear that
one-way messaging and message-initiation would resolve this particular problem.
The problems outlined here also arise during retransmissions initiated by a
WSRM source.
WS-Eventing (hereafter
WSE) is another scenarios where message initiation is needed. A message may
need to be reproduced to send the copies to multiple subscribing end
points.
2.
Other request-response
based problems
Sometimes an entity may
need to inform another entity without the need to receive a response. For
example, when we issue a WSRM acknowledgement we are not looking for an
acknowledgement to the WSRM acknowledgement.
3.
Ability to terminate
processing related to Message within a Handler chain
Currently there is no
ability to gracefully terminate processing related to a message within the
Handler chain associated with a service. Once a message has been received
within a handler chain there is no graceful way to prevent this message from
reaching the Service. A good example of the need for this feature would be the
case of acknowledgments in WSRM. Only the WSRM handler needs to know whether
the WSRM sink has received the message that was previously sent. Also, since
most WS specifications are aimed at incrementally adding functionality to a
service, situations may arise where similar such handshakes/control-messages
should be stopped from reaching the actual service. In most cases such messages result in
problems at the service.
Currently the only way to
do so is to throw an Exception. Furthermore, there is no way to correctly
access or interact with the handler-chain managing a specific handler. Although
access to the AxisEngine instance is available, we cannot stop the message
propagation.
We may need to retransmit
the message as it is required in reliable messaging. If an acknowledgment has
not been received from an end point, the message must be resent in order to
ensure reliable messaging. As we said, although it is easy in client part, this
task requires several tricks in server part.
4.
Handlers cannot inject
messages
This issue was mentioned
earlier too, but needs to be clarified in the case of handlers too. Most WS
specifications are naturally implemented as handlers that can augment a
service’s capabilities. However, such handlers need to be able to initiate
control-messages on their own accord. While there is access to the Handler
Chain there is no access to message propagation features. This feature may be
made available through the AxisEngine class or through the handler chain
itself.
5.
Static Handler chains
In Axis handlers are
currently statically configured – the configuration being made when a service
is being deployed. A handler can not be added or removed from a service.
Current axis architecture allows cloning the handler chain. The cloned chain
can replace a current one after required changes are applied. But, this is not
sufficient. Dynamic configuration of handler chains will be very useful. A
deployment may have lots of handlers but a user/handler should be able to
select a group of handlers that a message would need to go through.
This is especially true
in cases of retransmissions where the handler may have already processed the
message resulting in duplicate processing which may or may not lead to errors.
Similarly security requirements may result in a message be passed through a
different set of handler chains – here handlers related to message digest,
encryption and signing may be added to the outgoing path in the handler chain.
6.
Problems with initiating
responses and Corruption of SOAP Messages in Axis
We encountered several
problems during our implementation. One of them affected our implementation
strategy and we believe it should be fixed in newer axis versions; we used a
message-style Web Service. When we tried
to send a response back from the server, the original SOAPEnvelope is being
modified. There exist four valid signatures for message-style service methods.
Since we need the SOAP header, we are using following method:
public void
method(SOAPEnvelope request, SOAPEnvelope response);
The problem starts when
we try to inject my org.apache.axis.message.SOAPEnvelope
by using the getBody() getHeader() setBody()
and setHeader() methods of the SOAPEnvelope. After injection
of the response the SOAPBody and SOAPHeader include different prefixes than
those which were originally supplied. While change of prefixes is in itself not
a problem, there are problems with validation since the Axis processing
eliminates prefixes for the SOAP Body but not for the SOAP Envelope or the
Header. Please note that this is no longer a valid SOAP message since there is
no SOAP Body! Another interesting side effect is that the processing removes
prefixes from elements contained in the Body of the SOAPMessage, for e.g. a
WSRM Acknowledgement response will have some wsrm: prefixes removed and some
left intact. Needless to say such a message cannot be processed at another Axis
client not to mention another Container since the over-the-wire XML is invalid.
This results in
exceptions at the receiving side.
The scenario is as
follows;
Firstly, we create a
valid SOAPEnvelope:
org.apache.axis.message.SOAPEnvelope
soapEnvelope;
We get the SOAPBody and SOAPHeader from envelope:
org.apache.axis.message.SOAPBody soapBody =
(org.apache.axis.message.
SOAPBody)
soapEnvelope.getBody();
org.apache.axis.message.SOAPHeader soapHeader =
(org.apache.axis.message.
SOAPHeader) soapEnvelope.getHeader();
Next, we insert them into
response:
response.setBody(soapBody);
response.setHeader(soapHeader);
At this point, client
throws exception.
response.setEnvelope(soapEnvelope);
We tried setSOAPEnvelope
method of SOAPEnvelope class. Somehow, it does not work. The response message reaches to the client as
an empty message.
7.
Solutions to some of the
problems
We have temporary
solutions for some issues above; instead of blocking a message, a message can
be set to a dummy task. We had to choose this method because we wanted to stop
the propagation of the message without getting an exception. By letting the
message arrive at the end point we have prevented an exception being thrown. On
the other hand, there exists a downside to this solution. This adds to
performance costs because of the processing of the dummy task. At present we
take this as an acceptable performance degradation within the current axis
architecture.
Although messages can not
be initiated by the server part, we can bypass this restriction by using an
Axis client wherever a message initiation is required. In this architecture,
both source and destination will have client and server capability. Current
Axis architecture requires the server part to reside in a web container; we use
Apache Tomcat as the web container. As a
result, both source and destination should be in the web container.
Next, we developed a
sender thread which is responsible for sending any message to the other node.
Since we are using one-way messaging, we gave the responsibility of sending
messages to this thread instead of dealing with the Axis message responding
mechanism (because of problems related to message corruption). The thread enables non-blocking sending of
messages.
We did not use a response
chain because we came up with the idea of building our own chain structure.
After some point in the response handler chain, we diverted the massage path to
the sender thread and added our own handler chain. It allowed us one-way
messaging without breaking any of the already deployed handler structure at a
service. In addition, this can easily support dynamic handler chains.
For example, let’s assume
we have following two web services that send messages to each other.
We can add a reliable
messaging into the handler chain as shown in the following picture. For reliable messaging, while the request
handler chain should include two handlers, sink and source, the response
handler chain consists only of source handler. The messages are sent by “Sender
Thread”. In order to prevent the loss of Handler4 or Handler2’ functionality,
the chain structure, we mentioned above, is added to the system.
