You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2015/08/12 17:28:18 UTC

camel git commit: CAMEL-9066 Include any headers unmarshalled by SoapJaxbDataFormat in content marshalled by the same with thanks to Bob

Repository: camel
Updated Branches:
  refs/heads/master 9f245c2de -> 99a036b1d


CAMEL-9066 Include any headers unmarshalled by SoapJaxbDataFormat in content marshalled by the same with thanks to Bob


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/99a036b1
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/99a036b1
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/99a036b1

Branch: refs/heads/master
Commit: 99a036b1de51241fa771eff7864f20bd3a72e665
Parents: 9f245c2
Author: Willem Jiang <wi...@gmail.com>
Authored: Wed Aug 12 23:27:15 2015 +0800
Committer: Willem Jiang <wi...@gmail.com>
Committed: Wed Aug 12 23:28:01 2015 +0800

----------------------------------------------------------------------
 components/camel-soap/pom.xml                   |  36 +++++++
 .../soap/Soap11DataFormatAdapter.java           |  16 ++-
 .../soap/Soap12DataFormatAdapter.java           |  16 ++-
 .../dataformat/soap/SoapJaxbDataFormat.java     |   6 +-
 .../soap/SoapToSoapDontIgnoreTest.java          | 103 +++++++++++++++++++
 .../dataformat/soap/SoapToSoapIgnoreTest.java   | 103 +++++++++++++++++++
 .../soap/SoapToSoapSingleDataFormatterTest.java |  95 +++++++++++++++++
 .../dataformat/soap/SoapMarshalHeadersTest.xml  |  33 ++++++
 .../apache/camel/dataformat/soap/contact.xsd    |  33 ++++++
 .../dataformat/soap/custom-soap-headers.xsd     |  49 +++++++++
 .../camel/dataformat/soap/xjc-bindings.xml      |  11 ++
 11 files changed, 488 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-soap/pom.xml b/components/camel-soap/pom.xml
index 9c98122..9e0ce3e 100644
--- a/components/camel-soap/pom.xml
+++ b/components/camel-soap/pom.xml
@@ -120,6 +120,42 @@
             
             <plugin>
                 <groupId>org.apache.cxf</groupId>
+                <artifactId>cxf-xjc-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>generate-sources-jaxb</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>xsdtojava-tests</goal>
+                        </goals>
+                        <configuration>
+                            <testSourceRoot>${basedir}/target/generated/src/test/java</testSourceRoot>
+                            <xsdOptions>
+                                <xsdOption>
+                                    <extension>true</extension>
+                                    <xsd>
+                                        ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd
+                                    </xsd>
+                                    <bindingFile>
+                                        ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
+                                    </bindingFile>
+                                </xsdOption>
+                                <xsdOption>
+                                    <extension>true</extension>
+                                    <xsd>
+                                        ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd
+                                    </xsd>
+                                    <bindingFile>
+                                        ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
+                                    </bindingFile>
+                                </xsdOption>
+                            </xsdOptions>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.cxf</groupId>
                 <artifactId>cxf-codegen-plugin</artifactId>
                 <executions>
                     <execution>

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap11DataFormatAdapter.java
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap11DataFormatAdapter.java b/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap11DataFormatAdapter.java
index 2af00ff..8242e5e 100644
--- a/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap11DataFormatAdapter.java
+++ b/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap11DataFormatAdapter.java
@@ -70,19 +70,25 @@ public class Soap11DataFormatAdapter implements SoapDataFormatAdapter {
             exception = exchange.getIn().getHeader(Exchange.EXCEPTION_CAUGHT, Throwable.class);
         }
 
-        final List<JAXBElement<?>> bodyContent;
-        List<JAXBElement<?>> headerContent = new ArrayList<JAXBElement<?>>();
+        final List<Object> bodyContent;
+        List<Object> headerContent = new ArrayList<Object>();
         if (exception != null) {
-            bodyContent = new ArrayList<JAXBElement<?>>();
+            bodyContent = new ArrayList<Object>();
             bodyContent.add(createFaultFromException(exception));
         } else {
+            if (!dataFormat.isIgnoreUnmarshalledHeaders()) {
+                List<Object> inboundSoapHeaders = (List<Object>) exchange.getIn().getHeader(SoapJaxbDataFormat.SOAP_UNMARSHALLED_HEADER_LIST);
+                if (null != inboundSoapHeaders) {
+                    headerContent.addAll(inboundSoapHeaders);
+                }
+            }
             bodyContent = getDataFormat().createContentFromObject(inputObject, soapAction, headerContent);
         }
 
