You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by on...@apache.org on 2017/11/02 16:33:06 UTC

[camel] branch camel-2.20.x updated: CAMEL-11927 - Improve support for soap header transformations - [Thanks for the PR - Richard Groote(helping to raise a github PR by onders)]

This is an automated email from the ASF dual-hosted git repository.

onders pushed a commit to branch camel-2.20.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-2.20.x by this push:
     new c49b015  CAMEL-11927 - Improve support for soap header transformations - [Thanks for the PR - Richard Groote(helping to raise a github PR by onders)]
c49b015 is described below

commit c49b015e69a6ba101fdd6ce031b7891163b61b5f
Author: onders86 <on...@gmail.com>
AuthorDate: Mon Oct 23 21:32:25 2017 +0300

    CAMEL-11927 - Improve support for soap header transformations - [Thanks for the PR - Richard Groote(helping to raise a github PR by onders)]
---
 .../ws/filter/impl/CompositeMessageFilter.java     |  54 ++++++
 .../impl/HeaderTransformationMessageFilter.java    | 198 +++++++++++++++++++++
 .../component/spring/ws/SoapHeaderTest-context.xml |   9 +
 .../component/spring/ws/soap-header-transform.xslt |  13 ++
 4 files changed, 274 insertions(+)

diff --git a/components/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/filter/impl/CompositeMessageFilter.java b/components/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/filter/impl/CompositeMessageFilter.java
new file mode 100644
index 0000000..c291e4b
--- /dev/null
+++ b/components/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/filter/impl/CompositeMessageFilter.java
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.component.spring.ws.filter.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.spring.ws.filter.MessageFilter;
+import org.springframework.ws.WebServiceMessage;
+
+/**
+ * This filter is a composition of basic message filters
+ */
+public class CompositeMessageFilter implements MessageFilter {
+
+    private List<MessageFilter> filters = new ArrayList<>();
+
+    @Override
+    public void filterProducer(Exchange exchange, WebServiceMessage response) {
+        for (MessageFilter filter : filters) {
+            filter.filterProducer(exchange, response);
+        }
+    }
+
+    @Override
+    public void filterConsumer(Exchange exchange, WebServiceMessage response) {
+        for (MessageFilter filter : filters) {
+            filter.filterConsumer(exchange, response);
+        }
+    }
+
+    public void setFilters(List<MessageFilter> filters) {
+        this.filters = filters;
+    }
+
+    public List<MessageFilter> getFilters() {
+        return filters;
+    }
+}
diff --git a/components/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/filter/impl/HeaderTransformationMessageFilter.java b/components/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/filter/impl/HeaderTransformationMessageFilter.java
new file mode 100644
index 0000000..10bbb33
--- /dev/null
+++ b/components/camel-spring-ws/src/main/java/org/apache/camel/component/spring/ws/filter/impl/HeaderTransformationMessageFilter.java
@@ -0,0 +1,198 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.component.spring.ws.filter.impl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.builder.xml.XsltUriResolver;
+import org.apache.camel.component.spring.ws.filter.MessageFilter;
+import org.apache.camel.component.xslt.XsltComponent;
+import org.apache.camel.component.xslt.XsltEndpoint;
+import org.apache.camel.spi.ClassResolver;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.soap.SoapMessage;
+
+/**
+ * Message filter that transforms the header of a soap message
+ */
+public class HeaderTransformationMessageFilter implements MessageFilter {
+    private static final String SOAP_HEADER_TRANSFORMATION_PROBLEM = "Soap header transformation problem";
+    private static final Logger LOG = LoggerFactory.getLogger(HeaderTransformationMessageFilter.class);
+    private String xslt;
+    private boolean saxon;
+
+    /**
+     * @param xslt
+     */
+    public HeaderTransformationMessageFilter(String xslt) {
+        super();
+        this.xslt = xslt;
+    }
+
+    @Override
+    public void filterProducer(Exchange exchange, WebServiceMessage webServiceMessage) {
+        if (exchange != null) {
+            processHeader(exchange.getContext(), exchange.getIn(), webServiceMessage);
+        }
+    }
+
+    @Override
+    public void filterConsumer(Exchange exchange, WebServiceMessage webServiceMessage) {
+        if (exchange != null) {
+            Message responseMessage = exchange.hasOut() ? exchange.getOut() : exchange.getIn();
+            processHeader(exchange.getContext(), responseMessage, webServiceMessage);
+        }
+    }
+
+    /**
+     * Transform the header
+     * @param context
+     * @param inOrOut
+     * @param webServiceMessage
+     */
+    private void processHeader(CamelContext context, Message inOrOut, WebServiceMessage webServiceMessage) {
+        if (webServiceMessage instanceof SoapMessage) {
+            SoapMessage soapMessage = (SoapMessage) webServiceMessage;
+            try {
+                XsltUriResolver resolver = new XsltUriResolver(context, xslt);
+                Source stylesheetResource = resolver.resolve(xslt, null);
+
+                TransformerFactory transformerFactory = getTransformerFactory(context);
+                Transformer transformer = transformerFactory.newTransformer(stylesheetResource);
+
+                addParameters(inOrOut, transformer);
+                
+                transformer.transform(soapMessage.getSoapHeader().getSource(), soapMessage.getSoapHeader().getResult());
+            } catch (TransformerException e) {
+                throw new RuntimeException("Cannot transform the header of the soap message", e);
+            }
+        }
+    }
+
+    /**
+     * Adding the headers of the message as parameter to the transformer
+     * 
+     * @param inOrOut
+     * @param transformer
+     */
+    private void addParameters(Message inOrOut, Transformer transformer) {
+        Map<String, Object> headers = inOrOut.getHeaders();
+        for (Map.Entry<String, Object> headerEntry : headers.entrySet()) {
+            String key = headerEntry.getKey();
+
+            // Key's with '$' are not allowed in XSLT
+            if (key != null && !key.startsWith("$")) {
+                transformer.setParameter(key, String.valueOf(headerEntry.getValue()));
+            }
+        }
+    }
+
+    /**
+     * Getting a {@link TransformerFactory} with logging
+     *
+     * @return {@link TransformerFactory}
+     */
+    private TransformerFactory getTransformerFactory(CamelContext context) {
+        TransformerFactory transformerFactory = null;
+        if (saxon) {
+            transformerFactory = getSaxonTransformerFactory(context);
+        } else {
+            transformerFactory = TransformerFactory.newInstance();
+        }
+
+        if (transformerFactory == null) {
+            throw new IllegalStateException("Cannot resolve a transformer factory");
+        }
+
+        transformerFactory.setErrorListener(new ErrorListener() {
+
+            @Override
+            public void warning(TransformerException exception) throws TransformerException {
+                LOG.warn(SOAP_HEADER_TRANSFORMATION_PROBLEM, exception);
+            }
+
+            @Override
+            public void fatalError(TransformerException exception) throws TransformerException {
+                LOG.error(SOAP_HEADER_TRANSFORMATION_PROBLEM, exception);
+            }
+
+            @Override
+            public void error(TransformerException exception) throws TransformerException {
+                LOG.error(SOAP_HEADER_TRANSFORMATION_PROBLEM, exception);
+            }
+        });
+
+        return transformerFactory;
+    }
+
+    /**
+     * Loading the saxon transformer class
+     * 
+     * @param context
+     * @return
+     */
+    private TransformerFactory getSaxonTransformerFactory(CamelContext context) {
+        final ClassResolver resolver = context.getClassResolver();
+        try {
+            Class<TransformerFactory> factoryClass = resolver.resolveMandatoryClass(
+                    XsltEndpoint.SAXON_TRANSFORMER_FACTORY_CLASS_NAME, TransformerFactory.class,
+                    XsltComponent.class.getClassLoader());
+
+            if (factoryClass != null) {
+                return ObjectHelper.newInstance(factoryClass);
+            }
+
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Cannot load the saxon transformer class", e);
+        }
+
+        return null;
+    }
+
+    public String getXslt() {
+        return xslt;
+    }
+
+    public void setXslt(String xslt) {
+        this.xslt = xslt;
+    }
+
+    public boolean isSaxon() {
+        return saxon;
+    }
+
+    public void setSaxon(boolean saxon) {
+        this.saxon = saxon;
+    }
+
+}
\ No newline at end of file
diff --git a/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/SoapHeaderTest-context.xml b/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/SoapHeaderTest-context.xml
index 4494911..d707910 100644
--- a/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/SoapHeaderTest-context.xml
+++ b/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/SoapHeaderTest-context.xml
@@ -29,6 +29,11 @@
             <from uri="direct:stockQuoteWebservice"/>
             <to uri="spring-ws:http://localhost?webServiceTemplate=#webServiceTemplate&amp;soapAction=http://www.stockquotes.edu/GetQuote"/>
         </route>
