Search in sources :

Example 1 with ConcurrentAccessReplicator

use of org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator 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 2 with ConcurrentAccessReplicator

use of org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator in project wso2-synapse by wso2.

the class ConcurrencyThrottlingUtils method decrementConcurrencyThrottleAccessController.

/**
 * Decrement the internal counter for concurrency throttling, in case of normal response retrieval,
 * delayed response at synapse timeout, exceptional cases while mediation end up trigger fault.
 * In clustered environment, replicate the decremented value to other members.
 *
 * @param synCtx Synapse Message Context of which mediation occurs.
 */
public static void decrementConcurrencyThrottleAccessController(MessageContext synCtx) {
    Boolean isConcurrencyThrottleEnabled = (Boolean) synCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE);
    if (isConcurrencyThrottleEnabled != null && isConcurrencyThrottleEnabled) {
        ConcurrentAccessController concurrentAccessController = (ConcurrentAccessController) synCtx.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) synCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENT_ACCESS_REPLICATOR);
        String throttleKey = (String) synCtx.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE_KEY);
        if (concurrentAccessReplicator != null) {
            concurrentAccessReplicator.replicate(throttleKey, true);
        }
        // once decremented, clear the flag since we no longer required to decrement the value
        // concurrency throttle access controller
        synCtx.setProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE, false);
    }
}
Also used : ConcurrentAccessController(org.apache.synapse.commons.throttle.core.ConcurrentAccessController) ConcurrentAccessReplicator(org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator)

Example 3 with ConcurrentAccessReplicator

use of org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator in project wso2-synapse by wso2.

the class ThrottleMediator method init.

public void init(SynapseEnvironment se) {
    if (onAcceptMediator instanceof ManagedLifecycle) {
        ((ManagedLifecycle) onAcceptMediator).init(se);
    } else if (onAcceptSeqKey != null) {
        SequenceMediator onAcceptSeq = (SequenceMediator) se.getSynapseConfiguration().getSequence(onAcceptSeqKey);
        if (onAcceptSeq == null || onAcceptSeq.isDynamic()) {
            se.addUnavailableArtifactRef(onAcceptSeqKey);
        }
    }
    if (onRejectMediator instanceof ManagedLifecycle) {
        ((ManagedLifecycle) onRejectMediator).init(se);
    } else if (onRejectSeqKey != null) {
        SequenceMediator onRejectSeq = (SequenceMediator) se.getSynapseConfiguration().getSequence(onRejectSeqKey);
        if (onRejectSeq == null || onRejectSeq.isDynamic()) {
            se.addUnavailableArtifactRef(onRejectSeqKey);
        }
    }
    // reference to axis2 configuration context
    configContext = ((Axis2SynapseEnvironment) se).getAxis2ConfigurationContext();
    // throttling data holder initialization of
    // runtime throttle data eg :- throttle contexts
    dataHolder = (ThrottleDataHolder) configContext.getProperty(ThrottleConstants.THROTTLE_INFO_KEY);
    if (dataHolder == null) {
        log.debug("Data holder not present in current Configuration Context");
        synchronized (configContext) {
            dataHolder = (ThrottleDataHolder) configContext.getProperty(ThrottleConstants.THROTTLE_INFO_KEY);
            if (dataHolder == null) {
                dataHolder = new ThrottleDataHolder();
                configContext.setNonReplicableProperty(ThrottleConstants.THROTTLE_INFO_KEY, dataHolder);
            }
        }
    }
    // initializes whether clustering is enabled an Env. level
    ClusteringAgent clusteringAgent = configContext.getAxisConfiguration().getClusteringAgent();
    if (clusteringAgent != null) {
        isClusteringEnable = true;
    }
    // static policy initialization
    if (inLinePolicy != null) {
        log.debug("Initializing using static throttling policy : " + inLinePolicy);
        try {
            throttle = ThrottleFactory.createMediatorThrottle(PolicyEngine.getPolicy(inLinePolicy));
            if (throttle != null && concurrentAccessController == null) {
                concurrentAccessController = throttle.getConcurrentAccessController();
                if (concurrentAccessController != null) {
                    dataHolder.setConcurrentAccessController(key, concurrentAccessController);
                }
            }
        } catch (ThrottleException e) {
            handleException("Error processing the throttling policy", e, null);
        }
    }
    // access rate controller initialization
    accessControler = new AccessRateController();
    // replicator for global concurrent state maintenance
    if (isClusteringEnable) {
        concurrentAccessReplicator = new ConcurrentAccessReplicator(configContext);
    }
}
Also used : ThrottleDataHolder(org.apache.synapse.commons.throttle.core.ThrottleDataHolder) ThrottleException(org.apache.synapse.commons.throttle.core.ThrottleException) SequenceMediator(org.apache.synapse.mediators.base.SequenceMediator) AccessRateController(org.apache.synapse.commons.throttle.core.AccessRateController) ClusteringAgent(org.apache.axis2.clustering.ClusteringAgent) ConcurrentAccessReplicator(org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator)

