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( > > >