Package org.apache.synapse.transport.nhttp

Source Code of org.apache.synapse.transport.nhttp.Axis2HttpRequest

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you under the Apache License, Version 2.0 (the
*  "License"); you may not use this file except in compliance
*  with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*/
package org.apache.synapse.transport.nhttp;

import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.synapse.transport.nhttp.util.PipeImpl;
import org.apache.synapse.transport.nhttp.util.RESTUtil;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.MessageFormatter;
import org.apache.axis2.transport.TransportUtils;
import org.apache.http.*;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.protocol.HTTP;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Map;
import java.util.Iterator;

/**
* Represents an outgoing Axis2 HTTP/s request. It holds the EPR of the destination, the
* Axis2 MessageContext to be sent, an HttpHost object which captures information about the
* destination, and a Pipe used to write the message stream to the destination
*/
public class Axis2HttpRequest {

    private static final Log log = LogFactory.getLog(Axis2HttpRequest.class);

    /** the EPR of the destination */
    private EndpointReference epr = null;
    /** the HttpHost that contains the HTTP connection information */
    private HttpHost httpHost = null;
    /** the message context being sent */
    private MessageContext msgContext = null;
    /** the Pipe which facilitates the serialization output to be written to the channel */
    private PipeImpl pipe = null;
    /** The Axis2 MessageFormatter that will ensure proper serialization as per Axis2 semantics */
    MessageFormatter messageFormatter = null;
    /** The OM Output format holder */
    OMOutputFormat format = null;

    public Axis2HttpRequest(EndpointReference epr, HttpHost httpHost, MessageContext msgContext) {
        this.epr = epr;
        this.httpHost = httpHost;
        this.msgContext = msgContext;
        this.format = NhttpUtils.getOMOutputFormat(msgContext);
        try {
            messageFormatter = TransportUtils.getMessageFormatter(msgContext);
        } catch (AxisFault axisFault) {
            log.error("Cannot find a suitable MessageFormatter : " + axisFault.getMessage());
        }
        try {
            this.pipe = new PipeImpl();
        } catch (IOException e) {
            log.error("Error creating pipe to write message body", e);
        }
    }

    public EndpointReference getEpr() {
        return epr;
    }

    public HttpHost getHttpHost() {
        return httpHost;
    }

    public MessageContext getMsgContext() {
        return msgContext;
    }

    /**
     * Create and return a new HttpPost request to the destination EPR
     * @return the HttpRequest to be sent out
     */
    public HttpRequest getRequest() throws IOException {

        boolean doingGET = Constants.Configuration.HTTP_METHOD_GET.equals(
            msgContext.getProperty(Constants.Configuration.HTTP_METHOD));
        HttpRequest httpRequest = null;
        if (msgContext.isPropertyTrue(NhttpConstants.FORCE_HTTP_1_0)) {
           
            if (doingGET) {
               
                httpRequest = new BasicHttpRequest(
                    "GET", RESTUtil.getURI(
                    msgContext, epr.getAddress()), HttpVersion.HTTP_1_0);
               
            } else {
               
                httpRequest = new BasicHttpEntityEnclosingRequest(
                    "POST", epr.getAddress(), HttpVersion.HTTP_1_0);
               
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                messageFormatter.writeTo(msgContext, format, baos, true);
                BasicHttpEntity entity = new BasicHttpEntity();
                entity.setContentLength(baos.toByteArray().length);
                ((BasicHttpEntityEnclosingRequest) httpRequest).setEntity(entity);
            }


        } else {
           
            if (doingGET) {

                httpRequest = new BasicHttpRequest(
                    "GET", RESTUtil.getURI(msgContext, epr.getAddress()));

            } else {
                httpRequest = new BasicHttpEntityEnclosingRequest("POST", epr.getAddress());
                ((BasicHttpEntityEnclosingRequest) httpRequest).setEntity(new BasicHttpEntity());
            }
        }

        // set any transport headers
        Object o = msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
        if (o != null && o instanceof Map) {
            Map headers = (Map) o;
            Iterator iter = headers.keySet().iterator();
            while (iter.hasNext()) {
                Object header = iter.next();
                Object value = headers.get(header);
                if (header instanceof String && value != null && value instanceof String) {
                    httpRequest.setHeader((String) header, (String) value);
                }
            }
        }

        // if the message is SOAP 11 (for which a SOAPAction is *required*), and
        // the msg context has a SOAPAction or a WSA-Action (give pref to SOAPAction)
        // use that over any transport header that may be available
        String soapAction = msgContext.getSoapAction();
        if (soapAction == null) {
            soapAction = msgContext.getWSAAction();
        }
        if (soapAction == null) {
            msgContext.getAxisOperation().getInputAction();
        }

        if (msgContext.isSOAP11() && soapAction != null &&
            soapAction.length() > 0) {
            Header existingHeader =
                httpRequest.getFirstHeader(HTTPConstants.HEADER_SOAP_ACTION);
            if (existingHeader != null) {
                httpRequest.removeHeader(existingHeader);
            }
            httpRequest.setHeader(HTTPConstants.HEADER_SOAP_ACTION,
                soapAction);
        }

        httpRequest.setHeader(
            HTTP.CONTENT_TYPE,
            messageFormatter.getContentType(msgContext, format, msgContext.getSoapAction()));

        return httpRequest;
    }

    /**
     * Return the source channel of the pipe that bridges the serialized output to the socket
     * @return source channel to read serialized message contents
     */
    public ReadableByteChannel getSourceChannel() {
        if (log.isDebugEnabled()) {
            log.debug("get source channel of the pipe on which the outgoing response is written");
        }
        return pipe.source();
    }

    /**
     * Start streaming the message into the Pipe, so that the contents could be read off the source
     * channel returned by getSourceChannel()
     * @throws AxisFault on error
     */
    public void streamMessageContents() throws AxisFault {

        if (log.isDebugEnabled()) {
            log.debug("start streaming outgoing http request");
        }
        OutputStream out = Channels.newOutputStream(pipe.sink());

        messageFormatter.writeTo(msgContext, format, out, true);
            try {
            out.flush();
            out.close();
        } catch (IOException e) {
            handleException("Error closing outgoing message stream", e);
        }
    }

    // -------------- utility methods -------------
    private void handleException(String msg, Exception e) throws AxisFault {
        log.error(msg, e);
        throw new AxisFault(msg, e);
    }
}
TOP

Related Classes of org.apache.synapse.transport.nhttp.Axis2HttpRequest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.