Search in sources :

Example 1 with SourceConfiguration

use of org.apache.synapse.transport.passthru.config.SourceConfiguration in project wso2-synapse by wso2.

the class MessageHelper method cloneAxis2MessageContext.

/**
 * This method will simulate cloning the message context and creating an exact copy of the
 * passed message. One should use this method with care; that is because, inside the new MC,
 * most of the attributes of the MC like opCtx and so on are still kept as references. Otherwise
 * there will be perf issues. But ..... this may reveal in some conflicts in the cloned message
 * if you try to do advanced mediations with the cloned message, in which case you should
 * manually get a clone of the changing part of the MC and set that cloned part to your MC.
 * Changing the MC after doing that will solve most of the issues. (Note: You don't have to worry
 * about the SOAPEnvelope, it is a cloned copy and not a reference from any other MC)
 *
 * @param mc - this will be cloned for getting an exact copy
 * @param cloneSoapEnvelope The flag to say whether to clone the SOAP envelope or not.
 * @return cloned MessageContext from the given mc
 * @throws AxisFault if there is a failure in copying the certain attributes of the
 *          provided message context
 */
public static org.apache.axis2.context.MessageContext cloneAxis2MessageContext(org.apache.axis2.context.MessageContext mc, boolean cloneSoapEnvelope) throws AxisFault {
    // empty buffer in PASS_THROUGH_PIPE without the message payload.
    try {
        RelayUtils.buildMessage(mc, false);
    } catch (IOException e) {
        handleException(e);
    } catch (XMLStreamException e) {
        handleException(e);
    }
    org.apache.axis2.context.MessageContext newMC = clonePartially(mc);
    if (cloneSoapEnvelope) {
        newMC.setEnvelope(cloneSOAPEnvelope(mc.getEnvelope()));
    }
    // XXX: always this section must come after the above step. ie. after applying Envelope.
    // That is to get the existing headers into the new envelope.
    JsonUtil.cloneJsonPayload(mc, newMC);
    newMC.setOptions(cloneOptions(mc.getOptions()));
    newMC.setServiceContext(mc.getServiceContext());
    newMC.setOperationContext(mc.getOperationContext());
    newMC.setAxisMessage(mc.getAxisMessage());
    if (newMC.getAxisMessage() != null) {
        newMC.getAxisMessage().setParent(mc.getAxisOperation());
    }
    newMC.setAxisService(mc.getAxisService());
    // copying transport related parts from the original
    newMC.setTransportIn(mc.getTransportIn());
    newMC.setTransportOut(mc.getTransportOut());
    newMC.setProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO, mc.getProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO));
    newMC.setProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS, getClonedTransportHeaders(mc));
    if (newMC.getProperty(PassThroughConstants.PASS_THROUGH_PIPE) != null) {
        // clone passthrough pipe here..writer...
        // newMC.setProperty(PassThroughConstants.CLONE_PASS_THROUGH_PIPE_REQUEST,true);
        NHttpServerConnection conn = (NHttpServerConnection) newMC.getProperty("pass-through.Source-Connection");
        if (conn != null) {
            SourceConfiguration sourceConfiguration = (SourceConfiguration) newMC.getProperty("PASS_THROUGH_SOURCE_CONFIGURATION");
            Pipe pipe = new Pipe(conn, sourceConfiguration.getBufferFactory().getBuffer(), "source", sourceConfiguration);
            newMC.setProperty(PassThroughConstants.PASS_THROUGH_PIPE, pipe);
        } else {
            newMC.removeProperty(PassThroughConstants.PASS_THROUGH_PIPE);
        }
    }
    return newMC;
}
Also used : NHttpServerConnection(org.apache.http.nio.NHttpServerConnection) XMLStreamException(javax.xml.stream.XMLStreamException) SourceConfiguration(org.apache.synapse.transport.passthru.config.SourceConfiguration) IOException(java.io.IOException) Pipe(org.apache.synapse.transport.passthru.Pipe)

Example 2 with SourceConfiguration

use of org.apache.synapse.transport.passthru.config.SourceConfiguration in project wso2-synapse by wso2.

the class SynapseCallbackReceiver method handleMessage.

/**
 * Handle the response or error (during a failed send) message received for an outgoing request
 *
 * @param messageID        Request message ID
 * @param response         the Axis2 MessageContext that has been received and has to be handled
 * @param synapseOutMsgCtx the corresponding (outgoing) Synapse MessageContext for the above
 *                         Axis2 MC, that holds Synapse specific information such as the error
 *                         handler stack and local properties etc.
 * @throws AxisFault       if the message cannot be processed
 */
