You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ff...@apache.org on 2022/03/11 22:56:38 UTC

[camel-spring-boot] branch main updated: [CAMEL-17778]add tests in camel-soap-starter (#462)

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

ffang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot.git


The following commit(s) were added to refs/heads/main by this push:
     new a01b02c  [CAMEL-17778]add tests in camel-soap-starter (#462)
a01b02c is described below

commit a01b02cac236f7b62093b2f00dcba4325071da9f
Author: Freeman(Yue) Fang <fr...@gmail.com>
AuthorDate: Fri Mar 11 17:56:30 2022 -0500

    [CAMEL-17778]add tests in camel-soap-starter (#462)
    
    (cherry picked from commit 8a081046cb2ed5ef26095f3b89ec2e2d21c712f4)
---
 components-starter/camel-soap-starter/pom.xml      | 120 ++++++++++
 .../dataformat/soap/CustomerServiceCxfProxy.java   |  51 +++++
 .../camel/dataformat/soap/CustomerServiceImpl.java |  90 ++++++++
 .../camel/dataformat/soap/FileReplyProcessor.java  |  35 +++
 .../camel/dataformat/soap/SoapCxfClientTest.java   | 155 +++++++++++++
 .../camel/dataformat/soap/SoapCxfServerTest.java   | 131 +++++++++++
 .../dataformat/soap/SoapMarshalSetterTest.java     |  38 ++++
 .../camel/dataformat/soap/SoapMarshalTest.java     | 139 ++++++++++++
 .../camel/dataformat/soap/SoapRoundtripTest.java   | 100 +++++++++
 .../camel/dataformat/soap/SoapServerTest.java      | 115 ++++++++++
 .../dataformat/soap/SoapSpringRoundtripTest.java   |  92 ++++++++
 .../dataformat/soap/SoapToSoapDontIgnoreTest.java  | 145 ++++++++++++
 .../dataformat/soap/SoapToSoapIgnoreTest.java      | 146 ++++++++++++
 .../soap/SoapToSoapSingleDataFormatterTest.java    | 139 ++++++++++++
 .../camel/dataformat/soap/SoapUnMarshalTest.java   | 108 +++++++++
 .../camel/dataformat/soap/springboot/TestUtil.java |  55 +++++
 .../camel/dataformat/soap12/Soap12MarshalTest.java | 147 ++++++++++++
 .../soap12/Soap12SpringRoundtripTest.java          |  92 ++++++++
 .../dataformat/soap12/Soap12UnMarshalTest.java     | 115 ++++++++++
 .../src/test/resources/log4j2.properties           |  28 +++
 .../camel/dataformat/soap/CustomerService.wsdl     | 198 +++++++++++++++++
 .../camel/dataformat/soap/CustomerService.xsd      |  92 ++++++++
 .../camel/dataformat/soap/CustomerService2.wsdl    | 102 +++++++++
 .../dataformat/soap/MultiPartCustomerService.wsdl  | 247 +++++++++++++++++++++
 .../dataformat/soap/SoapMarshalHeadersTest.xml     |  33 +++
 .../soap/SoapMarshalTestExpectedFault.xml          |  32 +++
 .../soap/SoapMarshalTestExpectedResult.xml         |  26 +++
 .../org/apache/camel/dataformat/soap/binding.xml   |  28 +++
 .../org/apache/camel/dataformat/soap/contact.xsd   |  41 ++++
 .../camel/dataformat/soap/custom-soap-headers.xsd  |  67 ++++++
 .../camel/dataformat/soap/faultWithoutDetail.xml   |  27 +++
 .../org/apache/camel/dataformat/soap/request.xml   |  26 +++
 .../apache/camel/dataformat/soap/requestFault.xml  |  26 +++
 .../org/apache/camel/dataformat/soap/response.xml  |  30 +++
 .../apache/camel/dataformat/soap/responseFault.xml |  32 +++
 .../apache/camel/dataformat/soap/xjc-bindings.xml  |  29 +++
 .../soap12/SoapMarshalTestExpectedFault.xml        |  36 +++
 .../soap12/SoapMarshalTestExpectedResult.xml       |  26 +++
 .../camel/dataformat/soap12/faultWithoutDetail.xml |  34 +++
 .../org/apache/camel/dataformat/soap12/request.xml |  26 +++
 .../routes/Soap12SpringRoundtripTest-context.xml   |  27 +++
 .../routes/SoapSpringRoundtripTest-context.xml     |  30 +++
 42 files changed, 3256 insertions(+)

diff --git a/components-starter/camel-soap-starter/pom.xml b/components-starter/camel-soap-starter/pom.xml
index 912d2ac..1c1a16a 100644
--- a/components-starter/camel-soap-starter/pom.xml
+++ b/components-starter/camel-soap-starter/pom.xml
@@ -39,6 +39,27 @@
       <artifactId>camel-soap</artifactId>
       <version>${camel-version}</version>
     </dependency>
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-cxf</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-test</artifactId>
+      <scope>test</scope>
+    </dependency>
     <!--START OF GENERATED CODE-->
     <dependency>
       <groupId>org.apache.camel.springboot</groupId>
@@ -46,4 +67,103 @@
     </dependency>
     <!--END OF GENERATED CODE-->
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-xjc-plugin</artifactId>
+        <version>${cxf-xjc-plugin-version}</version>
+        <executions>
+          <execution>
+            <id>generate-sources-jaxb</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>xsdtojava-tests</goal>
+            </goals>
+            <configuration>
+              <fork>${cxf.codegenplugin.forkmode}</fork>
+              <additionalJvmArgs>${cxf.xjc.jvmArgs}</additionalJvmArgs>
+              <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>
+        <version>${cxf-version}</version>
+        <executions>
+          <execution>
+            <id>generate-sources-wsdl</id>
+            <phase>generate-sources</phase>
+            <configuration>
+              <fork>${cxf.codegenplugin.forkmode}</fork>
+              <additionalJvmArgs>${cxf.codegen.jvmArgs}</additionalJvmArgs>
+              <testSourceRoot>${basedir}/target/generated/src/test/java</testSourceRoot>
+              <defaultOptions>
+                <frontEnd>jaxws21</frontEnd>
+              </defaultOptions>
+              <wsdlOptions>
+                <wsdlOption>
+                  <wsdl>
+                    ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.wsdl
+                  </wsdl>
+                  <bindingFiles>
+                    <bindingFile>
+                      ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/binding.xml
+                    </bindingFile>
+                  </bindingFiles>
+                </wsdlOption>
+                <wsdlOption>
+                  <wsdl>
+                    ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/CustomerService2.wsdl
+                  </wsdl>
+                </wsdlOption>
+                <wsdlOption>
+                  <wsdl>
+                    ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl
+                  </wsdl>
+                  <bindingFiles>
+                    <bindingFile>
+                      ${basedir}/src/test/resources/org/apache/camel/dataformat/soap/binding.xml
+                    </bindingFile>
+                  </bindingFiles>
+                </wsdlOption>
+              </wsdlOptions>
+            </configuration>
+            <goals>
+              <goal>wsdl2java</goal>
+            </goals>
+          </execution>
+        </executions>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.cxf.xjcplugins</groupId>
+            <artifactId>cxf-xjc-ts</artifactId>
+            <version>${cxf-xjc-utils-version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/CustomerServiceCxfProxy.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/CustomerServiceCxfProxy.java
new file mode 100644
index 0000000..bc85967
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/CustomerServiceCxfProxy.java
@@ -0,0 +1,51 @@
+/*
+ * 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 javax.xml.namespace.QName;
+
+import com.example.customerservice.CustomerService;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+
+@ImportResource({"classpath:META-INF/cxf/cxf.xml", 
+    "classpath:META-INF/cxf/cxf-extension-camel.xml"})
+@Configuration
+public class CustomerServiceCxfProxy {
+    
+    @Autowired
+    Bus bus;
+    
+    @Bean
+    public CustomerService getCustomerService() {
+        JaxWsProxyFactoryBean clientProxyFactoryBean = new JaxWsProxyFactoryBean();
+        clientProxyFactoryBean.setBus(bus);
+        clientProxyFactoryBean.setAddress("camel://direct:cxfclient");
+        QName serviceName = new QName("http://customerservice.example.com/", "CustomerServiceService");
+        clientProxyFactoryBean.setServiceName(serviceName);
+        QName endpointName = new QName("http://customerservice.example.com/", "CustomerServiceEndpoint");
+        clientProxyFactoryBean.setEndpointName(endpointName);
+        clientProxyFactoryBean.setServiceClass(com.example.customerservice.CustomerService.class);
+        return (CustomerService)clientProxyFactoryBean.create();
+    }
+    
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/CustomerServiceImpl.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/CustomerServiceImpl.java
new file mode 100644
index 0000000..e7a0f7b
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/CustomerServiceImpl.java
@@ -0,0 +1,90 @@
+/*
+ * 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 com.example.customerservice.Customer;
+import com.example.customerservice.CustomerService;
+import com.example.customerservice.GetAllAmericanCustomersResponse;
+import com.example.customerservice.GetAllCustomersResponse;
+import com.example.customerservice.GetCustomersByName;
+import com.example.customerservice.GetCustomersByNameResponse;
+import com.example.customerservice.NoSuchCustomer;
+import com.example.customerservice.NoSuchCustomerException;
+import com.example.customerservice.SaveCustomer;
+
+/**
+ * Simple implementation of CustomerService that supports returning a customer or a NoSuchCustomerException depending on
+ * input
+ */
+public class CustomerServiceImpl implements CustomerService {
+    private Customer lastSavedCustomer;
+
+    public Customer getLastSavedCustomer() {
+        return lastSavedCustomer;
+    }
+
+    public void setLastSavedCustomer(Customer lastSavedCustomer) {
+        this.lastSavedCustomer = lastSavedCustomer;
+    }
+
+    /**
+     * If the request.name is "none" a NoSuchCustomerException is thrown in any other case a dummy customer is returned
+     * that has the same name as the request
+     */
+    public GetCustomersByNameResponse getCustomersByName(GetCustomersByName request) throws NoSuchCustomerException {
+        if ("none".equals(request.getName())) {
+            NoSuchCustomer noSuchCustomer = new NoSuchCustomer();
+            noSuchCustomer.setCustomerId(request.getName());
+            throw new NoSuchCustomerException("Customer not found", noSuchCustomer);
+        }
+        GetCustomersByNameResponse response = new GetCustomersByNameResponse();
+        Customer customer = new Customer();
+        customer.setName(request.getName());
+        customer.setRevenue(100000);
+        response.getReturn().add(customer);
+        return response;
+    }
+
+    /**
+     * This method is to test a call without input parameter
+     */
+    public GetAllCustomersResponse getAllCustomers() {
+        GetAllCustomersResponse response = new GetAllCustomersResponse();
+        Customer customer = new Customer();
+        customer.setName("Smith");
+        customer.setRevenue(100000);
+        response.getReturn().add(customer);
+        return response;
+    }
+
+    /**
+     * This method is to test a call without input parameter
+     */
+    public GetAllAmericanCustomersResponse getAllAmericanCustomers() {
+        GetAllAmericanCustomersResponse response = new GetAllAmericanCustomersResponse();
+        Customer customer = new Customer();
+        customer.setName("Schmitz");
+        customer.setRevenue(100000);
+        response.getReturn().add(customer);
+        return response;
+    }
+
+    public void saveCustomer(SaveCustomer request) {
+        lastSavedCustomer = request.getCustomer();
+    }
+
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/FileReplyProcessor.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/FileReplyProcessor.java
new file mode 100644
index 0000000..ff292d8
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/FileReplyProcessor.java
@@ -0,0 +1,35 @@
+/*
+ * 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.InputStream;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+
+final class FileReplyProcessor implements Processor {
+    private final InputStream in;
+
+    FileReplyProcessor(InputStream in) {
+        this.in = in;
+    }
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        exchange.getIn().setBody(in);
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapCxfClientTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapCxfClientTest.java
new file mode 100644
index 0000000..ca2ce6d
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapCxfClientTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.util.List;
+
+import javax.annotation.Resource;
+
+import com.example.customerservice.Customer;
+import com.example.customerservice.CustomerService;
+import com.example.customerservice.GetAllCustomersResponse;
+import com.example.customerservice.GetCustomersByName;
+import com.example.customerservice.GetCustomersByNameResponse;
+import com.example.customerservice.NoSuchCustomer;
+import com.example.customerservice.NoSuchCustomerException;
+import com.example.customerservice.SaveCustomer;
+
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
+import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        CustomerServiceCxfProxy.class,
+        SoapCxfClientTest.class,
+        SoapCxfClientTest.TestConfiguration.class
+    }
+)
+
+public class SoapCxfClientTest {
+
+    private static CustomerServiceImpl serverBean;
+
+    
+    
+    @Resource
+    CustomerService customerService;
+
+    @BeforeAll
+    public static void initServerBean() {
+        
+        serverBean = new CustomerServiceImpl();
+    }
+    
+    
+    @Test
+    public void testSuccess() throws NoSuchCustomerException {
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("test");
+        GetCustomersByNameResponse response = customerService.getCustomersByName(request);
+        assertNotNull(response);
+        List<Customer> customers = response.getReturn();
+        assertEquals(1, customers.size());
+        assertEquals("test", customers.get(0).getName());
+    }
+
+    @Test
+    public void testRoundTripGetAllCustomers() throws Exception {
+        GetAllCustomersResponse response = customerService.getAllCustomers();
+        assertEquals(1, response.getReturn().size());
+        Customer firstCustomer = response.getReturn().get(0);
+        assertEquals(100000.0, firstCustomer.getRevenue(), 0.00001);
+    }
+
+    @Test
+    public void testRoundTripSaveCustomer() throws Exception {
+        Customer testCustomer = new Customer();
+        testCustomer.setName("testName");
+        SaveCustomer request = new SaveCustomer();
+        request.setCustomer(testCustomer);
+        customerService.saveCustomer(request);
+        Customer customer2 = serverBean.getLastSavedCustomer();
+        assertEquals("testName", customer2.getName());
+    }
+
+    @Test
+    public void testFault() {
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("none");
+        try {
+            customerService.getCustomersByName(request);
+            fail("NoSuchCustomerException expected");
+        } catch (NoSuchCustomerException e) {
+            NoSuchCustomer info = e.getFaultInfo();
+            assertEquals("none", info.getCustomerId());
+        }
+
+    }
+    
+    
+    
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                
+                @Override
+                public void configure() throws Exception {
+                    String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+                    ElementNameStrategy elNameStrat = new ServiceInterfaceStrategy(CustomerService.class, false);
+                    SoapDataFormat soapDataFormat = new SoapDataFormat(jaxbPackage, elNameStrat);
+                    getContext().setTracing(true);
+                    from("direct:cxfclient") //
+                            .onException(Exception.class).handled(true).marshal(soapDataFormat).end() //
+                            .unmarshal(soapDataFormat) //
+                            .bean(serverBean) //
+                            .marshal(soapDataFormat);
+                }
+
+            };
+        }
+        
+        
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapCxfServerTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapCxfServerTest.java
new file mode 100644
index 0000000..1a17da4
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapCxfServerTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.util.List;
+
+import com.example.customerservice.Customer;
+import com.example.customerservice.CustomerService;
+import com.example.customerservice.GetCustomersByName;
+import com.example.customerservice.GetCustomersByNameResponse;
+import com.example.customerservice.NoSuchCustomer;
+import com.example.customerservice.NoSuchCustomerException;
+
+import org.apache.camel.Produce;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
+import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxws.EndpointImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapCxfServerTest.class,
+        SoapCxfServerTest.TestConfiguration.class
+    }
+)
+@ImportResource({"classpath:META-INF/cxf/cxf.xml", 
+    "classpath:META-INF/cxf/cxf-extension-camel.xml"})
+public class SoapCxfServerTest {
+
+    @Autowired
+    Bus bus;
+    
+    @Produce("direct:camelClient")
+    CustomerService customerServiceProxy;
+
+    
+    @Bean("serviceImpl") 
+    private CustomerServiceImpl getCustomerServiceImpl() {
+        return new CustomerServiceImpl();
+    }
+    
+    @Bean("customerServiceEndpoint")
+    private EndpointImpl getEndpointImpl(CustomerServiceImpl serviceImpl) {
+        EndpointImpl endpoint = new EndpointImpl(bus, serviceImpl);
+        endpoint.publish("camel://direct:cxfEndpoint");
+        return endpoint;
+    }
+    
+    @Test
+    public void testSuccess() throws NoSuchCustomerException {
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("test");
+        GetCustomersByNameResponse response = customerServiceProxy.getCustomersByName(request);
+        assertNotNull(response);
+        List<Customer> customers = response.getReturn();
+        assertEquals(1, customers.size());
+        assertEquals("test", customers.get(0).getName());
+    }
+
+    @Test
+    public void testFault() {
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("none");
+        try {
+            customerServiceProxy.getCustomersByName(request);
+            fail("NoSuchCustomerException expected");
+        } catch (NoSuchCustomerException e) {
+            NoSuchCustomer info = e.getFaultInfo();
+            assertEquals("none", info.getCustomerId());
+        }
+    }
+    
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                
+                @Override
+                public void configure() throws Exception {
+                    String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+                    ElementNameStrategy elNameStrat = new ServiceInterfaceStrategy(CustomerService.class, true);
+                    SoapDataFormat soapDataFormat = new SoapDataFormat(jaxbPackage, elNameStrat);
+                    from("direct:camelClient") //
+                            .marshal(soapDataFormat) //
+                            .to("direct:cxfEndpoint") //
+                            .unmarshal(soapDataFormat);
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapMarshalSetterTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapMarshalSetterTest.java
new file mode 100644
index 0000000..b457afc
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapMarshalSetterTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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 com.example.customerservice.GetCustomersByName;
+
+/**
+ * Works like SoapMarshalTest but the data format is initialized by using the setters instead of the constructor
+ */
+public class SoapMarshalSetterTest extends SoapMarshalTest {
+
+    /**
+     * Create Dataformat by using the setters
+     */
+    @Override
+    protected SoapDataFormat createDataFormat() {
+        String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+        SoapDataFormat dataFormat = new SoapDataFormat();
+        dataFormat.setContextPath(jaxbPackage);
+        dataFormat.setElementNameStrategy(null);
+        return dataFormat;
+    }
+
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapMarshalTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapMarshalTest.java
new file mode 100644
index 0000000..ec86943
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapMarshalTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+
+
+import com.example.customerservice.GetCustomersByName;
+import com.example.customerservice.NoSuchCustomer;
+import com.example.customerservice.NoSuchCustomerException;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.dataformat.soap.springboot.TestUtil;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapMarshalTest.class,
+        SoapMarshalTest.TestConfiguration.class
+    }
+)
+public class SoapMarshalTest {
+
+   
+ 
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Autowired
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+
+    /**
+     * Test Soap marshalling by sending a GetCustomerByName object and checking against a xml file.
+     * 
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    @Test
+    public void testMarshalNormalObject() throws IOException, InterruptedException {
+        resultEndpoint.reset();
+        InputStream in = this.getClass().getResourceAsStream("SoapMarshalTestExpectedResult.xml");
+        resultEndpoint.expectedMessageCount(1);
+        resultEndpoint.expectedBodiesReceived(TestUtil.readStream(in));
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("Smith");
+        producer.sendBody(request);
+        resultEndpoint.assertIsSatisfied();
+    }
+
+    /**
+     * Test Soap marshalling by sending a NoSuchCustomerException object and checking against a xml file. We expect to
+     * receive a SOAP fault here that contains a NoSuchCustomer object as detail.
+     * 
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    @Test
+    public void testMarshalException() throws IOException, InterruptedException {
+        resultEndpoint.reset();
+        InputStream in = this.getClass().getResourceAsStream("SoapMarshalTestExpectedFault.xml");
+        resultEndpoint.expectedMessageCount(1);
+        resultEndpoint.expectedBodiesReceived(TestUtil.readStream(in));
+        NoSuchCustomer noSuchCustomer = new NoSuchCustomer();
+        noSuchCustomer.setCustomerId("None");
+        NoSuchCustomerException exception = new NoSuchCustomerException("No customer found", noSuchCustomer);
+        producer.sendBodyAndHeader(null, Exchange.EXCEPTION_CAUGHT, exception);
+        resultEndpoint.assertIsSatisfied();
+    }
+
+    /**
+     * Create data format by using the constructor
+     */
+    protected SoapDataFormat createDataFormat() {
+        String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+        ElementNameStrategy elStrat = new TypeNameStrategy();
+        return new SoapDataFormat(jaxbPackage, elStrat);
+    }
+
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                
+                public void configure() throws Exception {
+                    SoapDataFormat df = createDataFormat();
+                    from("direct:start") //
+                            .marshal(df) //
+                            .to("mock:result");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapRoundtripTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapRoundtripTest.java
new file mode 100644
index 0000000..cabe4c5
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapRoundtripTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.IOException;
+
+import com.example.customerservice.GetCustomersByName;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapRoundtripTest.class,
+        SoapRoundtripTest.TestConfiguration.class
+    }
+)
+
+public class SoapRoundtripTest {
+
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+
+    @Test
+    public void testRoundTrip() throws IOException, InterruptedException {
+        resultEndpoint.expectedMessageCount(1);
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("Mueller");
+        producer.sendBody(request);
+        resultEndpoint.assertIsSatisfied();
+        Exchange exchange = resultEndpoint.getExchanges().get(0);
+        GetCustomersByName received = exchange.getIn().getBody(
+                GetCustomersByName.class);
+        assertNotNull(received);
+        assertEquals("Mueller", received.getName());
+    }
+
+    
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+
+                String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+
+                @Override
+                public void configure() throws Exception {
+                    ElementNameStrategy elNameStrat = new TypeNameStrategy();
+                    from("direct:start").marshal().soap(jaxbPackage, elNameStrat).unmarshal()
+                        .soap(jaxbPackage, elNameStrat).to("mock:result");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapServerTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapServerTest.java
new file mode 100644
index 0000000..448b209
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapServerTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+
+
+import com.example.customerservice.GetCustomersByName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.dataformat.soap.springboot.TestUtil;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapServerTest.class,
+        SoapServerTest.TestConfiguration.class
+    }
+)
+public class SoapServerTest {
+
+    @Autowired
+    CamelContext context;
+    
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+
+    @Test
+    public void testSuccess() throws IOException, InterruptedException {
+        sendAndCheckReply("request.xml", "response.xml");
+    }
+
+    @Test
+    public void testFault() throws IOException, InterruptedException {
+        sendAndCheckReply("requestFault.xml", "responseFault.xml");
+    }
+
+    private void sendAndCheckReply(String requestResource, String responseResource) throws IOException {
+        context.setTracing(true);
+        InputStream requestIs = this.getClass().getResourceAsStream(requestResource);
+        InputStream responseIs = this.getClass().getResourceAsStream(responseResource);
+        Object reply = producer.requestBody(requestIs);
+        String replySt = context.getTypeConverter().convertTo(String.class, reply);
+        assertEquals(TestUtil.readStream(responseIs), replySt);
+    }
+
+
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                
+                public void configure() throws Exception {
+                    String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+                    ElementNameStrategy elNameStrat = new TypeNameStrategy();
+                    SoapDataFormat soapDataFormat = new SoapDataFormat(jaxbPackage, elNameStrat);
+                    CustomerServiceImpl serverBean = new CustomerServiceImpl();
+                    from("direct:start").onException(Exception.class) // 
+                            .handled(true) //
+                            .marshal(soapDataFormat) //
+                            .end() //
+                            .unmarshal(soapDataFormat) //
+                            .bean(serverBean) //
+                            .marshal(soapDataFormat);
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapSpringRoundtripTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapSpringRoundtripTest.java
new file mode 100644
index 0000000..49afa33
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapSpringRoundtripTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.IOException;
+
+import com.example.customerservice.GetCustomersByName;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.SoapDataFormat;
+import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapSpringRoundtripTest.class
+    },
+    properties = {
+        "camel.springboot.routes-include-pattern=file:src/test/resources/routes/SoapSpringRoundtripTest-context.xml"}
+
+)
+public class SoapSpringRoundtripTest {
+
+    
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Autowired
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+    
+    @Bean("myNameStrategy") 
+    private ServiceInterfaceStrategy getServiceInterfaceStrategy() {
+        return new ServiceInterfaceStrategy(com.example.customerservice.CustomerService.class, true);
+    }
+
+    @Bean("soap")
+    private SoapDataFormat getSoapDataFormat(ServiceInterfaceStrategy serviceInterfaceStrategy) {
+        SoapDataFormat soapDataFormat = new SoapDataFormat();
+        soapDataFormat.setContextPath("com.example.customerservice");
+        soapDataFormat.setElementNameStrategy(serviceInterfaceStrategy);
+        soapDataFormat.setSchema("classpath:org/apache/camel/dataformat/soap/CustomerService.xsd,classpath:soap.xsd");
+        return soapDataFormat;
+    }
+  
+    @Test
+    public void testRoundTrip() throws IOException, InterruptedException {
+        resultEndpoint.expectedMessageCount(1);
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("Mueller");
+        producer.sendBody(request);
+        resultEndpoint.assertIsSatisfied();
+        Exchange exchange = resultEndpoint.getExchanges().get(0);
+        GetCustomersByName received = exchange.getIn().getBody(
+                GetCustomersByName.class);
+        assertNotNull(received);
+        assertEquals("Mueller", received.getName());
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java
new file mode 100644
index 0000000..d64cba8
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapDontIgnoreTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+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.spring.boot.CamelAutoConfiguration;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapToSoapDontIgnoreTest.class,
+        SoapToSoapDontIgnoreTest.TestConfiguration.class
+    }
+)
+public class SoapToSoapDontIgnoreTest {
+
+   
+ 
+    @EndpointInject("mock:end")
+    protected MockEndpoint mock;
+
+    @Autowired
+    protected ProducerTemplate template;
+
+    private static SoapDataFormat soapjaxbModel;
+    private static SoapDataFormat soapjaxbModelDontIgnoreUnmarshalled;
+    private static Map<String, String> namespacePrefixMap;
+
+    @BeforeAll
+    public static void setup() {
+        namespacePrefixMap = new HashMap<>();
+        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 SoapDataFormat("com.example.contact:com.example.soapheaders");
+        soapjaxbModel.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModel.setPrettyPrint(true);
+        soapjaxbModel.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModel.setIgnoreJAXBElement(false);
+        soapjaxbModel.setElementNameStrategy(new TypeNameStrategy());
+        soapjaxbModelDontIgnoreUnmarshalled = new SoapDataFormat(
+                "com.example.contact:com.example.soapheaders");
+        soapjaxbModelDontIgnoreUnmarshalled.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModelDontIgnoreUnmarshalled.setPrettyPrint(true);
+        soapjaxbModelDontIgnoreUnmarshalled.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModelDontIgnoreUnmarshalled.setElementNameStrategy(new TypeNameStrategy());
+    }
+
+    @AfterAll
+    public static void teardown() {
+        soapjaxbModel = null;
+        namespacePrefixMap = null;
+    }
+
+    @Test
+    public void testSoapMarshal() throws Exception {
+        mock.setExpectedMessageCount(1);
+
+        template.sendBody("direct:start", createRequest());
+
+        mock.assertIsSatisfied();
+        Exchange result = mock.assertExchangeReceived(0);
+
+        byte[] body = (byte[]) result.getIn().getBody();
+        InputStream stream = new ByteArrayInputStream(body);
+        SOAPMessage request = MessageFactory.newInstance().createMessage(null, stream);
+        assertTrue(null != request.getSOAPHeader()
+                && request.getSOAPHeader().extractAllHeaderElements().hasNext(),
+                "Expected headers");
+    }
+
+    private InputStream createRequest() throws Exception {
+        InputStream stream = this.getClass().getResourceAsStream("SoapMarshalHeadersTest.xml");
+        return stream;
+    }
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                
+                public void configure() {
+                    from("direct:start").unmarshal(soapjaxbModel).marshal(soapjaxbModelDontIgnoreUnmarshalled)
+                            .to("mock:end");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java
new file mode 100644
index 0000000..4eff029
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapIgnoreTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+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.spring.boot.CamelAutoConfiguration;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapToSoapIgnoreTest.class,
+        SoapToSoapIgnoreTest.TestConfiguration.class
+    }
+)
+public class SoapToSoapIgnoreTest {
+
+   
+ 
+    @EndpointInject("mock:end")
+    protected MockEndpoint mock;
+
+    @Autowired
+    protected ProducerTemplate template;
+
+    private static SoapDataFormat soapjaxbModel;
+    private static SoapDataFormat soapjaxbModelIgnoreUnmarshalled;
+    private static Map<String, String> namespacePrefixMap;
+
+    @BeforeAll
+    public static void setup() {
+        namespacePrefixMap = new HashMap<>();
+        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 SoapDataFormat("com.example.contact:com.example.soapheaders");
+        soapjaxbModel.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModel.setPrettyPrint(true);
+        soapjaxbModel.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModel.setIgnoreJAXBElement(false);
+        soapjaxbModel.setElementNameStrategy(new TypeNameStrategy());
+        soapjaxbModelIgnoreUnmarshalled = new SoapDataFormat(
+                "com.example.contact:com.example.soapheaders");
+        soapjaxbModelIgnoreUnmarshalled.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModelIgnoreUnmarshalled.setPrettyPrint(true);
+        soapjaxbModelIgnoreUnmarshalled.setIgnoreUnmarshalledHeaders(true);
+        soapjaxbModelIgnoreUnmarshalled.setElementNameStrategy(new TypeNameStrategy());
+    }
+
+    @AfterAll
+    public static void teardown() {
+        soapjaxbModel = null;
+        namespacePrefixMap = null;
+    }
+
+    @Test
+    public void testSoapMarshal() throws Exception {
+        mock.setExpectedMessageCount(1);
+
+        template.sendBody("direct:start", createRequest());
+
+        mock.assertIsSatisfied();
+        Exchange result = mock.assertExchangeReceived(0);
+
+        byte[] body = (byte[]) result.getIn().getBody();
+        InputStream stream = new ByteArrayInputStream(body);
+        SOAPMessage request = MessageFactory.newInstance().createMessage(null, stream);
+        assertTrue(null == request.getSOAPHeader()
+                || !request.getSOAPHeader().extractAllHeaderElements().hasNext(),
+                "Expected no headers");
+    }
+
+    private InputStream createRequest() throws Exception {
+        InputStream stream = this.getClass().getResourceAsStream("SoapMarshalHeadersTest.xml");
+        return stream;
+    }
+
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                
+                public void configure() {
+                    from("direct:start").unmarshal(soapjaxbModel).marshal(soapjaxbModelIgnoreUnmarshalled)
+                            .to("mock:end");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java
new file mode 100644
index 0000000..f649cb7
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapToSoapSingleDataFormatterTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.ProducerTemplate;
+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.spring.boot.CamelAutoConfiguration;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        SoapToSoapSingleDataFormatterTest.class,
+        SoapToSoapSingleDataFormatterTest.TestConfiguration.class
+    }
+)
+public class SoapToSoapSingleDataFormatterTest {
+
+   
+ 
+    @EndpointInject("mock:end")
+    protected MockEndpoint endpoint;
+
+    @Autowired
+    protected ProducerTemplate template;
+
+    private static SoapDataFormat soapjaxbModel;
+    private static Map<String, String> namespacePrefixMap;
+
+    @BeforeAll
+    public static void setup() {
+        namespacePrefixMap = new HashMap<>();
+        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 SoapDataFormat("com.example.contact:com.example.soapheaders");
+        soapjaxbModel.setNamespacePrefix(namespacePrefixMap);
+        soapjaxbModel.setPrettyPrint(true);
+        soapjaxbModel.setIgnoreUnmarshalledHeaders(false);
+        soapjaxbModel.setIgnoreJAXBElement(false);
+        soapjaxbModel.setElementNameStrategy(new TypeNameStrategy());
+    }
+
+    @AfterAll
+    public static void teardown() {
+        soapjaxbModel = null;
+        namespacePrefixMap = null;
+    }
+
+    @Test
+    public void testSoapMarshal() throws Exception {
+        
+        endpoint.setExpectedMessageCount(1);
+
+        template.sendBody("direct:start", createRequest());
+
+        endpoint.assertIsSatisfied();
+        Exchange result = endpoint.assertExchangeReceived(0);
+
+        byte[] body = (byte[]) result.getIn().getBody();
+        InputStream stream = new ByteArrayInputStream(body);
+        SOAPMessage request = MessageFactory.newInstance().createMessage(null, stream);
+        assertTrue(null != request.getSOAPHeader()
+                && request.getSOAPHeader().extractAllHeaderElements().hasNext(),
+                "Expected headers");
+    }
+
+    private InputStream createRequest() throws Exception {
+        InputStream stream = this.getClass().getResourceAsStream("SoapMarshalHeadersTest.xml");
+        return stream;
+    }
+
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+        
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                
+                public void configure() {
+                    from("direct:start").unmarshal(soapjaxbModel).marshal(soapjaxbModel).to("mock:end");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapUnMarshalTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapUnMarshalTest.java
new file mode 100644
index 0000000..a2202a5
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/SoapUnMarshalTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+
+import javax.xml.ws.soap.SOAPFaultException;
+
+import com.example.customerservice.GetCustomersByName;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(classes = {
+                           CamelAutoConfiguration.class, SoapUnMarshalTest.class,
+                           SoapUnMarshalTest.TestConfiguration.class
+})
+public class SoapUnMarshalTest {
+
+    private static final String SERVICE_PACKAGE = GetCustomersByName.class.getPackage().getName();
+
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+
+    @Test
+    public void testUnMarshalSoap() throws IOException, InterruptedException {
+        resultEndpoint.expectedMessageCount(1);
+        InputStream in = this.getClass().getResourceAsStream("request.xml");
+        producer.sendBody(in);
+        resultEndpoint.assertIsSatisfied();
+        Exchange exchange = resultEndpoint.getExchanges().get(0);
+        Object body = exchange.getIn().getBody();
+        assertEquals(GetCustomersByName.class, body.getClass());
+        GetCustomersByName request = (GetCustomersByName)body;
+        assertEquals("Smith", request.getName());
+    }
+
+    @Test
+    public void testUnMarshalSoapFaultWithoutDetail() throws IOException, InterruptedException {
+        try {
+            InputStream in = this.getClass().getResourceAsStream("faultWithoutDetail.xml");
+            producer.sendBody(in);
+            fail("Should have thrown an Exception.");
+        } catch (Exception e) {
+            assertEquals(SOAPFaultException.class, e.getCause().getClass());
+        }
+    }
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+
+                public void configure() throws Exception {
+                    SoapDataFormat dataFormate = new SoapDataFormat();
+                    dataFormate.setContextPath(SERVICE_PACKAGE);
+                    dataFormate
+                        .setSchema("classpath:org/apache/camel/dataformat/soap/CustomerService.xsd,classpath:soap.xsd");
+
+                    from("direct:start").unmarshal(dataFormate).to("mock:result");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/springboot/TestUtil.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/springboot/TestUtil.java
new file mode 100644
index 0000000..c1c81ee
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap/springboot/TestUtil.java
@@ -0,0 +1,55 @@
+/*
+ * 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.springboot;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.apache.camel.util.IOHelper;
+
+public final class TestUtil {
+    private TestUtil() {
+    }
+
+    public static String readStream(InputStream is) throws IOException {
+        try {
+            StringBuilder sb = new StringBuilder();
+            BufferedReader reader = IOHelper.buffered(new InputStreamReader(is, "UTF-8"));
+            String line;
+            boolean comment = false;
+            while ((line = reader.readLine()) != null) {
+
+                // skip comments such as ASF license headers
+                if (line.startsWith("<!--")) {
+                    comment = true;
+                } else if (line.startsWith("-->")) {
+                    comment = false;
+                } else {
+                    if (!comment) {
+                        sb.append(line).append("\n");
+                    }
+                }
+            }
+            return sb.toString();
+        } finally {
+            is.close();
+        }
+    }
+
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12MarshalTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12MarshalTest.java
new file mode 100644
index 0000000..3f00034
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12MarshalTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.soap12;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+
+
+import com.example.customerservice.GetCustomersByName;
+import com.example.customerservice.NoSuchCustomer;
+import com.example.customerservice.NoSuchCustomerException;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.SoapDataFormat;
+import org.apache.camel.dataformat.soap.name.ElementNameStrategy;
+import org.apache.camel.dataformat.soap.name.TypeNameStrategy;
+import org.apache.camel.dataformat.soap.springboot.TestUtil;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        Soap12MarshalTest.class,
+        Soap12MarshalTest.TestConfiguration.class
+    }
+)
+public class Soap12MarshalTest {
+
+   
+ 
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Autowired
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+
+    /**
+     * Test Soap marshalling by sending a GetCustomerByName object and checking against a xml file.
+     *
+     * @throws java.io.IOException
+     * @throws InterruptedException
+     */
+    @Test
+    public void testMarshalNormalObject() throws IOException, InterruptedException {
+        resultEndpoint.reset();
+        InputStream in = this.getClass().getResourceAsStream("SoapMarshalTestExpectedResult.xml");
+        resultEndpoint.expectedMessageCount(1);
+        resultEndpoint.expectedBodiesReceived(TestUtil.readStream(in));
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("Smith");
+        producer.sendBody(request);
+        resultEndpoint.assertIsSatisfied();
+    }
+
+    /**
+     * Test Soap marshalling by sending a NoSuchCustomerException object and checking against a xml file. We expect to
+     * receive a SOAP fault here that contains a NoSuchCustomer object as detail.
+     *
+     * @throws java.io.IOException
+     * @throws InterruptedException
+     */
+    @Test
+    public void testMarshalException() throws IOException, InterruptedException {
+        resultEndpoint.reset();
+        resultEndpoint.expectedMessageCount(1);
+        resultEndpoint.message(0).body(String.class).contains(
+                "<ns2:Envelope xmlns:ns2=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ns3=\"http://customerservice.example.com/\">");
+        resultEndpoint.message(0).body(String.class).contains("<ns2:Fault>");
+        resultEndpoint.message(0).body(String.class).contains("<ns2:Value>ns2:Receiver</ns2:Value>");
+        resultEndpoint.message(0).body(String.class).contains("<ns2:Text xml:lang=\"en\">No customer found</ns2:Text>");
+        resultEndpoint.message(0).body(String.class).contains("<customerId>None</customerId>");
+        resultEndpoint.message(0).body(String.class).contains("</ns2:Fault>");
+        NoSuchCustomer noSuchCustomer = new NoSuchCustomer();
+        noSuchCustomer.setCustomerId("None");
+        NoSuchCustomerException exception = new NoSuchCustomerException("No customer found", noSuchCustomer);
+        producer.sendBodyAndHeader(null, Exchange.EXCEPTION_CAUGHT, exception);
+        resultEndpoint.assertIsSatisfied();
+    }
+
+    /**
+     * Create data format by using the constructor
+     */
+    protected SoapDataFormat createDataFormat() {
+        String jaxbPackage = GetCustomersByName.class.getPackage().getName();
+        ElementNameStrategy elStrat = new TypeNameStrategy();
+        SoapDataFormat answer = new SoapDataFormat(jaxbPackage, elStrat);
+        answer.setVersion("1.2");
+        return answer;
+    }
+
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public class TestConfiguration {
+
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                
+                public void configure() throws Exception {
+                    SoapDataFormat df = createDataFormat();
+                    from("direct:start") //
+                            .marshal(df) //
+                            .to("mock:result");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12SpringRoundtripTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12SpringRoundtripTest.java
new file mode 100644
index 0000000..004c113
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12SpringRoundtripTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.soap12;
+
+
+import java.io.IOException;
+
+import com.example.customerservice.GetCustomersByName;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.soap.SoapDataFormat;
+import org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        Soap12SpringRoundtripTest.class
+    },
+    properties = {
+        "camel.springboot.routes-include-pattern=file:src/test/resources/routes/Soap12SpringRoundtripTest-context.xml"}
+
+)
+public class Soap12SpringRoundtripTest {
+
+    
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Autowired
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+    
+    @Bean("myNameStrategy") 
+    private ServiceInterfaceStrategy getServiceInterfaceStrategy() {
+        return new ServiceInterfaceStrategy(com.example.customerservice.CustomerService.class, true);
+    }
+
+    @Bean("soap")
+    private SoapDataFormat getSoapDataFormat(ServiceInterfaceStrategy serviceInterfaceStrategy) {
+        SoapDataFormat soapDataFormat = new SoapDataFormat();
+        soapDataFormat.setVersion("1.2");
+        soapDataFormat.setContextPath("com.example.customerservice");
+        soapDataFormat.setElementNameStrategy(serviceInterfaceStrategy);
+        return soapDataFormat;
+    }
+  
+    @Test
+    public void testRoundTrip() throws IOException, InterruptedException {
+        resultEndpoint.expectedMessageCount(1);
+        GetCustomersByName request = new GetCustomersByName();
+        request.setName("Mueller");
+        producer.sendBody(request);
+        resultEndpoint.assertIsSatisfied();
+        Exchange exchange = resultEndpoint.getExchanges().get(0);
+        GetCustomersByName received = exchange.getIn().getBody(
+                GetCustomersByName.class);
+        assertNotNull(received);
+        assertEquals("Mueller", received.getName());
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12UnMarshalTest.java b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12UnMarshalTest.java
new file mode 100644
index 0000000..584a631
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/java/org/apache/camel/dataformat/soap12/Soap12UnMarshalTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.soap12;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.ws.soap.SOAPFaultException;
+
+import com.example.customerservice.GetCustomersByName;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Exchange;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.annotation.DirtiesContext;
+import org.apache.camel.test.spring.junit5.CamelSpringBootTest;
+
+
+@DirtiesContext
+@CamelSpringBootTest
+@SpringBootTest(
+    classes = {
+        CamelAutoConfiguration.class,
+        Soap12UnMarshalTest.class,
+        Soap12UnMarshalTest.TestConfiguration.class
+    }
+)
+public class Soap12UnMarshalTest {
+
+   
+    private static final String SERVICE_PACKAGE = GetCustomersByName.class
+        .getPackage().getName();
+    
+
+    @EndpointInject("mock:result")
+    protected MockEndpoint resultEndpoint;
+
+    @Autowired
+    @Produce("direct:start")
+    protected ProducerTemplate producer;
+
+    @Test
+    public void testUnMarshalSoap() throws IOException, InterruptedException {
+        resultEndpoint.expectedMessageCount(1);
+        InputStream in = this.getClass().getResourceAsStream("request.xml");
+        producer.sendBody(in);
+        resultEndpoint.assertIsSatisfied();
+        Exchange exchange = resultEndpoint.getExchanges().get(0);
+        Object body = exchange.getIn().getBody();
+        assertEquals(GetCustomersByName.class, body.getClass());
+        GetCustomersByName request = (GetCustomersByName) body;
+        assertEquals("Smith", request.getName());
+    }
+
+    @Test
+    public void testUnMarshalSoapFaultWithoutDetail() throws IOException, InterruptedException {
+        try {
+            InputStream in = this.getClass().getResourceAsStream("faultWithoutDetail.xml");
+            producer.sendBody(in);
+            fail("Should have thrown an Exception.");
+        } catch (Exception e) {
+            assertEquals(SOAPFaultException.class, e.getCause().getClass());
+        }
+    }
+
+    
+    
+
+    // *************************************
+    // Config
+    // *************************************
+
+    @Configuration
+    public static class TestConfiguration {
+
+        @Bean
+        public RouteBuilder routeBuilder() {
+            return new RouteBuilder() {
+                @Override
+                public void configure() throws Exception {
+                    from("direct:start").unmarshal().soap12(SERVICE_PACKAGE)
+                            .to("mock:result");
+                }
+            };
+        }
+    }
+}
diff --git a/components-starter/camel-soap-starter/src/test/resources/log4j2.properties b/components-starter/camel-soap-starter/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..55b6d59
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/log4j2.properties
@@ -0,0 +1,28 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+appender.file.type = File
+appender.file.name = file
+appender.file.fileName = target/camel-soap-test.log
+appender.file.layout.type = PatternLayout
+appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+appender.stdout.type = Console
+appender.stdout.name = stdout
+appender.stdout.layout.type = PatternLayout
+appender.stdout.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
+rootLogger.level = INFO
+rootLogger.appenderRef.file.ref = file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.wsdl b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.wsdl
new file mode 100644
index 0000000..3973389
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.wsdl
@@ -0,0 +1,198 @@
+<?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.
+
+-->
+<wsdl:definitions name="CustomerServiceService"
+    targetNamespace="http://customerservice.example.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+    xmlns:tns="http://customerservice.example.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+    <wsdl:types>
+        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+            xmlns:tns="http://customerservice.example.com/" attributeFormDefault="unqualified"
+            elementFormDefault="unqualified" targetNamespace="http://customerservice.example.com/">
+            <xs:element name="getCustomersByName" type="tns:getCustomersByName" />
+            <xs:element name="getCustomersByNameResponse" type="tns:getCustomersByNameResponse" />
+            <xs:complexType name="getCustomersByName">
+                <xs:sequence>
+                    <xs:element minOccurs="0" name="name" type="xs:string" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:complexType name="getCustomersByNameResponse">
+                <xs:sequence>
+                    <xs:element maxOccurs="unbounded" minOccurs="0" name="return"
+                        type="tns:customer" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:complexType name="customer">
+                <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="test" type="xs:decimal" />
+                    <xs:element minOccurs="0" name="birthDate" type="xs:dateTime" />
+                    <xs:element minOccurs="0" name="type" type="tns:customerType" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:simpleType name="customerType">
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="PRIVATE" />
+                    <xs:enumeration value="BUSINESS" />
+                </xs:restriction>
+            </xs:simpleType>
+            <xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer" />
+            <xs:complexType name="NoSuchCustomer">
+                <xs:sequence>
+                    <xs:element name="customerId" nillable="true" type="xs:string" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:element name="getAllCustomers">
+            </xs:element>
+            <xs:element name="getAllCustomersResponse" type="tns:getAllCustomersResponse">
+            </xs:element>
+
+            <xs:complexType name="getAllCustomersResponse">
+                <xs:sequence>
+                    <xs:element name="return" type="tns:customer" maxOccurs="unbounded"
+                        minOccurs="0"></xs:element>
+                </xs:sequence>
+            </xs:complexType>
+            
+            <xs:element name="getAllAmericanCustomers">
+            </xs:element>
+            <xs:element name="getAllAmericanCustomersResponse" type="tns:getAllAmericanCustomersResponse">
+            </xs:element>
+
+            <xs:complexType name="getAllAmericanCustomersResponse">
+                <xs:sequence>
+                    <xs:element name="return" type="tns:customer" maxOccurs="unbounded"
+                        minOccurs="0"></xs:element>
+                </xs:sequence>
+            </xs:complexType>
+
+            <xs:element name="saveCustomer" type="tns:saveCustomer">
+            </xs:element>
+            <xs:complexType name="saveCustomer">
+                <xs:sequence>
+                    <xs:element name="customer" type="tns:customer"></xs:element>
+                </xs:sequence>
+            </xs:complexType>
+
+        </xs:schema>
+    </wsdl:types>
+    <wsdl:message name="getCustomersByNameResponse">
+        <wsdl:part name="parameters" element="tns:getCustomersByNameResponse">
+        </wsdl:part>
+    </wsdl:message>
+    <wsdl:message name="getCustomersByName">
+        <wsdl:part name="parameters" element="tns:getCustomersByName">
+        </wsdl:part>
+    </wsdl:message>
+    <wsdl:message name="NoSuchCustomerException">
+        <wsdl:part name="NoSuchCustomerException" element="tns:NoSuchCustomer">
+        </wsdl:part>
+    </wsdl:message>
+    <wsdl:message name="getAllCustomers">
+    </wsdl:message>
+    <wsdl:message name="getAllCustomersResponse">
+        <wsdl:part name="parameters" element="tns:getAllCustomersResponse"></wsdl:part>
+    </wsdl:message>   
+	<wsdl:message name="getAllAmericanCustomers">
+    </wsdl:message>
+    <wsdl:message name="getAllAmericanCustomersResponse">
+        <wsdl:part name="parameters" element="tns:getAllAmericanCustomersResponse"></wsdl:part>
+    </wsdl:message>   
+    <wsdl:message name="saveCustomerRequest">
+        <wsdl:part name="parameters" element="tns:saveCustomer"></wsdl:part>
+    </wsdl:message>
+    <wsdl:message name="saveCustomerResponse">
+    </wsdl:message>
+    <wsdl:portType name="CustomerService">
+        <wsdl:operation name="getCustomersByName">
+            <wsdl:input name="getCustomersByName" message="tns:getCustomersByName">
+            </wsdl:input>
+            <wsdl:output name="getCustomersByNameResponse" message="tns:getCustomersByNameResponse">
+            </wsdl:output>
+            <wsdl:fault name="NoSuchCustomerException" message="tns:NoSuchCustomerException">
+            </wsdl:fault>
+        </wsdl:operation>
+        <wsdl:operation name="getAllCustomers">
+            <wsdl:input message="tns:getAllCustomers"></wsdl:input>
+            <wsdl:output message="tns:getAllCustomersResponse"></wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="getAllAmericanCustomers">
+            <wsdl:input message="tns:getAllAmericanCustomers"></wsdl:input>
+            <wsdl:output message="tns:getAllAmericanCustomersResponse"></wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="saveCustomer">
+            <wsdl:input message="tns:saveCustomerRequest"></wsdl:input>
+            <wsdl:output message="tns:saveCustomerResponse"></wsdl:output>
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="CustomerServiceServiceSoapBinding"
+        type="tns:CustomerService">
+
+        <soap:binding style="document"
+            transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="getCustomersByName">
+
+            <soap:operation
+                soapAction="http://customerservice.example.com/getCustomersByName" />
+            <wsdl:input name="getCustomersByName">
+
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output name="getCustomersByNameResponse">
+
+                <soap:body use="literal" />
+            </wsdl:output>
+            <wsdl:fault name="NoSuchCustomerException">
+
+                <soap:fault use="literal" name="NoSuchCustomerException" />
+            </wsdl:fault>
+        </wsdl:operation>
+        <wsdl:operation name="getAllCustomers">
+            <soap:operation soapAction="http://customerservice.example.com/getAllCustomers" />
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="getAllAmericanCustomers">
+            <soap:operation soapAction="http://customerservice.example.com/getAllAmericanCustomers" />
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="saveCustomer">
+            <soap:operation soapAction="http://customerservice.example.com/saveCustomer" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="CustomerServiceService">
+        <wsdl:port name="CustomerServicePort" binding="tns:CustomerServiceServiceSoapBinding">
+            <soap:address location="http://localhost:9090/CustomerServicePort" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
+
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.xsd b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.xsd
new file mode 100644
index 0000000..f899b56
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService.xsd
@@ -0,0 +1,92 @@
+<?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://customerservice.example.com/" attributeFormDefault="unqualified"
+            elementFormDefault="unqualified" targetNamespace="http://customerservice.example.com/">
+            <xs:element name="getCustomersByName" type="tns:getCustomersByName" />
+            <xs:element name="getCustomersByNameResponse" type="tns:getCustomersByNameResponse" />
+            <xs:complexType name="getCustomersByName">
+                <xs:sequence>
+                    <xs:element minOccurs="0" name="name" type="xs:string" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:complexType name="getCustomersByNameResponse">
+                <xs:sequence>
+                    <xs:element maxOccurs="unbounded" minOccurs="0" name="return"
+                        type="tns:customer" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:complexType name="customer">
+                <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="test" type="xs:decimal" />
+                    <xs:element minOccurs="0" name="birthDate" type="xs:dateTime" />
+                    <xs:element minOccurs="0" name="type" type="tns:customerType" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:simpleType name="customerType">
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="PRIVATE" />
+                    <xs:enumeration value="BUSINESS" />
+                </xs:restriction>
+            </xs:simpleType>
+            <xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer" />
+            <xs:complexType name="NoSuchCustomer">
+                <xs:sequence>
+                    <xs:element name="customerId" nillable="true" type="xs:string" />
+                </xs:sequence>
+            </xs:complexType>
+            <xs:element name="getAllCustomers">
+            </xs:element>
+            <xs:element name="getAllCustomersResponse" type="tns:getAllCustomersResponse">
+            </xs:element>
+
+            <xs:complexType name="getAllCustomersResponse">
+                <xs:sequence>
+                    <xs:element name="return" type="tns:customer" maxOccurs="unbounded"
+                        minOccurs="0"></xs:element>
+                </xs:sequence>
+            </xs:complexType>
+            
+            <xs:element name="getAllAmericanCustomers">
+            </xs:element>
+            <xs:element name="getAllAmericanCustomersResponse" type="tns:getAllAmericanCustomersResponse">
+            </xs:element>
+
+            <xs:complexType name="getAllAmericanCustomersResponse">
+                <xs:sequence>
+                    <xs:element name="return" type="tns:customer" maxOccurs="unbounded"
+                        minOccurs="0"></xs:element>
+                </xs:sequence>
+            </xs:complexType>
+
+            <xs:element name="saveCustomer" type="tns:saveCustomer">
+            </xs:element>
+            <xs:complexType name="saveCustomer">
+                <xs:sequence>
+                    <xs:element name="customer" type="tns:customer"></xs:element>
+                </xs:sequence>
+            </xs:complexType>
+
+</xs:schema>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService2.wsdl b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService2.wsdl
new file mode 100644
index 0000000..553bc72
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/CustomerService2.wsdl
@@ -0,0 +1,102 @@
+<?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.
+
+-->
+<wsdl:definitions name="CustomerServiceService" targetNamespace="http://customerservice2.example.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://customerservice2.example.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+  <wsdl:types>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://customerservice2.example.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://customerservice2.example.com/">
+    <xs:element name="getCustomersByName" type="tns:getCustomersByName"/>
+    <xs:element name="getCustomersByNameResponse" type="tns:getCustomersByNameResponse"/>
+    <xs:complexType name="getCustomersByName">
+        <xs:sequence>
+            <xs:element minOccurs="0" name="name" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="getCustomersByNameResponse">
+        <xs:sequence>
+            <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="tns:customer"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="customer">
+        <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="test" type="xs:decimal"/>
+            <xs:element minOccurs="0" name="birthDate" type="xs:dateTime"/>
+            <xs:element minOccurs="0" name="type" type="tns:customerType"/>
+        </xs:sequence>
+    </xs:complexType>
+    <xs:simpleType name="customerType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="PRIVATE"/>
+            <xs:enumeration value="BUSINESS"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer"/>
+    <xs:complexType name="NoSuchCustomer">
+        <xs:sequence>
+            <xs:element name="customerId" nillable="true" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+</xs:schema>
+  </wsdl:types>
+  <wsdl:message name="getCustomersByNameResponse">
+    <wsdl:part name="parameters" element="tns:getCustomersByNameResponse">
+    </wsdl:part>
+  </wsdl:message>
+  <wsdl:message name="getCustomersByName">
+    <wsdl:part name="parameters" element="tns:getCustomersByName">
+    </wsdl:part>
+  </wsdl:message>
+  <wsdl:message name="NoSuchCustomerException">
+    <wsdl:part name="NoSuchCustomerException" element="tns:NoSuchCustomer">
+    </wsdl:part>
+  </wsdl:message>
+  <wsdl:portType name="CustomerService">
+    <wsdl:operation name="getCustomersByName">
+      <wsdl:input name="getCustomersByName" message="tns:getCustomersByName">
+    </wsdl:input>
+      <wsdl:output name="getCustomersByNameResponse" message="tns:getCustomersByNameResponse">
+    </wsdl:output>
+      <wsdl:fault name="NoSuchCustomerException" message="tns:NoSuchCustomerException">
+    </wsdl:fault>
+    </wsdl:operation>
+  </wsdl:portType>
+  <wsdl:binding name="CustomerServiceServiceSoapBinding" type="tns:CustomerService">
+    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+    <wsdl:operation name="getCustomersByName">
+      <soap:operation soapAction="getCustomersByName" style="document"/>
+      <wsdl:input name="getCustomersByName">
+        <soap:body use="literal"/>
+      </wsdl:input>
+      <wsdl:output name="getCustomersByNameResponse">
+        <soap:body use="literal"/>
+      </wsdl:output>
+      <wsdl:fault name="NoSuchCustomerException">
+        <soap:fault name="NoSuchCustomerException" use="literal"/>
+      </wsdl:fault>
+    </wsdl:operation>
+  </wsdl:binding>
+  <wsdl:service name="CustomerServiceService">
+    <wsdl:port name="CustomerServicePort" binding="tns:CustomerServiceServiceSoapBinding">
+      <soap:address location="http://localhost:9090/CustomerServicePort"/>
+    </wsdl:port>
+  </wsdl:service>
+</wsdl:definitions>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl
new file mode 100644
index 0000000..fde11a1
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/MultiPartCustomerService.wsdl
@@ -0,0 +1,247 @@
+<?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.
+
+-->
+<wsdl:definitions name="CustomerServiceMultiPart"
+    targetNamespace="http://multipart.customerservice.example.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+    xmlns:tns="http://multipart.customerservice.example.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:typens="http://multipart.customerservice.example.com/"
+    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
+
+	<wsdl:types>
+
+        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+            xmlns:tns="http://multipart.customerservice.example.com/" attributeFormDefault="unqualified"
+            elementFormDefault="unqualified" targetNamespace="http://multipart.customerservice.example.com/">
+            
+			<xs:element name="getCustomersByName" type="tns:getCustomersByName" />
+			<xs:element name="getCustomersByNameResponse" type="tns:getCustomersByNameResponse" />
+			<xs:complexType name="getCustomersByName">
+				<xs:sequence>
+					<xs:element minOccurs="0" name="name" type="xs:string" />
+				</xs:sequence>
+			</xs:complexType>
+			<xs:complexType name="getCustomersByNameResponse">
+				<xs:sequence>
+					<xs:element maxOccurs="unbounded" minOccurs="0" name="return"
+						type="tns:customer" />
+				</xs:sequence>
+			</xs:complexType>
+			<xs:complexType name="customer">
+				<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="test" type="xs:decimal" />
+					<xs:element minOccurs="0" name="birthDate" type="xs:dateTime" />
+					<xs:element minOccurs="0" name="type" type="tns:customerType" />
+				</xs:sequence>
+			</xs:complexType>
+			<xs:simpleType name="customerType">
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="PRIVATE" />
+					<xs:enumeration value="BUSINESS" />
+				</xs:restriction>
+			</xs:simpleType>
+			<xs:element name="NoSuchCustomer" type="tns:NoSuchCustomer" />
+			<xs:complexType name="NoSuchCustomer">
+				<xs:sequence>
+					<xs:element name="customerId" nillable="true" type="xs:string" />
+				</xs:sequence>
+			</xs:complexType>
+			<xs:element name="getAllCustomers">
+			</xs:element>
+			<xs:element name="getAllCustomersResponse" type="tns:getAllCustomersResponse">
+			</xs:element>
+
+			<xs:complexType name="getAllCustomersResponse">
+				<xs:sequence>
+					<xs:element name="return" type="tns:customer" maxOccurs="unbounded"
+						minOccurs="0"></xs:element>
+				</xs:sequence>
+			</xs:complexType>
+
+			<xs:element name="saveCustomer" type="tns:saveCustomer">
+			</xs:element>
+			
+			<!--  This element reuses the tns:SaveCustomer type, but applies a different element QName (than above) -->
+			<xs:element name="saveCustomerToo" type="tns:saveCustomer">
+            </xs:element>
+			<xs:complexType name="saveCustomer">
+				<xs:sequence>
+					<xs:element name="customer" type="tns:customer"></xs:element>
+				</xs:sequence>
+			</xs:complexType>
+			
+			<xs:element name="company" type="tns:company"></xs:element>
+			<xs:complexType name="company">
+				<xs:sequence>
+					<xs:element name="name" type="xs:string" />
+					<xs:element name="president" type="xs:string" />
+				</xs:sequence>
+			</xs:complexType>
+
+			<xs:element name="companyType" type="tns:companyType" />
+			<xs:simpleType name="companyType">
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="PRIVATE" />
+					<xs:enumeration value="PUBLIC" />
+				</xs:restriction>
+			</xs:simpleType>
+
+			<xs:element name="product" type="tns:product" />
+			<xs:complexType name="product">
+				<xs:sequence>
+					<xs:element name="name" type="xs:string" />
+					<xs:element name="description" type="xs:string" />
+				</xs:sequence>
+			</xs:complexType>
+		</xs:schema>
+
+	</wsdl:types>
+   
+
+    <!--  message with two parts -->
+    <wsdl:message name="getCustomersByName">
+        <wsdl:part name="parameters" element="typens:getCustomersByName"/>
+        <wsdl:part name="product" element="typens:product"/>
+    </wsdl:message>
+    <wsdl:message name="getCustomersByNameResponse">
+        <wsdl:part name="parameters" element="typens:getCustomersByNameResponse"/>
+    </wsdl:message>
+    
+    <wsdl:message name="NoSuchCustomerException">
+        <wsdl:part name="NoSuchCustomerException" element="typens:NoSuchCustomer"/>
+    </wsdl:message>
+     
+     <!--  message with an out part -->
+    <wsdl:message name="getAllCustomers">
+    </wsdl:message>
+    <wsdl:message name="getAllCustomersResponse">
+        <wsdl:part name="parameters" element="typens:getAllCustomersResponse"/>
+        <wsdl:part name="companyType" element="typens:companyType"/>
+    </wsdl:message> 
+        
+    <!--  multiple in parts and an inout -->  
+    <wsdl:message name="saveCustomer">
+        <wsdl:part name="parameters" element="typens:saveCustomer"/>
+        <wsdl:part name="product" element="typens:product"/>
+        <wsdl:part name="company" element="typens:company"/>          
+    </wsdl:message>    
+    <wsdl:message name="saveCustomerResponse">
+       <wsdl:part name="company" element="typens:company"/>
+    </wsdl:message>
+    
+    <wsdl:message name="saveCustomerToo">
+        <wsdl:part name="parameters" element="typens:saveCustomerToo"/>
+        <wsdl:part name="product" element="typens:product"/>
+        <wsdl:part name="company" element="typens:company"/>          
+    </wsdl:message>  
+    <wsdl:message name="saveCustomerResponseToo">
+       <wsdl:part name="company" element="typens:company"/>
+    </wsdl:message>
+    
+    <!--  message with an out part -->   
+    <wsdl:portType name="MultiPartCustomerService">
+        <wsdl:operation name="getCustomersByName">
+            <wsdl:input name="getCustomersByName" message="tns:getCustomersByName"/>
+            <wsdl:output name="getCustomersByNameResponse" message="tns:getCustomersByNameResponse"/>
+            <wsdl:fault name="NoSuchCustomerException" message="tns:NoSuchCustomerException"/>
+        </wsdl:operation>
+        <wsdl:operation name="getAllCustomers">
+            <wsdl:input message="tns:getAllCustomers"/>
+            <wsdl:output message="tns:getAllCustomersResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="saveCustomer">
+            <wsdl:input message="tns:saveCustomer"/>
+            <wsdl:output message="tns:saveCustomerResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="saveCustomerToo">
+            <wsdl:input message="tns:saveCustomerToo"/>
+            <wsdl:output name="saveCustomerResponseToo" message="tns:saveCustomerResponseToo"/>
+        </wsdl:operation>
+    </wsdl:portType>
+    
+    <wsdl:binding name="CustomerServiceMultiPart" type="tns:MultiPartCustomerService">
+    
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+    
+        <!--  operation with a single header part in the request -->      
+        <wsdl:operation name="getCustomersByName">
+            <soap:operation soapAction="http://multipart.customerservice.example.com/getCustomersByName" />
+            <wsdl:input>
+                <soap:header use="literal" part="product" message="tns:getCustomersByName" />
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output name="getCustomersByNameResponse">
+                <soap:body use="literal" />
+            </wsdl:output>
+            <wsdl:fault name="NoSuchCustomerException">
+                <soap:fault use="literal" name="NoSuchCustomerException" />
+            </wsdl:fault>
+        </wsdl:operation> 
+            
+        <!--  operation with a single header part in the response -->             
+        <wsdl:operation name="getAllCustomers">
+            <soap:operation soapAction="http://multipart.customerservice.example.com/getAllCustomers" />
+            <wsdl:input></wsdl:input>
+            <wsdl:output>
+                <soap:header use="literal" part="company" message="tns:getAllCustomers" />
+                <soap:body use="literal" />      
+            </wsdl:output>
+        </wsdl:operation>
+              
+        <!--  operation with two header values in request - one is an inout -->
+        <wsdl:operation name="saveCustomer">
+            <soap:operation soapAction="http://multipart.customerservice.example.com/saveCustomer" />
+            <wsdl:input>
+                <soap:header use="literal" part="product" message="tns:saveCustomer" />
+                <soap:header use="literal" part="company" message="tns:saveCustomer" />
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output name="saveCustomerResponse">
+	            <soap:header use="literal" part="company" message="tns:saveCustomer" />
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        
+        <!--  operation to test reused parameters and a parameters that reuses a type but applies a new namespace -->
+        <wsdl:operation name="saveCustomerToo">
+            <soap:operation soapAction="http://multipart.customerservice.example.com/saveCustomerToo" />
+            <wsdl:input>
+                <soap:header use="literal" part="product" message="tns:saveCustomerToo" />
+                <soap:header use="literal" part="company" message="tns:saveCustomerToo" />
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output name="saveCustomerResponseToo">
+                <soap:header use="literal" part="company" message="tns:saveCustomerToo" />
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>  
+              
+    </wsdl:binding>
+    
+    
+    <wsdl:service name="MultiPartCustomerServiceService">
+        <wsdl:port name="MultiPartCustomerServicePort" binding="tns:CustomerServiceMultiPart">
+            <soap:address location="http://localhost:9090/MultipartCustomerService" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalHeadersTest.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalHeadersTest.xml
new file mode 100644
index 0000000..7a256f8
--- /dev/null
+++ b/components-starter/camel-soap-starter/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
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalTestExpectedFault.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalTestExpectedFault.xml
new file mode 100644
index 0000000..41701de
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalTestExpectedFault.xml
@@ -0,0 +1,32 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="http://customerservice.example.com/">
+    <ns2:Body>
+        <ns2:Fault>
+            <faultcode>ns2:Receiver</faultcode>
+            <faultstring>No customer found</faultstring>
+            <detail>
+                <ns3:NoSuchCustomer>
+                    <customerId>None</customerId>
+                </ns3:NoSuchCustomer>
+            </detail>
+        </ns2:Fault>
+    </ns2:Body>
+</ns2:Envelope>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalTestExpectedResult.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalTestExpectedResult.xml
new file mode 100644
index 0000000..b26ba35
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/SoapMarshalTestExpectedResult.xml
@@ -0,0 +1,26 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="http://customerservice.example.com/">
+    <ns2:Body>
+        <ns3:getCustomersByName>
+            <name>Smith</name>
+        </ns3:getCustomersByName>
+    </ns2:Body>
+</ns2:Envelope>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/binding.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/binding.xml
new file mode 100644
index 0000000..d3cb397
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/binding.xml
@@ -0,0 +1,28 @@
+<?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.
+
+-->
+<bindings
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+    wsdlLocation=""
+    xmlns="http://java.sun.com/xml/ns/jaxws">
+    <bindings node="wsdl:definitions">
+        <enableWrapperStyle>false</enableWrapperStyle>
+    </bindings>
+</bindings>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd
new file mode 100644
index 0000000..4476ef7
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/contact.xsd
@@ -0,0 +1,41 @@
+<?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
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd
new file mode 100644
index 0000000..a4cd6bf
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/custom-soap-headers.xsd
@@ -0,0 +1,67 @@
+<?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.
+
+-->
+<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>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/faultWithoutDetail.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/faultWithoutDetail.xml
new file mode 100644
index 0000000..bc987ef
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/faultWithoutDetail.xml
@@ -0,0 +1,27 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="http://customerservice.example.com/">
+    <ns2:Body>
+        <ns2:Fault>
+            <faultcode>ns2:Receiver</faultcode>
+            <faultstring>Customer not found</faultstring>
+        </ns2:Fault>
+    </ns2:Body>
+</ns2:Envelope>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/request.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/request.xml
new file mode 100644
index 0000000..60f95e1
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/request.xml
@@ -0,0 +1,26 @@
+<?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.
+
+-->
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+	<soap:Body>
+		<ns2:getCustomersByName xmlns:ns2="http://customerservice.example.com/">
+			<name>Smith</name>
+		</ns2:getCustomersByName>
+	</soap:Body>
+</soap:Envelope>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/requestFault.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/requestFault.xml
new file mode 100644
index 0000000..6240a01
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/requestFault.xml
@@ -0,0 +1,26 @@
+<?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.
+
+-->
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+	<soap:Body>
+		<ns2:getCustomersByName xmlns:ns2="http://customerservice.example.com/">
+			<name>none</name>
+		</ns2:getCustomersByName>
+	</soap:Body>
+</soap:Envelope>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/response.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/response.xml
new file mode 100644
index 0000000..9ee4b13
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/response.xml
@@ -0,0 +1,30 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="http://customerservice.example.com/">
+    <ns2:Body>
+        <ns3:getCustomersByNameResponse>
+            <return>
+                <name>Smith</name>
+                <numOrders>0</numOrders>
+                <revenue>100000.0</revenue>
+            </return>
+        </ns3:getCustomersByNameResponse>
+    </ns2:Body>
+</ns2:Envelope>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/responseFault.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/responseFault.xml
new file mode 100644
index 0000000..28e5087
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/responseFault.xml
@@ -0,0 +1,32 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="http://customerservice.example.com/">
+    <ns2:Body>
+        <ns2:Fault>
+            <faultcode>ns2:Receiver</faultcode>
+            <faultstring>Customer not found</faultstring>
+            <detail>
+                <ns3:NoSuchCustomer>
+                    <customerId>none</customerId>
+                </ns3:NoSuchCustomer>
+            </detail>
+        </ns2:Fault>
+    </ns2:Body>
+</ns2:Envelope>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
new file mode 100644
index 0000000..255f6b0
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap/xjc-bindings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+
+    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.
+
+-->
+<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
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/SoapMarshalTestExpectedFault.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/SoapMarshalTestExpectedFault.xml
new file mode 100644
index 0000000..87a27d1
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/SoapMarshalTestExpectedFault.xml
@@ -0,0 +1,36 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://www.w3.org/2003/05/soap-envelope" xmlns:ns3="http://customerservice.example.com/">
+	<ns2:Body>
+		<ns2:Fault>
+			<ns2:Code>
+				<ns2:Value>ns2:Receiver</ns2:Value>
+			</ns2:Code>
+			<ns2:Reason>
+				<ns2:Text xml:lang="en">No customer found</ns2:Text>
+			</ns2:Reason>
+			<ns2:Detail>
+				<ns3:NoSuchCustomer>
+					<customerId>None</customerId>
+				</ns3:NoSuchCustomer>
+			</ns2:Detail>
+		</ns2:Fault>
+	</ns2:Body>
+</ns2:Envelope>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/SoapMarshalTestExpectedResult.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/SoapMarshalTestExpectedResult.xml
new file mode 100644
index 0000000..95727bf
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/SoapMarshalTestExpectedResult.xml
@@ -0,0 +1,26 @@
+<?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.
+
+-->
+<ns2:Envelope xmlns:ns2="http://www.w3.org/2003/05/soap-envelope" xmlns:ns3="http://customerservice.example.com/">
+    <ns2:Body>
+        <ns3:getCustomersByName>
+            <name>Smith</name>
+        </ns3:getCustomersByName>
+    </ns2:Body>
+</ns2:Envelope>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/faultWithoutDetail.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/faultWithoutDetail.xml
new file mode 100644
index 0000000..723ea13
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/faultWithoutDetail.xml
@@ -0,0 +1,34 @@
+<?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.
+
+-->
+<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
+	<env:Body>
+		<env:Fault>
+			<env:Code>
+				<env:Value>Sender</env:Value>
+				<env:Subcode>
+					<env:Value>Timeout</env:Value>
+				</env:Subcode>
+			</env:Code>
+			<env:Reason>
+				<env:Text xml:lang="en">Timeout</env:Text>
+			</env:Reason>
+		</env:Fault>
+	</env:Body>
+</env:Envelope>
diff --git a/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/request.xml b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/request.xml
new file mode 100644
index 0000000..5ac6bf7
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/org/apache/camel/dataformat/soap12/request.xml
@@ -0,0 +1,26 @@
+<?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.
+
+-->
+<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
+	<soap:Body>
+		<ns2:getCustomersByName xmlns:ns2="http://customerservice.example.com/">
+			<name>Smith</name>
+		</ns2:getCustomersByName>
+	</soap:Body>
+</soap:Envelope>
\ No newline at end of file
diff --git a/components-starter/camel-soap-starter/src/test/resources/routes/Soap12SpringRoundtripTest-context.xml b/components-starter/camel-soap-starter/src/test/resources/routes/Soap12SpringRoundtripTest-context.xml
new file mode 100644
index 0000000..04d91f7
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/routes/Soap12SpringRoundtripTest-context.xml
@@ -0,0 +1,27 @@
+<?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.
+
+-->
+    <routes id="camel" xmlns="http://camel.apache.org/schema/spring">   
+        <route>
+            <from uri="direct:start"/>
+            <marshal><custom ref="soap"/></marshal>
+            <unmarshal><custom ref="soap"/></unmarshal>
+            <to uri="mock:result"/>
+        </route>
+    </routes>
diff --git a/components-starter/camel-soap-starter/src/test/resources/routes/SoapSpringRoundtripTest-context.xml b/components-starter/camel-soap-starter/src/test/resources/routes/SoapSpringRoundtripTest-context.xml
new file mode 100644
index 0000000..1e67ffc
--- /dev/null
+++ b/components-starter/camel-soap-starter/src/test/resources/routes/SoapSpringRoundtripTest-context.xml
@@ -0,0 +1,30 @@
+<?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.
+
+-->
+    
+    <routes id="camel" xmlns="http://camel.apache.org/schema/spring">
+        
+
+        <route>
+            <from uri="direct:start"/>
+            <marshal><custom ref="soap"/></marshal>
+            <unmarshal><custom ref="soap"/></unmarshal>
+            <to uri="mock:result"/>
+        </route>
+    </routes>