Package org.wso2.carbon.transport.relay

Source Code of org.wso2.carbon.transport.relay.ServerWorker

/**
*  Copyright (c) 2009, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  Licensed 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.wso2.carbon.transport.relay;

import org.apache.axiom.om.util.UUIDGenerator;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
import org.apache.axis2.Constants;
import org.apache.axis2.AxisFault;
import org.apache.axis2.builder.BuilderUtil;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.transport.TransportUtils;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.axis2.transport.http.HTTPTransportUtils;
import org.apache.axis2.util.MessageContextBuilder;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.protocol.HTTP;
import org.wso2.carbon.transport.relay.config.SourceConfiguration;

import java.util.*;

/**
* This is a worker thread for executing an incoming request in to the transport.
*/
public class ServerWorker implements Runnable {
    private static final Log log = LogFactory.getLog(ServerWorker.class);
    /** the incoming message to be processed */
    private org.apache.axis2.context.MessageContext msgContext = null;
    /** the http request */
    private SourceRequest request = null;
    /** The configuration of the receiver */
    private SourceConfiguration sourceConfiguration = null;

    private static final String SOAP_ACTION_HEADER = "SOAPAction";

    public ServerWorker(final SourceRequest request,
                        final SourceConfiguration sourceConfiguration) {
        this.request = request;
        this.sourceConfiguration = sourceConfiguration;

        this.msgContext = createMessageContext(request);

        // set these properties to be accessed by the engine
        msgContext.setProperty(
                RelayConstants.RELAY_SOURCE_REQUEST, request);
        msgContext.setProperty(
                RelayConstants.RELAY_SOURCE_CONFIGURATION, sourceConfiguration);
        msgContext.setProperty(RelayConstants.RELAY_SOURCE_CONNECTION,
                request.getConnection());
    }

    public void run() {
        if (log.isDebugEnabled()) {
            log.debug("Starting a new Server Worker instance");
        }
        ConfigurationContext cfgCtx = sourceConfiguration.getConfigurationContext();       
        msgContext.setProperty(Constants.Configuration.HTTP_METHOD, request.getMethod());

        String uri = request.getUri();
        String oriUri = uri;

        if (uri.indexOf(cfgCtx.getServicePath()) != -1) {
            // discard upto servicePath
            uri = uri.substring(uri.indexOf(cfgCtx.getServicePath()) +
                    cfgCtx.getServicePath().length());
            // discard [proxy] service name if any
            int pos = uri.indexOf("/", 1);
            if (pos > 0) {
                uri = uri.substring(pos);
            } else {
                pos = uri.indexOf("?");
                if (pos != -1) {
                    uri = uri.substring(pos);
                } else {
                    uri = "";
                }
            }
        } else {
            // remove any absolute prefix if any
            int pos = uri.indexOf("://");
            if (pos != -1) {
                uri = uri.substring(pos + 3);
                pos = uri.indexOf("/");
                if (pos != -1) {
                    uri = uri.substring(pos + 1);
                }
            }
        }

        msgContext.setTo(new EndpointReference(uri));
        msgContext.setProperty(RelayConstants.REST_URL_POSTFIX, uri);

        if (request.isEntityEnclosing()) {
            processEntityEnclosingRequest();
        } else {
            processNonEntityEnclosingMethod();
        }
    }

    private void processNonEntityEnclosingMethod() {
        String soapAction = request.getHeaders().get(SOAP_ACTION_HEADER);
        if ((soapAction != null) && soapAction.startsWith("\"") && soapAction.endsWith("\"")) {
            soapAction = soapAction.substring(1, soapAction.length() - 1);
        }

        msgContext.setSoapAction(soapAction);
        msgContext.setTo(new EndpointReference(request.getUri()));
        msgContext.setServerSide(true);
        msgContext.setDoingREST(true);
        msgContext.setProperty(RelayConstants.NO_ENTITY_BODY, Boolean.TRUE);

        try {
            msgContext.setEnvelope(new SOAP11Factory().getDefaultEnvelope());

            AxisEngine.receive(msgContext);
        } catch (AxisFault axisFault) {
            handleException("Error processing " + request.getMethod() +
                " request for : " + request.getUri(), axisFault);
        }
    }