private void handleMessage(String messageID, MessageContext response, org.apache.synapse.MessageContext synapseOutMsgCtx, AsyncCallback callback) throws AxisFault {
    // apply the tenant information to the out message context
    TenantInfoConfigurator configurator = synapseOutMsgCtx.getEnvironment().getTenantInfoConfigurator();
    if (configurator != null) {
        configurator.applyTenantInfo(synapseOutMsgCtx);
    }
    Boolean isConcurrencyThrottleEnabled = (Boolean) synapseOutMsgCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE);
    if (isConcurrencyThrottleEnabled != null && isConcurrencyThrottleEnabled) {
        ConcurrentAccessController concurrentAccessController = (ConcurrentAccessController) synapseOutMsgCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENT_ACCESS_CONTROLLER);
        int available = concurrentAccessController.incrementAndGet();
        int concurrentLimit = concurrentAccessController.getLimit();
        if (log.isDebugEnabled()) {
            log.debug("Concurrency Throttle : Connection returned" + " :: " + available + " of available of " + concurrentLimit + " connections");
        }
        ConcurrentAccessReplicator concurrentAccessReplicator = (ConcurrentAccessReplicator) synapseOutMsgCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENT_ACCESS_REPLICATOR);
        String throttleKey = (String) synapseOutMsgCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE_KEY);
        if (concurrentAccessReplicator != null) {
            concurrentAccessReplicator.replicate(throttleKey, true);
        }
    }
    Object o = response.getProperty(SynapseConstants.SENDING_FAULT);
    if (o != null && Boolean.TRUE.equals(o)) {
        // This path hits with a fault. Sequence mediator threads should not remove faultSequence.
        // SynapseCallbackReceiver thread should handle the faultStack.
        Pipe pipe = (Pipe) ((Axis2MessageContext) synapseOutMsgCtx).getAxis2MessageContext().getProperty(PassThroughConstants.PASS_THROUGH_PIPE);
        if (pipe != null && pipe.isSerializationComplete()) {
            NHttpServerConnection conn = (NHttpServerConnection) ((Axis2MessageContext) synapseOutMsgCtx).getAxis2MessageContext().getProperty("pass-through.Source-Connection");
            SourceConfiguration sourceConfiguration = (SourceConfiguration) ((Axis2MessageContext) synapseOutMsgCtx).getAxis2MessageContext().getProperty("PASS_THROUGH_SOURCE_CONFIGURATION");
            Pipe newPipe = new Pipe(conn, sourceConfiguration.getBufferFactory().getBuffer(), "source", sourceConfiguration);
            ((Axis2MessageContext) synapseOutMsgCtx).getAxis2MessageContext().setProperty(PassThroughConstants.PASS_THROUGH_PIPE, newPipe);
        }
        // there is a sending fault. propagate the fault to fault handlers.
        Stack faultStack = synapseOutMsgCtx.getFaultStack();
        if (faultStack != null && !faultStack.isEmpty()) {
            // fault envelope
            try {
                synapseOutMsgCtx.getEnvelope().build();
            } catch (Exception x) {
                synapseOutMsgCtx.setEnvelope(response.getEnvelope());
            }
            Exception e = (Exception) response.getProperty(SynapseConstants.ERROR_EXCEPTION);
            synapseOutMsgCtx.setProperty(SynapseConstants.SENDING_FAULT, Boolean.TRUE);
            synapseOutMsgCtx.setProperty(SynapseConstants.ERROR_CODE, response.getProperty(SynapseConstants.ERROR_CODE));
            synapseOutMsgCtx.setProperty(SynapseConstants.ERROR_MESSAGE, response.getProperty(SynapseConstants.ERROR_MESSAGE));
            synapseOutMsgCtx.setProperty(SynapseConstants.ERROR_DETAIL, response.getProperty(SynapseConstants.ERROR_DETAIL));
            synapseOutMsgCtx.setProperty(SynapseConstants.ERROR_EXCEPTION, e);
            if (synapseOutMsgCtx.getEnvironment().isContinuationEnabled()) {
                synapseOutMsgCtx.setContinuationEnabled(true);
            }
            if (log.isDebugEnabled()) {
                log.debug("[Failed Request Message ID : " + messageID + "]" + " [New to be Retried Request Message ID : " + synapseOutMsgCtx.getMessageID() + "]");
            }
            int errorCode = (Integer) response.getProperty(SynapseConstants.ERROR_CODE);
            // If a timeout has occured and the timeout action of the callback is to discard the message
            if (errorCode == SynapseConstants.NHTTP_CONNECTION_TIMEOUT && callback.getTimeOutAction() == SynapseConstants.DISCARD) {
                // Do not execute any fault sequences. Discard message
                if (log.isWarnEnabled()) {
                    log.warn("Synapse timed out for the request with Message ID : " + messageID + ". Ignoring fault handlers since the timeout action is DISCARD");
                }
                faultStack.removeAllElements();
            } else {
                ((FaultHandler) faultStack.pop()).handleFault(synapseOutMsgCtx, null);
            }
        }
    } else {
        // there can always be only one instance of an Endpoint in the faultStack of a message
        // if the send was successful, so remove it before we proceed any further
        Stack faultStack = synapseOutMsgCtx.getFaultStack();
        Endpoint successfulEndpoint = null;
        if (faultStack != null && !faultStack.isEmpty() && faultStack.peek() instanceof Endpoint) {
            successfulEndpoint = (Endpoint) faultStack.pop();
        }
        if (log.isDebugEnabled()) {
            log.debug("Synapse received an asynchronous response message");
            log.debug("Received To: " + (response.getTo() != null ? response.getTo().getAddress() : "null"));
            log.debug("SOAPAction: " + (response.getSoapAction() != null ? response.getSoapAction() : "null"));
            log.debug("WSA-Action: " + (response.getWSAAction() != null ? response.getWSAAction() : "null"));
            String[] cids = null;
            try {
                cids = response.getAttachmentMap().getAllContentIDs();
            } catch (Exception ex) {
                // partially read stream could lead to corrupted attachment map and hence this exception
                // corrupted attachment map leads to inconsistent runtime exceptions and behavior
                // discard the attachment map for the fault handler invocation
                // ensure the successful completion for fault handler flow
                response.setAttachmentMap(null);
                log.error("Synapse encountered an exception when reading attachments from bytes stream. " + "Hence Attachments map is dropped from the message context.", ex);
            }
            if (cids != null && cids.length > 0) {
                for (String cid : cids) {
                    log.debug("Attachment : " + cid);
                }
            }
            log.debug("Body : \n" + response.getEnvelope());
        }
        MessageContext axisOutMsgCtx = ((Axis2MessageContext) synapseOutMsgCtx).getAxis2MessageContext();
        // Processes 'Accept-Encoding'
        ResponseAcceptEncodingProcessor.process(response, axisOutMsgCtx);
        response.setServiceContext(null);
        response.setOperationContext(axisOutMsgCtx.getOperationContext());
        response.setAxisMessage(axisOutMsgCtx.getAxisOperation().getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE));
        // set properties on response
        response.setServerSide(true);
        response.setProperty(SynapseConstants.ISRESPONSE_PROPERTY, Boolean.TRUE);
        response.setProperty(MessageContext.TRANSPORT_OUT, axisOutMsgCtx.getProperty(MessageContext.TRANSPORT_OUT));
        response.setProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO, axisOutMsgCtx.getProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO));
        response.setTransportIn(axisOutMsgCtx.getTransportIn());
        response.setTransportOut(axisOutMsgCtx.getTransportOut());
        // response.setDoingREST(axisOutMsgCtx.isDoingREST()); This information already present, hence removing
        if (axisOutMsgCtx.isDoingMTOM() && (axisOutMsgCtx.getProperty(org.apache.axis2.Constants.Configuration.ENABLE_MTOM) == null || Boolean.getBoolean((String) axisOutMsgCtx.getProperty(org.apache.axis2.Constants.Configuration.ENABLE_MTOM)) == true)) {
            response.setDoingMTOM(true);
            response.setProperty(org.apache.axis2.Constants.Configuration.ENABLE_MTOM, org.apache.axis2.Constants.VALUE_TRUE);
        }
        if (axisOutMsgCtx.isDoingSwA()) {
            response.setDoingSwA(true);
            response.setProperty(org.apache.axis2.Constants.Configuration.ENABLE_SWA, org.apache.axis2.Constants.VALUE_TRUE);
        }
        // property state to original state.
        if (axisOutMsgCtx.getProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES) != null) {
            response.setProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES, axisOutMsgCtx.getProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES));
        } else {
            response.removeProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES);
        }
        Object messageType = axisOutMsgCtx.getProperty(org.apache.axis2.Constants.Configuration.MESSAGE_TYPE);
        if (!HTTPConstants.MEDIA_TYPE_X_WWW_FORM.equals(messageType)) {
            // copy the message type property that's used by the out message to the
            // response message
            response.setProperty(org.apache.axis2.Constants.Configuration.MESSAGE_TYPE, messageType);
        }
        if (axisOutMsgCtx.getMessageID() != null) {
            response.setRelationships(new RelatesTo[] { new RelatesTo(axisOutMsgCtx.getMessageID()) });
        }
        response.setReplyTo(axisOutMsgCtx.getReplyTo());
        response.setFaultTo(axisOutMsgCtx.getFaultTo());
        if (axisOutMsgCtx.isPropertyTrue(NhttpConstants.IGNORE_SC_ACCEPTED)) {
            response.setProperty(NhttpConstants.FORCE_SC_ACCEPTED, Constants.VALUE_TRUE);
        }
        // axis2 client options still contains properties such as policy files used in
        // outgoing request. Need to remove those.
        removeUnwantedClientOptions(response);
        // create the synapse message context for the response
        Axis2MessageContext synapseInMessageContext = new Axis2MessageContext(response, synapseOutMsgCtx.getConfiguration(), synapseOutMsgCtx.getEnvironment());
        synapseInMessageContext.setResponse(true);
        Object obj = synapseOutMsgCtx.getProperty(SynapseConstants.FORCE_ERROR_PROPERTY);
        String errorOnSOAPFault = (String) obj;
        if (Constants.VALUE_TRUE.equals(errorOnSOAPFault) && successfulEndpoint != null) {
            if (log.isDebugEnabled()) {
                log.debug("FORCE_ERROR_ON_SOAP_FAULT is true, checking for SOAPFault");
            }
            try {
                RelayUtils.buildMessage(((Axis2MessageContext) synapseInMessageContext).getAxis2MessageContext(), true);
            } catch (Exception e) {
            // handleException("Error while building message", e, synapseInMessageContext);
            }
            if ((synapseInMessageContext.getEnvelope() != null) && synapseInMessageContext.getEnvelope().hasFault()) {
                if (log.isDebugEnabled()) {
                    log.debug("SOAPFault found in response message, forcing endpoint " + successfulEndpoint.getName() + " to fail");
                }
                // setup new pipe configuration..if failure happens (this will be setup as the source writer and during the TargetContext
                // clean up operation the writer will be reset and pull to the buffer
                MessageContext axis2OUTMC = ((Axis2MessageContext) synapseOutMsgCtx).getAxis2MessageContext();
                NHttpServerConnection conn = (NHttpServerConnection) axis2OUTMC.getProperty("pass-through.Source-Connection");
                if (conn != null) {
                    SourceConfiguration sourceConfiguration = (SourceConfiguration) axis2OUTMC.getProperty("PASS_THROUGH_SOURCE_CONFIGURATION");
                    Pipe pipe = new Pipe(conn, sourceConfiguration.getBufferFactory().getBuffer(), "source", sourceConfiguration);
                    axis2OUTMC.setProperty(PassThroughConstants.PASS_THROUGH_PIPE, pipe);
                }
                synapseOutMsgCtx.setProperty(SynapseConstants.SENDING_FAULT, Boolean.TRUE);
                synapseOutMsgCtx.setProperty(SynapseConstants.ERROR_CODE, SynapseConstants.ENDPOINT_CUSTOM_ERROR);
                boolean failOver = false;
                if (successfulEndpoint instanceof AbstractEndpoint) {
                    Endpoint endpoint = ((AbstractEndpoint) successfulEndpoint).getParentEndpoint();
                    if (endpoint != null && (endpoint instanceof FailoverEndpoint)) {
                        failOver = true;
                    }
                }
                for (Object key : synapseOutMsgCtx.getPropertyKeySet()) {
                    synapseInMessageContext.setProperty((String) key, synapseOutMsgCtx.getProperty((String) key));
                }
                if (failOver) {
                    // we may required to handle same message for failover cases only other than that
                    // should treat based on the incoming message
                    ((FaultHandler) successfulEndpoint).handleFault(synapseOutMsgCtx, null);
                } else {
                    faultStack = synapseOutMsgCtx.getFaultStack();
                    if (faultStack != null) {
                        synapseInMessageContext.getFaultStack().addAll(faultStack);
                        ((FaultHandler) successfulEndpoint).handleFault(synapseInMessageContext, null);
                    }
                }
                return;
            } else {
                successfulEndpoint.onSuccess();
            }
        } else if (successfulEndpoint != null) {
            successfulEndpoint.onSuccess();
        }
        synapseInMessageContext.setTo(new EndpointReference(AddressingConstants.Final.WSA_ANONYMOUS_URL));
        synapseInMessageContext.setTracingState(synapseOutMsgCtx.getTracingState());
        synapseInMessageContext.setMessageFlowTracingState(synapseOutMsgCtx.getMessageFlowTracingState());
        for (Object key : synapseOutMsgCtx.getPropertyKeySet()) {
            synapseInMessageContext.setProperty((String) key, synapseOutMsgCtx.getProperty((String) key));
        }
        // Copy SequenceCallStack from original MC to the new MC
        Boolean isContinuationCall = (Boolean) synapseOutMsgCtx.getProperty(SynapseConstants.CONTINUATION_CALL);
        if (isContinuationCall != null && isContinuationCall) {
            // Set the message direction
            if (!synapseOutMsgCtx.isResponse()) {
                synapseInMessageContext.setResponse(false);
            }
            Stack<ContinuationState> seqContinuationStates = synapseOutMsgCtx.getContinuationStateStack();
            for (int i = 0; i < seqContinuationStates.size(); i++) {
                synapseInMessageContext.pushContinuationState(seqContinuationStates.get(i));
            }
        }
        // If this response is related to session affinity endpoints -Server initiated session
        Dispatcher dispatcher = (Dispatcher) synapseOutMsgCtx.getProperty(SynapseConstants.PROP_SAL_ENDPOINT_CURRENT_DISPATCHER);
        if (dispatcher != null && dispatcher.isServerInitiatedSession()) {
            dispatcher.updateSession(synapseInMessageContext);
        }
        // send the response message through the synapse mediation flow
        try {
            synapseOutMsgCtx.getEnvironment().injectMessage(synapseInMessageContext);
        } catch (Exception syne) {
            // introduced to handle runtime exceptions which are occurred inside Synapse handlers
            // partially read stream could lead to corrupted attachment map and hence this exception
            // corrupted attachment map leads to inconsistent runtime exceptions and behavior
            // discard the attachment map for the fault handler invocation
            // ensure the successful completion for fault handler flow
            // even we drop attachment map for both cases messages which have attachment /
            // messages which do not have attachments it would still not be any impact.
            // However setting attachment map to null for messages which do not have attachments is not required.
            // introduced due to the fact conflicts between Axiom exceptions for attachment/ non attachments cases
            // and performance impact that could cause of regular expression matching of exceptional stack traces.
            Axis2MessageContext axis2smc = (Axis2MessageContext) synapseInMessageContext;
            org.apache.axis2.context.MessageContext axis2MessageCtx = axis2smc.getAxis2MessageContext();
            // Set correct status code
            axis2MessageCtx.setProperty(PassThroughConstants.HTTP_SC, HttpStatus.SC_INTERNAL_SERVER_ERROR);
            axis2MessageCtx.setAttachmentMap(null);
            Stack stack = synapseInMessageContext.getFaultStack();
            if (stack != null && stack.isEmpty()) {
                registerFaultHandler(synapseInMessageContext);
            }
            if (stack != null && !stack.isEmpty()) {
                ((FaultHandler) stack.pop()).handleFault(synapseInMessageContext, syne);
            } else {
                log.error("Synapse encountered an exception, " + "No error handlers found - [Message Dropped]\n" + syne.getMessage());
            }
        }
    }
}
Also used : Dispatcher(org.apache.synapse.endpoints.dispatch.Dispatcher) FailoverEndpoint(org.apache.synapse.endpoints.FailoverEndpoint) RelatesTo(org.apache.axis2.addressing.RelatesTo) NHttpServerConnection(org.apache.http.nio.NHttpServerConnection) Endpoint(org.apache.synapse.endpoints.Endpoint) AbstractEndpoint(org.apache.synapse.endpoints.AbstractEndpoint) FailoverEndpoint(org.apache.synapse.endpoints.FailoverEndpoint) ConcurrentAccessController(org.apache.synapse.commons.throttle.core.ConcurrentAccessController) MessageContext(org.apache.axis2.context.MessageContext) FaultHandler(org.apache.synapse.FaultHandler) MediatorFaultHandler(org.apache.synapse.mediators.MediatorFaultHandler) AbstractEndpoint(org.apache.synapse.endpoints.AbstractEndpoint) Pipe(org.apache.synapse.transport.passthru.Pipe) Endpoint(org.apache.synapse.endpoints.Endpoint) AbstractEndpoint(org.apache.synapse.endpoints.AbstractEndpoint) FailoverEndpoint(org.apache.synapse.endpoints.FailoverEndpoint) ConcurrentAccessReplicator(org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator) Stack(java.util.Stack) EndpointReference(org.apache.axis2.addressing.EndpointReference) ContinuationState(org.apache.synapse.ContinuationState) TenantInfoConfigurator(org.apache.synapse.carbonext.TenantInfoConfigurator) SourceConfiguration(org.apache.synapse.transport.passthru.config.SourceConfiguration)

