Hi Deepal,

As Nick pointed out in his response to Sanjiva, this didn't change the
API -- people using the ServiceClient will not notice a thing and anyone
using the OperationClient will now get the correct behavior when using
RM and sync 2-way messaging.  The modification simply moved
implementation logic from the ServiceClient down to the
OperationClient.  

I can point out 100s of instances of this pattern of modification
without any discussion on the mailing list what so ever.

-Bill



On Thu, 2007-01-25 at 14:16 +0530, Deepal Jayasinghe wrote:
> 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
> >
> >[EMAIL PROTECTED] 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: [EMAIL PROTECTED]
> >>For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >>
> >> 
> >>
> >>    
> >>
> >
> >  
> >
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to