Hi Chamikara:
+1 and -1 to parts of this patch. :)
First, I agree about merging the chains (op-specifc and global) into one
- that was the intent (a single EC) from the first Axis2 meetings. The
problem with doing it here is that I think this method might get called
before operation dispatching has occurred (so getAxisOperation() will
probably give you a null, resulting in a NPE). The way this should
probably work is that the act of dispatching to the AxisOperation itself
(i.e. MessageContext.setAxisOperation()) should cause the chains to be
merged/replaced. Then this portion of the code only needs to worry
about pausing/resuming a single chain.
Along the lines of making this simpler, I don't like having resumeSend()
and resumeReceive() - why should the core execution code care which
direction things are going? I believe that the correct thing to do here
is to slightly refactor the chains, and simply have the transport sender
/ message receiver as Handlers on the ends of the execution chain. That
way we could remove all the extra logic of calling senders/receivers
manually, and just have them invoked automatically by executing the
handler chain (that's how Axis 1 did it too).
So the end result is a single execution chain which pauses/resumes
simply by indexes, updates itself at operation dispatch, and no extra
logic to split receiving/sending.
Sound reasonable?
--Glen
Chamikara Jayalath wrote:
> Hi All,
>
> There seems to be a bug in the AxisEngine.resume() method (which was
> recently added)
>
> Wihtin this, only the currently attached execution chain is resumed.
> But AxisEngine.send() method attachs two execution chains (service
> specific and global) and invoke both. Because of this if pausing happen
> in a service specific out handler, the global out handlers are ommitted
> when resuming. Also resume mothod does not seem to be calling the
> MessageReceiver or TransportSender.
>
> I have attached a fix to this. First doing two msgContext.invoke() calls
> in the send() method will not work because when resuming we don't know
> weather the first or second chain we were in when pausing. So I combined
> both chains to a one ArrayList and invoked at once.
>
> Also since we have to call the MessageReceiver or TransportSender after
> the invocation of handlers (depending on weather we paused in the send()
> method or receive() method) it seems better to have two resume methods
> named resumeSend() and resumeReceive() which will call TransportSender
> and MessageReceiver respectively (after invoking the execution chain).
>
> Please see the attached patch.
>
> Thank you,
> Chamikara
>
>
> ------------------------------------------------------------------------
>
> Index: engine/AxisEngine.java
> ===================================================================
> --- engine/AxisEngine.java (revision 356796)
> +++ engine/AxisEngine.java (working copy)
> @@ -66,12 +66,13 @@
> public void send(MessageContext msgContext) throws AxisFault {
> //find and invoke the Phases
> OperationContext operationContext = msgContext.getOperationContext();
> - ArrayList executionChain =
> operationContext.getAxisOperation().getPhasesOutFlow();
> - msgContext.setExecutionChain((ArrayList) executionChain.clone());
> + ArrayList outFlow = (ArrayList)
> operationContext.getAxisOperation().getPhasesOutFlow().clone();
> + ArrayList globalOutFlow = (ArrayList)
> msgContext.getConfigurationContext().getAxisConfiguration().getGlobalOutPhases().clone();
> +
> + outFlow.addAll(globalOutFlow);
> +
> + msgContext.setExecutionChain(outFlow);
> msgContext.invoke();
> -
> msgContext.setExecutionChain((ArrayList)msgContext.getConfigurationContext().
> - getAxisConfiguration().getGlobalOutPhases().clone());
> - msgContext.invoke();
>
> if (!msgContext.isPaused()) {
> //write the Message to the Wire
> @@ -385,10 +386,29 @@
> }
>
>
> - public void resume(MessageContext msgctx)
> + public void resumeSend(MessageContext msgctx)
> throws AxisFault {
> msgctx.resume();
> +
> + if (!msgctx.isPaused()) {
> + //write the Message to the Wire
> + TransportOutDescription transportOut = msgctx.getTransportOut();
> + TransportSender sender = transportOut.getSender();
> + sender.invoke(msgctx);
> + }
> }
> +
> + public void resumeReceive(MessageContext msgctx)
> + throws AxisFault {
> + msgctx.resume();
> +
> + if (msgctx.isServerSide() && !msgctx.isPaused()) {
> + // invoke the Message Receivers
> + checkMustUnderstand(msgctx);
> + MessageReceiver receiver =
> msgctx.getAxisOperation().getMessageReceiver();
> + receiver.receive(msgctx);
> + }
> + }
>
> private String getSenderFaultCode(String soapNamespace) {
> return SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(
>
>
>