axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matthew Lovett <MLOV...@uk.ibm.com>
Subject [Axis2] Re: svn commit: r499521 - in /webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2: client/ServiceClient.java description/OutInAxisOperation.java
Date Thu, 25 Jan 2007 09:27:07 GMT
Hi Deepal (and everyone else)

Sorry that I didn't bring this up on the mailing list, I thought that the 
doc in the Jira was sufficient:
https://issues.apache.org/jira/browse/AXIS2-2020

However, I'm more than happy to have a proper discussion. Perhaps the 
right place to start is the overview I gave in the Jira:

"I have been doing some testing with jax-ws applications with Sandesha 
engaged, and I hit an issue with sync-2-way messaging. The axis 
ServiceClient and OutInOperationClient have some logic to force the 
invocation down the async path, which is what is needed in this case. (The 
addition of RM into the mix effectively makes the invocation async, even 
though we are using synchronous comms). Unfortunately, the jax-ws layer 
calls into the OutInOperationClient, and bypasses the logic in the 
ServiceClient. The same issue would apply to any other component that 
chooses to use the operation client directly. 

My suggested fix is to push some of the logic that is currently in the 
ServiceClient down into the operation client. I'll attach a patch soon, 
but the basic idea is to move the SyncCallBack class down. "

I certainly don't mean to steamroller this into the codebase, but I do 
think that the changes make sense. There is no API change, but some of the 
impl has been moved.

Thanks

Matt


Deepal Jayasinghe <deepal@opensource.lk> wrote on 25/01/2007 08:46:38:

