Java tutorial
/******************************************************************************* * 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; } } }