/* * TODO: This is a first pass at filtering the properties that are set on the * RequestContext. Right now it's called during the invoke, but needs to be * moved over to when the property is set. This should not be in the path * of performance. */ private void setupProperties(MessageContext mc) { // , Options ops) { // Enable MTOM Message msg = mc.getMessage(); if (msg.isMTOMEnabled()) { mc.setProperty(Configuration.ENABLE_MTOM, "true"); } // Enable session management if (mc.isMaintainSession()) { mc.getAxisMessageContext().getOptions().setManageSession(true); } // Check to see if BASIC_AUTH is enabled. If so, make sure // the properties are setup correctly. if (mc.containsKey(BindingProvider.USERNAME_PROPERTY) || mc.containsKey(BindingProvider.PASSWORD_PROPERTY)) { String userId = (String) mc.getProperty(BindingProvider.USERNAME_PROPERTY); if (userId == null || userId == "") { throw ExceptionFactory.makeWebServiceException(Messages.getMessage("checkUserName")); } String password = null; if (mc.containsKey(BindingProvider.PASSWORD_PROPERTY)) { password = (String) mc.getProperty(BindingProvider.PASSWORD_PROPERTY); } URL url = null; try { url = new URL((String) mc.getProperty(BindingProvider.ENDPOINT_ADDRESS_PROPERTY)); } catch (MalformedURLException e) { throw ExceptionFactory.makeWebServiceException(e); } HttpTransportProperties.Authenticator basicAuthentication = new HttpTransportProperties.Authenticator(); basicAuthentication.setUsername(userId); basicAuthentication.setPassword(password); basicAuthentication.setHost(url.getHost()); basicAuthentication.setPort(url.getPort()); basicAuthentication.setPreemptiveAuthentication(true); mc.setProperty(HTTPConstants.AUTHENTICATE, basicAuthentication); } }
/* * (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; }
private void initOperationClient(OperationClient opClient, MessageContext requestMsgCtx) { org.apache.axis2.context.MessageContext axisRequest = requestMsgCtx.getAxisMessageContext(); setupProperties(requestMsgCtx); // , axisRequest.getOptions()); if (opClient != null) { Options options = opClient.getOptions(); // Get the target endpoint address and setup the TO endpoint // reference. This tells us where the request is going. EndpointReference toEPR = axisRequest.getTo(); if (toEPR == null) { String targetUrl = (String) requestMsgCtx.getProperty(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); toEPR = new EndpointReference(targetUrl); } options.setTo(toEPR); // Get the SOAP Action (if needed) String soapAction = ClientUtils.findSOAPAction(requestMsgCtx); options.setAction(soapAction); // get the timeout from the request message context options as it may have been // set by the user; if it was not set by the user we will just be setting the // timeout on the operation client to the default so it will not have a negative // effect; this logic is reliant on the fact the JAX-WS MessageContext is delegating // to the Axis2 Options object and not storing its own property bag long timeout = axisRequest.getOptions().getTimeOutInMilliSeconds(); options.setTimeOutInMilliSeconds(timeout); // Use the OperationClient to send the request and put the contents // of the response in the response MessageContext. try { // Set the Axis2 request MessageContext opClient.addMessageContext(axisRequest); } catch (Exception e) { // TODO: Do something } } }
/** * Adds the appropriate properties to the MessageContext that the user will see * * @param soapMessageContext * @param jaxwsMessageContext */ public static void addProperties( SOAPMessageContext soapMessageContext, MessageContext jaxwsMessageContext) { // Copy Axis2 MessageContext properties. It's possible that some set of Axis2 handlers // have run and placed some properties in the context that need to be visible. soapMessageContext.putAll(jaxwsMessageContext.getProperties()); EndpointDescription description = jaxwsMessageContext.getEndpointDescription(); if (description != null) { // Set the WSDL properties ServiceDescription sd = description.getServiceDescription(); if (sd != null) { String wsdlLocation = ((ServiceDescriptionWSDL) sd).getWSDLLocation(); if (wsdlLocation != null && !"".equals(wsdlLocation)) { URI wsdlLocationURI = JavaUtils.createURI(wsdlLocation); if (wsdlLocationURI == null) { log.warn( Messages.getMessage( "addPropertiesErr", wsdlLocation.toString(), description.getServiceQName().toString())); } setProperty( soapMessageContext, javax.xml.ws.handler.MessageContext.WSDL_DESCRIPTION, wsdlLocationURI, true); } setProperty( soapMessageContext, javax.xml.ws.handler.MessageContext.WSDL_SERVICE, description.getServiceQName(), true); } } // Lazily provide a list of available reference parameters. org.apache.axis2.context.MessageContext msgContext = jaxwsMessageContext.getAxisMessageContext(); SOAPHeader header = null; if (msgContext != null && msgContext.getEnvelope() != null) { header = msgContext.getEnvelope().getHeader(); } List<Element> list = new ReferenceParameterList(header); setProperty(soapMessageContext, javax.xml.ws.handler.MessageContext.REFERENCE_PARAMETERS, list); if (log.isDebugEnabled()) { log.debug("Added reference parameter list."); } // If we are running within a servlet container, then JAX-WS requires that the // servlet related properties be set on the MessageContext ServletContext servletContext = (ServletContext) jaxwsMessageContext.getProperty(HTTPConstants.MC_HTTP_SERVLETCONTEXT); if (servletContext != null) { log.debug("Servlet Context Set"); setProperty( soapMessageContext, javax.xml.ws.handler.MessageContext.SERVLET_CONTEXT, servletContext); } else { log.debug("Servlet Context not found"); } HttpServletRequest req = (HttpServletRequest) jaxwsMessageContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); if (req == null) { if (log.isDebugEnabled()) { log.debug("HTTPServletRequest not found"); } } else { setProperty(soapMessageContext, javax.xml.ws.handler.MessageContext.SERVLET_REQUEST, req); if (log.isDebugEnabled()) { log.debug("SERVLET_REQUEST Set"); } String pathInfo = null; try { pathInfo = req.getPathInfo(); } catch (Throwable t) { log.debug("exception in getPathInfo", t); } setProperty(soapMessageContext, javax.xml.ws.handler.MessageContext.PATH_INFO, pathInfo); if (log.isDebugEnabled()) { if (pathInfo != null) { log.debug("HTTP_REQUEST_PATHINFO Set"); } else { log.debug("HTTP_REQUEST_PATHINFO not found"); } } String queryString = req.getQueryString(); setProperty( soapMessageContext, javax.xml.ws.handler.MessageContext.QUERY_STRING, queryString); if (log.isDebugEnabled()) { if (queryString != null) { log.debug("HTTP_REQUEST_QUERYSTRING Set"); } else { log.debug("HTTP_REQUEST_QUERYSTRING not found"); } } String method = req.getMethod(); setProperty( soapMessageContext, javax.xml.ws.handler.MessageContext.HTTP_REQUEST_METHOD, method); if (log.isDebugEnabled()) { if (method != null) { log.debug("HTTP_REQUEST_METHOD Set"); } else { log.debug("HTTP_REQUEST_METHOD not found"); } } } HttpServletResponse res = (HttpServletResponse) jaxwsMessageContext.getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE); if (res == null) { if (log.isDebugEnabled()) { log.debug("Servlet Response not found"); } } else { setProperty(soapMessageContext, javax.xml.ws.handler.MessageContext.SERVLET_RESPONSE, res); if (log.isDebugEnabled()) { log.debug("SERVLET_RESPONSE Set"); } } }
/* * (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(); }