-        for (JAXBElement<?> elem : bodyContent) {
+        for (Object elem : bodyContent) {
             body.getAny().add(elem);
         }
-        for (JAXBElement<?> elem : headerContent) {
+        for (Object elem : headerContent) {
             header.getAny().add(elem);
         }
         Envelope envelope = new Envelope();

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap12DataFormatAdapter.java
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap12DataFormatAdapter.java b/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap12DataFormatAdapter.java
index 9ce0599c..cd63c79 100644
--- a/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap12DataFormatAdapter.java
+++ b/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/Soap12DataFormatAdapter.java
@@ -73,19 +73,25 @@ public class Soap12DataFormatAdapter implements SoapDataFormatAdapter {
             exception = exchange.getIn().getHeader(Exchange.EXCEPTION_CAUGHT, Throwable.class);
         }
 
-        final List<JAXBElement<?>> bodyContent;
-        List<JAXBElement<?>> headerContent = new ArrayList<JAXBElement<?>>();
+        final List<Object> bodyContent;
+        List<Object> headerContent = new ArrayList<Object>();
         if (exception != null) {
-            bodyContent = new ArrayList<JAXBElement<?>>();
+            bodyContent = new ArrayList<Object>();
             bodyContent.add(createFaultFromException(exception));
         } else {
+            if (!dataFormat.isIgnoreUnmarshalledHeaders()) {
+                List<Object> inboundSoapHeaders = (List<Object>) exchange.getIn().getHeader(SoapJaxbDataFormat.SOAP_UNMARSHALLED_HEADER_LIST);
+                if (null != inboundSoapHeaders) {
+                    headerContent.addAll(inboundSoapHeaders);
+                }
+            }
             bodyContent = getDataFormat().createContentFromObject(inputObject, soapAction, headerContent);
         }
 
-        for (JAXBElement<?> elem : bodyContent) {
+        for (Object elem : bodyContent) {
             body.getAny().add(elem);
         }
-        for (JAXBElement<?> elem : headerContent) {
+        for (Object elem : headerContent) {
             header.getAny().add(elem);
         }
         Envelope envelope = new Envelope();

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java b/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
index 4bb5969..cdc3a5e 100644
--- a/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
+++ b/components/camel-soap/src/main/java/org/apache/camel/dataformat/soap/SoapJaxbDataFormat.java
@@ -163,8 +163,8 @@ public class SoapJaxbDataFormat extends JaxbDataFormat {
      *            
      * @return JAXBElement for the body content
      */
-    protected List<JAXBElement<?>> createContentFromObject(final Object inputObject, String soapAction,
-                                                         List<JAXBElement<?>> headerElements) {
+    protected List<Object> createContentFromObject(final Object inputObject, String soapAction,
+                                                         List<Object> headerElements) {
         List<Object> bodyParts = new ArrayList<Object>();
         List<Object> headerParts = new ArrayList<Object>();
         if (inputObject instanceof BeanInvocation) {
@@ -206,7 +206,7 @@ public class SoapJaxbDataFormat extends JaxbDataFormat {
             bodyParts.add(inputObject);
         }
 
-        List<JAXBElement<?>> bodyElements = new ArrayList<JAXBElement<?>>();
+        List<Object> bodyElements = new ArrayList<Object>();
         for (Object bodyObj : bodyParts) {
             QName name = elementNameStrategy.findQNameForSoapActionOrType(soapAction, bodyObj.getClass());
             if (name == null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java b/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java
new file mode 100644
index 0000000..2c363eb
--- /dev/null
+++ b/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java
@@ -0,0 +1,103 @@
+/**
+ * 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.dataformat.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SoapToSoapDontIgnoreTest extends CamelTestSupport {
+    private static SoapJaxbDataFormat soapjaxbModel;
+    private static SoapJaxbDataFormat soapjaxbModelDontIgnoreUnmarshalled;
+    private static Map<String, String> namespacePrefixMap;
+
+    @BeforeClass
+    public static void setup() {
+        namespacePrefixMap = new HashMap<String, String>();
+        namespacePrefixMap.put("http://schemas.xmlsoap.org/soap/envelope/", "soap");
+        namespacePrefixMap.put("http://www.w3.org/2001/XMLSchema", "xsd");
+        namespacePrefixMap.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
+        namespacePrefixMap.put("http://www.example.com/contact", "cont");
+        namespacePrefixMap.put("http://www.example.com/soapheaders", "custom");
+        soapjaxbModel = new SoapJaxbDataFormat("com.example.contact:com.example.soapheaders");
+        soapjaxbModel.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModel.setPrettyPrint(true);
+        soapjaxbModel.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModel.setIgnoreJAXBElement(false);
+        soapjaxbModel.setElementNameStrategy(new TypeNameStrategy());
+        soapjaxbModelDontIgnoreUnmarshalled = new SoapJaxbDataFormat(
+                                                                     "com.example.contact:com.example.soapheaders");
+        soapjaxbModelDontIgnoreUnmarshalled.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModelDontIgnoreUnmarshalled.setPrettyPrint(true);
+        soapjaxbModelDontIgnoreUnmarshalled.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModelDontIgnoreUnmarshalled.setElementNameStrategy(new TypeNameStrategy());
+    }
+
+    @AfterClass
+    public static void teardown() {
+        soapjaxbModel = null;
+        namespacePrefixMap = null;
+    }
+
+    @Test
+    public void testSoapMarshal() throws Exception {
+        MockEndpoint endpoint = getMockEndpoint("mock:end");
+        endpoint.setExpectedMessageCount(1);
+
+        template.sendBody("direct:start", createRequest());
+
+        assertMockEndpointsSatisfied();
+        Exchange result = endpoint.assertExchangeReceived(0);
+
+        byte[] body = (byte[])result.getIn().getBody();
+        InputStream stream = new ByteArrayInputStream(body);
+        SOAPMessage request = MessageFactory.newInstance().createMessage(null, stream);
+        assertTrue("Expected headers", null != request.getSOAPHeader()
+                                       && request.getSOAPHeader().extractAllHeaderElements().hasNext());
+    }
+
+    private InputStream createRequest() throws Exception {
+        InputStream stream = this.getClass().getResourceAsStream("SoapMarshalHeadersTest.xml");
+        return stream;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        context.getProperties().put(Exchange.LOG_DEBUG_BODY_MAX_CHARS, "0");
+        context.setTracing(true);
+
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start").unmarshal(soapjaxbModel).marshal(soapjaxbModelDontIgnoreUnmarshalled)
+                    .to("mock:end");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java b/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java
new file mode 100644
index 0000000..0afa0b2
--- /dev/null
+++ b/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java
@@ -0,0 +1,103 @@
+/**
+ * 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.dataformat.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SoapToSoapIgnoreTest extends CamelTestSupport {
+    private static SoapJaxbDataFormat soapjaxbModel;
+    private static SoapJaxbDataFormat soapjaxbModelIgnoreUnmarshalled;
+    private static Map<String, String> namespacePrefixMap;
+
+    @BeforeClass
+    public static void setup() {
+        namespacePrefixMap = new HashMap<String, String>();
+        namespacePrefixMap.put("http://schemas.xmlsoap.org/soap/envelope/", "soap");
+        namespacePrefixMap.put("http://www.w3.org/2001/XMLSchema", "xsd");
+        namespacePrefixMap.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
+        namespacePrefixMap.put("http://www.example.com/contact", "cont");
+        namespacePrefixMap.put("http://www.example.com/soapheaders", "custom");
+        soapjaxbModel = new SoapJaxbDataFormat("com.example.contact:com.example.soapheaders");
+        soapjaxbModel.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModel.setPrettyPrint(true);
+        soapjaxbModel.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModel.setIgnoreJAXBElement(false);
+        soapjaxbModel.setElementNameStrategy(new TypeNameStrategy());
+        soapjaxbModelIgnoreUnmarshalled = new SoapJaxbDataFormat(
+                                                                 "com.example.contact:com.example.soapheaders");
+        soapjaxbModelIgnoreUnmarshalled.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModelIgnoreUnmarshalled.setPrettyPrint(true);
+        soapjaxbModelIgnoreUnmarshalled.setIgnoreUnmarshalledHeaders(true);
+        soapjaxbModelIgnoreUnmarshalled.setElementNameStrategy(new TypeNameStrategy());
+    }
+
+    @AfterClass
+    public static void teardown() {
+        soapjaxbModel = null;
+        namespacePrefixMap = null;
+    }
+
+    @Test
+    public void testSoapMarshal() throws Exception {
+        MockEndpoint endpoint = getMockEndpoint("mock:end");
+        endpoint.setExpectedMessageCount(1);
+
+        template.sendBody("direct:start", createRequest());
+
+        assertMockEndpointsSatisfied();
+        Exchange result = endpoint.assertExchangeReceived(0);
+
+        byte[] body = (byte[])result.getIn().getBody();
+        InputStream stream = new ByteArrayInputStream(body);
+        SOAPMessage request = MessageFactory.newInstance().createMessage(null, stream);
+        assertTrue("Expected no headers", null == request.getSOAPHeader()
+                                          || !request.getSOAPHeader().extractAllHeaderElements().hasNext());
+    }
+
+    private InputStream createRequest() throws Exception {
+        InputStream stream = this.getClass().getResourceAsStream("SoapMarshalHeadersTest.xml");
+        return stream;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        context.getProperties().put(Exchange.LOG_DEBUG_BODY_MAX_CHARS, "0");
+        context.setTracing(true);
+
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start").unmarshal(soapjaxbModel).marshal(soapjaxbModelIgnoreUnmarshalled)
+                    .to("mock:end");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java b/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java
new file mode 100644
index 0000000..8bc0adc
--- /dev/null
+++ b/components/camel-soap/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java
@@ -0,0 +1,95 @@
+/**
+ * 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.dataformat.soap;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SoapToSoapSingleDataFormatterTest extends CamelTestSupport {
+    private static SoapJaxbDataFormat soapjaxbModel;
+    private static Map<String, String> namespacePrefixMap;
+
+    @BeforeClass
+    public static void setup() {
+        namespacePrefixMap = new HashMap<String, String>();
+        namespacePrefixMap.put("http://schemas.xmlsoap.org/soap/envelope/", "soap");
+        namespacePrefixMap.put("http://www.w3.org/2001/XMLSchema", "xsd");
+        namespacePrefixMap.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
+        namespacePrefixMap.put("http://www.example.com/contact", "cont");
+        namespacePrefixMap.put("http://www.example.com/soapheaders", "custom");
+        soapjaxbModel = new SoapJaxbDataFormat("com.example.contact:com.example.soapheaders");
+        soapjaxbModel.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModel.setPrettyPrint(true);
+        soapjaxbModel.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModel.setIgnoreJAXBElement(false);
+        soapjaxbModel.setElementNameStrategy(new TypeNameStrategy());
+    }
+
+    @AfterClass
+    public static void teardown() {
+        soapjaxbModel = null;
+        namespacePrefixMap = null;
+    }
+
+    @Test
+    public void testSoapMarshal() throws Exception {
+        MockEndpoint endpoint = getMockEndpoint("mock:end");
+        endpoint.setExpectedMessageCount(1);
+
+        template.sendBody("direct:start", createRequest());
+
+        assertMockEndpointsSatisfied();
+        Exchange result = endpoint.assertExchangeReceived(0);
+
+        byte[] body = (byte[])result.getIn().getBody();
+        InputStream stream = new ByteArrayInputStream(body);
+        SOAPMessage request = MessageFactory.newInstance().createMessage(null, stream);
+        assertTrue("Expected headers", null != request.getSOAPHeader()
+                                       && request.getSOAPHeader().extractAllHeaderElements().hasNext());
+    }
+
+    private InputStream createRequest() throws Exception {
+        InputStream stream = this.getClass().getResourceAsStream("SoapMarshalHeadersTest.xml");
+        return stream;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        context.getProperties().put(Exchange.LOG_DEBUG_BODY_MAX_CHARS, "0");
+        context.setTracing(true);
+
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct:start").unmarshal(soapjaxbModel).marshal(soapjaxbModel).to("mock:end");
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalHeadersTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalHeadersTest.xml b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalHeadersTest.xml
new file mode 100644
index 0000000..f40f7f0
--- /dev/null
+++ b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalHeadersTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+    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.
+
+-->
+<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cont="http://www.example.com/contact">
+    <env:Header>
+        <custom:comment
+            env:actor="http://schemas.xmlsoap.org/soap/actor/next"
+            env:mustUnderstand="0" xmlns:custom="http://www.example.com/soapheaders">gotcha</custom:comment>
+    </env:Header>
+    <env:Body>
+        <cont:contact>
+            <name>Smith</name>
+            <numOrders>0</numOrders>
+            <revenue>100000.0</revenue>
+        </cont:contact>
+    </env:Body>
+</env:Envelope>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd
new file mode 100644
index 0000000..c67fe95
--- /dev/null
+++ b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	xmlns:tns="http://www.example.com/contact" attributeFormDefault="unqualified"
+	elementFormDefault="unqualified" targetNamespace="http://www.example.com/contact">
+	<xs:element name="contact" type="tns:contact" />
+		<xs:complexType name="contact">
+			<xs:sequence>
+				<xs:element minOccurs="0" name="name" type="xs:string" />
+				<xs:element maxOccurs="unbounded" minOccurs="0" name="address"
+					nillable="true" type="xs:string" />
+				<xs:element name="numOrders" type="xs:int" />
+				<xs:element name="revenue" type="xs:double" />
+				<xs:element minOccurs="0" name="birthDate" type="xs:dateTime" />
+				<xs:element minOccurs="0" name="type" type="tns:contactType" />
+			</xs:sequence>
+		</xs:complexType>
+		<xs:simpleType name="contactType">
+			<xs:restriction base="xs:string">
+				<xs:enumeration value="PRIVATE" />
+				<xs:enumeration value="BUSINESS" />
+			</xs:restriction>
+		</xs:simpleType>
+</xs:schema>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd
new file mode 100644
index 0000000..e36435f
--- /dev/null
+++ b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.com/soapheaders" targetNamespace="http://www.example.com/soapheaders" elementFormDefault="qualified">
+	<xsd:element name="referenceUri" type="tns:AttributedURIType"/>
+	<xsd:element name="comment" type="tns:AttributedStringType"/>
+	<xsd:element name="retryCount" type="tns:AttributedIntegerType"/>
+	<xsd:element name="refusal" type="tns:AttributedSimpleEnumType"/>
+
+	<xsd:complexType name="AttributedURIType" mixed="false">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:anyURI">
+				<xsd:anyAttribute namespace="##other" processContents="lax"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	
+	<xsd:complexType name="AttributedStringType" mixed="false">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:string">
+				<xsd:anyAttribute namespace="##other" processContents="lax"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	
+	<xsd:complexType name="AttributedIntegerType" mixed="false">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:integer">
+				<xsd:anyAttribute namespace="##other" processContents="lax"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	
+	<xsd:complexType name="AttributedSimpleEnumType" mixed="false">
+		<xsd:simpleContent>
+			<xsd:extension base="tns:sampleEnumType">
+				<xsd:anyAttribute namespace="##other" processContents="lax"/>
+			</xsd:extension>
+		</xsd:simpleContent>
+	</xsd:complexType>
+	
+	<xsd:simpleType name="sampleEnumType">
+		<xsd:restriction base="xsd:string">
+			<xsd:enumeration value="cant" />
+			<xsd:enumeration value="wont" />
+			<xsd:enumeration value="dont" />
+			<xsd:enumeration value="isnt" />
+			<xsd:enumeration value="aint" />
+		</xsd:restriction>
+	</xsd:simpleType>
+</xsd:schema>

http://git-wip-us.apache.org/repos/asf/camel/blob/99a036b1/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
----------------------------------------------------------------------
diff --git a/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
new file mode 100644
index 0000000..58dfaea
--- /dev/null
+++ b/components/camel-soap/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<jaxb:bindings version="2.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
+	xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	jaxb:extensionBindingPrefixes="xjc"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">
+	<jaxb:globalBindings>
+		<jaxb:serializable uid="1" />
+		<xjc:simple />
+	</jaxb:globalBindings>
+</jaxb:bindings>
\ No newline at end of file