Esempio n. 1
0
  public static SynapseMessageContext createLightweightSynapseMessageContext(String payload)
      throws Exception {
    MessageContext mc = new OldMessageContext();
    SynapseConfiguration config = new SynapseConfiguration();
    SynapseEnvironment env = new Axis2SynapseEnvironment(config);
    SynapseMessageContext synMc = Axis2SynapseMessageContextImpl.newInstance(mc, config, env);
    SOAPEnvelope envelope = OMAbstractFactory.getSOAP11Factory().getDefaultEnvelope();
    OMDocument omDoc = OMAbstractFactory.getSOAP11Factory().createOMDocument();
    omDoc.addChild(envelope);

    envelope.getBody().addChild(createOMElement(payload));

    synMc.setEnvelope(envelope);
    return synMc;
  }
  private OMElement createRequestPayload() {
    SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
    OMNamespace omNs = fac.createOMNamespace("http://services.samples", "ns");
    OMElement top = fac.createOMElement("getQuotes", omNs);

    for (int i = 0; i < 3; i++) {
      OMElement method = fac.createOMElement("getQuote", omNs);
      OMElement value1 = fac.createOMElement("request", omNs);
      OMElement value2 = fac.createOMElement("symbol", omNs);
      value2.addChild(fac.createOMText(value1, "WSO2"));
      value1.addChild(value2);
      method.addChild(value1);
      top.addChild(method);
    }

    for (int i = 0; i < 3; i++) {
      OMElement method = fac.createOMElement("dummy", omNs);
      OMElement value1 = fac.createOMElement("request", omNs);
      OMElement value2 = fac.createOMElement("symbol", omNs);
      value2.addChild(fac.createOMText(value1, "WSO2"));
      value1.addChild(value2);
      method.addChild(value1);
      top.addChild(method);
    }

    return top;
  }
Esempio n. 3
0
  public static String sendSOAP(
      EndpointReference soapEPR, String requestString, String action, String operation)
      throws Exception {

    ServiceClient sender = PmServiceClient.getServiceClient();
    OperationClient operationClient = sender.createClient(ServiceClient.ANON_OUT_IN_OP);

    // creating message context
    MessageContext outMsgCtx = new MessageContext();
    // assigning message context's option object into instance variable
    Options opts = outMsgCtx.getOptions();
    // setting properties into option
    log.debug(soapEPR);
    opts.setTo(soapEPR);
    opts.setAction(action);
    opts.setTimeOutInMilliSeconds(180000);

    log.debug(requestString);

    SOAPEnvelope envelope = null;

    try {
      SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
      envelope = fac.getDefaultEnvelope();
      OMNamespace omNs =
          fac.createOMNamespace(
              "http://rpdr.partners.org/", //$NON-NLS-1$
              "rpdr"); //$NON-NLS-1$

      // creating the SOAP payload
      OMElement method = fac.createOMElement(operation, omNs);
      OMElement value = fac.createOMElement("RequestXmlString", omNs); // $NON-NLS-1$
      value.setText(requestString);
      method.addChild(value);
      envelope.getBody().addChild(method);
    } catch (FactoryConfigurationError e) {
      log.error(e.getMessage());
      throw new Exception(e);
    }

    outMsgCtx.setEnvelope(envelope);

    operationClient.addMessageContext(outMsgCtx);
    operationClient.execute(true);

    MessageContext inMsgtCtx = operationClient.getMessageContext("In"); // $NON-NLS-1$
    SOAPEnvelope responseEnv = inMsgtCtx.getEnvelope();

    OMElement soapResponse = responseEnv.getBody().getFirstElement();
    //		System.out.println("Sresponse: "+ soapResponse.toString());
    OMElement soapResult = soapResponse.getFirstElement();
    //		System.out.println("Sresult: "+ soapResult.toString());

    String i2b2Response = soapResult.getText();
    log.debug(i2b2Response);

    return i2b2Response;
  }
 @Override
 public void setSoapVersion(SoapVersion version) {
   if (SoapVersion.SOAP_11 == version) {
     soapFactory = OMAbstractFactory.getSOAP11Factory();
   } else if (SoapVersion.SOAP_12 == version) {
     soapFactory = OMAbstractFactory.getSOAP12Factory();
   } else {
     throw new IllegalArgumentException(
         "Invalid version [" + version + "]. " + "Expected the SOAP_11 or SOAP_12 constant");
   }
 }