Example 3 with SourceConfiguration

use of org.apache.synapse.transport.passthru.config.SourceConfiguration in project wso2-synapse by wso2.

the class PassThroughHttpSender method submitResponse.

public void submitResponse(MessageContext msgContext) throws IOException, HttpException {
    SourceConfiguration sourceConfiguration = (SourceConfiguration) msgContext.getProperty(PassThroughConstants.PASS_THROUGH_SOURCE_CONFIGURATION);
    NHttpServerConnection conn = (NHttpServerConnection) msgContext.getProperty(PassThroughConstants.PASS_THROUGH_SOURCE_CONNECTION);
    if (conn == null) {
        ServerWorker serverWorker = (ServerWorker) msgContext.getProperty(Constants.OUT_TRANSPORT_INFO);
        if (serverWorker != null) {
            MessageContext requestContext = serverWorker.getRequestContext();
            conn = (NHttpServerConnection) requestContext.getProperty(PassThroughConstants.PASS_THROUGH_SOURCE_CONNECTION);
            sourceConfiguration = (SourceConfiguration) requestContext.getProperty(PassThroughConstants.PASS_THROUGH_SOURCE_CONFIGURATION);
        } else {
            throw new IllegalStateException("Unable to correlate the response to a request");
        }
    }
    // Handle ETag caching
    if (msgContext.getProperty(PassThroughConstants.HTTP_ETAG_ENABLED) != null && (Boolean) msgContext.getProperty(PassThroughConstants.HTTP_ETAG_ENABLED)) {
        try {
            RelayUtils.buildMessage(msgContext);
        } catch (IOException e) {
            handleException("IO Error occurred while building the message", e);
        } catch (XMLStreamException e) {
            handleException("XML Error occurred while building the message", e);
        }
        String hash = digestGenerator.getDigest(msgContext);
        Map headers = (Map) msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
        headers.put(HttpHeaders.ETAG, "\"" + hash + "\"");
    }
    if (msgContext.getProperty(Constants.Configuration.ENABLE_MTOM) != null && !Boolean.TRUE.equals(msgContext.getProperty(PassThroughConstants.MESSAGE_BUILDER_INVOKED))) {
        try {
            RelayUtils.buildMessage(msgContext);
        } catch (IOException e) {
            handleException("IO Error occurred while building the message", e);
        } catch (XMLStreamException e) {
            handleException("XML Error occurred while building the message", e);
        }
    }
    SourceRequest sourceRequest = SourceContext.getRequest(conn);
    if (sourceRequest == null) {
        // this is a special case we dropped source connection where message size exceeds the user defined threshold
        if (conn.getContext().getAttribute(PassThroughConstants.SOURCE_CONNECTION_DROPPED) != null && (Boolean) conn.getContext().getAttribute(PassThroughConstants.SOURCE_CONNECTION_DROPPED)) {
            // already submitted response for this case, hence return
            return;
        }
        log.warn("Trying to submit a response to an already closed connection : " + conn);
        return;
    }
    SourceResponse sourceResponse = SourceResponseFactory.create(msgContext, sourceRequest, sourceConfiguration);
    sourceResponse.checkResponseChunkDisable(msgContext);
    SourceContext.setResponse(conn, sourceResponse);
    Boolean noEntityBody = (Boolean) msgContext.getProperty(PassThroughConstants.NO_ENTITY_BODY);
    Pipe pipe = (Pipe) msgContext.getProperty(PassThroughConstants.PASS_THROUGH_PIPE);
    if ((noEntityBody == null || !noEntityBody) || pipe != null) {
        if (pipe == null) {
            pipe = new Pipe(sourceConfiguration.getBufferFactory().getBuffer(), "Test", sourceConfiguration);
            msgContext.setProperty(PassThroughConstants.PASS_THROUGH_PIPE, pipe);
            msgContext.setProperty(PassThroughConstants.MESSAGE_BUILDER_INVOKED, Boolean.TRUE);
        }
        pipe.attachConsumer(conn);
        sourceResponse.connect(pipe);
    }
    Integer errorCode = (Integer) msgContext.getProperty(PassThroughConstants.ERROR_CODE);
    if (errorCode != null) {
        sourceResponse.setStatus(HttpStatus.SC_BAD_GATEWAY);
        SourceContext.get(conn).setShutDown(true);
    }
    ProtocolState state = SourceContext.getState(conn);
    if (state != null && state.compareTo(ProtocolState.REQUEST_DONE) <= 0) {
        // start sending the response if we
        boolean noEntityBodyResponse = false;
        if (noEntityBody != null && Boolean.TRUE == noEntityBody && pipe != null) {
            OutputStream out = pipe.getOutputStream();
            out.write(new byte[0]);
            pipe.setRawSerializationComplete(true);
            out.close();
            noEntityBodyResponse = true;
        }
        if (!noEntityBodyResponse && msgContext.isPropertyTrue(PassThroughConstants.MESSAGE_BUILDER_INVOKED) && pipe != null) {
            OutputStream out = pipe.getOutputStream();
            // when there is no SOAPAction.
            if (Constants.VALUE_TRUE.equals(msgContext.getProperty(Constants.Configuration.ENABLE_MTOM)) || Constants.VALUE_TRUE.equals(msgContext.getProperty(Constants.Configuration.ENABLE_SWA))) {
                msgContext.setProperty(Constants.Configuration.CONTENT_TYPE, PassThroughConstants.CONTENT_TYPE_MULTIPART_RELATED);
                msgContext.setProperty(Constants.Configuration.MESSAGE_TYPE, PassThroughConstants.CONTENT_TYPE_MULTIPART_RELATED);
            }
            MessageFormatter formatter = MessageFormatterDecoratorFactory.createMessageFormatterDecorator(msgContext);
            OMOutputFormat format = PassThroughTransportUtils.getOMOutputFormat(msgContext);
            Object contentTypeInMsgCtx = msgContext.getProperty(org.apache.axis2.Constants.Configuration.CONTENT_TYPE);
            boolean isContentTypeSetFromMsgCtx = false;
            // If ContentType header is set in the axis2 message context, use it.
            if (contentTypeInMsgCtx != null) {
                String contentTypeValueInMsgCtx = contentTypeInMsgCtx.toString();
                // Skip multipart/related as it should be taken from formatter.
                if (!(contentTypeValueInMsgCtx.contains(PassThroughConstants.CONTENT_TYPE_MULTIPART_RELATED) || contentTypeValueInMsgCtx.contains(PassThroughConstants.CONTENT_TYPE_MULTIPART_FORM_DATA))) {
                    // adding charset only if charset is not available,
                    if (contentTypeValueInMsgCtx.indexOf(HTTPConstants.CHAR_SET_ENCODING) == -1 && format != null) {
                        String encoding = format.getCharSetEncoding();
                        if (encoding != null) {
                            sourceResponse.removeHeader(HTTP.CONTENT_TYPE);
                            contentTypeValueInMsgCtx += "; charset=" + encoding;
                        }
                    }
                    sourceResponse.addHeader(HTTP.CONTENT_TYPE, contentTypeValueInMsgCtx);
                    isContentTypeSetFromMsgCtx = true;
                }
            }
            // If ContentType is not set from msg context, get the formatter ContentType
            if (!isContentTypeSetFromMsgCtx) {
                sourceResponse.removeHeader(HTTP.CONTENT_TYPE);
                sourceResponse.addHeader(HTTP.CONTENT_TYPE, formatter.getContentType(msgContext, format, msgContext.getSoapAction()));
            }
            try {
                formatter.writeTo(msgContext, format, out, false);
            } catch (RemoteException fault) {
                IOUtils.closeQuietly(out);
                throw fault;
            } finally {
                // Serialization should be set as complete so that the state of the socket can be
                // reset to readable
                pipe.setSerializationComplete(true);
            }
            out.close();
        }
        conn.requestOutput();
    } else {
        // nothing much to do as we have started the response already
        if (errorCode != null) {
            if (log.isDebugEnabled()) {
                log.warn("A Source connection is closed because of an " + "error in target: " + conn);
            }
        } else {
            log.debug("A Source Connection is closed, because source handler " + "is already in the process of writing a response while " + "another response is submitted: " + conn);
        }
        pipe.consumerError();
        SourceContext.updateState(conn, ProtocolState.CLOSED);
        sourceConfiguration.getSourceConnections().shutDownConnection(conn, true);
    }
}
Also used : OutputStream(java.io.OutputStream) IOException(java.io.IOException) MessageFormatter(org.apache.axis2.transport.MessageFormatter) NHttpServerConnection(org.apache.http.nio.NHttpServerConnection) XMLStreamException(javax.xml.stream.XMLStreamException) SourceConfiguration(org.apache.synapse.transport.passthru.config.SourceConfiguration) MessageContext(org.apache.axis2.context.MessageContext) OMOutputFormat(org.apache.axiom.om.OMOutputFormat) RemoteException(java.rmi.RemoteException) Map(java.util.Map)

