Package org.talend.esb.sam.agent.flowidprocessor

Source Code of org.talend.esb.sam.agent.flowidprocessor.FlowIdProducerOut

/*
* #%L
* Service Activity Monitoring :: Agent
* %%
* Copyright (C) 2011 - 2012 Talend Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package org.talend.esb.sam.agent.flowidprocessor;

import java.lang.ref.WeakReference;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.ws.addressing.ContextUtils;
import org.talend.esb.sam.agent.eventproducer.EventProducerInterceptor;
import org.talend.esb.sam.agent.message.FlowIdHelper;

/**
* The Class FlowIdProducerOut used for writing FlowId in outcoming messages.
*
* @param <T>
*            the generic type
*/
public class FlowIdProducerOut<T extends Message> extends
        AbstractPhaseInterceptor<T> {

    private static final Logger LOG = Logger.getLogger(FlowIdProducerOut.class
            .getName());

    /**
     * Instantiates a new flow id producer out.
     */
    public FlowIdProducerOut() {
        super(Phase.USER_LOGICAL);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message
     * .Message)
     */
    public void handleMessage(T message) throws Fault {
        if (LOG.isLoggable(Level.FINEST)) {
            LOG.finest("FlowIdProducerOut Interceptor called. isOutbound: "
                    + MessageUtils.isOutbound(message) + ", isRequestor: "
                    + MessageUtils.isRequestor(message));
        }

        if (MessageUtils.isRequestor(message)) {
            handleRequestOut(message);
        } else {
            handleResponseOut(message);
        }

        // Don't write flowId for Oneway responses
        if (isOnewayResponse(message)) {
            return;
        }

        // write FlowId to HTTP and Soap layer
        String flowId = FlowIdHelper.getFlowId(message);
        FlowIdProtocolHeaderCodec.writeFlowId(message, flowId);
        FlowIdSoapCodec.writeFlowId(message, flowId);

    }

    /**
     * Handling out responce.
     *
     * @param message
     *            the message
     * @throws Fault
     *             the fault
     */
    protected void handleResponseOut(T message) throws Fault {
        Message reqMsg = message.getExchange().getInMessage();
        if (reqMsg == null) {
            LOG.warning("InMessage is null!");
            return;
        }

        // No flowId for oneway message
        Exchange ex = reqMsg.getExchange();
        if (ex.isOneWay()) {
            return;
        }

        String reqFid = FlowIdHelper.getFlowId(reqMsg);

        // if some interceptor throws fault before FlowIdProducerIn fired
        if (reqFid == null) {
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("Some interceptor throws fault.Setting FlowId in response.");
            }
            reqFid = FlowIdProtocolHeaderCodec.readFlowId(message);
        }

        // write IN message to SAM repo in case fault
        if (reqFid == null) {
            Message inMsg = ex.getInMessage();

            reqFid = FlowIdProtocolHeaderCodec.readFlowId(inMsg);
            if (null != reqFid) {
                if (LOG.isLoggable(Level.FINE)) {
                    LOG.fine("FlowId '" + reqFid
                            + "' found in message of fault incoming exchange.");
                    LOG.fine("Calling EventProducerInterceptor to log IN message");
                }
                handleINEvent(ex, reqFid);
            }
        }

        if (reqFid == null) {
            reqFid = FlowIdSoapCodec.readFlowId(message);
        }

        if (reqFid != null) {
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("FlowId '" + reqFid + "' found in incoming message.");
            }
        } else {
            reqFid = ContextUtils.generateUUID();
            // write IN message to SAM repo in case fault
            if (null != ex.getOutFaultMessage()) {
                if (LOG.isLoggable(Level.FINE)) {
                    LOG.fine("FlowId '" + reqFid
                            + "' generated for fault message.");
                    LOG.fine("Calling EventProducerInterceptor to log IN message");
                }
                handleINEvent(ex, reqFid);
            }

            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("No flowId found in incoming message! Generate new flowId "
                        + reqFid);
            }
        }

        FlowIdHelper.setFlowId(message, reqFid);

    }

    /**
     * Handling out request.
     *
     * @param message
     *            the message
     * @throws Fault
     *             the fault
     */
    protected void handleRequestOut(T message) throws Fault {
        String flowId = FlowIdHelper.getFlowId(message);
        if (flowId == null
                && message.containsKey(PhaseInterceptorChain.PREVIOUS_MESSAGE)) {
            // Web Service consumer is acting as an intermediary
            @SuppressWarnings("unchecked")
            WeakReference<Message> wrPreviousMessage = (WeakReference<Message>) message
                    .get(PhaseInterceptorChain.PREVIOUS_MESSAGE);
            Message previousMessage = (Message) wrPreviousMessage.get();
            flowId = FlowIdHelper.getFlowId(previousMessage);
            if (flowId != null && LOG.isLoggable(Level.FINE)) {
                LOG.fine("flowId '" + flowId + "' found in previous message");
            }
        }

        if (flowId == null) {
            // No flowId found. Generate one.
            flowId = ContextUtils.generateUUID();
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("Generate new flowId '" + flowId + "'");
            }
        }

        FlowIdHelper.setFlowId(message, flowId);
    }

    /**
     * Calling EventProducerInterceptor in case of logging faults.
     *
     * @param exchange
     *            the message exchange
     * @param reqFid
     *            the FlowId
     *
     * @throws Fault
     *             the fault
     */
    protected void handleINEvent(Exchange exchange, String reqFid) throws Fault {
        Message inMsg = exchange.getInMessage();

        EventProducerInterceptor epi = null;
        FlowIdHelper.setFlowId(inMsg, reqFid);

        ListIterator<Interceptor<? extends Message>> interceptors = inMsg
                .getInterceptorChain().getIterator();

        while (interceptors.hasNext() && epi == null) {
            Interceptor<? extends Message> interceptor = interceptors.next();

            if (interceptor instanceof EventProducerInterceptor) {
                epi = (EventProducerInterceptor) interceptor;
                epi.handleMessage(inMsg);
            }
        }
    }


    protected boolean isOnewayResponse(T message) {
        boolean isRequestor = MessageUtils.isRequestor(message);
        boolean isFault = MessageUtils.isFault(message);
        boolean isOutbound = MessageUtils.isOutbound(message);

        return (message.getExchange().isOneWay()
                  && ((isOutbound && !isRequestor) || (!isOutbound && isRequestor))
                  && !isFault);
    }
}
TOP

Related Classes of org.talend.esb.sam.agent.flowidprocessor.FlowIdProducerOut

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