Example 4 with ConcurrentAccessReplicator

use of org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator in project wso2-synapse by wso2.

the class Axis2Sender method handleConcurrentThrottleCount.

/**
 * handles the concurrent access limits
 *
 * @param smc SynapseMessageContext
 */
private static void handleConcurrentThrottleCount(org.apache.synapse.MessageContext smc) {
    Boolean isConcurrencyThrottleEnabled = (Boolean) smc.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE);
    Boolean isAccessAllowed = (Boolean) smc.getProperty(SynapseConstants.SYNAPSE_IS_CONCURRENT_ACCESS_ALLOWED);
    if (isAccessAllowed != null && isAccessAllowed && isConcurrencyThrottleEnabled != null && isConcurrencyThrottleEnabled) {
        ConcurrentAccessController concurrentAccessController = (ConcurrentAccessController) smc.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) smc.getProperty(SynapseConstants.SYNAPSE_CONCURRENT_ACCESS_REPLICATOR);
        String throttleKey = (String) smc.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE_KEY);
        if (concurrentAccessReplicator != null) {
            concurrentAccessReplicator.replicate(throttleKey, true);
        }
    }
}
Also used : ConcurrentAccessController(org.apache.synapse.commons.throttle.core.ConcurrentAccessController) ConcurrentAccessReplicator(org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator)

Example 5 with ConcurrentAccessReplicator

use of org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator in project wso2-synapse by wso2.

the class Axis2FlexibleMEPClient method send.

