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] > > > > > -- Thanks, Deepal ................................................................ "The highest tower is built one brick at a time" --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