+        
+        <route>
+            <from uri="direct:stockQuoteWebserviceHeaderTransformation"/>
+            <to uri="spring-ws:http://localhost?webServiceTemplate=#webServiceTemplate&amp;soapAction=http://www.stockquotes.edu/GetQuote&amp;messageFilter=#headerTransformationFilter"/>
+        </route>        
 
         <!-- consumer route (providing the actual web service) that responds with the request so we can see SOAP headers -->
         <route>
@@ -51,5 +56,9 @@
             <bean class="net.javacrumbs.springws.test.helper.InMemoryWebServiceMessageSender"/>
         </property>
     </bean>
+    
+    <bean id="headerTransformationFilter" class="org.apache.camel.component.spring.ws.filter.impl.HeaderTransformationMessageFilter">
+    		<constructor-arg index="0" value="org/apache/camel/component/spring/ws/soap-header-transform.xslt"/>
+    </bean>
 
 </beans>
\ No newline at end of file
diff --git a/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/soap-header-transform.xslt b/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/soap-header-transform.xslt
new file mode 100644
index 0000000..06ad8cb
--- /dev/null
+++ b/components/camel-spring-ws/src/test/resources/org/apache/camel/component/spring/ws/soap-header-transform.xslt
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:h="http://www.webserviceX.NET/">
+    <xsl:strip-space elements="*"/>
+    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
+
+	<!-- copy everything else -->
+	<xsl:template match="node()|@*">
+		<xsl:copy>
+			<xsl:copy-of select="@*"/>
+			<xsl:apply-templates select="node()"/>
+		</xsl:copy>
+	</xsl:template>
+</xsl:stylesheet>
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
['"commits@camel.apache.org" <co...@camel.apache.org>'].