Example 4 with SourceConfiguration

use of org.apache.synapse.transport.passthru.config.SourceConfiguration in project wso2-synapse by wso2.

the class PassThroughHttpListener method init.

public void init(ConfigurationContext cfgCtx, TransportInDescription transportInDescription) throws AxisFault {
    log.info("Initializing Pass-through HTTP/S Listener...");
    pttInDescription = transportInDescription;
    namePrefix = transportInDescription.getName().toUpperCase(Locale.US);
    scheme = initScheme();
    int portOffset = Integer.parseInt(System.getProperty("portOffset", "0"));
    Parameter portParam = transportInDescription.getParameter("port");
    int port = Integer.parseInt(portParam.getValue().toString());
    operatingPort = port + portOffset;
    portParam.setValue(String.valueOf(operatingPort));
    portParam.getParameterElement().setText(String.valueOf(operatingPort));
    System.setProperty(transportInDescription.getName() + ".nio.port", String.valueOf(operatingPort));
    Object obj = cfgCtx.getProperty(PassThroughConstants.PASS_THROUGH_TRANSPORT_WORKER_POOL);
    WorkerPool workerPool = null;
    if (obj != null) {
        workerPool = (WorkerPool) obj;
    }
    PassThroughTransportMetricsCollector metrics = new PassThroughTransportMetricsCollector(true, scheme.getName());
    TransportView view = new TransportView(this, null, metrics, null);
    MBeanRegistrar.getInstance().registerMBean(view, "Transport", "passthru-" + namePrefix.toLowerCase() + "-receiver");
    sourceConfiguration = new SourceConfiguration(cfgCtx, transportInDescription, scheme, workerPool, metrics);
    sourceConfiguration.build();
    HttpHost host = new HttpHost(sourceConfiguration.getHostname(), sourceConfiguration.getPort(), sourceConfiguration.getScheme().getName());
    ServerConnFactoryBuilder connFactoryBuilder = initConnFactoryBuilder(transportInDescription, host);
    connFactory = connFactoryBuilder.build(sourceConfiguration.getHttpParams());
    handler = new SourceHandler(sourceConfiguration);
    passThroughListeningIOReactorManager = PassThroughListeningIOReactorManager.getInstance();
    // register to receive updates on services for lifetime management
    // cfgCtx.getAxisConfiguration().addObservers(axisObserver);
    String prefix = namePrefix + "-Listener I/O dispatcher";
    try {
        ioReactor = (DefaultListeningIOReactor) passThroughListeningIOReactorManager.initIOReactor(operatingPort, handler, new PassThroughSharedListenerConfiguration(new NativeThreadFactory(new ThreadGroup(prefix + " thread group"), prefix), connFactory, sourceConfiguration));
    } catch (IOReactorException e) {
        handleException("Error initiating " + namePrefix + " ListeningIOReactor", e);
    }
    Map<String, String> o = (Map<String, String>) cfgCtx.getProperty(PassThroughConstants.EPR_TO_SERVICE_NAME_MAP);
    if (o != null) {
        this.eprToServiceNameMap = o;
    } else {
        eprToServiceNameMap = new HashMap<String, String>();
        cfgCtx.setProperty(PassThroughConstants.EPR_TO_SERVICE_NAME_MAP, eprToServiceNameMap);
    }
    cfgCtx.setProperty(PassThroughConstants.PASS_THROUGH_TRANSPORT_WORKER_POOL, sourceConfiguration.getWorkerPool());
    /* register to receive updates on services */
    serviceTracker = new AxisServiceTracker(cfgCtx.getAxisConfiguration(), new AxisServiceFilter() {

        public boolean matches(AxisService service) {
            return // these are "private" services
            !service.getName().startsWith("__") && BaseUtils.isUsingTransport(service, pttInDescription.getName());
        }
    }, new AxisServiceTrackerListener() {

        public void serviceAdded(AxisService service) {
            addToServiceURIMap(service);
        }

        public void serviceRemoved(AxisService service) {
            removeServiceFfromURIMap(service);
        }
    });
}
Also used : PassThroughSharedListenerConfiguration(org.apache.synapse.transport.passthru.core.PassThroughSharedListenerConfiguration) AxisServiceFilter(org.apache.axis2.transport.base.tracker.AxisServiceFilter) AxisServiceTrackerListener(org.apache.axis2.transport.base.tracker.AxisServiceTrackerListener) PassThroughTransportMetricsCollector(org.apache.synapse.transport.passthru.jmx.PassThroughTransportMetricsCollector) AxisService(org.apache.axis2.description.AxisService) NativeThreadFactory(org.apache.axis2.transport.base.threads.NativeThreadFactory) IOReactorException(org.apache.http.nio.reactor.IOReactorException) AxisServiceTracker(org.apache.axis2.transport.base.tracker.AxisServiceTracker) WorkerPool(org.apache.axis2.transport.base.threads.WorkerPool) HttpHost(org.apache.http.HttpHost) TransportView(org.apache.synapse.transport.passthru.jmx.TransportView) SourceConfiguration(org.apache.synapse.transport.passthru.config.SourceConfiguration) Parameter(org.apache.axis2.description.Parameter) Map(java.util.Map) HashMap(java.util.HashMap) ServerConnFactoryBuilder(org.apache.synapse.transport.nhttp.config.ServerConnFactoryBuilder)