Esempio n. 5
0
  public static MessageContext sendUsingSwA(String fileName, String targetEPR) throws IOException {

    Options options = new Options();
    options.setTo(new EndpointReference(targetEPR));
    options.setAction("urn:uploadFileUsingSwA");
    options.setProperty(Constants.Configuration.ENABLE_SWA, Constants.VALUE_TRUE);

    ServiceClient sender = new ServiceClient();
    sender.setOptions(options);
    OperationClient mepClient = sender.createClient(ServiceClient.ANON_OUT_IN_OP);

    MessageContext mc = new MessageContext();

    System.out.println("Sending file : " + fileName + " as SwA");
    FileDataSource fileDataSource = new FileDataSource(new File(fileName));
    DataHandler dataHandler = new DataHandler(fileDataSource);
    String attachmentID = mc.addAttachment(dataHandler);

    SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
    SOAPEnvelope env = factory.getDefaultEnvelope();
    OMNamespace ns = factory.createOMNamespace("http://services.samples/xsd", "m0");
    OMElement payload = factory.createOMElement("uploadFileUsingSwA", ns);
    OMElement request = factory.createOMElement("request", ns);
    OMElement imageId = factory.createOMElement("imageId", ns);
    imageId.setText(attachmentID);
    request.addChild(imageId);
    payload.addChild(request);
    env.getBody().addChild(payload);
    mc.setEnvelope(env);

    mepClient.addMessageContext(mc);
    mepClient.execute(true);
    MessageContext response = mepClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);

    SOAPBody body = response.getEnvelope().getBody();
    String imageContentId =
        body.getFirstChildWithName(
                new QName("http://services.samples/xsd", "uploadFileUsingSwAResponse"))
            .getFirstChildWithName(new QName("http://services.samples/xsd", "response"))
            .getFirstChildWithName(new QName("http://services.samples/xsd", "imageId"))
            .getText();

    Attachments attachment = response.getAttachmentMap();
    dataHandler = attachment.getDataHandler(imageContentId);
    File tempFile = File.createTempFile("swa-", ".gif");
    FileOutputStream fos = new FileOutputStream(tempFile);
    dataHandler.writeTo(fos);
    fos.flush();
    fos.close();

    System.out.println("Saved response to file : " + tempFile.getAbsolutePath());

    return response;
  }
  public static void transferFile(File file, String destinationFile) throws Exception {

    Options options = new Options();
    options.setTo(targetEPR);
    options.setProperty(Constants.Configuration.ENABLE_SWA, Constants.VALUE_TRUE);
    options.setSoapVersionURI(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
    // Increase the time out when sending large attachments
    options.setTimeOutInMilliSeconds(10000);
    options.setTo(targetEPR);
    options.setAction("urn:uploadFile");

    // assume the use runs this sample at
    // <axis2home>/samples/soapwithattachments/ dir
    ConfigurationContext configContext =
        ConfigurationContextFactory.createConfigurationContextFromFileSystem(
            "../../repository", null);

    ServiceClient sender = new ServiceClient(configContext, null);
    sender.setOptions(options);
    OperationClient mepClient = sender.createClient(ServiceClient.ANON_OUT_IN_OP);

    MessageContext mc = new MessageContext();
    FileDataSource fileDataSource = new FileDataSource(file);

    // Create a dataHandler using the fileDataSource. Any implementation of
    // javax.activation.DataSource interface can fit here.
    DataHandler dataHandler = new DataHandler(fileDataSource);
    String attachmentID = mc.addAttachment(dataHandler);

    SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
    SOAPEnvelope env = fac.getDefaultEnvelope();
    OMNamespace omNs = fac.createOMNamespace("http://service.soapwithattachments.sample", "swa");
    OMElement uploadFile = fac.createOMElement("uploadFile", omNs);
    OMElement nameEle = fac.createOMElement("name", omNs);
    nameEle.setText(destinationFile);
    OMElement idEle = fac.createOMElement("attchmentID", omNs);
    idEle.setText(attachmentID);
    uploadFile.addChild(nameEle);
    uploadFile.addChild(idEle);
    env.getBody().addChild(uploadFile);
    mc.setEnvelope(env);

    mepClient.addMessageContext(mc);
    mepClient.execute(true);
    MessageContext response = mepClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
    SOAPBody body = response.getEnvelope().getBody();
    OMElement element =
        body.getFirstElement()
            .getFirstChildWithName(
                new QName("http://service.soapwithattachments.sample", "return"));
    System.out.println(element.getText());
  }
  private OMElement createMultipleQuoteRequestBody(String symbol, int iterations) {
    SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
    OMNamespace omNs = fac.createOMNamespace("http://services.samples", "ns");
    OMElement method1 = fac.createOMElement("getQuotes", omNs);
    OMElement method2 = fac.createOMElement("getQuote", omNs);

    for (int i = 0; i < iterations; i++) {
      OMElement value1 = fac.createOMElement("request", omNs);
      OMElement value2 = fac.createOMElement("symbol", omNs);
      value2.addChild(fac.createOMText(value1, symbol));
      value1.addChild(value2);
      method2.addChild(value1);
      method1.addChild(method2);
    }
    return method1;
  }
Esempio n. 8
0
  private void createAndSendSOAPResponse(
      Map<String, Object> serviceResults, String serviceName, HttpServletResponse response)
      throws EventHandlerException {
    try {
      // setup the response
      Debug.logVerbose("[EventHandler] : Setting up response message", module);
      String xmlResults = SoapSerializer.serialize(serviceResults);
      // Debug.logInfo("xmlResults ==================" + xmlResults, module);
      XMLStreamReader reader =
          XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xmlResults));
      StAXOMBuilder resultsBuilder = new StAXOMBuilder(reader);
      OMElement resultSer = resultsBuilder.getDocumentElement();

      // create the response soap
      SOAPFactory factory = OMAbstractFactory.getSOAP11Factory();
      SOAPEnvelope resEnv = factory.createSOAPEnvelope();
      SOAPBody resBody = factory.createSOAPBody();
      OMElement resService = factory.createOMElement(new QName(serviceName + "Response"));
      resService.addChild(resultSer.getFirstElement());
      resBody.addChild(resService);
      resEnv.addChild(resBody);

      // The declareDefaultNamespace method doesn't work see
      // (https://issues.apache.org/jira/browse/AXIS2-3156)
      // so the following doesn't work:
      // resService.declareDefaultNamespace(ModelService.TNS);
      // instead, create the xmlns attribute directly:
      OMAttribute defaultNS = factory.createOMAttribute("xmlns", null, ModelService.TNS);
      resService.addAttribute(defaultNS);

      // log the response message
      if (Debug.verboseOn()) {
        try {
          Debug.logInfo("Response Message:\n" + resEnv + "\n", module);
        } catch (Throwable t) {
        }
      }

      resEnv.serialize(response.getOutputStream());
      response.getOutputStream().flush();
    } catch (Exception e) {
      Debug.logError(e, module);
      throw new EventHandlerException(e.getMessage(), e);
    }
  }
Esempio n. 9
0
  /** This will be invoked by the schedular to inject the message in to the SynapseEnvironment */
  public void execute() {
    log.debug("execute");
    if (synapseEnvironment == null) {
      log.error("Synapse Environment not set");
      return;
    }
    if (message == null) {
      log.error("message not set");
      return;
    }
    if (to == null) {
      log.error("to address not set");
      return;
    }

    MessageContext mc = synapseEnvironment.createMessageContext();
    //        AspectHelper.setGlobalAudit(mc);    TODO
    mc.pushFaultHandler(new MediatorFaultHandler(mc.getFaultSequence()));
    mc.setTo(new EndpointReference(to));
    if (format == null) {
      PayloadHelper.setXMLPayload(mc, message.cloneOMElement());
    } else {
      try {
        if (SOAP11_FORMAT.equalsIgnoreCase(format)) {
          mc.setEnvelope(OMAbstractFactory.getSOAP11Factory().createSOAPEnvelope());
        } else if (SOAP12_FORMAT.equalsIgnoreCase(format)) {
          mc.setEnvelope(OMAbstractFactory.getSOAP12Factory().createSOAPEnvelope());
        } else if (POX_FORMAT.equalsIgnoreCase(format)) {
          mc.setDoingPOX(true);
        } else if (GET_FORMAT.equalsIgnoreCase(format)) {
          mc.setDoingGET(true);
        }
        PayloadHelper.setXMLPayload(mc, message.cloneOMElement());
      } catch (AxisFault axisFault) {
        String msg = "Error in setting the message payload : " + message;
        log.error(msg, axisFault);
        throw new SynapseException(msg, axisFault);
      }
    }
    if (soapAction != null) {
      mc.setSoapAction(soapAction);
    }
    synapseEnvironment.injectMessage(mc);
  }
Esempio n. 10
0
 public OMElement processDocument(InputStream inputStream, String s, MessageContext messageContext)
     throws AxisFault {
   messageContext.setProperty(JsonConstant.IS_JSON_STREAM, true);
   JsonReader jsonReader;
   String charSetEncoding = null;
   try {
     charSetEncoding =
         (String) messageContext.getProperty(Constants.Configuration.CHARACTER_SET_ENCODING);
     jsonReader = new JsonReader(new InputStreamReader(inputStream, charSetEncoding));
     GsonXMLStreamReader gsonXMLStreamReader = new GsonXMLStreamReader(jsonReader);
     messageContext.setProperty(JsonConstant.GSON_XML_STREAM_READER, gsonXMLStreamReader);
     // dummy envelop
     SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();
     return soapFactory.getDefaultEnvelope();
   } catch (UnsupportedEncodingException e) {
     throw new AxisFault(
         charSetEncoding + " encoding is may not supported by json inputStream ", e);
   }
 }
