org.eclipse.swordfish.internal.core.integration.nmr.SwordfishExchangeListener.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.swordfish.internal.core.integration.nmr.SwordfishExchangeListener.java

Source

/*******************************************************************************
 * Copyright (c) 2008, 2009 SOPERA GmbH.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SOPERA GmbH - initial API and implementation
 *******************************************************************************/
package org.eclipse.swordfish.internal.core.integration.nmr;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jbi.messaging.MessageExchange.Role;
import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.jbi.runtime.impl.MessageExchangeImpl;
import org.apache.servicemix.nmr.api.Exchange;
import org.apache.servicemix.nmr.api.Message;
import org.apache.servicemix.nmr.api.NMR;
import org.apache.servicemix.nmr.api.event.ExchangeListener;
import org.apache.servicemix.nmr.core.ExchangeImpl;
import org.eclipse.swordfish.core.Interceptor;
import org.eclipse.swordfish.core.SwordfishContext;
import org.eclipse.swordfish.core.SwordfishException;
import org.eclipse.swordfish.core.event.TrackingEvent;
import org.eclipse.swordfish.core.planner.Planner;
import org.eclipse.swordfish.core.resolver.EndpointMetadata;
import org.eclipse.swordfish.core.util.Registry;
import org.eclipse.swordfish.internal.core.event.TrackingEventImpl;
import org.eclipse.swordfish.internal.core.exception.InterceptorExceptionNotificationSender;
import org.eclipse.swordfish.internal.core.util.smx.ExchangeRole;
import org.eclipse.swordfish.internal.core.util.smx.JbiConstants;
import org.eclipse.swordfish.internal.core.util.xml.XPathUtil;
import org.eclipse.swordfish.internal.core.util.xml.XmlUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class SwordfishExchangeListener implements ExchangeListener, InitializingBean {

    private transient static final Log LOG = LogFactory.getLog(SwordfishExchangeListener.class);

    private NMR nmr;
    private Planner planner;
    private Interceptor endpointResolverInterceptor;
    private Registry<Interceptor> interceptorRegistry;
    private InterceptorExceptionNotificationSender exceptionNotificationSender;
    private SwordfishContext swordfishContext;

    public Registry<Interceptor> getInterceptorRegistry() {
        return interceptorRegistry;
    }

    public void setInterceptorRegistry(Registry<Interceptor> interceptorRegistry) {
        this.interceptorRegistry = interceptorRegistry;
    }

    public void exchangeDelivered(Exchange exchange) {
        LOG.debug("ExchangeDelivered exchangeId=" + exchange.getId());

    }

    public InterceptorExceptionNotificationSender getExceptionNotificationSender() {
        return exceptionNotificationSender;
    }

    public void setExceptionNotificationSender(InterceptorExceptionNotificationSender exceptionNotificationSender) {
        this.exceptionNotificationSender = exceptionNotificationSender;
    }

    public void exchangeSent(Exchange exchange) {
        MessageExchangeImpl exchangeImpl = new MessageExchangeImpl(exchange);
        try {

            sendTrackingEvent(exchangeImpl);

            // explicitly call EndpointResolverInterceptor before calculating the
            // interceptor chain
            try {
                endpointResolverInterceptor.process(exchangeImpl, null);
            } catch (SwordfishException ex) {
                LOG.warn("The EndpointResolver has thrown exception", ex);
                exceptionNotificationSender.sendNotification(ex, exchangeImpl, endpointResolverInterceptor);
                exchangeImpl.setError(ex);
                // send tracking event
                sendTrackingEvent(exchangeImpl);

                if (exchangeImpl.getRole() == Role.CONSUMER) {
                    throw ex;
                }
            }
            setMessageHeaders(exchangeImpl);

            List<Interceptor> interceptors = planner.getInterceptorChain(interceptorRegistry.getKeySet(),
                    exchangeImpl);
            for (Interceptor interceptor : interceptors) {
                try {
                    QName typeProperty = (QName) interceptor.getProperties().get(Interceptor.TYPE_PROPERTY);
                    @SuppressWarnings("unchecked")
                    Map<String, Object> contextProps = (Map<String, Object>) exchange
                            .getProperty(typeProperty.toString());

                    interceptor.process(exchangeImpl, contextProps);
                } catch (SwordfishException ex) {
                    LOG.warn("The interceptor has thrown exception", ex);
                    exceptionNotificationSender.sendNotification(ex, exchangeImpl, interceptor);

                    exchangeImpl.setError(ex);
                    // send tracking event
                    sendTrackingEvent(exchangeImpl);

                    if (exchangeImpl.getRole() == Role.CONSUMER) {
                        throw ex;
                    }
                }
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private void setMessageHeaders(MessageExchangeImpl me) {
        Exchange exchange = me.getInternalExchange();

        if (ExchangeRole.valueOf(me) == ExchangeRole.ConsumerRequest) {
            processOutgoingRequestHeaders(exchange);
        } else if (ExchangeRole.valueOf(me) == ExchangeRole.ProviderResponse) {
            processOutgoingResponseHeaders(exchange);
        }
    }

    private void processOutgoingRequestHeaders(Exchange exchange) {
        EndpointMetadata<?> metadata = (EndpointMetadata<?>) exchange
                .getProperty(EndpointMetadata.ENDPOINT_METADATA);
        if (metadata == null) {
            return;
        }
        DocumentFragment policy = metadata.toXml();

        // create wsa:ReplyTo SOAP header containing traded policy
        Document doc = XmlUtil.getDocumentBuilder().newDocument();
        Element replyTo = doc.createElementNS(JbiConstants.WSA_NS, JbiConstants.WSA_REPLY_TO_NAME);
        replyTo.setPrefix(JbiConstants.WSA_PREFIX);

        Element addr = doc.createElementNS(JbiConstants.WSA_NS, JbiConstants.WSA_ADDRESS_NAME);
        addr.setPrefix(JbiConstants.WSA_PREFIX);
        addr.appendChild(doc.createTextNode(JbiConstants.WSA_ANONYMOUS));
        replyTo.appendChild(addr);

        Element refParams = doc.createElementNS(JbiConstants.WSA_NS, JbiConstants.WSA_REFERENCE_PARAMS_NAME);
        refParams.setPrefix(JbiConstants.WSA_PREFIX);
        Node policyNode = doc.importNode(policy, true);
        refParams.appendChild(policyNode);
        replyTo.appendChild(refParams);

        DocumentFragment replyToHeader = doc.createDocumentFragment();
        replyToHeader.appendChild(replyTo);

        Map<QName, DocumentFragment> headers = new HashMap<QName, DocumentFragment>();

        QName policyKey = new QName(policy.getFirstChild().getNamespaceURI(),
                policy.getFirstChild().getLocalName());
        headers.put(policyKey, policy);
        headers.put(JbiConstants.WSA_REPLY_TO_QNAME, replyToHeader);

        exchange.getIn(false).setHeader(JbiConstants.SOAP_HEADERS, headers);
    }

    @SuppressWarnings("unchecked")
    private void processOutgoingResponseHeaders(Exchange exchange) {
        Message inMessage = exchange.getIn(false);
        Message outMessage = exchange.getOut(false);

        if (inMessage == null || outMessage == null) {
            LOG.debug("Skip processing of SOAP headers for outgoing response.");
            return;
        }

        Map<QName, DocumentFragment> outHeaders = (Map<QName, DocumentFragment>) outMessage
                .getHeader(JbiConstants.SOAP_HEADERS);
        if (outHeaders == null) {
            outHeaders = new HashMap<QName, DocumentFragment>();
        }

        Map<QName, DocumentFragment> inHeaders = (Map<QName, DocumentFragment>) inMessage
                .getHeader(JbiConstants.SOAP_HEADERS);
        if (inHeaders != null && inHeaders.containsKey(JbiConstants.WSA_REPLY_TO_QNAME)) {
            // include all elements from wsa:ReferenceParameters
            // to SOAP headers of outgoing message
            DocumentFragment replyToFrag = inHeaders.get(JbiConstants.WSA_REPLY_TO_QNAME);
            Node refParams = XPathUtil.getElementByName(replyToFrag, JbiConstants.WSA_REFERENCE_PARAMS_QNAME);
            NodeList params = refParams.getChildNodes();

            for (int i = 0; i < params.getLength(); i++) {
                DocumentFragment fragment = XmlUtil.wrapWithDocumentFragment(params.item(i));
                Node fragmentNode = fragment.getFirstChild();
                QName fragmentName = new QName(fragmentNode.getNamespaceURI(), fragmentNode.getLocalName());
                outHeaders.put(fragmentName, fragment);
            }
        }
        outMessage.setHeader(JbiConstants.SOAP_HEADERS, outHeaders);
    }

    private void sendTrackingEvent(MessageExchangeImpl me) {
        InternalEventExchange eventExchange = new InternalEventExchange(me.getInternalExchange());
        MessageExchangeImpl eventMessageExchange = new MessageExchangeImpl(eventExchange);
        TrackingEvent trackingEvent = new TrackingEventImpl(eventMessageExchange);
        swordfishContext.getEventService().postEvent(trackingEvent);
    }

    public NMR getNmr() {
        return nmr;
    }

    public void setNmr(NMR nmr) {
        this.nmr = nmr;
    }

    public Planner getPlanner() {
        return planner;
    }

    public void setPlanner(Planner planner) {
        this.planner = planner;
    }

    public Interceptor getEndpointResolverInterceptor() {
        return endpointResolverInterceptor;
    }

    public void setEndpointResolverInterceptor(Interceptor endpointResolverInterceptor) {
        this.endpointResolverInterceptor = endpointResolverInterceptor;
    }

    protected void start() {
        nmr.getListenerRegistry().register(this, null);
    }

    public void setSwordfishContext(SwordfishContext swordfishContext) {
        this.swordfishContext = swordfishContext;
    }

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(nmr);
        Assert.notNull(planner);
        Assert.notNull(interceptorRegistry);
        Assert.notNull(swordfishContext);
        start();
    }

    public void exchangeFailed(Exchange arg0) {
        // TODO Auto-generated method stub

    }

    private class InternalEventExchange extends ExchangeImpl {

        private String exchangeId;

        public InternalEventExchange(Exchange exchange) {
            super(exchange.getPattern());
            exchangeId = exchange.getId();

            copyFrom(exchange);
            setOperation(exchange.getOperation());
            setStatus(exchange.getStatus());
        }

        @Override
        public String getId() {
            return exchangeId;
        }
    }
}