Example 5 with SourceConfiguration

use of org.apache.synapse.transport.passthru.config.SourceConfiguration in project wso2-synapse by wso2.

the class MessageHelper method cloneAxis2MessageContextForAggregate.

private static org.apache.axis2.context.MessageContext cloneAxis2MessageContextForAggregate(org.apache.axis2.context.MessageContext mc) throws AxisFault {
    org.apache.axis2.context.MessageContext newMC = clonePartiallyForAggregate(mc);
    newMC.setEnvelope(cloneSOAPEnvelope(mc.getEnvelope()));
    newMC.setOptions(cloneOptions(mc.getOptions()));
    newMC.setServiceContext(mc.getServiceContext());
    newMC.setOperationContext(mc.getOperationContext());
    newMC.setAxisMessage(mc.getAxisMessage());
    if (newMC.getAxisMessage() != null) {
        newMC.getAxisMessage().setParent(mc.getAxisOperation());
    }
    newMC.setAxisService(mc.getAxisService());
    // copying transport related parts from the original
    newMC.setTransportIn(mc.getTransportIn());
    newMC.setTransportOut(mc.getTransportOut());
    newMC.setProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO, mc.getProperty(org.apache.axis2.Constants.OUT_TRANSPORT_INFO));
    newMC.setProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS, getClonedTransportHeaders(mc));
    if (newMC.getProperty(PassThroughConstants.PASS_THROUGH_PIPE) != null) {
        // clone passthrough pipe here..writer...
        // newMC.setProperty(PassThroughConstants.CLONE_PASS_THROUGH_PIPE_REQUEST,true);
        NHttpServerConnection conn = (NHttpServerConnection) newMC.getProperty("pass-through.Source-Connection");
        if (conn != null) {
            SourceConfiguration sourceConfiguration = (SourceConfiguration) newMC.getProperty("PASS_THROUGH_SOURCE_CONFIGURATION");
            Pipe pipe = new Pipe(conn, sourceConfiguration.getBufferFactory().getBuffer(), "source", sourceConfiguration);
            newMC.setProperty(PassThroughConstants.PASS_THROUGH_PIPE, pipe);
        }
    }
    return newMC;
}
Also used : NHttpServerConnection(org.apache.http.nio.NHttpServerConnection) SourceConfiguration(org.apache.synapse.transport.passthru.config.SourceConfiguration) Pipe(org.apache.synapse.transport.passthru.Pipe)