/**
 * 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;
    boolean wsAddressingEnabled = false;
    String wsAddressingVersion = null;
    if (endpoint != null) {
        separateListener = endpoint.isUseSeparateListener();
        wsSecurityEnabled = endpoint.isSecurityOn();
        wsSecPolicyKey = endpoint.getWsSecPolicyKey();
        inboundWsSecPolicyKey = endpoint.getInboundWsSecPolicyKey();
        outboundWsSecPolicyKey = endpoint.getOutboundWsSecPolicyKey();
        wsAddressingEnabled = endpoint.isAddressingOn();
        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 + (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() + "]");
    }
    // so that we can use the original message context for resending through different endpoints
    if (endpoint != null) {
        // get the endpoint encoding attribute
        String strCharSetEncoding = "";
        if (endpoint.getCharSetEncoding() != null) {
            strCharSetEncoding = ";" + endpoint.getCharSetEncoding();
        }
        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 + strCharSetEncoding);
            }
        } 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 transportHeaders = (Map) o;
            if (transportHeaders != null) {
                // Fix ESBJAVA-3645 Should not do this for multipart/related
                String trpContentType = (String) transportHeaders.get(HTTP.CONTENT_TYPE);
                // if content type is not found, setting the content type
                if (trpContentType == null) {
                    transportHeaders.put(HTTP.CONTENT_TYPE, org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_TEXT_XML + strCharSetEncoding);
                } else if (!trpContentType.contains(PassThroughConstants.CONTENT_TYPE_MULTIPART_RELATED)) {
                    transportHeaders.remove(HTTP.CONTENT_TYPE);
                    try {
                        // ESBJAVA-3447, Appending charset, if exist in property
                        ContentType contentType = new ContentType(trpContentType);
                        if (contentType.getParameter(HTTPConstants.CHAR_SET_ENCODING) != null) {
                            strCharSetEncoding = "; charset=" + contentType.getParameter(HTTPConstants.CHAR_SET_ENCODING);
                        }
                    } catch (ParseException e) {
                        log.warn("Error occurred while parsing ContentType header, using default: " + HTTPConstants.MEDIA_TYPE_TEXT_XML);
                    }
                    transportHeaders.put(HTTP.CONTENT_TYPE, org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_TEXT_XML + strCharSetEncoding);
                }
            }
        } 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 transportHeaders = (Map) o;
            if (transportHeaders != null) {
                // Fix ESBJAVA-3645 Should not do this for multipart/related
                String trpContentType = (String) transportHeaders.get(HTTP.CONTENT_TYPE);
                // if content type is not found, setting the content type
                if (trpContentType == null) {
                    transportHeaders.put(HTTP.CONTENT_TYPE, org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML + strCharSetEncoding);
                } else if (!trpContentType.contains(PassThroughConstants.CONTENT_TYPE_MULTIPART_RELATED)) {
                    transportHeaders.remove(HTTP.CONTENT_TYPE);
                    try {
                        // ESBJAVA-3447, Appending charset, if exist in property
                        ContentType contentType = new ContentType(trpContentType);
                        if (contentType.getParameter(HTTPConstants.CHAR_SET_ENCODING) != null) {
                            strCharSetEncoding = "; charset=" + contentType.getParameter(HTTPConstants.CHAR_SET_ENCODING);
                        }
                    } catch (ParseException e) {
                        log.warn("Error occurred while parsing ContentType header in property, using default: " + HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML);
                    }
                    if (axisOutMsgCtx.getSoapAction() != null) {
                        String actionHeaderPrefix = ";action=\"";
                        String contentTypeWithAction = new StringBuilder(org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML.length() + axisOutMsgCtx.getSoapAction().length() + actionHeaderPrefix.length() + 1).append(org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML).append(actionHeaderPrefix).append(axisOutMsgCtx.getSoapAction()).append('\"').toString();
                        transportHeaders.put(HTTP.CONTENT_TYPE, contentTypeWithAction + strCharSetEncoding);
                    } else {
                        transportHeaders.put(HTTP.CONTENT_TYPE, org.apache.axis2.transport.http.HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML + strCharSetEncoding);
                    }
                }
            }
        } else if (SynapseConstants.FORMAT_REST.equals(endpoint.getFormat())) {
            /* 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());
        }
        // 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 {
                    if (!address.startsWith("jms")) {
                        url = address + restSuffix;
                    } else {
                        url = address;
                    }
                }
                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 security is enabled,
    if (wsSecurityEnabled) {
        // if a WS-Sec policy is specified, use it
        if (wsSecPolicyKey != null) {
            if (endpoint.isDynamicPolicy()) {
                wsSecPolicyKey = endpoint.evaluateDynamicEndpointSecurityPolicy(synapseOutMessageContext);
            }
            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.getEffectiveTimeout() > 0) {
        if (!endpoint.isDynamicTimeoutEndpoint()) {
            axisOutMsgCtx.setProperty(SynapseConstants.SEND_TIMEOUT, endpoint.getEffectiveTimeout());
        } else {
            axisOutMsgCtx.setProperty(SynapseConstants.SEND_TIMEOUT, endpoint.evaluateDynamicEndpointTimeout(synapseOutMessageContext));
        }
    }
    // 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) {
            // TimeoutHandler can detect timed out callbacks and take appropriate action.
            if (!endpoint.isDynamicTimeoutEndpoint()) {
                long endpointTimeout = endpoint.getEffectiveTimeout();
                callback.setTimeout(endpointTimeout);
                callback.setTimeOutAction(endpoint.getTimeoutAction());
                callback.setTimeoutType(endpoint.getEndpointTimeoutType());
                if (log.isDebugEnabled()) {
                    log.debug("Setting Timeout for endpoint : " + getEndpointLogMessage(synapseOutMessageContext, axisOutMsgCtx) + " to static timeout value : " + endpointTimeout);
                }
            } else {
                long endpointTimeout = endpoint.evaluateDynamicEndpointTimeout(synapseOutMessageContext);
                callback.setTimeout(endpointTimeout);
                callback.setTimeOutAction(endpoint.getTimeoutAction());
                callback.setTimeoutType(endpoint.getEndpointTimeoutType());
                if (log.isDebugEnabled()) {
                    log.debug("Setting Timeout for endpoint : " + getEndpointLogMessage(synapseOutMessageContext, axisOutMsgCtx) + " to dynamic timeout value : " + endpointTimeout);
                }
            }
        } else {
            long globalTimeout = synapseOutMessageContext.getEnvironment().getGlobalTimeout();
            callback.setTimeout(globalTimeout);
            callback.setTimeoutType(SynapseConstants.ENDPOINT_TIMEOUT_TYPE.GLOBAL_TIMEOUT);
            if (log.isDebugEnabled()) {
                log.debug("Setting timeout for implicit endpoint : " + getEndpointLogMessage(synapseOutMessageContext, axisOutMsgCtx) + " to global timeout value of " + globalTimeout);
            }
        }
    }
    mepClient.setCallback(callback);
    // 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);
    }
    // clear the message context properties related to endpoint in last service invocation
    Set keySet = synapseOutMessageContext.getPropertyKeySet();
    if (keySet != null) {
        keySet.remove(EndpointDefinition.DYNAMIC_URL_VALUE);
    }
    // throttling count for OUT_ONLY messages
    if (outOnlyMessage) {
        Boolean isConcurrencyThrottleEnabled = (Boolean) synapseOutMessageContext.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE);
        if (isConcurrencyThrottleEnabled != null && isConcurrencyThrottleEnabled) {
            ConcurrentAccessController concurrentAccessController = (ConcurrentAccessController) synapseOutMessageContext.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) synapseOutMessageContext.getProperty(SynapseConstants.SYNAPSE_CONCURRENT_ACCESS_REPLICATOR);
            String throttleKey = (String) synapseOutMessageContext.getProperty(SynapseConstants.SYNAPSE_CONCURRENCY_THROTTLE_KEY);
            if (concurrentAccessReplicator != null) {
                concurrentAccessReplicator.replicate(throttleKey, true);
            }
        }
    }
    mepClient.execute(true);
}
Also used : AxisConfiguration(org.apache.axis2.engine.AxisConfiguration) Options(org.apache.axis2.client.Options) Set(java.util.Set) ContentType(javax.mail.internet.ContentType) AxisOperation(org.apache.axis2.description.AxisOperation) AxisService(org.apache.axis2.description.AxisService) SOAPFactory(org.apache.axiom.soap.SOAPFactory) ConcurrentAccessController(org.apache.synapse.commons.throttle.core.ConcurrentAccessController) MessageContext(org.apache.axis2.context.MessageContext) TransportOutDescription(org.apache.axis2.description.TransportOutDescription) ConfigurationContext(org.apache.axis2.context.ConfigurationContext) OperationClient(org.apache.axis2.client.OperationClient) ServiceContext(org.apache.axis2.context.ServiceContext) QName(javax.xml.namespace.QName) EndpointReference(org.apache.axis2.addressing.EndpointReference) ConcurrentAccessReplicator(org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator) ServiceGroupContext(org.apache.axis2.context.ServiceGroupContext) ParseException(javax.mail.internet.ParseException) Map(java.util.Map)

Aggregations

ConcurrentAccessReplicator (org.apache.synapse.commons.throttle.core.ConcurrentAccessReplicator)6 ConcurrentAccessController (org.apache.synapse.commons.throttle.core.ConcurrentAccessController)5 EndpointReference (org.apache.axis2.addressing.EndpointReference)2 MessageContext (org.apache.axis2.context.MessageContext)2 Map (java.util.Map)1 Set (java.util.Set)1 Stack (java.util.Stack)1 ContentType (javax.mail.internet.ContentType)1 ParseException (javax.mail.internet.ParseException)1 QName (javax.xml.namespace.QName)1 SOAPFactory (org.apache.axiom.soap.SOAPFactory)1 RelatesTo (org.apache.axis2.addressing.RelatesTo)1 OperationClient (org.apache.axis2.client.OperationClient)1 Options (org.apache.axis2.client.Options)1 ClusteringAgent (org.apache.axis2.clustering.ClusteringAgent)1 ConfigurationContext (org.apache.axis2.context.ConfigurationContext)1 ServiceContext (org.apache.axis2.context.ServiceContext)1 ServiceGroupContext (org.apache.axis2.context.ServiceGroupContext)1 AxisOperation (org.apache.axis2.description.AxisOperation)1 AxisService (org.apache.axis2.description.AxisService)1