    private void processEntityEnclosingRequest() {
        try {
            String contentTypeHeader = request.getHeaders().get(HTTP.CONTENT_TYPE);
            contentTypeHeader = contentTypeHeader != null ? contentTypeHeader : inferContentType();

            String charSetEncoding = BuilderUtil.getCharSetEncoding(contentTypeHeader);
            String contentType = TransportUtils.getContentType(contentTypeHeader, msgContext);

            // get the contentType of char encoding
            if (charSetEncoding == null) {
                charSetEncoding = MessageContext.DEFAULT_CHAR_SET_ENCODING;
            }

            msgContext.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING, charSetEncoding);
            msgContext.setProperty(Constants.Configuration.CONTENT_TYPE, contentType);
            msgContext.setProperty(Constants.Configuration.MESSAGE_TYPE, contentType);

            msgContext.setTo(new EndpointReference(request.getUri()));
            msgContext.setProperty(HTTPConstants.HTTP_METHOD, request.getMethod());
            msgContext.setServerSide(true);

            if (HTTPTransportUtils.isRESTRequest(contentTypeHeader)) {

                msgContext.setProperty(RelayConstants.REST_REQUEST_CONTENT_TYPE, contentType);
                msgContext.setDoingREST(true);

                String messageType =
                        (String) msgContext.getProperty(Constants.Configuration.MESSAGE_TYPE);
                if (HTTPConstants.MEDIA_TYPE_X_WWW_FORM.equals(messageType) ||
                        HTTPConstants.MEDIA_TYPE_MULTIPART_FORM_DATA.equals(messageType)) {
                    msgContext.setProperty(Constants.Configuration.MESSAGE_TYPE,
                            HTTPConstants.MEDIA_TYPE_APPLICATION_XML);
                }

                SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
                SOAPEnvelope envelope = fac.getDefaultEnvelope();

                msgContext.setEnvelope(envelope);
            } else {
                String soapAction = request.getHeaders().get(SOAP_ACTION_HEADER);

                int soapVersion = HTTPTransportUtils.
                        initializeMessageContext(msgContext, soapAction,
                                request.getUri(), contentTypeHeader);
                SOAPEnvelope envelope;

                if (soapVersion == 1) {
                    SOAPFactory fac = OMAbstractFactory.getSOAP11Factory();
                    envelope = fac.getDefaultEnvelope();
                } else if (soapVersion == 2) {
                    SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
                    envelope = fac.getDefaultEnvelope();
                } else {
                    SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
                    envelope = fac.getDefaultEnvelope();
                }

                msgContext.setEnvelope(envelope);
            }

            msgContext.setProperty(RelayConstants.RELAY_PIPE, request.getPipe());

            AxisEngine.receive(msgContext);
        } catch (AxisFault axisFault) {
            handleException("Error processing " + request.getMethod() +
                " request for : " + request.getUri(), axisFault);
        }
    }


    /**
     * Create an Axis2 message context for the given http request. The request may be in the
     * process of being streamed
     *
     * @param request the http request to be used to create the corresponding Axis2 message context
     * @return the Axis2 message context created
     */
    private MessageContext createMessageContext(SourceRequest request) {
        ConfigurationContext cfgCtx = sourceConfiguration.getConfigurationContext();
        MessageContext msgContext =
                new MessageContext();
        msgContext.setMessageID(UUIDGenerator.getUUID());

        // Axis2 spawns a new threads to send a message if this is TRUE - and it has to
        // be the other way
        msgContext.setProperty(MessageContext.CLIENT_API_NON_BLOCKING,
                Boolean.FALSE);
        msgContext.setConfigurationContext(cfgCtx);

        msgContext.setTransportOut(cfgCtx.getAxisConfiguration()
                .getTransportOut(Constants.TRANSPORT_HTTP));
        msgContext.setTransportIn(cfgCtx.getAxisConfiguration()
                .getTransportIn(Constants.TRANSPORT_HTTP));
        msgContext.setIncomingTransportName(Constants.TRANSPORT_HTTP);
        msgContext.setProperty(Constants.OUT_TRANSPORT_INFO, this);

        msgContext.setServerSide(true);
        msgContext.setProperty(
                Constants.Configuration.TRANSPORT_IN_URL, request.getUri());

        // http transport header names are case insensitive
        Map<String, String> headers = new TreeMap<String, String>(new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.compareToIgnoreCase(o2);
            }
        });

        Set<Map.Entry<String, String>> entries = request.getHeaders().entrySet();
        for (Map.Entry<String, String> entry : entries) {
            headers.put(entry.getKey(), entry.getValue());
        }
        msgContext.setProperty(MessageContext.TRANSPORT_HEADERS, headers);

        return msgContext;
    }

    private void handleException(String msg, Exception e) {
        if (e == null) {
            log.error(msg);
        } else {
            log.error(msg, e);
        }

        if (e == null) {
            e = new Exception(msg);
        }

        try {
            MessageContext faultContext =
                    MessageContextBuilder.createFaultMessageContext(
                    msgContext, e);
            AxisEngine.sendFault(faultContext);
        } catch (Exception ignored) {}
    }

    private String inferContentType() {
        Parameter param = sourceConfiguration.getConfigurationContext().getAxisConfiguration().
                getParameter(RelayConstants.REQUEST_CONTENT_TYPE);
        if (param != null) {
            return param.getValue().toString();
        }
        return null;
    }
}
TOP

Related Classes of org.wso2.carbon.transport.relay.ServerWorker

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.