Esempio n. 11
0
 public static SOAPFactory getOMSOAP11Factory() {
   if (reuse) return OMAbstractFactory.getSOAP11Factory();
   String omFactory;
   try {
     omFactory = System.getProperty(SOAP11_FACTORY_NAME_PROPERTY);
     if (omFactory == null || "".equals(omFactory)) {
       omFactory = DEFAULT_SOAP11_FACTORY_CLASS_NAME;
     }
   } catch (SecurityException e) {
     omFactory = DEFAULT_SOAP11_FACTORY_CLASS_NAME;
   }
   SOAPFactory defaultSOAP11OMFactory;
   try {
     defaultSOAP11OMFactory =
         (SOAPFactory) ClassLoader.getSystemClassLoader().loadClass(omFactory).newInstance();
   } catch (InstantiationException e) {
     throw new OMException(e);
   } catch (IllegalAccessException e) {
     throw new OMException(e);
   } catch (ClassNotFoundException e) {
     throw new OMException(e);
   }
   return defaultSOAP11OMFactory;
 }
  public static void testConnect(
      String strOperation, String strParamName, AbstractConnector connector) throws AxisFault {

    org.apache.axis2.context.MessageContext axis2Ctx =
        new org.apache.axis2.context.MessageContext();
    SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
    org.apache.axiom.soap.SOAPEnvelope envelope = fac.getDefaultEnvelope();
    axis2Ctx.setEnvelope(envelope);
    Collection<String> collection = new java.util.ArrayList<String>();
    collection.add(strParamName);
    testCtx.setProperty(
        TEST_TEMPLATE + ":" + strParamName,
        new Value(
            "<sfdc:sObjects xmlns:sfdc='sfdc' type='Account'><sfdc:sObject><sfdc:Name>name01</sfdc:Name></sfdc:sObject></sfdc:sObjects>"));
    TemplateContext context = new TemplateContext(TEST_TEMPLATE, collection);
    Stack<TemplateContext> stack = new Stack<TemplateContext>();
    stack.add(context);
    context.setupParams(testCtx);

    testCtx.setProperty(SynapseConstants.SYNAPSE__FUNCTION__STACK, stack);
    try {
      connector.connect(testCtx);
    } catch (Exception e) {
      assertTrue(false);
    }

    Iterator<OMElement> iIteratorElements =
        testCtx.getEnvelope().getBody().getChildrenWithLocalName(strOperation);
    OMElement element = iIteratorElements.next();
    iIteratorElements = element.getChildren();
    if (iIteratorElements.hasNext()) {
      assertTrue(true);
    } else {
      assertTrue(false);
    }
  }
 public static void testUpsertConnect() throws AxisFault {
   SOAPEnvelope envelope = OMAbstractFactory.getSOAP11Factory().getDefaultEnvelope();
   envelope.getBody().addChild(createOMElement("<upsert/>"));
   testCtx.setEnvelope(envelope);
   testConnect("upsert", SalesforceUtil.SALESFORCE_SOBJECTS, new SetupUpsertSobjects());
 }
  /**
   * Actual transformation of the current message into a fault message
   *
   * @param synCtx the current message context
   * @param soapVersion SOAP version of the resulting fault desired
   * @param synLog the Synapse log to use
   */
  private void makeSOAPFault(MessageContext synCtx, int soapVersion, SynapseLog synLog) {

    if (synLog.isTraceOrDebugEnabled()) {
      synLog.traceOrDebug("Creating a SOAP " + (soapVersion == SOAP11 ? "1.1" : "1.2") + " fault");
    }

    // get the correct SOAP factory to be used
    SOAPFactory factory =
        (soapVersion == SOAP11
            ? OMAbstractFactory.getSOAP11Factory()
            : OMAbstractFactory.getSOAP12Factory());

    // create the SOAP fault document and envelope
    OMDocument soapFaultDocument = factory.createOMDocument();
    SOAPEnvelope faultEnvelope = factory.getDefaultFaultEnvelope();
    soapFaultDocument.addChild(faultEnvelope);

    // create the fault element  if it is need
    SOAPFault fault = faultEnvelope.getBody().getFault();
    if (fault == null) {
      fault = factory.createSOAPFault();
    }

    // populate it
    setFaultCode(synCtx, factory, fault, soapVersion);
    setFaultReason(synCtx, factory, fault, soapVersion);
    setFaultNode(factory, fault);
    setFaultRole(factory, fault);
    setFaultDetail(synCtx, factory, fault);

    // set the all headers of original SOAP Envelope to the Fault Envelope
    if (synCtx.getEnvelope() != null) {
      SOAPHeader soapHeader = synCtx.getEnvelope().getHeader();
      if (soapHeader != null) {
        for (Iterator iter = soapHeader.examineAllHeaderBlocks(); iter.hasNext(); ) {
          Object o = iter.next();
          if (o instanceof SOAPHeaderBlock) {
            SOAPHeaderBlock header = (SOAPHeaderBlock) o;
            faultEnvelope.getHeader().addChild(header);
          } else if (o instanceof OMElement) {
            faultEnvelope.getHeader().addChild((OMElement) o);
          }
        }
      }
    }

    if (synLog.isTraceOrDebugEnabled()) {
      String msg =
          "Original SOAP Message : "
              + synCtx.getEnvelope().toString()
              + "Fault Message created : "
              + faultEnvelope.toString();
      if (synLog.isTraceTraceEnabled()) {
        synLog.traceTrace(msg);
      }
      if (log.isTraceEnabled()) {
        log.trace(msg);
      }
    }

    // overwrite current message envelope with new fault envelope
    try {
      synCtx.setEnvelope(faultEnvelope);
    } catch (AxisFault af) {
      handleException(
          "Error replacing current SOAP envelope " + "with the fault envelope", af, synCtx);
    }

    if (synCtx.getFaultTo() != null) {
      synCtx.setTo(synCtx.getFaultTo());
    } else if (synCtx.getReplyTo() != null) {
      synCtx.setTo(synCtx.getReplyTo());
    } else {
      synCtx.setTo(null);
    }

    // set original messageID as relatesTo
    if (synCtx.getMessageID() != null) {
      RelatesTo relatesTo = new RelatesTo(synCtx.getMessageID());
      synCtx.setRelatesTo(new RelatesTo[] {relatesTo});
    }

    synLog.traceOrDebug("End : Fault mediator");
  }
Esempio n. 15
0
 public static SOAPFactory getSoapFactory(String soapVersionURI) {
   if ("http://www.w3.org/2003/05/soap-envelope".equals(soapVersionURI))
     return OMAbstractFactory.getSOAP12Factory();
   else return OMAbstractFactory.getSOAP11Factory();
 }
 @Override
 protected SoapEnvelope createSoapEnvelope() throws Exception {
   SOAPFactory axiomFactory = OMAbstractFactory.getSOAP11Factory();
   AxiomSoapMessage axiomSoapMessage = new AxiomSoapMessage(axiomFactory);
   return axiomSoapMessage.getEnvelope();
 }