> Hi ;
> 
> My mistake I didnt see the JIRA , but I am still in -1 state until we
> come to a conclusion.
> 
> Specially when we change API and their implementation we need to discuss
> that in the mailing list and then implement .
> 
> Thnaks
> Deepal
> 
> Deepal Jayasinghe wrote:
> 
> >Hi Bill;
> >
> >I am -1 on this since no one discuss about this change before in the
> >mailing list  and I didnt find any JIRA related to this. So I think we
> >need to revert this changes until we come to an conclusion.
> >
> >Thanks
> >Deepal
> >
> >nagy@apache.org wrote:
> >
> > 
> >
> >>Author: nagy
> >>Date: Wed Jan 24 10:38:56 2007
> >>New Revision: 499521
> >>
> >>URL: http://svn.apache.org/viewvc?view=rev&rev=499521
> >>Log:
> >>AXIS2-2020
> >>Contributor: Matt Lovett
> >>Fix to allow clients/other layers that use the OperationClient 
> directly (as opposed to going through the ServiceClient) to function
> correctly with sync 2-way messaging and RM enabled.
> >>
> >>Modified:
> >> 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient.
> java
> >> 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation.
> java
> >>
> >>Modified: 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient.
> java
> >>URL: http://svn.apache.
> 
org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient.
> java?view=diff&rev=499521&r1=499520&r2=499521
> 
>>==============================================================================
> >>--- 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient.
> java (original)
> >>+++ 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/client/ServiceClient.
> java Wed Jan 24 10:38:56 2007
> >>@@ -20,17 +20,13 @@
> >>import org.apache.axiom.om.OMElement;
> >>import org.apache.axiom.soap.*;
> >>import org.apache.axis2.AxisFault;
> >>-import org.apache.axis2.Constants;
> >>import org.apache.axis2.addressing.EndpointReference;
> >>-import org.apache.axis2.client.async.AsyncResult;
> >>import org.apache.axis2.client.async.Callback;
> >>import org.apache.axis2.context.*;
> >>import org.apache.axis2.description.*;
> >>import org.apache.axis2.engine.AxisConfiguration;
> >>import org.apache.axis2.engine.ListenerManager;
> >>-import org.apache.axis2.engine.MessageReceiver;
> >>import org.apache.axis2.i18n.Messages;
> >>-import org.apache.axis2.util.CallbackReceiver;
> >>import org.apache.axis2.wsdl.WSDLConstants;
> >>
> >>import javax.wsdl.Definition;
> >>@@ -396,65 +392,11 @@
> >>     * @see #createClient(QName)
> >>     */
> >>    public void sendRobust(QName operation, OMElement elem) throws
> AxisFault {
> >>-        if (options.isUseSeparateListener()) {
> >>-
> >>-            // This mean doing a Fault may come through a 
> different channel .
> >>-            // If the
> >>-            // transport is two way transport (e.g. http) Only 
> one channel is
> >>-            // used (e.g. in http cases
> >>-            // 202 OK is sent to say no response available). 
> Axis2 get blocked
> >>-            // return when the response is available.
> >>-            SyncCallBack callback = new SyncCallBack();
> >>-
> >>-            // this method call two channel non blocking method 
> to do the work
> >>-            // and wait on the callback
> >>-            sendReceiveNonBlocking(operation, elem, callback);
> >>-
> >>-            long timeout = options.getTimeOutInMilliSeconds();
> >>-            long waitTime = timeout;
> >>-            long startTime = System.currentTimeMillis();
> >>-
> >>-            synchronized (callback) {
> >>-                while (! callback.isComplete() && waitTime >= 0)
{
> >>-                    try {
> >>-                        callback.wait(timeout);
> >>-                    } catch (InterruptedException e) {
> >>-                        // We were interrupted for some reason, 
> keep waiting
> >>-                        // or throw new AxisFault( "Callback was 
> interrupted by someone?" );
> >>-                    }
> >>-                    // The wait finished, compute remaining time
> >>-                    // - wait can end prematurely, see Object.
> wait( int timeout )
> >>-                    waitTime = timeout - (System.
> currentTimeMillis() - startTime);
> >>-                }
> >>-
> >>-            }
> >>-            SOAPEnvelope envelope = callback.envelope;
> >>-            // process the result of the invocation
> >>-            if (envelope != null) {
> >>-                // building soap envelope
> >>-                envelope.build();
> >>-                // closing transport
> >>-                if (envelope.getBody().hasFault()) {
> >>-                    SOAPFault soapFault = 
envelope.getBody().getFault();
> >>-                    throw new AxisFault(soapFault.getCode(), 
> soapFault.getReason(),
> >>-                            soapFault.getNode(), soapFault.
> getRole(), soapFault.getDetail());
> >>-                }
> >>-            } else {
> >>-                if (callback.error instanceof AxisFault) {
> >>-                    throw (AxisFault) callback.error;
> >>-                } else if (callback.error != null) {
> >>-                    throw new AxisFault(callback.error);
> >>-                } else if (! callback.isComplete()) {
> >>-                    //no exception has occurred
> >>-                }
> >>-            }
> >>-        } else {
> >>-            MessageContext mc = new MessageContext();
> >>-            fillSOAPEnvelope(mc, elem);
> >>-            OperationClient mepClient = createClient(operation);
> >>-            mepClient.addMessageContext(mc);
> >>-            mepClient.execute(true);
> >>-        }
> >>+        MessageContext mc = new MessageContext();
> >>+        fillSOAPEnvelope(mc, elem);
> >>+        OperationClient mepClient = createClient(operation);
> >>+        mepClient.addMessageContext(mc);
> >>+        mepClient.execute(true);
> >>    }
> >>
> >>    /**
> >>@@ -524,76 +466,14 @@
> >>     */
> >>    public OMElement sendReceive(QName operationQName, OMElement 
xmlPayload)
> >>            throws AxisFault {
> >>-        /**
> >>-         * If a module has set the USE_ASYNC_OPERATIONS option 
> then we override the behaviour
> >>-         * for sync calls. However we leave real async calls alone.
> >>-         */
> >>-        boolean useAsync = false;
> >>-        if (!options.isUseSeparateListener()) {
> >>-            Boolean useAsyncOption = (Boolean) configContext.
> getProperty(Constants.Configuration.USE_ASYNC_OPERATIONS);
> >>-            if (useAsyncOption != null) useAsync = 
> useAsyncOption.booleanValue();
> >>-        }
> >>-
> >>-        if (useAsync || options.isUseSeparateListener()) {
> >>-
> >>-            // Here we are trying to do a request-response 
> invocation using two different channels for the request
> >>-            // and the response.
> >>-            // For example, if the IN and OUT transports are 
> HTTP, then two different HTTP channels will be used. The first
> >>-            // channel will be used to send the request, which 
> the server respond sending HTTP 200, if accepted and uses
> >>-            // a completely different channel to send the 
> response. This flag, informs the Axis2 client engine to
> >>-            // keep listeners ready to receive the response.
> >>-
> >>-            // even if the client is blocking we use a Callback, 
> internally, to relate the response back to the client.
> >>-            SyncCallBack callback = new SyncCallBack();
> >>-
> >>-            // this method call two channel non blocking method 
> to do the work
> >>-            // and wait on the callback
> >>-            sendReceiveNonBlocking(operationQName, xmlPayload, 
callback);
> >>-
> >>-            long timeout = options.getTimeOutInMilliSeconds();
> >>-            long waitTime = timeout;
> >>-            long startTime = System.currentTimeMillis();
> >>-
> >>-            synchronized (callback) {
> >>-                while (! callback.isComplete() && waitTime >= 0)
{
> >>-                    try {
> >>-                        callback.wait(timeout);
> >>-                    } catch (InterruptedException e) {
> >>-                        // We were interrupted for some reason, 
> keep waiting
> >>-                        // or throw new AxisFault( "Callback was 
> interrupted by someone?" );
> >>-                    }
> >>-                    // The wait finished, compute remaining time
> >>-                    // - wait can end prematurely, see Object.
> wait( int timeout )
> >>-                    waitTime = timeout - (System.
> currentTimeMillis() - startTime);
> >>-                }
> >>-
> >>-            }
> >>-            // process the result of the invocation
> >>-            if (callback.envelope != null) {
> >>-                // transport was already returned by the call back 
receiver
> >>-                //Building of the Envelope should happen at the 
> setComplete()
> >>-                // or onComplete() methods of the Callback class
> >>-                return callback.envelope.getBody().getFirstElement();
> >>-            } else {
> >>-                if (callback.error instanceof AxisFault) {
> >>-                    throw (AxisFault) callback.error;
> >>-                } else if (callback.error != null) {
> >>-                    throw new AxisFault(callback.error);
> >>-                } else if (! callback.isComplete()) {
> >>-                    throw new AxisFault(Messages.
> getMessage("responseTimeOut"));
> >>-                } else
> >>-                    throw new AxisFault(Messages.
> getMessage("callBackCompletedWithError"));
> >>-            }
> >>-        } else {
> >>-            MessageContext messageContext = new MessageContext();
> >>-            fillSOAPEnvelope(messageContext, xmlPayload);
> >>-            OperationClient operationClient = 
createClient(operationQName);
> >>-            operationClient.addMessageContext(messageContext);
> >>-            operationClient.execute(true);
> >>-            MessageContext response = operationClient
> >>-                    .getMessageContext(WSDLConstants.
> MESSAGE_LABEL_IN_VALUE);
> >>-            return 
response.getEnvelope().getBody().getFirstElement();
> >>-        }
> >>+        MessageContext messageContext = new MessageContext();
> >>+        fillSOAPEnvelope(messageContext, xmlPayload);
> >>+        OperationClient operationClient = 
createClient(operationQName);
> >>+        operationClient.addMessageContext(messageContext);
> >>+        operationClient.execute(true);
> >>+        MessageContext response = operationClient
> >>+ .getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
> >>+        return response.getEnvelope().getBody().getFirstElement();
> >>    }
> >>
> >>    /**
> >>@@ -635,24 +515,6 @@
> >>        // progamming model is non blocking
> >>        mepClient.setCallback(callback);
> >>        mepClient.addMessageContext(mc);
> >>-
> >>-        /**
> >>-         * If a module has set the USE_ASYNC_OPERATIONS option 
> then we override the behaviour
> >>-         * for sync calls. However we leave real async calls alone.
> >>-         */
> >>-        boolean useAsync = false;
> >>-        if (!options.isUseSeparateListener()) {
> >>-            Boolean useAsyncOption = (Boolean) configContext.
> getProperty(Constants.Configuration.USE_ASYNC_OPERATIONS);
> >>-            if (useAsyncOption != null) useAsync = 
> useAsyncOption.booleanValue();
> >>-        }
> >>-
> >>-        if (useAsync || options.isUseSeparateListener()) {
> >>-            MessageReceiver messageReceiver = axisService.
> getOperation(operation).getMessageReceiver();
> >>-            if (messageReceiver == null || !(messageReceiver 
> instanceof CallbackReceiver)) {
> >>-                CallbackReceiver callbackReceiver = new 
CallbackReceiver();
> >>-                axisService.getOperation(operation).
> setMessageReceiver(callbackReceiver);
> >>-            }
> >>-        }
> >>        mepClient.execute(false);
> >>    }
> >>
> >>@@ -785,42 +647,6 @@
> >>        serviceContext.setCachingOperationContext(cachingOpContext);
> >>    }
> >>
> >>-
> >>-    /**
> >>-     * This class acts as a callback that allows users to wait on
> the result.
> >>-     */
> >>-    private class SyncCallBack extends Callback {
> >>-        private SOAPEnvelope envelope;
> >>-
> >>-        private MessageContext msgctx;
> >>-
> >>-        private Exception error;
> >>-
> >>-        public void onComplete(AsyncResult result) {
> >>-            this.envelope = result.getResponseEnvelope();
> >>-            // Transport input stream gets closed after calling 
setComplete
> >>-            // method. Have to build the whole envelope including the
> >>-            // attachments at this stage. Data might get lost if the 
input
> >>-            // stream gets closed before building the whole envelope.
> >>-            this.envelope.buildWithAttachments();
> >>-            this.msgctx = result.getResponseMessageContext();
> >>-        }
> >>-
> >>-        public void setComplete(boolean complete) {
> >>-            super.setComplete(complete);
> >>-            synchronized (this) {
> >>-                notify();
> >>-            }
> >>-        }
> >>-
> >>-        public void onError(Exception e) {
> >>-            error = e;
> >>-        }
> >>-
> >>-        public MessageContext getMsgctx() {
> >>-            return msgctx;
> >>-        }
> >>-    }
> >>
> >>    /**
> >>     * Get the service context.
> >>
> >>Modified: 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation.
> java
> >>URL: http://svn.apache.
> 
org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation.
> java?view=diff&rev=499521&r1=499520&r2=499521
> 
>>==============================================================================
> >>--- 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation.
> java (original)
> >>+++ 
> 
webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/description/OutInAxisOperation.
> java Wed Jan 24 10:38:56 2007
> >>@@ -35,6 +35,8 @@
> >>import org.apache.axis2.util.CallbackReceiver;
> >>import org.apache.axiom.om.util.UUIDGenerator;
> >>import org.apache.axis2.wsdl.WSDLConstants;
> >>+import org.apache.commons.logging.Log;
> >>+import org.apache.commons.logging.LogFactory;
> >>
> >>import javax.xml.namespace.QName;
> >>import java.util.HashMap;
> >>@@ -95,6 +97,8 @@
> >> */
> >>class OutInAxisOperationClient extends OperationClient {
> >>
> >>+    private static Log log = LogFactory.
> getLog(OutInAxisOperationClient.class);
> >>+ 
> >>    OutInAxisOperationClient(OutInAxisOperation axisOp, ServiceContext 
sc,
> >>                             Options options) {
> >>        super(axisOp, sc, options);
> >>@@ -149,6 +153,7 @@
> >>     * @throws AxisFault if something goes wrong during the 
> execution of the MEP.
> >>     */
> >>    public void execute(boolean block) throws AxisFault {
> >>+       if(log.isDebugEnabled()) log.debug("Entry: 
> OutInAxisOperationClient::execute, " + block);
> >>        if (completed) {
> >>            throw new AxisFault(Messages.getMessage("mepiscomplted"));
> >>        }
> >>@@ -181,9 +186,29 @@
> >>        }
> >> 
> >>        if (useAsync || options.isUseSeparateListener()) {
> >>-            CallbackReceiver callbackReceiver = (CallbackReceiver) 
axisOp
> >>-                    .getMessageReceiver();
> >>-            callbackReceiver.addCallback(mc.getMessageID(), 
callback);
> >>+           if(log.isDebugEnabled())
> >>+              log.debug("useAsync=" + useAsync + ", 
> seperateListener=" + options.isUseSeparateListener());
> >>+           /**
> >>+            * We are following the async path. If the user hasn't
> set a callback object then we must
> >>+            * block until the whole MEP is complete, as they have
> no other way to get their reply message.
> >>+            */
> >>+           CallbackReceiver callbackReceiver = null;
> >>+           if(axisOp.getMessageReceiver() != null && axisOp.
> getMessageReceiver() instanceof CallbackReceiver) {
> >>+              callbackReceiver = (CallbackReceiver) axisOp.
> getMessageReceiver();
> >>+           } else {
> >>+               if(log.isDebugEnabled()) log.debug("Creating new 
> callback receiver");
> >>+              callbackReceiver = new CallbackReceiver();
> >>+              axisOp.setMessageReceiver(callbackReceiver);
> >>+           }
> >>+ 
> >>+           SyncCallBack internalCallback = null;
> >>+           if(callback != null) {
> >>+                callbackReceiver.addCallback(mc.getMessageID(), 
callback);
> >>+           } else {
> >>+               if(log.isDebugEnabled()) log.debug("Creating 
> internal callback");
> >>+              internalCallback = new SyncCallBack();
> >>+              callbackReceiver.addCallback(mc.getMessageID(), 
> internalCallback);
> >>+           }
> >> 
> >>            /**
> >>             * If USE_CUSTOM_LISTENER is set to 'true' the replyTo
> value will not be replaced and Axis2 will not
> >>@@ -205,14 +230,45 @@
> >>                    mc.getReplyTo().
> setAddress(replyToFromTransport.getAddress());
> >>                }
> >>            }
> >>-
> >>-
> >> 
> >>            //if we don't do this , this guy will wait till it 
> gets HTTP 202 in the HTTP case
> >>            mc.setProperty(MessageContext.TRANSPORT_NON_BLOCKING, 
> Boolean.TRUE);
> >>            AxisEngine engine = new AxisEngine(cc);
> >>            mc.getConfigurationContext().
> registerOperationContext(mc.getMessageID(), oc);
> >>            engine.send(mc);
> >>+ 
> >>+            if(internalCallback != null) {
> >>+               long timeout = options.getTimeOutInMilliSeconds();
> >>+               long waitTime = timeout;
> >>+               long startTime = System.currentTimeMillis();
> >>+ 
> >>+               synchronized (internalCallback) {
> >>+                   while (! internalCallback.isComplete() && 
> waitTime >= 0) {
> >>+                       try {
> >>+                          internalCallback.wait(timeout);
> >>+                       } catch (InterruptedException e) {
> >>+                           // We were interrupted for some 
> reason, keep waiting
> >>+                           // or throw new AxisFault( "Callback 
> was interrupted by someone?" );
> >>+                       }
> >>+                       // The wait finished, compute remaining time
> >>+                       // - wait can end prematurely, see Object.
> wait( int timeout )
> >>+                       waitTime = timeout - (System.
> currentTimeMillis() - startTime);
> >>+                   }
> >>+               }
> >>+            // process the result of the invocation
> >>+            if (internalCallback.envelope != null) {
> >>+               // The call ended normally, so there is nothing to do
> >>+            } else {
> >>+               if (internalCallback.error instanceof AxisFault) {
> >>+                  throw (AxisFault) internalCallback.error;
> >>+               } else if (internalCallback.error != null) {
> >>+                  throw new AxisFault(internalCallback.error);
> >>+               } else if (! internalCallback.isComplete()) {
> >>+                  throw new AxisFault(Messages.
> getMessage("responseTimeOut"));
> >>+               } else
> >>+                  throw new AxisFault(Messages.
> getMessage("callBackCompletedWithError"));
> >>+            }
> >>+            }
> >>        } else {
> >>            if (block) {
> >>                // Send the SOAP Message and receive a response
> >>@@ -344,4 +400,41 @@
> >>         }
> >>        }
> >>    }
> >>+ 
> >>+    /**
> >>+     * This class acts as a callback that allows users to wait on
> the result.
> >>+     */
> >>+    private class SyncCallBack extends Callback {
> >>+
> >>+      private SOAPEnvelope envelope;
> >>+
> >>+      private Exception error;
> >>+
> >>+      public void onComplete(AsyncResult result) {
> >>+           if(log.isDebugEnabled()) log.debug("Entry: 
> OutInAxisOperationClient$SyncCallBack::onComplete");
> >>+            // Transport input stream gets closed after calling 
setComplete
> >>+            // method. Have to build the whole envelope including the
> >>+            // attachments at this stage. Data might get lost if the 
input
> >>+            // stream gets closed before building the whole envelope.
> >>+            this.envelope = result.getResponseEnvelope();
> >>+            this.envelope.buildWithAttachments();
> >>+           if(log.isDebugEnabled()) log.debug("Exit: 
> OutInAxisOperationClient$SyncCallBack::onComplete");
> >>+        }
> >>+
> >>+        public void setComplete(boolean complete) {
> >>+           if(log.isDebugEnabled()) log.debug("Entry: 
> OutInAxisOperationClient$SyncCallBack::setComplete, " + complete);
> >>+            super.setComplete(complete);
> >>+            synchronized (this) {
> >>+                notify();
> >>+            }
> >>+           if(log.isDebugEnabled()) log.debug("Exit: 
> OutInAxisOperationClient$SyncCallBack::setComplete, " + complete);
> >>+        }
> >>+
> >>+        public void onError(Exception e) {
> >>+           if(log.isDebugEnabled()) log.debug("Entry: 
> OutInAxisOperationClient$SyncCallBack::onError, " + e);
> >>+            error = e;
> >>+           if(log.isDebugEnabled()) log.debug("Exit: 
> OutInAxisOperationClient$SyncCallBack::onError");
> >>+        }
> >>+    }
> >>+
> >>}
> >>
> >>
> >>
> >>---------------------------------------------------------------------
> >>To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
> >>For additional commands, e-mail: axis-cvs-help@ws.apache.org
> >>
> >>
> >>
> >> 
> >>
> >> 
> >>
> >
> > 
> >
> 
> -- 
> Thanks,
> Deepal
> ................................................................
> "The highest tower is built one brick at a time"
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-dev-help@ws.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: axis-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-dev-help@ws.apache.org


Mime
View raw message