Aggregations

SourceConfiguration (org.apache.synapse.transport.passthru.config.SourceConfiguration)5 NHttpServerConnection (org.apache.http.nio.NHttpServerConnection)4 Pipe (org.apache.synapse.transport.passthru.Pipe)3 IOException (java.io.IOException)2 Map (java.util.Map)2 XMLStreamException (javax.xml.stream.XMLStreamException)2 MessageContext (org.apache.axis2.context.MessageContext)2 OutputStream (java.io.OutputStream)1 RemoteException (java.rmi.RemoteException)1 HashMap (java.util.HashMap)1 Stack (java.util.Stack)1 OMOutputFormat (org.apache.axiom.om.OMOutputFormat)1 EndpointReference (org.apache.axis2.addressing.EndpointReference)1 RelatesTo (org.apache.axis2.addressing.RelatesTo)1 AxisService (org.apache.axis2.description.AxisService)1 Parameter (org.apache.axis2.description.Parameter)1 MessageFormatter (org.apache.axis2.transport.MessageFormatter)1 NativeThreadFactory (org.apache.axis2.transport.base.threads.NativeThreadFactory)1 WorkerPool (org.apache.axis2.transport.base.threads.WorkerPool)1 AxisServiceFilter (org.apache.axis2.transport.base.tracker.AxisServiceFilter)1