/**
 * Axiom-specific implementation of the {@link org.springframework.ws.WebServiceMessageFactory
 * WebServiceMessageFactory} interface. Creates {@link
 * org.springframework.ws.soap.axiom.AxiomSoapMessage AxiomSoapMessages}.
 *
 * <p>To increase reading performance on the the SOAP request created by this message factory, you
 * can set the {@link #setPayloadCaching(boolean) payloadCaching} property to {@code false} (default
 * is {@code true}). This this will read the contents of the body directly from the stream. However,
 * <strong>when this setting is enabled, the payload can only be read once</strong>. This means that
 * any endpoint mappings or interceptors which are based on the message payload (such as the {@link
 * PayloadRootAnnotationMethodEndpointMapping}, the {@link PayloadValidatingInterceptor}, or the
 * {@link PayloadLoggingInterceptor}) cannot be used. Instead, use an endpoint mapping that does not
 * consume the payload (i.e. the {@link SoapActionAnnotationMethodEndpointMapping}).
 *
 * <p>Additionally, this message factory can cache large attachments to disk by setting the {@link
 * #setAttachmentCaching(boolean) attachmentCaching} property to {@code true} (default is {@code
 * false}). Optionally, the location where attachments are stored can be defined via the {@link
 * #setAttachmentCacheDir(File) attachmentCacheDir} property (defaults to the system temp file
 * path).
 *
 * <p>Mostly derived from {@code org.apache.axis2.transport.http.HTTPTransportUtils} and {@code
 * org.apache.axis2.transport.TransportUtils}, which we cannot use since they are not part of the
 * Axiom distribution.
 *
 * @author Arjen Poutsma
 * @see AxiomSoapMessage
 * @see #setPayloadCaching(boolean)
 * @since 1.0.0
 */
public class AxiomSoapMessageFactory implements SoapMessageFactory, InitializingBean {

  private static final String CHARSET_PARAMETER = "charset";

  private static final String DEFAULT_CHARSET_ENCODING = "UTF-8";

  private static final String MULTI_PART_RELATED_CONTENT_TYPE = "multipart/related";

  private static final Log logger = LogFactory.getLog(AxiomSoapMessageFactory.class);

  private XMLInputFactory inputFactory;

  private boolean payloadCaching = true;

  private boolean attachmentCaching = false;

  private File attachmentCacheDir;

  private int attachmentCacheThreshold = 4096;

  // use SOAP 1.1 by default
  private SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory();

  private boolean langAttributeOnSoap11FaultString = true;

  private boolean replacingEntityReferences = false;

  private boolean supportingExternalEntities = false;

  /**
   * Indicates whether the SOAP Body payload should be cached or not. Default is {@code true}.
   *
   * <p>Setting this to {@code false} will increase performance, but also result in the fact that
   * the message payload can only be read once.
   */
  public void setPayloadCaching(boolean payloadCaching) {
    this.payloadCaching = payloadCaching;
  }

  /**
   * Indicates whether SOAP attachments should be cached or not. Default is {@code false}.
   *
   * <p>Setting this to {@code true} will cause Axiom to store larger attachments on disk, rather
   * than in memory. This decreases memory consumption, but decreases performance.
   */
  public void setAttachmentCaching(boolean attachmentCaching) {
    this.attachmentCaching = attachmentCaching;
  }

  /**
   * Sets the directory where SOAP attachments will be stored. Only used when {@link
   * #setAttachmentCaching(boolean) attachmentCaching} is set to {@code true}.
   *
   * <p>The parameter should be an existing, writable directory. This property defaults to the
   * temporary directory of the operating system (i.e. the value of the {@code java.io.tmpdir}
   * system property).
   */
  public void setAttachmentCacheDir(File attachmentCacheDir) {
    Assert.notNull(attachmentCacheDir, "'attachmentCacheDir' must not be null");
    Assert.isTrue(attachmentCacheDir.isDirectory(), "'attachmentCacheDir' must be a directory");
    Assert.isTrue(attachmentCacheDir.canWrite(), "'attachmentCacheDir' must be writable");
    this.attachmentCacheDir = attachmentCacheDir;
  }

  /**
   * Sets the threshold for attachments caching, in bytes. Attachments larger than this threshold
   * will be cached in the {@link #setAttachmentCacheDir(File) attachment cache directory}. Only
   * used when {@link #setAttachmentCaching(boolean) attachmentCaching} is set to {@code true}.
   *
   * <p>Defaults to 4096 bytes (i.e. 4 kilobytes).
   */
  public void setAttachmentCacheThreshold(int attachmentCacheThreshold) {
    Assert.isTrue(attachmentCacheThreshold > 0, "'attachmentCacheThreshold' must be larger than 0");
    this.attachmentCacheThreshold = attachmentCacheThreshold;
  }

  @Override
  public void setSoapVersion(SoapVersion version) {
    if (SoapVersion.SOAP_11 == version) {
      soapFactory = OMAbstractFactory.getSOAP11Factory();
    } else if (SoapVersion.SOAP_12 == version) {
      soapFactory = OMAbstractFactory.getSOAP12Factory();
    } else {
      throw new IllegalArgumentException(
          "Invalid version [" + version + "]. " + "Expected the SOAP_11 or SOAP_12 constant");
    }
  }

  /**
   * Defines whether a {@code xml:lang} attribute should be set on SOAP 1.1 {@code <faultstring>}
   * elements.
   *
   * <p>The default is {@code true}, to comply with WS-I, but this flag can be set to {@code false}
   * to the older W3C SOAP 1.1 specification.
   *
   * @see <a href="http://www.ws-i.org/Profiles/BasicProfile-1.1.html#SOAP_Fault_Language">WS-I
   *     Basic Profile 1.1</a>
   */
  public void setLangAttributeOnSoap11FaultString(boolean langAttributeOnSoap11FaultString) {
    this.langAttributeOnSoap11FaultString = langAttributeOnSoap11FaultString;
  }

  /**
   * Sets whether internal entity references should be replaced with their replacement text and
   * report them as characters.
   *
   * @see XMLInputFactory#IS_REPLACING_ENTITY_REFERENCES
   */
  public void setReplacingEntityReferences(boolean replacingEntityReferences) {
    this.replacingEntityReferences = replacingEntityReferences;
  }

  /**
   * Sets whether external parsed entities should be resolved.
   *
   * @see XMLInputFactory#IS_SUPPORTING_EXTERNAL_ENTITIES
   */
  public void setSupportingExternalEntities(boolean supportingExternalEntities) {
    this.supportingExternalEntities = supportingExternalEntities;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    if (logger.isInfoEnabled()) {
      logger.info(payloadCaching ? "Enabled payload caching" : "Disabled payload caching");
    }
    if (attachmentCacheDir == null) {
      String tempDir = System.getProperty("java.io.tmpdir");
      setAttachmentCacheDir(new File(tempDir));
    }
    inputFactory = createXmlInputFactory();
  }

  @Override
  public AxiomSoapMessage createWebServiceMessage() {
    return new AxiomSoapMessage(soapFactory, payloadCaching, langAttributeOnSoap11FaultString);
  }

