/*
   * (non-Javadoc)
   * @see org.apache.axis2.jaxws.core.controller.InvocationController#prepareRequest(org.apache.axis2.jaxws.core.MessageContext)
   */
  protected void prepareRequest(MessageContext requestMsgCtx) {
    try {
      if (requestMsgCtx == null) {
        // throw an exception
      }

      org.apache.axis2.context.MessageContext axisRequestMsgCtx =
          requestMsgCtx.getAxisMessageContext();

      // The MessageContext will contain a Message object with the
      // contents that need to be sent.  We need to get those contents
      // in a form that Axis2 can consume them, an AXIOM SOAPEnvelope.
      MessageUtils.putMessageOnMessageContext(
          requestMsgCtx.getMessage(), // JAX-WS Message
          axisRequestMsgCtx // Axis 2 MessageContext
          );

      if (log.isDebugEnabled()) {
        log.debug("Properties: " + axisRequestMsgCtx.getProperties().toString());
      }
    } catch (WebServiceException e) {
      throw ExceptionFactory.makeWebServiceException(Messages.getMessage("prepareRequestFail"));
    } catch (AxisFault e) {
      throw ExceptionFactory.makeWebServiceException(Messages.getMessage("prepareRequestFail"), e);
    }
  }
  /**
   * Use the provided ServiceClient instance to create an OperationClient identified by the
   * operation QName provided.
   *
   * @param sc
   * @param operation
   * @return
   */
  private OperationClient createOperationClient(ServiceClient sc, QName operation) {
    if (sc == null) {
      throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICCreateOpClientErr1"));
    }
    if (operation == null) {
      throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ICCreateOpClientErr2"));
    }

    if (log.isDebugEnabled()) {
      log.debug("Creating OperationClient for operation: " + operation);
    }

    try {
      OperationClient client = sc.createClient(operation);
      return client;
    } catch (AxisFault e) {
      throw ExceptionFactory.makeWebServiceException(e);
    }
  }
  /*
   * 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#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;
  }
Ejemplo n.º 5
0
  /**
   * 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#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();
  }