/* * (non-Javadoc) * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext) */ public Response doInvokeAsync(MessageContext request) { // We need the qname of the operation being invoked to know which // AxisOperation the OperationClient should be based on. // Note that the OperationDesc is only set through use of the Proxy. Dispatch // clients do not use operations, so the operationDesc will be null. In this // case an anonymous AxisService with anoymouns AxisOperations for the supported // MEPs will be created; and it is that anonymous operation name which needs to // be specified QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP); // TODO: Will the ServiceClient stick around on the InvocationContext // or will we need some other mechanism of creating this? // Try to create an OperationClient from the passed in ServiceClient InvocationContext ic = request.getInvocationContext(); ServiceClient svcClient = ic.getServiceClient(); OperationClient opClient = createOperationClient(svcClient, operationName); initOperationClient(opClient, request); // Setup the client so that it knows whether the underlying call to // Axis2 knows whether or not to start a listening port for an // asynchronous response. Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP); if ((useAsyncMep != null && useAsyncMep.booleanValue()) || opClient.getOptions().isUseSeparateListener()) { configureAsyncListener(opClient); } else { if (log.isDebugEnabled()) { log.debug( "Asynchronous message exchange not enabled. The invocation will be synchronous."); } } AsyncResponse resp = ic.getAsyncResponseListener(); PollingFuture pf = new PollingFuture(ic); opClient.setCallback(pf); org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext(); try { execute(opClient, false, axisRequestMsgCtx); } catch (AxisFault af) { if (log.isDebugEnabled()) { log.debug( axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " + af.getMessage()); } /* * Save the exception on the callback. The client will learn about the error when they try to * retrieve the async results via the Response.get(). "Errors that occur during the invocation * are reported via an exception when the client attempts to retrieve the results of the operation." * -- JAXWS 4.3.3 */ pf.onError(af); } return resp; }
/* * (non-Javadoc) * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeOneWay(org.apache.axis2.jaxws.core.InvocationContext) */ public void doInvokeOneWay(MessageContext request) throws WebServiceException { // Make sure that a one-way invocation does not attempt to use a separate channel // for the response. Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP); if (useAsyncMep != null && useAsyncMep.booleanValue()) { throw ExceptionFactory.makeWebServiceException(Messages.getMessage("onewayAsync")); } // We need the qname of the operation being invoked to know which // AxisOperation the OperationClient should be based on. // Note that the OperationDesc is only set through use of the Proxy. Dispatch // clients do not use operations, so the operationDesc will be null. In this // case an anonymous AxisService with anoymouns AxisOperations for the supported // MEPs will be created; and it is that anonymous operation name which needs to // be specified QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_ONLY_OP); InvocationContext ic = request.getInvocationContext(); ServiceClient svcClient = ic.getServiceClient(); OperationClient opClient = createOperationClient(svcClient, operationName); initOperationClient(opClient, request); org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext(); try { execute(opClient, true, axisRequestMsgCtx); } catch (AxisFault af) { // JAXWS 6.4.2 says to throw it... // Whatever exception we get here will not be from the server since a one-way // invocation has no response. This will always be a SENDER fault if (log.isDebugEnabled()) { log.debug( axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " + af.getMessage()); } throw ExceptionFactory.makeWebServiceException(ClassUtils.getRootCause(af)); } return; }
/* * (non-Javadoc) * @see org.apache.axis2.jaxws.core.controller.InvocationController#invoke(org.apache.axis2.jaxws.core.InvocationContext) */ public MessageContext doInvoke(MessageContext request) { // We need the qname of the operation being invoked to know which // AxisOperation the OperationClient should be based on. // Note that the OperationDesc is only set through use of the Proxy. Dispatch // clients do not use operations, so the operationDesc will be null. In this // case an anonymous AxisService with anoymouns AxisOperations for the supported // MEPs will be created; and it is that anonymous operation name which needs to // be specified QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP); // TODO: Will the ServiceClient stick around on the InvocationContext // or will we need some other mechanism of creating this? // Try to create an OperationClient from the passed in ServiceClient InvocationContext ic = request.getInvocationContext(); ServiceClient svcClient = ic.getServiceClient(); OperationClient opClient = createOperationClient(svcClient, operationName); initOperationClient(opClient, request); // Setup the client so that it knows whether the underlying call to // Axis2 knows whether or not to start a listening port for an // asynchronous response. Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP); if ((useAsyncMep != null && useAsyncMep.booleanValue()) || opClient.getOptions().isUseSeparateListener()) { configureAsyncListener(opClient); } else { if (log.isDebugEnabled()) { log.debug( "Asynchronous message exchange not enabled. The invocation will be synchronous."); } } org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext(); org.apache.axis2.context.MessageContext axisResponseMsgCtx = null; MessageContext response = null; AxisFault faultexception = null; // don't let the keyword "fault" confuse you. This is an exception class. try { execute(opClient, true, axisRequestMsgCtx); } catch (AxisFault af) { // If an AxisFault was thrown, we need to cleanup the original OperationContext. // Failure to do so results in a memory leak. opClient.getOperationContext().cleanup(); // save the fault in case it didn't come from the endpoint, and thus // there would be no message on the MessageContext faultexception = af; if (log.isDebugEnabled()) { log.debug( axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " + af.getMessage()); } } try { // Collect the response MessageContext and envelope axisResponseMsgCtx = opClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); response = new MessageContext(axisResponseMsgCtx); response.setMEPContext(request.getMEPContext()); // If the Message object is still null, then it's possible that a // local AxisFault was thrown and we need to save it for later throwing // We do not want to create a message and go through the whole handler or // XMLFault processing because it's unnecessary. // // Same is true if we get a valid non-fault server response but some jaxws // client processing (a handler, perhaps) throws an exception. // // If the response message itself is a fault message, let it pass through. if ((faultexception != null) && ((response.getMessage() == null) || (!response.getMessage().isFault()))) { MessageFactory factory = (MessageFactory) FactoryRegistry.getFactory(MessageFactory.class); Message message = factory.create(request.getMessage().getProtocol()); response.setLocalException(faultexception); response.setMessage(message); } // This assumes that we are on the ultimate execution thread ThreadContextMigratorUtil.performMigrationToThread( Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisResponseMsgCtx); } catch (Exception e) { throw ExceptionFactory.makeWebServiceException(e); } return response; }
/* * (non-Javadoc) * @see org.apache.axis2.jaxws.core.controller.InvocationController#invokeAsync(org.apache.axis2.jaxws.core.InvocationContext, javax.xml.ws.AsyncHandler) */ public Future<?> doInvokeAsync(MessageContext request, AsyncHandler callback) { // We need the qname of the operation being invoked to know which // AxisOperation the OperationClient should be based on. // Note that the OperationDesc is only set through use of the Proxy. Dispatch // clients do not use operations, so the operationDesc will be null. In this // case an anonymous AxisService with anoymouns AxisOperations for the supported // MEPs will be created; and it is that anonymous operation name which needs to // be specified QName operationName = getOperationNameToUse(request, ServiceClient.ANON_OUT_IN_OP); // TODO: Will the ServiceClient stick around on the InvocationContext // or will we need some other mechanism of creating this? // Try to create an OperationClient from the passed in ServiceClient InvocationContext ic = request.getInvocationContext(); ServiceClient svcClient = ic.getServiceClient(); OperationClient opClient = createOperationClient(svcClient, operationName); initOperationClient(opClient, request); // Setup the client so that it knows whether the underlying call to // Axis2 knows whether or not to start a listening port for an // asynchronous response. Boolean useAsyncMep = (Boolean) request.getProperty(Constants.USE_ASYNC_MEP); if ((useAsyncMep != null && useAsyncMep.booleanValue()) || opClient.getOptions().isUseSeparateListener()) { configureAsyncListener(opClient); } else { if (log.isDebugEnabled()) { log.debug( "Asynchronous message exchange not enabled. The invocation will be synchronous."); } } CallbackFuture cbf = null; if (callback != null) { cbf = new CallbackFuture(ic, callback); } else { throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICErr4")); } opClient.setCallback(cbf); org.apache.axis2.context.MessageContext axisRequestMsgCtx = request.getAxisMessageContext(); try { execute(opClient, false, axisRequestMsgCtx); } catch (AxisFault af) { if (log.isDebugEnabled()) { log.debug( axisRequestMsgCtx.getLogIDString() + " AxisFault received from client: " + af.getMessage()); } /* * Save the exception on the callback. The client will learn about the error when they try to * retrieve the async results via the Response.get(). "Errors that occur during the invocation * are reported via an exception when the client attempts to retrieve the results of the operation." * -- JAXWS 4.3.3 */ /* * TODO: This is the appropriate thing to do here since the thrown exception may occur before * we switch threads to the async thread. But... what happens if we've already switched over * to the async thread? So far, it appears that the exception gets set on the FutureTask * Concurrent object, and we never hit this scope. This means that later, when the client * calls future.get(), no exception will be thrown despite what the spec says. The client can, * however, retrieve errors via it's AsyncHandler. */ cbf.onError(af); } return cbf.getFutureTask(); }