  @Override
  public AxiomSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
    Assert.isInstanceOf(
        TransportInputStream.class,
        inputStream,
        "AxiomSoapMessageFactory requires a TransportInputStream");
    if (inputFactory == null) {
      inputFactory = createXmlInputFactory();
    }
    TransportInputStream transportInputStream = (TransportInputStream) inputStream;
    String contentType =
        getHeaderValue(transportInputStream, TransportConstants.HEADER_CONTENT_TYPE);
    if (!StringUtils.hasLength(contentType)) {
      if (logger.isDebugEnabled()) {
        logger.debug(
            "TransportInputStream has no Content-Type header; defaulting to \""
                + SoapVersion.SOAP_11.getContentType()
                + "\"");
      }
      contentType = SoapVersion.SOAP_11.getContentType();
    }
    String soapAction = getHeaderValue(transportInputStream, TransportConstants.HEADER_SOAP_ACTION);
    if (!StringUtils.hasLength(soapAction)) {
      soapAction = SoapUtils.extractActionFromContentType(contentType);
    }
    try {
      if (isMultiPartRelated(contentType)) {
        return createMultiPartAxiomSoapMessage(inputStream, contentType, soapAction);
      } else {
        return createAxiomSoapMessage(inputStream, contentType, soapAction);
      }
    } catch (XMLStreamException ex) {
      throw new AxiomSoapMessageCreationException(
          "Could not parse request: " + ex.getMessage(), ex);
    } catch (OMException ex) {
      throw new AxiomSoapMessageCreationException(
          "Could not create message: " + ex.getMessage(), ex);
    }
  }

  private String getHeaderValue(TransportInputStream transportInputStream, String header)
      throws IOException {
    String contentType = null;
    Iterator<String> iterator = transportInputStream.getHeaders(header);
    if (iterator.hasNext()) {
      contentType = iterator.next();
    }
    return contentType;
  }

  private boolean isMultiPartRelated(String contentType) {
    contentType = contentType.toLowerCase(Locale.ENGLISH);
    return contentType.contains(MULTI_PART_RELATED_CONTENT_TYPE);
  }

  /** Creates an AxiomSoapMessage without attachments. */
  private AxiomSoapMessage createAxiomSoapMessage(
      InputStream inputStream, String contentType, String soapAction) throws XMLStreamException {
    XMLStreamReader reader =
        inputFactory.createXMLStreamReader(inputStream, getCharSetEncoding(contentType));
    String envelopeNamespace = getSoapEnvelopeNamespace(contentType);
    StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(reader, soapFactory, envelopeNamespace);
    SOAPMessage soapMessage = builder.getSoapMessage();
    return new AxiomSoapMessage(
        soapMessage, soapAction, payloadCaching, langAttributeOnSoap11FaultString);
  }

  /** Creates an AxiomSoapMessage with attachments. */
  private AxiomSoapMessage createMultiPartAxiomSoapMessage(
      InputStream inputStream, String contentType, String soapAction) throws XMLStreamException {
    Attachments attachments =
        new Attachments(
            inputStream,
            contentType,
            attachmentCaching,
            attachmentCacheDir.getAbsolutePath(),
            Integer.toString(attachmentCacheThreshold));
    XMLStreamReader reader =
        inputFactory.createXMLStreamReader(
            attachments.getRootPartInputStream(),
            getCharSetEncoding(attachments.getRootPartContentType()));
    StAXSOAPModelBuilder builder;
    String envelopeNamespace = getSoapEnvelopeNamespace(contentType);
    if (MTOMConstants.SWA_TYPE.equals(attachments.getAttachmentSpecType())
        || MTOMConstants.SWA_TYPE_12.equals(attachments.getAttachmentSpecType())) {
      builder = new StAXSOAPModelBuilder(reader, soapFactory, envelopeNamespace);
    } else if (MTOMConstants.MTOM_TYPE.equals(attachments.getAttachmentSpecType())) {
      builder = new MTOMStAXSOAPModelBuilder(reader, attachments, envelopeNamespace);
    } else {
      throw new AxiomSoapMessageCreationException(
          "Unknown attachment type: [" + attachments.getAttachmentSpecType() + "]");
    }
    return new AxiomSoapMessage(
        builder.getSoapMessage(),
        attachments,
        soapAction,
        payloadCaching,
        langAttributeOnSoap11FaultString);
  }

  private String getSoapEnvelopeNamespace(String contentType) {
    if (contentType.contains(SOAP11Constants.SOAP_11_CONTENT_TYPE)) {
      return SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI;
    } else if (contentType.contains(SOAP12Constants.SOAP_12_CONTENT_TYPE)) {
      return SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
    } else {
      throw new AxiomSoapMessageCreationException("Unknown content type '" + contentType + "'");
    }
  }

  /**
   * Returns the character set from the given content type. Mostly copied
   *
   * @return the character set encoding
   */
  protected String getCharSetEncoding(String contentType) {
    int charSetIdx = contentType.indexOf(CHARSET_PARAMETER);
    if (charSetIdx == -1) {
      return DEFAULT_CHARSET_ENCODING;
    }
    int eqIdx = contentType.indexOf("=", charSetIdx);

    int indexOfSemiColon = contentType.indexOf(";", eqIdx);
    String value;

    if (indexOfSemiColon > 0) {
      value = contentType.substring(eqIdx + 1, indexOfSemiColon);
    } else {
      value = contentType.substring(eqIdx + 1, contentType.length()).trim();
    }
    if (value.startsWith("\"")) {
      value = value.substring(1);
    }
    if (value.endsWith("\"")) {
      return value.substring(0, value.length() - 1);
    }
    if ("null".equalsIgnoreCase(value)) {
      return DEFAULT_CHARSET_ENCODING;
    } else {
      return value.trim();
    }
  }

  /**
   * Create a {@code XMLInputFactory} that this resolver will use to create {@link XMLStreamReader}
   * objects.
   *
   * <p>Can be overridden in subclasses, adding further initialization of the factory. The resulting
   * factory is cached, so this method will only be called once.
   *
   * <p>By default this method creates a standard {@link XMLInputFactory} and configures it based on
   * the {@link #setReplacingEntityReferences(boolean) replacingEntityReferences} and {@link
   * #setSupportingExternalEntities(boolean) supportingExternalEntities} properties.
   *
   * @return the created factory
   */
  protected XMLInputFactory createXmlInputFactory() {
    XMLInputFactory inputFactory = XMLInputFactory.newInstance();
    inputFactory.setProperty(
        XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, replacingEntityReferences);
    inputFactory.setProperty(
        XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, supportingExternalEntities);
    return inputFactory;
  }

  public String toString() {
    StringBuilder builder = new StringBuilder("AxiomSoapMessageFactory[");
    if (soapFactory.getSOAPVersion() == SOAP11Version.getSingleton()) {
      builder.append("SOAP 1.1");
    } else if (soapFactory.getSOAPVersion() == SOAP12Version.getSingleton()) {
      builder.append("SOAP 1.2");
    }
    builder.append(',');
    if (payloadCaching) {
      builder.append("PayloadCaching enabled");
    } else {
      builder.append("PayloadCaching disabled");
    }
    builder.append(']');
    return builder.toString();
  }
}
  /**
   * Based on the Axis2 client code. Sends the Axis2 Message context out and returns the Axis2
   * message context for the response.
   *
   * <p>Here Synapse works as a Client to the service. It would expect 200 ok, 202 ok and 500
   * internal server error as possible responses.
   *
   * @param endpoint the endpoint being sent to, maybe null
   * @param synapseOutMessageContext the outgoing synapse message
   * @throws AxisFault on errors
   */
  public static void send(
      EndpointDefinition endpoint, org.apache.synapse.MessageContext synapseOutMessageContext)
      throws AxisFault {

    boolean separateListener = false;
    boolean wsSecurityEnabled = false;
    String wsSecPolicyKey = null;
    String inboundWsSecPolicyKey = null;
    String outboundWsSecPolicyKey = null;
    boolean wsRMEnabled = false;
    String wsRMPolicyKey = null;
    boolean wsAddressingEnabled = false;
    String wsAddressingVersion = null;

    if (endpoint != null) {
      separateListener = endpoint.isUseSeparateListener();
      wsSecurityEnabled = endpoint.isSecurityOn();
      wsSecPolicyKey = endpoint.getWsSecPolicyKey();
      inboundWsSecPolicyKey = endpoint.getInboundWsSecPolicyKey();
      outboundWsSecPolicyKey = endpoint.getOutboundWsSecPolicyKey();
      wsRMEnabled = endpoint.isReliableMessagingOn();
      wsRMPolicyKey = endpoint.getWsRMPolicyKey();
      wsAddressingEnabled = endpoint.isAddressingOn() || wsRMEnabled;
      wsAddressingVersion = endpoint.getAddressingVersion();
    }

    if (log.isDebugEnabled()) {
      String to;
      if (endpoint != null && endpoint.getAddress() != null) {
        to = endpoint.getAddress(synapseOutMessageContext);
      } else {
        to = synapseOutMessageContext.getTo().toString();
      }

      log.debug(
          "Sending [add = "
              + wsAddressingEnabled
              + "] [sec = "
              + wsSecurityEnabled
              + "] [rm = "
              + wsRMEnabled
              + (endpoint != null
                  ? "] [mtom = "
                      + endpoint.isUseMTOM()
                      + "] [swa = "
                      + endpoint.isUseSwa()
                      + "] [format = "
                      + endpoint.getFormat()
                      + "] [force soap11="
                      + endpoint.isForceSOAP11()
                      + "] [force soap12="
                      + endpoint.isForceSOAP12()
                      + "] [pox="
                      + endpoint.isForcePOX()
                      + "] [get="
                      + endpoint.isForceGET()
                      + "] [encoding="
                      + endpoint.getCharSetEncoding()
                  : "")
              + "] [to="
              + to
              + "]");
    }

    // save the original message context without altering it, so we can tie the response
    MessageContext originalInMsgCtx =
        ((Axis2MessageContext) synapseOutMessageContext).getAxis2MessageContext();

    // TODO Temp hack: ESB removes the session id from request in a random manner.
    Map headers = (Map) originalInMsgCtx.getProperty(MessageContext.TRANSPORT_HEADERS);
    String session = (String) synapseOutMessageContext.getProperty("LB_COOKIE_HEADER");
    if (session != null) {
      headers.put("Cookie", session);
    }

    // create a new MessageContext to be sent out as this should not corrupt the original
    // we need to create the response to the original message later on
    String preserveAddressingProperty =
        (String) synapseOutMessageContext.getProperty(SynapseConstants.PRESERVE_WS_ADDRESSING);
    MessageContext axisOutMsgCtx = cloneForSend(originalInMsgCtx, preserveAddressingProperty);

    if (log.isDebugEnabled()) {
      log.debug(
          "Message [Original Request Message ID : "
              + synapseOutMessageContext.getMessageID()
              + "]"
              + " [New Cloned Request Message ID : "
              + axisOutMsgCtx.getMessageID()
              + "]");
    }
    // set all the details of the endpoint only to the cloned message context
    // so that we can use the original message context for resending through different endpoints
    if (endpoint != null) {

      if (SynapseConstants.FORMAT_POX.equals(endpoint.getFormat())) {
        axisOutMsgCtx.setDoingREST(true);
        axisOutMsgCtx.setProperty(
            org.apache.axis2.Constants.Configuration.MESSAGE_TYPE,
            org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_XML);
        axisOutMsgCtx.setProperty(
            Constants.Configuration.CONTENT_TYPE,
            org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_XML);

        Object o =
            axisOutMsgCtx.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
        Map _headers = (Map) o;
        if (_headers != null) {
          _headers.remove(HTTP.CONTENT_TYPE);
          _headers.put(
              HTTP.CONTENT_TYPE,
              org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_XML);
        }

      } else if (SynapseConstants.FORMAT_GET.equals(endpoint.getFormat())) {
        axisOutMsgCtx.setDoingREST(true);
        axisOutMsgCtx.setProperty(
            Constants.Configuration.HTTP_METHOD, Constants.Configuration.HTTP_METHOD_GET);
        axisOutMsgCtx.setProperty(
            org.apache.axis2.Constants.Configuration.MESSAGE_TYPE,
            org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_X_WWW_FORM);

      } else if (SynapseConstants.FORMAT_SOAP11.equals(endpoint.getFormat())) {
        axisOutMsgCtx.setDoingREST(false);
        axisOutMsgCtx.removeProperty(org.apache.axis2.Constants.Configuration.MESSAGE_TYPE);
        // We need to set this explicitly here in case the request was not a POST
        axisOutMsgCtx.setProperty(
            Constants.Configuration.HTTP_METHOD, Constants.Configuration.HTTP_METHOD_POST);
        if (axisOutMsgCtx.getSoapAction() == null && axisOutMsgCtx.getWSAAction() != null) {
          axisOutMsgCtx.setSoapAction(axisOutMsgCtx.getWSAAction());
        }
        if (!axisOutMsgCtx.isSOAP11()) {
          SOAPUtils.convertSOAP12toSOAP11(axisOutMsgCtx);
        }
        Object o =
            axisOutMsgCtx.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
        Map _headers = (Map) o;
        if (_headers != null) {
          _headers.remove(HTTP.CONTENT_TYPE);
          _headers.put(
              HTTP.CONTENT_TYPE, org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_TEXT_XML);
        }

      } else if (SynapseConstants.FORMAT_SOAP12.equals(endpoint.getFormat())) {
        axisOutMsgCtx.setDoingREST(false);
        axisOutMsgCtx.removeProperty(org.apache.axis2.Constants.Configuration.MESSAGE_TYPE);
        // We need to set this explicitly here in case the request was not a POST
        axisOutMsgCtx.setProperty(
            Constants.Configuration.HTTP_METHOD, Constants.Configuration.HTTP_METHOD_POST);
        if (axisOutMsgCtx.getSoapAction() == null && axisOutMsgCtx.getWSAAction() != null) {
          axisOutMsgCtx.setSoapAction(axisOutMsgCtx.getWSAAction());
        }
        if (axisOutMsgCtx.isSOAP11()) {
          SOAPUtils.convertSOAP11toSOAP12(axisOutMsgCtx);
        }
        Object o =
            axisOutMsgCtx.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
        Map _headers = (Map) o;
        if (_headers != null) {
          _headers.remove(HTTP.CONTENT_TYPE);
          _headers.put(
              HTTP.CONTENT_TYPE,
              org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML);
        }

      } else if (SynapseConstants.FORMAT_REST.equals(endpoint.getFormat())) {
        /*format=rest is kept only backword compatibility. We no longer needed that.*/
        /* Remove Message Type  for GET and DELETE Request */
        if (originalInMsgCtx.getProperty(Constants.Configuration.HTTP_METHOD) != null) {
          if (originalInMsgCtx
                  .getProperty(Constants.Configuration.HTTP_METHOD)
                  .toString()
                  .equals(Constants.Configuration.HTTP_METHOD_GET)
              || originalInMsgCtx
                  .getProperty(Constants.Configuration.HTTP_METHOD)
                  .toString()
                  .equals(Constants.Configuration.HTTP_METHOD_DELETE)) {
            axisOutMsgCtx.removeProperty(org.apache.axis2.Constants.Configuration.MESSAGE_TYPE);
          }
        }
        axisOutMsgCtx.setDoingREST(true);
      } else {
        processWSDL2RESTRequestMessageType(originalInMsgCtx, axisOutMsgCtx);
      }

      if (endpoint.isUseMTOM()) {
        axisOutMsgCtx.setDoingMTOM(true);
        // fix / workaround for AXIS2-1798
        axisOutMsgCtx.setProperty(
            org.apache.axis2.Constants.Configuration.ENABLE_MTOM,
            org.apache.axis2.Constants.VALUE_TRUE);
        axisOutMsgCtx.setDoingMTOM(true);

      } else if (endpoint.isUseSwa()) {
        axisOutMsgCtx.setDoingSwA(true);
        // fix / workaround for AXIS2-1798
        axisOutMsgCtx.setProperty(
            org.apache.axis2.Constants.Configuration.ENABLE_SWA,
            org.apache.axis2.Constants.VALUE_TRUE);
        axisOutMsgCtx.setDoingSwA(true);
      }

      if (endpoint.getCharSetEncoding() != null) {
        axisOutMsgCtx.setProperty(
            Constants.Configuration.CHARACTER_SET_ENCODING, endpoint.getCharSetEncoding());
        // Need to Clean this up. TargetRequest line 176 contains a code block which over writes the
        // Content-Type returned by the message formatter with the Content-Type in
        // TRANSPORT_HEADERS. Because of that, even when
        // the Character set encoding is set by the message formatter, it will be replaced by the
        // Content-Type header in TRANSPORT_HEADERS.
        // So Im setting a property to check in TargetRequest before over writing the header.
        axisOutMsgCtx.setProperty("EndpointCharEncodingSet", "true");
      }

      // HTTP Endpoint : use the specified HTTP method and remove REST_URL_POSTFIX, it's not
      // supported in HTTP Endpoint
      if (endpoint.isHTTPEndpoint()) {
        axisOutMsgCtx.setProperty(
            Constants.Configuration.HTTP_METHOD,
            synapseOutMessageContext.getProperty(Constants.Configuration.HTTP_METHOD));
        axisOutMsgCtx.removeProperty(NhttpConstants.REST_URL_POSTFIX);
      }

      // add rest request' suffix URI
      String restSuffix = (String) axisOutMsgCtx.getProperty(NhttpConstants.REST_URL_POSTFIX);
      boolean isRest = SynapseConstants.FORMAT_REST.equals(endpoint.getFormat());

      if (!isRest && !endpoint.isForceSOAP11() && !endpoint.isForceSOAP12()) {
        isRest = isRequestRest(originalInMsgCtx);
      }

      if (endpoint.getAddress() != null) {
        String address = endpoint.getAddress(synapseOutMessageContext);
        if (isRest && restSuffix != null && !"".equals(restSuffix)) {

          String url;
          if (!address.endsWith("/")
              && !restSuffix.startsWith("/")
              && !restSuffix.startsWith("?")) {
            url = address + "/" + restSuffix;
          } else if (address.endsWith("/") && restSuffix.startsWith("/")) {
            url = address + restSuffix.substring(1);
          } else if (address.endsWith("/") && restSuffix.startsWith("?")) {
            url = address.substring(0, address.length() - 1) + restSuffix;
          } else {
            url = address + restSuffix;
          }
          axisOutMsgCtx.setTo(new EndpointReference(url));

        } else {
          axisOutMsgCtx.setTo(new EndpointReference(address));
        }
        axisOutMsgCtx.setProperty(NhttpConstants.ENDPOINT_PREFIX, address);
        synapseOutMessageContext.setProperty(SynapseConstants.ENDPOINT_PREFIX, address);
      } else {
        // Supporting RESTful invocation
        if (isRest && restSuffix != null && !"".equals(restSuffix)) {
          EndpointReference epr = axisOutMsgCtx.getTo();
          if (epr != null) {
            String address = epr.getAddress();
            String url;
            if (!address.endsWith("/")
                && !restSuffix.startsWith("/")
                && !restSuffix.startsWith("?")) {
              url = address + "/" + restSuffix;
            } else {
              url = address + restSuffix;
            }
            axisOutMsgCtx.setTo(new EndpointReference(url));
          }
        }
      }

      if (endpoint.isUseSeparateListener()) {
        axisOutMsgCtx.getOptions().setUseSeparateListener(true);
      }
    } else {
      processWSDL2RESTRequestMessageType(originalInMsgCtx, axisOutMsgCtx);
    }

    // only put whttp:location for the REST (GET) requests, otherwise causes issues for POX messages
    if (axisOutMsgCtx.isDoingREST()
        && HTTPConstants.MEDIA_TYPE_X_WWW_FORM.equals(
            axisOutMsgCtx.getProperty(Constants.Configuration.MESSAGE_TYPE))) {
      if (axisOutMsgCtx.getProperty(WSDL2Constants.ATTR_WHTTP_LOCATION) == null
          && axisOutMsgCtx.getEnvelope().getBody().getFirstElement() != null) {
        axisOutMsgCtx.setProperty(
            WSDL2Constants.ATTR_WHTTP_LOCATION,
            axisOutMsgCtx.getEnvelope().getBody().getFirstElement().getQName().getLocalPart());
      }
    }

    if (wsAddressingEnabled) {

      if (wsAddressingVersion != null
          && SynapseConstants.ADDRESSING_VERSION_SUBMISSION.equals(wsAddressingVersion)) {

        axisOutMsgCtx.setProperty(
            AddressingConstants.WS_ADDRESSING_VERSION,
            AddressingConstants.Submission.WSA_NAMESPACE);

      } else if (wsAddressingVersion != null
          && SynapseConstants.ADDRESSING_VERSION_FINAL.equals(wsAddressingVersion)) {

        axisOutMsgCtx.setProperty(
            AddressingConstants.WS_ADDRESSING_VERSION, AddressingConstants.Final.WSA_NAMESPACE);
      }

      axisOutMsgCtx.setProperty(
          AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.FALSE);
    } else {
      axisOutMsgCtx.setProperty(
          AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES, Boolean.TRUE);
    }

    // remove the headers if we don't need to preserve them.
    // determine weather we need to preserve the processed headers
    String preserveHeaderProperty =
        (String) synapseOutMessageContext.getProperty(SynapseConstants.PRESERVE_PROCESSED_HEADERS);
    if (preserveHeaderProperty == null || !Boolean.parseBoolean(preserveHeaderProperty)) {
      // default behaviour is to remove the headers
      MessageHelper.removeProcessedHeaders(
          axisOutMsgCtx,
          (preserveAddressingProperty != null && Boolean.parseBoolean(preserveAddressingProperty)));
    }

    ConfigurationContext axisCfgCtx = axisOutMsgCtx.getConfigurationContext();
    AxisConfiguration axisCfg = axisCfgCtx.getAxisConfiguration();

    AxisService anoymousService =
        AnonymousServiceFactory.getAnonymousService(
            synapseOutMessageContext.getConfiguration(),
            axisCfg,
            wsAddressingEnabled,
            wsRMEnabled,
            wsSecurityEnabled);
    // mark the anon services created to be used in the client side of synapse as hidden
    // from the server side of synapse point of view
    anoymousService.getParent().addParameter(SynapseConstants.HIDDEN_SERVICE_PARAM, "true");
    ServiceGroupContext sgc =
        new ServiceGroupContext(axisCfgCtx, (AxisServiceGroup) anoymousService.getParent());
    ServiceContext serviceCtx = sgc.getServiceContext(anoymousService);

    boolean outOnlyMessage =
        "true".equals(synapseOutMessageContext.getProperty(SynapseConstants.OUT_ONLY));

    // get a reference to the DYNAMIC operation of the Anonymous Axis2 service
    AxisOperation axisAnonymousOperation =
        anoymousService.getOperation(
            outOnlyMessage
                ? new QName(AnonymousServiceFactory.OUT_ONLY_OPERATION)
                : new QName(AnonymousServiceFactory.OUT_IN_OPERATION));

    Options clientOptions = MessageHelper.cloneOptions(originalInMsgCtx.getOptions());
    clientOptions.setUseSeparateListener(separateListener);
    // if RM is requested,
    if (wsRMEnabled) {
      // if a WS-RM policy is specified, use it
      if (wsRMPolicyKey != null) {
        Object property = synapseOutMessageContext.getEntry(wsRMPolicyKey);
        if (property instanceof OMElement) {
          OMElement policyOMElement = (OMElement) property;
          RMAssertionBuilder builder = new RMAssertionBuilder();
          SandeshaPolicyBean sandeshaPolicyBean =
              (SandeshaPolicyBean) builder.build(policyOMElement, null);
          Parameter policyParam =
              new Parameter(Sandesha2Constants.SANDESHA_PROPERTY_BEAN, sandeshaPolicyBean);
          anoymousService.addParameter(policyParam);
        }
      }
    }

    // if security is enabled,
    if (wsSecurityEnabled) {
      // if a WS-Sec policy is specified, use it
      if (wsSecPolicyKey != null) {
        clientOptions.setProperty(
            SynapseConstants.RAMPART_POLICY,
            MessageHelper.getPolicy(synapseOutMessageContext, wsSecPolicyKey));
      } else {
        if (inboundWsSecPolicyKey != null) {
          clientOptions.setProperty(
              SynapseConstants.RAMPART_IN_POLICY,
              MessageHelper.getPolicy(synapseOutMessageContext, inboundWsSecPolicyKey));
        }
        if (outboundWsSecPolicyKey != null) {
          clientOptions.setProperty(
              SynapseConstants.RAMPART_OUT_POLICY,
              MessageHelper.getPolicy(synapseOutMessageContext, outboundWsSecPolicyKey));
        }
      }
      // temporary workaround for https://issues.apache.org/jira/browse/WSCOMMONS-197
      if (axisOutMsgCtx.getEnvelope().getHeader() == null) {
        SOAPFactory fac =
            axisOutMsgCtx.isSOAP11()
                ? OMAbstractFactory.getSOAP11Factory()
                : OMAbstractFactory.getSOAP12Factory();
        fac.createSOAPHeader(axisOutMsgCtx.getEnvelope());
      }
    }

    OperationClient mepClient = axisAnonymousOperation.createClient(serviceCtx, clientOptions);
    mepClient.addMessageContext(axisOutMsgCtx);
    axisOutMsgCtx.setAxisMessage(
        axisAnonymousOperation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE));

    // set the SEND_TIMEOUT for transport sender
    if (endpoint != null && endpoint.getTimeoutDuration() > 0) {
      axisOutMsgCtx.setProperty(SynapseConstants.SEND_TIMEOUT, endpoint.getTimeoutDuration());
    }

    // always set a callback as we decide if the send it blocking or non blocking within
    // the MEP client. This does not cause an overhead, as we simply create a 'holder'
    // object with a reference to the outgoing synapse message context
    // synapseOutMessageContext
    AsyncCallback callback = new AsyncCallback(axisOutMsgCtx, synapseOutMessageContext);
    if (!outOnlyMessage) {
      if (endpoint != null) {
        // set the timeout time and the timeout action to the callback, so that the
        // TimeoutHandler can detect timed out callbacks and take approprite action.
        callback.setTimeOutOn(System.currentTimeMillis() + endpoint.getTimeoutDuration());
        callback.setTimeOutAction(endpoint.getTimeoutAction());
      } else {
        callback.setTimeOutOn(System.currentTimeMillis());
      }
    }
    mepClient.setCallback(callback);
    //
    //        if (Utils.isClientThreadNonBlockingPropertySet(axisOutMsgCtx)) {
    //            SynapseCallbackReceiver synapseCallbackReceiver = (SynapseCallbackReceiver)
    // axisOutMsgCtx.getAxisOperation().getMessageReceiver();
    //            synapseCallbackReceiver.addCallback(axisOutMsgCtx.getMessageID(), new
    // FaultCallback(axisOutMsgCtx, synapseOutMessageContext));
    //        }

    // this is a temporary fix for converting messages from HTTP 1.1 chunking to HTTP 1.0.
    // Without this HTTP transport can block & become unresponsive because we are streaming
    // HTTP 1.1 messages and HTTP 1.0 require the whole message to caculate the content length
    if (originalInMsgCtx.isPropertyTrue(NhttpConstants.FORCE_HTTP_1_0)) {
      synapseOutMessageContext.getEnvelope().toString();
    }

    // with the nio transport, this causes the listener not to write a 202
    // Accepted response, as this implies that Synapse does not yet know if
    // a 202 or 200 response would be written back.
    originalInMsgCtx
        .getOperationContext()
        .setProperty(org.apache.axis2.Constants.RESPONSE_WRITTEN, "SKIP");

    // if the transport out is explicitly set use it
    Object o = originalInMsgCtx.getProperty("TRANSPORT_OUT_DESCRIPTION");
    if (o != null && o instanceof TransportOutDescription) {
      axisOutMsgCtx.setTransportOut((TransportOutDescription) o);
      clientOptions.setTransportOut((TransportOutDescription) o);
      clientOptions.setProperty("TRANSPORT_OUT_DESCRIPTION", o);
    }

    mepClient.execute(true);
    if (wsRMEnabled) {
      Object rm11 = clientOptions.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
      if ((rm11 != null) && rm11.equals(Sandesha2Constants.SPEC_VERSIONS.v1_1)) {
        ServiceClient serviceClient =
            new ServiceClient(
                axisOutMsgCtx.getConfigurationContext(), axisOutMsgCtx.getAxisService());
        serviceClient.setTargetEPR(
            new EndpointReference(endpoint.getAddress(synapseOutMessageContext)));
        serviceClient.setOptions(clientOptions);
        serviceClient
            .getOptions()
            .setTo(new EndpointReference(endpoint.getAddress(synapseOutMessageContext)));
        SandeshaClient.terminateSequence(serviceClient);
      }
    }
  }