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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 690a5104cc3 CAMEL-21040: ensure more consistency in the document 
sections (#15032)
690a5104cc3 is described below

commit 690a5104cc347398efa03bd0245d8c5cb38129ad
Author: Otavio Rodolfo Piske <orpi...@users.noreply.github.com>
AuthorDate: Tue Aug 6 21:15:11 2024 +0200

    CAMEL-21040: ensure more consistency in the document sections (#15032)
---
 .../src/main/docs/crypto-component.adoc            |    2 +-
 .../camel-csv/src/main/docs/csv-dataformat.adoc    |   18 +-
 .../src/main/docs/cxfrs-component.adoc             |   12 +-
 .../src/main/docs/cxf-component.adoc               | 1618 ++++++++++----------
 .../src/main/docs/dataset-component.adoc           |   62 +-
 .../src/main/docs/datasonnet-language.adoc         |  133 +-
 6 files changed, 929 insertions(+), 916 deletions(-)

diff --git a/components/camel-crypto/src/main/docs/crypto-component.adoc 
b/components/camel-crypto/src/main/docs/crypto-component.adoc
index 4837da3602f..a6f91ff73ff 100644
--- a/components/camel-crypto/src/main/docs/crypto-component.adoc
+++ b/components/camel-crypto/src/main/docs/crypto-component.adoc
@@ -106,7 +106,7 @@ include::partial$component-endpoint-options.adoc[]
 include::partial$component-endpoint-headers.adoc[]
 // component headers: END
 
-== Using
+== Usage
 
 === Raw keys
 
diff --git a/components/camel-csv/src/main/docs/csv-dataformat.adoc 
b/components/camel-csv/src/main/docs/csv-dataformat.adoc
index bb8158a0e66..78964040f81 100644
--- a/components/camel-csv/src/main/docs/csv-dataformat.adoc
+++ b/components/camel-csv/src/main/docs/csv-dataformat.adoc
@@ -37,7 +37,9 @@ The following headers are supported by this component:
 
 |===
 
-== Marshalling a Map to CSV
+== Examples
+
+=== Marshalling a Map to CSV
 
 The component allows you to marshal a Java Map (or any other message
 type that can be converted in a Map) into a
@@ -86,7 +88,7 @@ then it will produce
 abc,123
 ----
 
-== Unmarshalling a CSV message into a Java List
+=== Unmarshalling a CSV message into a Java List
 
 Unmarshalling will transform a CSV message into a Java List with CSV
 file lines (containing another List with all the field values).
@@ -122,7 +124,7 @@ for (List<String> line : data) {
 }
 
--------------------------------------------------------------------------------------------------------------
 
-== Marshalling a List<Map> to CSV
+=== Marshalling a List<Map> to CSV
 
 *Since Camel 2.1*
 
@@ -131,7 +133,7 @@ format, you can now store the message payload as a
 `List<Map<String, Object>>` object where the list contains a Map for
 each row.
 
-== File Poller of CSV, then unmarshaling
+=== File Poller of CSV, then unmarshaling
 
 Given a bean which can handle the incoming data...
 
@@ -158,7 +160,7 @@ public void doHandleCsvData(List<List<String>> csvData)
 </route>
 
------------------------------------------------------------------------------------------------
 
-== Marshaling with a pipe as delimiter
+=== Marshaling with a pipe as delimiter
 Considering the following body:
 
 [source,java]
@@ -244,7 +246,7 @@ should illustrate this customization.
 </bean>
 
-----------------------------------------------------------------------------------------------------------------------------
 
-== Collecting header record
+=== Collecting header record
 
 You can instruct the CSV Data Format to collect the headers into
 a message header called CamelCsvHeaderRecord.
@@ -260,7 +262,7 @@ from("direct:start")
 --------------------------------------------
 
 
-== Using skipFirstLine or skipHeaderRecord option while unmarshaling
+=== Using skipFirstLine or skipHeaderRecord option while unmarshaling
 
 *For Camel >= 2.16.5 
 The instruction for CSV Data format to skip headers or first line is the 
following. 
@@ -313,7 +315,7 @@ XML::
 
 
 
-== Unmarshaling with a pipe as delimiter
+=== Unmarshaling with a pipe as delimiter
 
 
 [tabs]
diff --git 
a/components/camel-cxf/camel-cxf-rest/src/main/docs/cxfrs-component.adoc 
b/components/camel-cxf/camel-cxf-rest/src/main/docs/cxfrs-component.adoc
index 4d077681a5c..b173c61f803 100644
--- a/components/camel-cxf/camel-cxf-rest/src/main/docs/cxfrs-component.adoc
+++ b/components/camel-cxf/camel-cxf-rest/src/main/docs/cxfrs-component.adoc
@@ -83,7 +83,9 @@ Please check the following files for more details:
 * http://cxf.apache.org/docs/jax-rs.html[CXF JAX-RS documentation].
 ====
 
-== How to configure the REST endpoint in Camel
+== Examples
+
+=== How to configure the REST endpoint in Camel
 
 In the
 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-rest/src/main/resources/schema/cxfJaxrsEndpoint.xsd[camel-cxf
 schema file], there are two elements for the REST endpoint definition:
@@ -93,7 +95,7 @@ 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-
 
 You can find a Camel REST service route configuration example there.
 
-== How to override the CXF producer address from message header
+=== How to override the CXF producer address from message header
 
 The `camel-cxfrs` producer supports overriding the service address by setting 
the message with the key of `CamelDestinationOverrideUrl`.
 
@@ -103,7 +105,7 @@ The `camel-cxfrs` producer supports overriding the service 
address by setting th
  exchange.getIn().setHeader(Exchange.DESTINATION_OVERRIDE_URL, 
constant(getServiceAddress()));
 
----------------------------------------------------------------------------------------------
 
-== Consuming a REST Request - Simple Binding Style
+=== Consuming a REST Request - Simple Binding Style
 
 *Since Camel 2.11*
 
@@ -220,7 +222,7 @@ found
 
https://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/jaxrs/simplebinding/[here].
 ====
 
-== Consuming a REST Request - Default Binding Style
+=== Consuming a REST Request - Default Binding Style
 
 The http://cxf.apache.org/docs/jax-rs.html[CXF JAXRS front end]
 implements the https://javaee.github.io/jsr311/[JAX-RS (JSR-311) API], so we 
can
@@ -314,7 +316,7 @@ public interface CustomerServiceResource {
 }
 ----
 
-== How to invoke the REST service through camel-cxfrs producer
+=== How to invoke the REST service through camel-cxfrs producer
 
 The http://cxf.apache.org/docs/jax-rs.html[CXF JAXRS front end]
 implements
diff --git 
a/components/camel-cxf/camel-cxf-soap/src/main/docs/cxf-component.adoc 
b/components/camel-cxf/camel-cxf-soap/src/main/docs/cxf-component.adoc
index 4849e66e833..c646a081b07 100644
--- a/components/camel-cxf/camel-cxf-soap/src/main/docs/cxf-component.adoc
+++ b/components/camel-cxf/camel-cxf-soap/src/main/docs/cxf-component.adoc
@@ -120,1053 +120,1059 @@ exchange property, `CamelCXFDataFormat`. The exchange 
key constant is
 defined in
 
`org.apache.camel.component.cxf.common.message.CxfConstants.DATA_FORMAT_PROPERTY`.
 
-== How to create a simple CXF service with POJO data format
+== Usage
 
-Having simple java web service interface:
+=== RAW Mode
 
+Attachments are not supported as it does not process the message at all.
 
-[source,java]
-----
-package org.apache.camel.component.cxf.soap.server;
+===  CXF_MESSAGE Mode
 
-@WebService(targetNamespace = 
"http://server.soap.cxf.component.camel.apache.org/";, name = "EchoService")
-public interface EchoService {
+MTOM is supported, and Attachments can be retrieved by Camel Message APIs 
mentioned above. Note that when receiving a multipart (i.e., MTOM) message, the 
default `SOAPMessag`e to `String` converter will provide the complete multipart 
payload on the body.
+If you require just the SOAP XML as a String, you can set the message body
+with `message.getSOAPPart()`, and the Camel converter can do the rest of the 
work
+for you.
 
-    String echo(String text);
-}
-----
+=== Streaming Support in PAYLOAD mode
 
-And implementation:
+The Camel CXF component now supports streaming of incoming
+messages when using PAYLOAD mode. Previously, the incoming messages
+would have been completely DOM parsed. For large messages, this is 
time-consuming and uses a significant amount of memory.
+The incoming messages can remain as a `javax.xml.transform.Source` while
+being routed and, if nothing modifies the payload, can then be directly
+streamed out to the target destination. For common "simple proxy" use
+cases (example: `from("cxf:...").to("cxf:...")`), this can provide very
+significant performance increases as well as significantly lowered
+memory requirements.
 
-[source,java]
-----
+However, there are cases where streaming may not be appropriate or
+desired. Due to the streaming nature, invalid incoming XML may not be
+caught until later in the processing chain. Also, certain actions may
+require the message to be DOM parsed anyway (like WS-Security or message
+tracing and such) in which case, the advantages of the streaming are
+limited. At this point, there are two ways to control the streaming:
 
-package org.apache.camel.component.cxf.soap.server;
+* Endpoint property: you can add `allowStreaming=false` as an endpoint
+property to turn the streaming on/off.
 
-@WebService(name = "EchoService", serviceName = "EchoService", targetNamespace 
= "http://server.soap.cxf.component.camel.apache.org/";)
-public class EchoServiceImpl implements EchoService {
+* Component property: the `CxfComponent` object also has an `allowStreaming`
+property that can set the default for endpoints created from that
+component.
 
-    @Override
-    public String echo(String text) {
-        return text;
-    }
+Global system property: you can add a system property of
+`org.apache.camel.component.cxf.streaming` to `false` to turn it off.
+That sets the global default, but setting the endpoint property above
+will override this value for that endpoint.
 
-}
-----
+=== Using the generic CXF Dispatch mode
 
-We can then create the simplest CXF service (note we didn't specify the `POJO` 
mode, as it is the default mode):
+The Camel CXF component supports the generic
+https://cxf.apache.org/docs/jax-ws-dispatch-api.html[CXF dispatch mode] that 
can transport messages of arbitrary structures (i.e., not bound to a specific 
XML schema).
+To use this mode, you omit specifying the `wsdlURL` and `serviceClass` 
attributes of the CXF endpoint.
 
+[tabs]
+====
+Java (Quarkus)::
++
 [source,java]
 ----
-    
from("cxf:echoServiceResponseFromImpl?serviceClass=org.apache.camel.component.cxf.soap.server.EchoServiceImpl&address=/echo-impl")//
 no body set here; the response comes from EchoServiceImpl
-                .log("${body}");
-----
+import org.apache.camel.component.cxf.common.DataFormat;
+import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Named;
 
-For more complicated implementation of the service (more "Camel way"), we can 
set the body from the route instead:
+...
 
-[source,java]
-----
-    
from("cxf:echoServiceResponseFromRoute?serviceClass=org.apache.camel.component.cxf.soap.server.EchoServiceImpl&address=/echo-route")
-                .setBody(exchange -> 
exchange.getMessage().getBody(String.class) + " from Camel route");
+@Produces
+@SessionScoped
+@Named
+CxfEndpoint dispatchEndpoint() {
+    final CxfEndpoint result = new CxfEndpoint();
+    result.setDataFormat(DataFormat.PAYLOAD);
+    result.setAddress("/SoapAnyPort");
+    return result;
+}
 ----
 
+XML (Spring)::
++
+[source,xml]
+----
+<cxf:cxfEndpoint id="dispatchEndpoint" 
address="http://localhost:9000/SoapContext/SoapAnyPort";>
+    <cxf:properties>
+        <entry key="dataFormat" value="PAYLOAD"/>
+    </cxf:properties>
+</cxf:cxfEndpoint>
+----
+====
 
-== How to consume a message from a Camel CXF endpoint in POJO data format
+It is noted that the default CXF dispatch client does not send a
+specific `SOAPAction` header. Therefore, when the target service requires
+a specific `SOAPAction` value, it is supplied in the Camel header using
+the key `SOAPAction` (case-insensitive).
 
-The Camel CXF endpoint consumer POJO data format is based on the
-http://cxf.apache.org/docs/invokers.html[CXF invoker], so the
-message header has a property with the name of
-`CxfConstants.OPERATION_NAME` and the message body is a list of the SEI
-method parameters.
+[#cxf-loggingout-interceptor-in-message-mode]
+==== How to enable CXF's LoggingOutInterceptor in RAW mode
 
-Consider the 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/wsdl_first/PersonProcessor.java[PersonProcessor]
 example code:
+CXF's `LoggingOutInterceptor` outputs outbound message that goes on the
+wire to logging system (Java Util Logging). Since the
+`LoggingOutInterceptor` is in `PRE_STREAM` phase (but `PRE_STREAM` phase
+is removed in `RAW` mode), you have to configure
+`LoggingOutInterceptor` to be run during the `WRITE` phase. The
+following is an example.
 
+[tabs]
+====
+Java (Quarkus)::
++
 [source,java]
 ----
-public class PersonProcessor implements Processor {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(PersonProcessor.class);
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void process(Exchange exchange) throws Exception {
-        LOG.info("processing exchange in camel");
-
-        BindingOperationInfo boi = (BindingOperationInfo) 
exchange.getProperty(BindingOperationInfo.class.getName());
-        if (boi != null) {
-            LOG.info("boi.isUnwrapped" + boi.isUnwrapped());
-        }
-        // Get the parameter list which element is the holder.
-        MessageContentsList msgList = (MessageContentsList) 
exchange.getIn().getBody();
-        Holder<String> personId = (Holder<String>) msgList.get(0);
-        Holder<String> ssn = (Holder<String>) msgList.get(1);
-        Holder<String> name = (Holder<String>) msgList.get(2);
-
-        if (personId.value == null || personId.value.length() == 0) {
-            LOG.info("person id 123, so throwing exception");
-            // Try to throw out the soap fault message
-            org.apache.camel.wsdl_first.types.UnknownPersonFault personFault
-                    = new 
org.apache.camel.wsdl_first.types.UnknownPersonFault();
-            personFault.setPersonId("");
-            org.apache.camel.wsdl_first.UnknownPersonFault fault
-                    = new org.apache.camel.wsdl_first.UnknownPersonFault("Get 
the null value of person name", personFault);
-            exchange.getMessage().setBody(fault);
-            return;
-        }
+import java.util.List;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.common.DataFormat;
+import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
+import org.apache.cxf.interceptor.LoggingOutInterceptor;
+import org.apache.cxf.phase.Phase;
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Named;
 
-        name.value = "Bonjour";
-        ssn.value = "123";
-        LOG.info("setting Bonjour as the response");
-        // Set the response message, the first element is the return value of 
the operation,
-        // the others are the holders of method parameters
-        exchange.getMessage().setBody(new Object[] { null, personId, ssn, name 
});
-    }
+...
 
+@Produces
+@SessionScoped
+@Named
+CxfEndpoint soapMtomEnabledServerPayloadModeEndpoint() {
+    final CxfEndpoint result = new CxfEndpoint();
+    result.setServiceClass(HelloService.class);
+    result.setDataFormat(DataFormat.RAW);
+    result.setOutFaultInterceptors(List.of(new 
LoggingOutInterceptor(Phase.WRITE)));;
+    result.setAddress("/helloworld");
+    return result;
 }
 ----
 
-== How to prepare the message for the Camel CXF endpoint in POJO data format
+XML (Spring)::
++
+[source,xml]
+----
+<bean id="loggingOutInterceptor" 
class="org.apache.cxf.interceptor.LoggingOutInterceptor">
+    <!--  it really should have been user-prestream, but CXF does have such a 
phase! -->
+    <constructor-arg value="write"/>
+</bean>
 
-The Camel CXF endpoint producer is based on the
-https://github.com/apache/cxf/blob/master/core/src/main/java/org/apache/cxf/endpoint/Client.java[CXF
 client API].
-First, you need to specify the operation name in the message
-header, then add the method parameters to a list, and initialize the
-message with this parameter list. The response message's body is a
-messageContentsList, you can get the result from that list.
+<cxf:cxfEndpoint id="serviceEndpoint" 
address="http://localhost:${CXFTestSupport.port2}/LoggingInterceptorInMessageModeTest/helloworld";
+    serviceClass="org.apache.camel.component.cxf.HelloService">
+    <cxf:outInterceptors>
+        <ref bean="loggingOutInterceptor"/>
+    </cxf:outInterceptors>
+    <cxf:properties>
+        <entry key="dataFormat" value="RAW"/>
+    </cxf:properties>
+</cxf:cxfEndpoint>
+----
+====
 
-If you don't specify the operation name in the message header,
-`CxfProducer` will try to use the `defaultOperationName` from
-`CxfEndpoint`, if there is no `defaultOperationName` set on
-`CxfEndpoint`, it will pick up the first operationName from the Operation
-list.
+=== Description of CxfHeaderFilterStrategy options
 
-If you want to get the object array from the message body, you can get
-the body using `message.getBody(Object[].class)`, as shown in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfProducerRouterTest.java#L117[CxfProducerRouterTest.testInvokingSimpleServerWithParams]:
+There are _in-band_ and _out-of-band_ on-the-wire headers from the
+perspective of a JAXWS WSDL-first developer.
 
-[source,java]
-----
-Exchange senderExchange = new DefaultExchange(context, ExchangePattern.InOut);
-final List<String> params = new ArrayList<>();
-// Prepare the request message for the camel-cxf procedure
-params.add(TEST_MESSAGE);
-senderExchange.getIn().setBody(params);
-senderExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ECHO_OPERATION);
+The _in-band_ headers are headers that are explicitly defined as part of
+the WSDL binding contract for an endpoint such as SOAP headers.
 
-Exchange exchange = template.send("direct:EndpointA", senderExchange);
+The _out-of-band_ headers are headers that are serialized over the wire,
+but are not explicitly part of the WSDL binding contract.
 
-org.apache.camel.Message out = exchange.getMessage();
-// The response message's body is a MessageContentsList which first element is 
the return value of the operation,
-// If there are some holder parameters, the holder parameter will be filled in 
the reset of List.
-// The result will be extracted from the MessageContentsList with the String 
class type
-MessageContentsList result = (MessageContentsList) out.getBody();
-LOG.info("Received output text: " + result.get(0));
-Map<String, Object> responseContext = CastUtils.cast((Map<?, ?>) 
out.getHeader(Client.RESPONSE_CONTEXT));
-assertNotNull(responseContext);
-assertEquals("UTF-8", 
responseContext.get(org.apache.cxf.message.Message.ENCODING),
-        "We should get the response context here");
-assertEquals("echo " + TEST_MESSAGE, result.get(0), "Reply body on Camel is 
wrong");
-----
+Headers relaying/filtering is bi-directional.
 
-== How to consume a message from a Camel CXF endpoint in PAYLOAD data format
+When a route has a CXF endpoint and the developer needs to have
+on-the-wire headers, such as SOAP headers, be relayed along the route to
+be consumed say by another JAXWS endpoint, a `CxfHeaderFilterStrategy`
+instance should be set on the CXF endpoint, then `relayHeaders` property
+of the `CxfHeaderFilterStrategy` instance should be set to `true`, which
+is the default value. Plus, the `CxfHeaderFilterStrategy` instance also
+holds a list of `MessageHeaderFilter` interface, which decides if a specific
+header will be relayed or not.
 
-`PAYLOAD` means that you process the payload from the SOAP
-envelope as a native CxfPayload. `Message.getBody()` will return a
-`org.apache.camel.component.cxf.CxfPayload` object, with getters
-for SOAP message headers and the SOAP body.
+Take a look at the tests that show how you'd be able to relay/drop
+headers here:
 
-See 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerPayloadTest.java#L68[CxfConsumerPayloadTest]:
+https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/soap/headers/CxfMessageHeadersRelayTest.java[CxfMessageHeadersRelayTest]
 
-[source,java]
-----
-protected RouteBuilder createRouteBuilder() {
-    return new RouteBuilder() {
-        public void configure() {
-            from(simpleEndpointURI + 
"&dataFormat=PAYLOAD").to("log:info").process(new Processor() {
-                @SuppressWarnings("unchecked")
-                public void process(final Exchange exchange) throws Exception {
-                    CxfPayload<SoapHeader> requestPayload = 
exchange.getIn().getBody(CxfPayload.class);
-                    List<Source> inElements = requestPayload.getBodySources();
-                    List<Source> outElements = new ArrayList<>();
-                    // You can use a customer toStringConverter to turn a 
CxfPayLoad message into String as you want
-                    String request = exchange.getIn().getBody(String.class);
-                    XmlConverter converter = new XmlConverter();
-                    String documentString = ECHO_RESPONSE;
+* The `relayHeaders=true` expresses an intent to relay the headers. The
+actual decision on whether a given header is relayed is delegated to a
+pluggable instance that implements the `MessageHeaderFilter` interface.
+A concrete implementation of `MessageHeaderFilter` will be consulted to
+decide if a header needs to be relayed or not. There is already an
+implementation of `SoapMessageHeaderFilter` which binds itself to
+well-known SOAP name spaces.  If there is a header on the wire whose name space
+is unknown to the runtime, the header will be simply relayed.
 
-                    Element in = new 
XmlConverter().toDOMElement(inElements.get(0));
-                    // Check the element namespace
-                    if (!in.getNamespaceURI().equals(ELEMENT_NAMESPACE)) {
-                        throw new IllegalArgumentException("Wrong element 
namespace");
-                    }
-                    if (in.getLocalName().equals("echoBoolean")) {
-                        documentString = ECHO_BOOLEAN_RESPONSE;
-                        checkRequest("ECHO_BOOLEAN_REQUEST", request);
-                    } else {
-                        documentString = ECHO_RESPONSE;
-                        checkRequest("ECHO_REQUEST", request);
-                    }
-                    Document outDocument = 
converter.toDOMDocument(documentString, exchange);
-                    outElements.add(new 
DOMSource(outDocument.getDocumentElement()));
-                    // set the payload header with null
-                    CxfPayload<SoapHeader> responsePayload = new 
CxfPayload<>(null, outElements, null);
-                    exchange.getMessage().setBody(responsePayload);
-                }
-            });
-        }
-    };
-}
-----
+* `POJO` and `PAYLOAD` modes are supported. In `POJO` mode, only
+out-of-band message headers are available for filtering as the in-band
+headers have been processed and removed from the header list by CXF. The
+in-band headers are incorporated into the `MessageContentList` in POJO
+mode. The Camel CXF component does make any attempt to remove the
+in-band headers from the `MessageContentList`. If filtering of in-band
+headers is required, please use `PAYLOAD` mode or plug in a (pretty
+straightforward) CXF interceptor/JAXWS Handler to the CXF endpoint.
+Here is an example of configuring the `CxfHeaderFilterStrategy`.
 
-== How to get and set SOAP headers in POJO mode
 
-`POJO` means that the data format is a _"list of Java objects"_ when the
-Camel CXF endpoint produces or consumes Camel exchanges. Even though
-Camel exposes the message body as POJOs in this mode, Camel CXF still
-provides access to read and write SOAP headers. However, since CXF
-interceptors remove in-band SOAP headers from the header list, after they
-have been processed, only out-of-band SOAP headers are available to
-Camel CXF in POJO mode.
+[source,xml]
+----
+<bean id="dropAllMessageHeadersStrategy" 
class="org.apache.camel.component.cxf.transport.header.CxfHeaderFilterStrategy">
 
-The following example illustrates how to get/set SOAP headers. Suppose we
-have a route that forwards from one Camel CXF endpoint to another. That
-is, `SOAP Client -> Camel -> CXF service`. We can attach two processors to
-obtain/insert SOAP headers at (1) before a request goes out to the CXF
-service and (2) before the response comes back to the SOAP Client. Processors
-(1) and (2) in this example are `InsertRequestOutHeaderProcessor` and
-`InsertResponseOutHeaderProcessor`. Our route looks like this:
+    <!--  Set relayHeaders to false to drop all SOAP headers -->
+    <property name="relayHeaders" value="false"/>
 
-[tabs]
-====
-Java::
-+
-[source,java]
-----
-from("cxf:bean:routerRelayEndpointWithInsertion")
-    .process(new InsertRequestOutHeaderProcessor())
-    .to("cxf:bean:serviceRelayEndpointWithInsertion")
-    .process(new InsertResponseOutHeaderProcessor());
+</bean>
 ----
 
-XML::
-+
+Then, your endpoint can reference the `CxfHeaderFilterStrategy`:
+
 [source,xml]
 ----
 <route>
-    <from uri="cxf:bean:routerRelayEndpointWithInsertion"/>
-    <process ref="InsertRequestOutHeaderProcessor" />
-    <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/>
-    <process ref="InsertResponseOutHeaderProcessor" />
+    <from 
uri="cxf:bean:routerNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/>
+    <to 
uri="cxf:bean:serviceNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/>
 </route>
 ----
-====
 
-SOAP headers are propagated to and from Camel Message headers. The Camel
-message header name is `org.apache.cxf.headers.Header.list` which is a
-constant defined in CXF (`org.apache.cxf.headers.Header.HEADER_LIST`). The
-header value is a List of CXF `SoapHeader` objects
-(`org.apache.cxf.binding.soap.SoapHeader`).
-The following snippet is the `InsertResponseOutHeaderProcessor` (that inserts 
a new SOAP header in the response message). The way to access SOAP headers in 
both
-`InsertResponseOutHeaderProcessor` and `InsertRequestOutHeaderProcessor` are
-actually the same.
-The only difference between the two processors is setting the direction of the 
inserted SOAP header.
+* You can plug in your own `MessageHeaderFilter` implementations overriding
+or adding additional ones to the list of relays. To override a
+preloaded relay instance, make sure that your `MessageHeaderFilter`
+implementation services the same name spaces as the one you are looking to
+override.
 
-You can find the `InsertResponseOutHeaderProcessor` example in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/soap/headers/CxfMessageHeadersRelayTest.java#L731[CxfMessageHeadersRelayTest]:
+Here is an example of configuring user defined Message Header Filters:
 
-[source,java]
+[source,xml]
 ----
-public static class InsertResponseOutHeaderProcessor implements Processor {
-
-    public void process(Exchange exchange) throws Exception {
-        List<SoapHeader> soapHeaders = 
CastUtils.cast((List<?>)exchange.getIn().getHeader(Header.HEADER_LIST));
-
-        // Insert a new header
-        String xml = "<?xml version=\"1.0\" 
encoding=\"utf-8\"?><outofbandHeader "
-            + "xmlns=\"http://cxf.apache.org/outofband/Header\"; 
hdrAttribute=\"testHdrAttribute\" "
-            + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"; 
soap:mustUnderstand=\"1\">"
-            + 
"<name>New_testOobHeader</name><value>New_testOobHeaderValue</value></outofbandHeader>";
-        SoapHeader newHeader = new SoapHeader(soapHeaders.get(0).getName(),
-                       DOMUtils.readXml(new 
StringReader(xml)).getDocumentElement());
-        // make sure the direction is OUT since it is a response message.
-        newHeader.setDirection(Direction.DIRECTION_OUT);
-        //newHeader.setMustUnderstand(false);
-        soapHeaders.add(newHeader);
-
-    }
+<bean id="customMessageFilterStrategy" 
class="org.apache.camel.component.cxf.transport.header.CxfHeaderFilterStrategy">
+    <property name="messageHeaderFilters">
+        <list>
+            <!--  SoapMessageHeaderFilter is the built-in filter.  It can be 
removed by omitting it. -->
+            <bean 
class="org.apache.camel.component.cxf.common.header.SoapMessageHeaderFilter"/>
 
-}
+            <!--  Add custom filter here -->
+            <bean 
class="org.apache.camel.component.cxf.soap.headers.CustomHeaderFilter"/>
+        </list>
+    </property>
+</bean>
 ----
 
-== How to get and set SOAP headers in PAYLOAD mode
+* In addition to `relayHeaders`, the following properties can be
+configured in `CxfHeaderFilterStrategy`.
 
-We've already shown how to access the SOAP message as `CxfPayload` object in
-PAYLOAD mode in the section <<How to consume a message from a Camel CXF 
endpoint in PAYLOAD data format>>.
+[width="100%",cols="10%,10%,80%",options="header",]
+|=======================================================================
+|Name |Required |Description
+|`relayHeaders` |No |All message headers will be processed by Message Header 
Filters
+_Type_: `boolean`
+_Default_: `true`
 
-Once you obtain a `CxfPayload` object, you can invoke the
-`CxfPayload.getHeaders()` method that returns a List of DOM Elements (SOAP
-headers).
+|`relayAllMessageHeaders` | No |All message headers will be propagated 
(without processing by Message
+Header Filters)
+_Type_: `boolean`
+_Default_: `false`
 
-For example, see 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfPayLoadSoapHeaderTest.java#L53[CxfPayLoadSoapHeaderTest]:
+|`allowFilterNamespaceClash` |No |If two filters overlap in activation 
namespace, the property controls how
+it should be handled. If the value is `true`, last one wins. If the
+value is `false`, it will throw an exception
+_Type_: `boolean`
+_Default_: `false`
+|=======================================================================
 
-[source,java]
-----
-from(getRouterEndpointURI()).process(new Processor() {
-    @SuppressWarnings("unchecked")
-    public void process(Exchange exchange) throws Exception {
-        CxfPayload<SoapHeader> payload = 
exchange.getIn().getBody(CxfPayload.class);
-        List<Source> elements = payload.getBodySources();
-        assertNotNull(elements, "We should get the elements here");
-        assertEquals(1, elements.size(), "Get the wrong elements size");
+===  How to make the Camel CXF component use log4j instead of java.util.logging
 
-        Element el = new XmlConverter().toDOMElement(elements.get(0));
-        elements.set(0, new DOMSource(el));
-        assertEquals("http://camel.apache.org/pizza/types";,
-                el.getNamespaceURI(), "Get the wrong namespace URI");
+CXF's default logger is `java.util.logging`. If you want to change it to
+log4j, proceed as follows. Create a file, in the classpath, named
+`META-INF/cxf/org.apache.cxf.logger`. This file should contain the
+fully qualified name of the class,
+`org.apache.cxf.common.logging.Log4jLogger`, with no comments, on a
+single line.
 
-        List<SoapHeader> headers = payload.getHeaders();
-        assertNotNull(headers, "We should get the headers here");
-        assertEquals(1, headers.size(), "Get the wrong headers size");
-        assertEquals("http://camel.apache.org/pizza/types";,
-                ((Element) (headers.get(0).getObject())).getNamespaceURI(), 
"Get the wrong namespace URI");
-        // alternatively, you can also get the SOAP header via the camel 
header:
-        headers = exchange.getIn().getHeader(Header.HEADER_LIST, List.class);
-        assertNotNull(headers, "We should get the headers here");
-        assertEquals(1, headers.size(), "Get the wrong headers size");
-        assertEquals("http://camel.apache.org/pizza/types";,
-                ((Element) (headers.get(0).getObject())).getNamespaceURI(), 
"Get the wrong namespace URI");
+===  How to let Camel CXF response start with xml processing instruction
 
-    }
+If you are using some SOAP client such as PHP, you will get this kind of
+error because CXF doesn't add the XML processing instruction
+`<?xml version="1.0" encoding="utf-8"?>`:
 
-})
-.to(getServiceEndpointURI());
+----
+Error:sendSms: SoapFault exception: [Client] looks like we got no XML document 
in [...]
 ----
 
-You can also use the same way as described in
-subchapter "How to get and set SOAP headers in POJO mode" to set or get
-the SOAP headers. So, you can use the
-header `org.apache.cxf.headers.Header.list` to get and set a list of
-SOAP headers.This does also mean that if you have a route that forwards
-from one Camel CXF endpoint to another (`SOAP Client -> Camel -> CXF
-service`), now also the SOAP headers sent by the SOAP client are
-forwarded to the CXF service. If you do not want that these headers are
-forwarded, you have to remove them in the Camel header
-`org.apache.cxf.headers.Header.list`.
-
-== SOAP headers are not available in RAW mode
-
-SOAP headers are not available in RAW mode as SOAP processing is
-skipped.
-
-== How to throw a SOAP Fault from Camel
-
-If you are using a Camel CXF endpoint to consume the SOAP request, you
-may need to throw the SOAP Fault from the camel context. +
- Basically, you can use the `throwFault` DSL to do that; it works for
-`POJO`, `PAYLOAD` and `RAW` data format. +
- You can define the soap fault as shown in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfCustomizedExceptionTest.java#L65[CxfCustomizedExceptionTest]:
+To resolve this issue, you need to tell `StaxOutInterceptor` to
+write the XML start document for you, as in the 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/WriteXmlDeclarationInterceptor.java[WriteXmlDeclarationInterceptor]
 below:
 
 [source,java]
 ----
-SOAP_FAULT = new SoapFault(EXCEPTION_MESSAGE, SoapFault.FAULT_CODE_CLIENT);
-Element detail = SOAP_FAULT.getOrCreateDetail();
-Document doc = detail.getOwnerDocument();
-Text tn = doc.createTextNode(DETAIL_TEXT);
-detail.appendChild(tn);
-----
+public class WriteXmlDeclarationInterceptor extends 
AbstractPhaseInterceptor<SoapMessage> {
+    public WriteXmlDeclarationInterceptor() {
+        super(Phase.PRE_STREAM);
+        addBefore(StaxOutInterceptor.class.getName());
+    }
 
-Then throw it as you like:
+    public void handleMessage(SoapMessage message) throws Fault {
+        message.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE);
+    }
 
-[source,java]
-----
-from(routerEndpointURI).setFaultBody(constant(SOAP_FAULT));
+}
 ----
 
-
-If your CXF endpoint is working in the `RAW` data format, you could
-set the SOAP Fault message in the message body and set the response
-code in the message header as demonstrated by 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfMessageStreamExceptionTest.java#L43[CxfMessageStreamExceptionTest]:
+As an alternative, you can add a message header for it as demonstrated in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerTest.java#L62[CxfConsumerTest]:
 
 [source,java]
 ----
-from(routerEndpointURI).process(new Processor() {
-
-    public void process(Exchange exchange) throws Exception {
-        Message out = exchange.getMessage();
-        // Set the message body
-        
out.setBody(this.getClass().getResourceAsStream("SoapFaultMessage.xml"));
-        // Set the response code here
-        out.setHeader(org.apache.cxf.message.Message.RESPONSE_CODE, new 
Integer(500));
-    }
-
-});
+ // set up the response context which force start document
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE);
+ exchange.getMessage().setHeader(Client.RESPONSE_CONTEXT, map);
 ----
 
-Same for using POJO data format. You can set the SOAPFault on the _OUT_ body.
-
-[#propagate-request-response-context]
-== How to propagate a Camel CXF endpoint's request and response context
+=== Configure the CXF endpoints with Spring
 
-https://github.com/apache/cxf/blob/master/core/src/main/java/org/apache/cxf/endpoint/Client.java[CXF
 client API] provides a way to invoke the operation with request and
-response context.
-If you are using a Camel CXF endpoint producer to
-invoke the outside web service, you can set the request context and get
-response context with the following code:
+You can configure the CXF endpoint with the Spring configuration file
+shown below, and you can also embed the endpoint into the `camelContext`
+tags. When you are invoking the service endpoint, you can set the
+`operationName` and `operationNamespace` headers to explicitly state
+which operation you are calling.
 
-[source,java]
+[source,xml]
 ----
-CxfExchange exchange = (CxfExchange)template.send(getJaxwsEndpointUri(), new 
Processor() {
-     public void process(final Exchange exchange) {
-         final List<String> params = new ArrayList<String>();
-         params.add(TEST_MESSAGE);
-         // Set the request context to the inMessage
-         Map<String, Object> requestContext = new HashMap<String, Object>();
-         requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
JAXWS_SERVER_ADDRESS);
-         exchange.getIn().setBody(params);
-         exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext);
-         exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, 
GREET_ME_OPERATION);
-     }
-});
-org.apache.camel.Message out = exchange.getMessage();
-// The output is an object array, the first element of the array is the return 
value
-Object\[\] output = out.getBody(Object\[\].class);
-LOG.info("Received output text: " + output\[0\]);
-// Get the response context form outMessage
-Map<String, Object> responseContext = 
CastUtils.cast((Map)out.getHeader(Client.RESPONSE_CONTEXT));
-assertNotNull(responseContext);
-assertEquals("Get the wrong wsdl operation name", 
"{http://apache.org/hello_world_soap_http}greetMe";,
-    responseContext.get("javax.xml.ws.wsdl.operation").toString());
+<beans xmlns="http://www.springframework.org/schema/beans";
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+        xmlns:cxf="http://camel.apache.org/schema/cxf";
+        xsi:schemaLocation="
+        http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://camel.apache.org/schema/cxf 
http://camel.apache.org/schema/cxf/camel-cxf.xsd
+        http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd";>
+     <cxf:cxfEndpoint id="routerEndpoint" 
address="http://localhost:9003/CamelContext/RouterPort";
+            serviceClass="org.apache.hello_world_soap_http.GreeterImpl"/>
+     <cxf:cxfEndpoint id="serviceEndpoint" 
address="http://localhost:9000/SoapContext/SoapPort";
+            wsdlURL="testutils/hello_world.wsdl"
+            serviceClass="org.apache.hello_world_soap_http.Greeter"
+            endpointName="s:SoapPort"
+            serviceName="s:SOAPService"
+        xmlns:s="http://apache.org/hello_world_soap_http"; />
+     <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring";>
+       <route>
+         <from uri="cxf:bean:routerEndpoint" />
+         <to uri="cxf:bean:serviceEndpoint" />
+       </route>
+    </camelContext>
+  </beans>
 ----
 
-== Attachment Support
-
-=== POJO Mode
+Be sure to include the JAX-WS `schemaLocation` attribute specified on
+the root `beans` element. This allows CXF to validate the file and is
+required. Also note the namespace declarations at the end of the
+`<cxf:cxfEndpoint/>` tag. These declarations are required because the combined 
`\{namespace}localName` syntax is presently not supported for this tag's
+attribute values.
 
-Message Transmission Optimization Mechanism (MTOM) is supported if enabled - 
check
-the example in Payload Mode for enabling MTOM.
-Since attachments are marshalled and unmarshalled into POJOs, the attachments 
should be
-retrieved from the Apache Camel message body (as a parameter list), and it 
isn't
-possible to retrieve attachments by Camel Message API
+The `cxf:cxfEndpoint` element supports many additional attributes:
 
-[source,java]
-----
-DataHandler handler = 
Exchange.getIn(AttachmentMessage.class).getAttachment("id");
-----
+[width="100%",cols="50%,50%",options="header",]
+|=======================================================================
+|Name |Value
 
-=== Payload Mode
+|`PortName` |The endpoint name this service is implementing, it maps to the
+`wsdl:port@name`. In the format of `ns:PORT_NAME` where `ns` is a
+namespace prefix valid at this scope.
 
-Message Transmission Optimization Mechanism (MTOM) is supported by this Mode.
-Attachments can be retrieved by Camel Message APIs mentioned above.
-SOAP with Attachment (SwA) is supported and attachments can be retrieved.
-SwA is the default (same as setting the CXF endpoint property `mtomEnabled` to 
`false`).
+|`serviceName` |The service name this service is implementing, it maps to the
+`wsdl:service@name`. In the format of `ns:SERVICE_NAME` where `ns` is a
+namespace prefix valid at this scope.
 
-To enable MTOM, set the CXF endpoint property `mtomEnabled` to `true`.
+|`wsdlURL` |The location of the WSDL. Can be on the classpath, file system, or 
be
+hosted remotely.
 
-[tabs]
-====
-Java (Quarkus)::
-+
-[source,java]
-----
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.cxf.common.DataFormat;
-import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.enterprise.context.SessionScoped;
-import jakarta.enterprise.inject.Produces;
-import jakarta.inject.Named;
+|`bindingId` |The `bindingId` for the service model to use.
 
-@ApplicationScoped
-public class CxfSoapMtomRoutes extends RouteBuilder {
+|`address` |The service publish address.
 
-    @Override
-    public void configure() {
-        from("cxf:bean:mtomPayloadModeEndpoint")
-                .process( exchange -> { ... });
-    }
+|`bus` |The bus name that will be used in the JAX-WS endpoint.
 
-    @Produces
-    @SessionScoped
-    @Named
-    CxfEndpoint mtomPayloadModeEndpoint() {
-        final CxfEndpoint result = new CxfEndpoint();
-        result.setServiceClass(MyMtomService.class);
-        result.setDataFormat(DataFormat.PAYLOAD);
-        result.setMtomEnabled(true);
-        result.setAddress("/mtom/hello");
-        return result;
-    }
-}
-----
+|`serviceClass` |The class name of the SEI (Service Endpoint Interface) class 
which could
+have JSR181 annotation or not.
+|=======================================================================
 
-XML (Spring)::
-+
-[source,xml]
-----
-<cxf:cxfEndpoint id="mtomPayloadModeEndpoint" 
address="http://localhost:${CXFTestSupport.port1}/CxfMtomRouterPayloadModeTest/mtom";
-        wsdlURL="mtom.wsdl"
-        serviceName="ns:MyMtomService"
-        endpointName="ns:MyMtomPort"
-        xmlns:ns="http://apache.org/camel/cxf/mtom_feature";>
+It also supports many child elements:
 
-    <cxf:properties>
-        <!--  enable mtom by setting this property to true -->
-        <entry key="mtom-enabled" value="true"/>
-        <!--  set the Camel CXF endpoint data fromat to PAYLOAD mode -->
-        <entry key="dataFormat" value="PAYLOAD"/>
-    </cxf:properties>
-</cxf:cxfEndpoint>
-----
-====
+[width="100%",cols="50%,50%",options="header",]
+|=======================================================================
+|Name |Value
 
-You can produce a Camel message with attachment to send to a CXF endpoint in 
Payload mode.
+|`cxf:inInterceptors` |The incoming interceptors for this endpoint. A list of 
`<bean>` or
+`<ref>`.
 
-[source,java]
-----
-Exchange exchange = 
context.createProducerTemplate().send("direct:testEndpoint", new Processor() {
+|`cxf:inFaultInterceptors` |The incoming fault interceptors for this endpoint. 
A list of `<bean>` or
+`<ref>`.
 
-    public void process(Exchange exchange) throws Exception {
-        exchange.setPattern(ExchangePattern.InOut);
-        List<Source> elements = new ArrayList<Source>();
-        elements.add(new DOMSource(DOMUtils.readXml(new 
StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement()));
-        CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new 
ArrayList<SoapHeader>(),
-            elements, null);
-        exchange.getIn().setBody(body);
-        
exchange.getIn(AttachmentMessage.class).addAttachment(MtomTestHelper.REQ_PHOTO_CID,
-            new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.REQ_PHOTO_DATA, 
"application/octet-stream")));
+|`cxf:outInterceptors` |The outgoing interceptors for this endpoint. A list of 
`<bean>` or
+`<ref>`.
 
-        
exchange.getIn(AttachmentMessage.class).addAttachment(MtomTestHelper.REQ_IMAGE_CID,
-            new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.requestJpeg, "image/jpeg")));
+|`cxf:outFaultInterceptors` |The outgoing fault interceptors for this 
endpoint. A list of `<bean>` or
+`<ref>`.
 
-    }
+|`cxf:properties` | A properties map which should be supplied to the JAX-WS 
endpoint. See
+below.
 
-});
+|`cxf:handlers` |A JAX-WS handler list which should be supplied to the JAX-WS 
endpoint.
+See below.
 
-// process response
+|`cxf:dataBinding` |You can specify which `DataBinding` will be used in the 
endpoint.
+This can be supplied using the Spring `<bean class="MyDataBinding"/>`
+syntax.
 
-CxfPayload<SoapHeader> out = exchange.getMessage().getBody(CxfPayload.class);
-assertEquals(1, out.getBody().size());
+|`cxf:binding` |You can specify the `BindingFactory` for this endpoint to use. 
This can
+be supplied using the Spring `<bean class="MyBindingFactory"/>` syntax.
 
-Map<String, String> ns = new HashMap<>();
-ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS);
-ns.put("xop", MtomTestHelper.XOP_NS);
+|`cxf:features` |The features that hold the interceptors for this endpoint. A 
list of
+beans or refs
 
-XPathUtils xu = new XPathUtils(ns);
-Element oute = new XmlConverter().toDOMElement(out.getBody().get(0));
-Element ele = (Element) 
xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", oute,
-                XPathConstants.NODE);
-String photoId = ele.getAttribute("href").substring(4); // skip "cid:"
+|`cxf:schemaLocations` |The schema locations for endpoint to use. A list of 
schemaLocations
 
-ele = (Element) xu.getValue("//ns:DetailResponse/ns:image/xop:Include", oute,
-                XPathConstants.NODE);
-String imageId = ele.getAttribute("href").substring(4); // skip "cid:"
+|`cxf:serviceFactory` |The service factory for this endpoint to use. This can 
be supplied using
+the Spring `<bean class="MyServiceFactory"/>` syntax
+|=======================================================================
 
-DataHandler dr = 
exchange.getMessage(AttachmentMessage.class).getAttachment(decodingReference(photoId));
-assertEquals("application/octet-stream", dr.getContentType());
-assertArrayEquals(MtomTestHelper.RESP_PHOTO_DATA, 
IOUtils.readBytesFromStream(dr.getInputStream()));
+You can find more advanced examples that show how to provide
+interceptors, properties and handlers on the CXF
+http://cxf.apache.org/docs/jax-ws-configuration.html[JAX-WS
+Configuration page].
 
-dr = 
exchange.getMessage(AttachmentMessage.class).getAttachment(decodingReference(imageId));
-assertEquals("image/jpeg", dr.getContentType());
+[NOTE]
+====
+You can use `cxf:properties` to set the Camel CXF endpoint's dataFormat
+and setDefaultBus properties from spring configuration file.
 
-BufferedImage image = ImageIO.read(dr.getInputStream());
-assertEquals(560, image.getWidth());
-assertEquals(300, image.getHeight());
+[source,xml]
+----
+<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/router";
+     serviceClass="org.apache.camel.component.cxf.HelloService"
+     endpointName="s:HelloPort"
+     serviceName="s:HelloService"
+     xmlns:s="http://www.example.com/test";>
+     <cxf:properties>
+       <entry key="dataFormat" value="RAW"/>
+       <entry key="setDefaultBus" value="true"/>
+     </cxf:properties>
+   </cxf:cxfEndpoint>
 ----
+====
+
+== Examples
+
+=== How to create a simple CXF service with POJO data format
+
+Having simple java web service interface:
 
-You can also consume a Camel message received from a CXF endpoint in Payload 
mode.
-The 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/mtom/CxfMtomConsumerPayloadModeTest.java#L97[CxfMtomConsumerPayloadModeTest]
 illustrates how this works:
 
 [source,java]
 ----
-public static class MyProcessor implements Processor {
+package org.apache.camel.component.cxf.soap.server;
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public void process(Exchange exchange) throws Exception {
-        CxfPayload<SoapHeader> in = exchange.getIn().getBody(CxfPayload.class);
+@WebService(targetNamespace = 
"http://server.soap.cxf.component.camel.apache.org/";, name = "EchoService")
+public interface EchoService {
 
-        // verify request
-        assertEquals(1, in.getBody().size());
+    String echo(String text);
+}
+----
 
-        Map<String, String> ns = new HashMap<>();
-        ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS);
-        ns.put("xop", MtomTestHelper.XOP_NS);
+And implementation:
 
-        XPathUtils xu = new XPathUtils(ns);
-        Element body = new XmlConverter().toDOMElement(in.getBody().get(0));
-        Element ele = (Element) 
xu.getValue("//ns:Detail/ns:photo/xop:Include", body,
-                XPathConstants.NODE);
-        String photoId = ele.getAttribute("href").substring(4); // skip "cid:"
-        assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId);
+[source,java]
+----
 
-        ele = (Element) xu.getValue("//ns:Detail/ns:image/xop:Include", body,
-                XPathConstants.NODE);
-        String imageId = ele.getAttribute("href").substring(4); // skip "cid:"
-        assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId);
+package org.apache.camel.component.cxf.soap.server;
 
-        DataHandler dr = 
exchange.getIn(AttachmentMessage.class).getAttachment(photoId);
-        assertEquals("application/octet-stream", dr.getContentType());
-        assertArrayEquals(MtomTestHelper.REQ_PHOTO_DATA, 
IOUtils.readBytesFromStream(dr.getInputStream()));
+@WebService(name = "EchoService", serviceName = "EchoService", targetNamespace 
= "http://server.soap.cxf.component.camel.apache.org/";)
+public class EchoServiceImpl implements EchoService {
 
-        dr = exchange.getIn(AttachmentMessage.class).getAttachment(imageId);
-        assertEquals("image/jpeg", dr.getContentType());
-        assertArrayEquals(MtomTestHelper.requestJpeg, 
IOUtils.readBytesFromStream(dr.getInputStream()));
+    @Override
+    public String echo(String text) {
+        return text;
+    }
 
-        // create response
-        List<Source> elements = new ArrayList<>();
-        elements.add(new DOMSource(StaxUtils.read(new 
StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement()));
-        CxfPayload<SoapHeader> sbody = new CxfPayload<>(
-                new ArrayList<SoapHeader>(),
-                elements, null);
-        exchange.getMessage().setBody(sbody);
-        
exchange.getMessage(AttachmentMessage.class).addAttachment(MtomTestHelper.RESP_PHOTO_CID,
-                new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.RESP_PHOTO_DATA, 
"application/octet-stream")));
+}
+----
 
-        
exchange.getMessage(AttachmentMessage.class).addAttachment(MtomTestHelper.RESP_IMAGE_CID,
-                new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.responseJpeg, "image/jpeg")));
+We can then create the simplest CXF service (note we didn't specify the `POJO` 
mode, as it is the default mode):
 
-    }
-}
+[source,java]
+----
+    
from("cxf:echoServiceResponseFromImpl?serviceClass=org.apache.camel.component.cxf.soap.server.EchoServiceImpl&address=/echo-impl")//
 no body set here; the response comes from EchoServiceImpl
+                .log("${body}");
 ----
 
-=== RAW Mode
+For more complicated implementation of the service (more "Camel way"), we can 
set the body from the route instead:
 
-Attachments are not supported as it does not process the message at all.
+[source,java]
+----
+    
from("cxf:echoServiceResponseFromRoute?serviceClass=org.apache.camel.component.cxf.soap.server.EchoServiceImpl&address=/echo-route")
+                .setBody(exchange -> 
exchange.getMessage().getBody(String.class) + " from Camel route");
+----
 
-===  CXF_MESSAGE Mode
 
-MTOM is supported, and Attachments can be retrieved by Camel Message APIs 
mentioned above. Note that when receiving a multipart (i.e., MTOM) message, the 
default `SOAPMessag`e to `String` converter will provide the complete multipart 
payload on the body.
-If you require just the SOAP XML as a String, you can set the message body
-with `message.getSOAPPart()`, and the Camel converter can do the rest of the 
work
-for you.
+=== How to consume a message from a Camel CXF endpoint in POJO data format
 
-== Streaming Support in PAYLOAD mode
+The Camel CXF endpoint consumer POJO data format is based on the
+http://cxf.apache.org/docs/invokers.html[CXF invoker], so the
+message header has a property with the name of
+`CxfConstants.OPERATION_NAME` and the message body is a list of the SEI
+method parameters.
 
-The Camel CXF component now supports streaming of incoming
-messages when using PAYLOAD mode. Previously, the incoming messages
-would have been completely DOM parsed. For large messages, this is 
time-consuming and uses a significant amount of memory.
-The incoming messages can remain as a `javax.xml.transform.Source` while
-being routed and, if nothing modifies the payload, can then be directly
-streamed out to the target destination. For common "simple proxy" use
-cases (example: `from("cxf:...").to("cxf:...")`), this can provide very
-significant performance increases as well as significantly lowered
-memory requirements.
+Consider the 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/wsdl_first/PersonProcessor.java[PersonProcessor]
 example code:
 
-However, there are cases where streaming may not be appropriate or
-desired. Due to the streaming nature, invalid incoming XML may not be
-caught until later in the processing chain. Also, certain actions may
-require the message to be DOM parsed anyway (like WS-Security or message
-tracing and such) in which case, the advantages of the streaming are
-limited. At this point, there are two ways to control the streaming:
+[source,java]
+----
+public class PersonProcessor implements Processor {
 
-* Endpoint property: you can add `allowStreaming=false` as an endpoint
-property to turn the streaming on/off.
+    private static final Logger LOG = 
LoggerFactory.getLogger(PersonProcessor.class);
 
-* Component property: the `CxfComponent` object also has an `allowStreaming`
-property that can set the default for endpoints created from that
-component.
+    @Override
+    @SuppressWarnings("unchecked")
+    public void process(Exchange exchange) throws Exception {
+        LOG.info("processing exchange in camel");
 
-Global system property: you can add a system property of
-`org.apache.camel.component.cxf.streaming` to `false` to turn it off.
-That sets the global default, but setting the endpoint property above
-will override this value for that endpoint.
+        BindingOperationInfo boi = (BindingOperationInfo) 
exchange.getProperty(BindingOperationInfo.class.getName());
+        if (boi != null) {
+            LOG.info("boi.isUnwrapped" + boi.isUnwrapped());
+        }
+        // Get the parameter list which element is the holder.
+        MessageContentsList msgList = (MessageContentsList) 
exchange.getIn().getBody();
+        Holder<String> personId = (Holder<String>) msgList.get(0);
+        Holder<String> ssn = (Holder<String>) msgList.get(1);
+        Holder<String> name = (Holder<String>) msgList.get(2);
+
+        if (personId.value == null || personId.value.length() == 0) {
+            LOG.info("person id 123, so throwing exception");
+            // Try to throw out the soap fault message
+            org.apache.camel.wsdl_first.types.UnknownPersonFault personFault
+                    = new 
org.apache.camel.wsdl_first.types.UnknownPersonFault();
+            personFault.setPersonId("");
+            org.apache.camel.wsdl_first.UnknownPersonFault fault
+                    = new org.apache.camel.wsdl_first.UnknownPersonFault("Get 
the null value of person name", personFault);
+            exchange.getMessage().setBody(fault);
+            return;
+        }
 
-== Using the generic CXF Dispatch mode
+        name.value = "Bonjour";
+        ssn.value = "123";
+        LOG.info("setting Bonjour as the response");
+        // Set the response message, the first element is the return value of 
the operation,
+        // the others are the holders of method parameters
+        exchange.getMessage().setBody(new Object[] { null, personId, ssn, name 
});
+    }
 
-The Camel CXF component supports the generic
-https://cxf.apache.org/docs/jax-ws-dispatch-api.html[CXF dispatch mode] that 
can transport messages of arbitrary structures (i.e., not bound to a specific 
XML schema).
-To use this mode, you omit specifying the `wsdlURL` and `serviceClass` 
attributes of the CXF endpoint.
+}
+----
+
+=== How to prepare the message for the Camel CXF endpoint in POJO data format
+
+The Camel CXF endpoint producer is based on the
+https://github.com/apache/cxf/blob/master/core/src/main/java/org/apache/cxf/endpoint/Client.java[CXF
 client API].
+First, you need to specify the operation name in the message
+header, then add the method parameters to a list, and initialize the
+message with this parameter list. The response message's body is a
+messageContentsList, you can get the result from that list.
+
+If you don't specify the operation name in the message header,
+`CxfProducer` will try to use the `defaultOperationName` from
+`CxfEndpoint`, if there is no `defaultOperationName` set on
+`CxfEndpoint`, it will pick up the first operationName from the Operation
+list.
+
+If you want to get the object array from the message body, you can get
+the body using `message.getBody(Object[].class)`, as shown in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfProducerRouterTest.java#L117[CxfProducerRouterTest.testInvokingSimpleServerWithParams]:
 
-[tabs]
-====
-Java (Quarkus)::
-+
 [source,java]
 ----
-import org.apache.camel.component.cxf.common.DataFormat;
-import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
-import jakarta.enterprise.context.SessionScoped;
-import jakarta.enterprise.inject.Produces;
-import jakarta.inject.Named;
+Exchange senderExchange = new DefaultExchange(context, ExchangePattern.InOut);
+final List<String> params = new ArrayList<>();
+// Prepare the request message for the camel-cxf procedure
+params.add(TEST_MESSAGE);
+senderExchange.getIn().setBody(params);
+senderExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ECHO_OPERATION);
 
-...
+Exchange exchange = template.send("direct:EndpointA", senderExchange);
 
-@Produces
-@SessionScoped
-@Named
-CxfEndpoint dispatchEndpoint() {
-    final CxfEndpoint result = new CxfEndpoint();
-    result.setDataFormat(DataFormat.PAYLOAD);
-    result.setAddress("/SoapAnyPort");
-    return result;
-}
+org.apache.camel.Message out = exchange.getMessage();
+// The response message's body is a MessageContentsList which first element is 
the return value of the operation,
+// If there are some holder parameters, the holder parameter will be filled in 
the reset of List.
+// The result will be extracted from the MessageContentsList with the String 
class type
+MessageContentsList result = (MessageContentsList) out.getBody();
+LOG.info("Received output text: " + result.get(0));
+Map<String, Object> responseContext = CastUtils.cast((Map<?, ?>) 
out.getHeader(Client.RESPONSE_CONTEXT));
+assertNotNull(responseContext);
+assertEquals("UTF-8", 
responseContext.get(org.apache.cxf.message.Message.ENCODING),
+        "We should get the response context here");
+assertEquals("echo " + TEST_MESSAGE, result.get(0), "Reply body on Camel is 
wrong");
 ----
 
-XML (Spring)::
-+
-[source,xml]
+=== How to consume a message from a Camel CXF endpoint in PAYLOAD data format
+
+`PAYLOAD` means that you process the payload from the SOAP
+envelope as a native CxfPayload. `Message.getBody()` will return a
+`org.apache.camel.component.cxf.CxfPayload` object, with getters
+for SOAP message headers and the SOAP body.
+
+See 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerPayloadTest.java#L68[CxfConsumerPayloadTest]:
+
+[source,java]
 ----
-<cxf:cxfEndpoint id="dispatchEndpoint" 
address="http://localhost:9000/SoapContext/SoapAnyPort";>
-    <cxf:properties>
-        <entry key="dataFormat" value="PAYLOAD"/>
-    </cxf:properties>
-</cxf:cxfEndpoint>
+protected RouteBuilder createRouteBuilder() {
+    return new RouteBuilder() {
+        public void configure() {
+            from(simpleEndpointURI + 
"&dataFormat=PAYLOAD").to("log:info").process(new Processor() {
+                @SuppressWarnings("unchecked")
+                public void process(final Exchange exchange) throws Exception {
+                    CxfPayload<SoapHeader> requestPayload = 
exchange.getIn().getBody(CxfPayload.class);
+                    List<Source> inElements = requestPayload.getBodySources();
+                    List<Source> outElements = new ArrayList<>();
+                    // You can use a customer toStringConverter to turn a 
CxfPayLoad message into String as you want
+                    String request = exchange.getIn().getBody(String.class);
+                    XmlConverter converter = new XmlConverter();
+                    String documentString = ECHO_RESPONSE;
+
+                    Element in = new 
XmlConverter().toDOMElement(inElements.get(0));
+                    // Check the element namespace
+                    if (!in.getNamespaceURI().equals(ELEMENT_NAMESPACE)) {
+                        throw new IllegalArgumentException("Wrong element 
namespace");
+                    }
+                    if (in.getLocalName().equals("echoBoolean")) {
+                        documentString = ECHO_BOOLEAN_RESPONSE;
+                        checkRequest("ECHO_BOOLEAN_REQUEST", request);
+                    } else {
+                        documentString = ECHO_RESPONSE;
+                        checkRequest("ECHO_REQUEST", request);
+                    }
+                    Document outDocument = 
converter.toDOMDocument(documentString, exchange);
+                    outElements.add(new 
DOMSource(outDocument.getDocumentElement()));
+                    // set the payload header with null
+                    CxfPayload<SoapHeader> responsePayload = new 
CxfPayload<>(null, outElements, null);
+                    exchange.getMessage().setBody(responsePayload);
+                }
+            });
+        }
+    };
+}
 ----
-====
 
-It is noted that the default CXF dispatch client does not send a
-specific `SOAPAction` header. Therefore, when the target service requires
-a specific `SOAPAction` value, it is supplied in the Camel header using
-the key `SOAPAction` (case-insensitive).
+=== How to get and set SOAP headers in POJO mode
 
-[#cxf-loggingout-interceptor-in-message-mode]
-=== How to enable CXF's LoggingOutInterceptor in RAW mode
+`POJO` means that the data format is a _"list of Java objects"_ when the
+Camel CXF endpoint produces or consumes Camel exchanges. Even though
+Camel exposes the message body as POJOs in this mode, Camel CXF still
+provides access to read and write SOAP headers. However, since CXF
+interceptors remove in-band SOAP headers from the header list, after they
+have been processed, only out-of-band SOAP headers are available to
+Camel CXF in POJO mode.
 
-CXF's `LoggingOutInterceptor` outputs outbound message that goes on the
-wire to logging system (Java Util Logging). Since the
-`LoggingOutInterceptor` is in `PRE_STREAM` phase (but `PRE_STREAM` phase
-is removed in `RAW` mode), you have to configure
-`LoggingOutInterceptor` to be run during the `WRITE` phase. The
-following is an example.
+The following example illustrates how to get/set SOAP headers. Suppose we
+have a route that forwards from one Camel CXF endpoint to another. That
+is, `SOAP Client -> Camel -> CXF service`. We can attach two processors to
+obtain/insert SOAP headers at (1) before a request goes out to the CXF
+service and (2) before the response comes back to the SOAP Client. Processors
+(1) and (2) in this example are `InsertRequestOutHeaderProcessor` and
+`InsertResponseOutHeaderProcessor`. Our route looks like this:
 
 [tabs]
 ====
-Java (Quarkus)::
+Java::
 +
 [source,java]
 ----
-import java.util.List;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.cxf.common.DataFormat;
-import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
-import org.apache.cxf.interceptor.LoggingOutInterceptor;
-import org.apache.cxf.phase.Phase;
-import jakarta.enterprise.context.SessionScoped;
-import jakarta.enterprise.inject.Produces;
-import jakarta.inject.Named;
-
-...
-
-@Produces
-@SessionScoped
-@Named
-CxfEndpoint soapMtomEnabledServerPayloadModeEndpoint() {
-    final CxfEndpoint result = new CxfEndpoint();
-    result.setServiceClass(HelloService.class);
-    result.setDataFormat(DataFormat.RAW);
-    result.setOutFaultInterceptors(List.of(new 
LoggingOutInterceptor(Phase.WRITE)));;
-    result.setAddress("/helloworld");
-    return result;
-}
+from("cxf:bean:routerRelayEndpointWithInsertion")
+    .process(new InsertRequestOutHeaderProcessor())
+    .to("cxf:bean:serviceRelayEndpointWithInsertion")
+    .process(new InsertResponseOutHeaderProcessor());
 ----
 
-XML (Spring)::
+XML::
 +
 [source,xml]
 ----
-<bean id="loggingOutInterceptor" 
class="org.apache.cxf.interceptor.LoggingOutInterceptor">
-    <!--  it really should have been user-prestream, but CXF does have such a 
phase! -->
-    <constructor-arg value="write"/>
-</bean>
-
-<cxf:cxfEndpoint id="serviceEndpoint" 
address="http://localhost:${CXFTestSupport.port2}/LoggingInterceptorInMessageModeTest/helloworld";
-    serviceClass="org.apache.camel.component.cxf.HelloService">
-    <cxf:outInterceptors>
-        <ref bean="loggingOutInterceptor"/>
-    </cxf:outInterceptors>
-    <cxf:properties>
-        <entry key="dataFormat" value="RAW"/>
-    </cxf:properties>
-</cxf:cxfEndpoint>
+<route>
+    <from uri="cxf:bean:routerRelayEndpointWithInsertion"/>
+    <process ref="InsertRequestOutHeaderProcessor" />
+    <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/>
+    <process ref="InsertResponseOutHeaderProcessor" />
+</route>
 ----
 ====
 
-== Description of CxfHeaderFilterStrategy options
+SOAP headers are propagated to and from Camel Message headers. The Camel
+message header name is `org.apache.cxf.headers.Header.list` which is a
+constant defined in CXF (`org.apache.cxf.headers.Header.HEADER_LIST`). The
+header value is a List of CXF `SoapHeader` objects
+(`org.apache.cxf.binding.soap.SoapHeader`).
+The following snippet is the `InsertResponseOutHeaderProcessor` (that inserts 
a new SOAP header in the response message). The way to access SOAP headers in 
both
+`InsertResponseOutHeaderProcessor` and `InsertRequestOutHeaderProcessor` are
+actually the same.
+The only difference between the two processors is setting the direction of the 
inserted SOAP header.
 
-There are _in-band_ and _out-of-band_ on-the-wire headers from the
-perspective of a JAXWS WSDL-first developer.
+You can find the `InsertResponseOutHeaderProcessor` example in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/soap/headers/CxfMessageHeadersRelayTest.java#L731[CxfMessageHeadersRelayTest]:
 
-The _in-band_ headers are headers that are explicitly defined as part of
-the WSDL binding contract for an endpoint such as SOAP headers.
+[source,java]
+----
+public static class InsertResponseOutHeaderProcessor implements Processor {
 
-The _out-of-band_ headers are headers that are serialized over the wire,
-but are not explicitly part of the WSDL binding contract.
+    public void process(Exchange exchange) throws Exception {
+        List<SoapHeader> soapHeaders = 
CastUtils.cast((List<?>)exchange.getIn().getHeader(Header.HEADER_LIST));
 
-Headers relaying/filtering is bi-directional.
+        // Insert a new header
+        String xml = "<?xml version=\"1.0\" 
encoding=\"utf-8\"?><outofbandHeader "
+            + "xmlns=\"http://cxf.apache.org/outofband/Header\"; 
hdrAttribute=\"testHdrAttribute\" "
+            + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"; 
soap:mustUnderstand=\"1\">"
+            + 
"<name>New_testOobHeader</name><value>New_testOobHeaderValue</value></outofbandHeader>";
+        SoapHeader newHeader = new SoapHeader(soapHeaders.get(0).getName(),
+                       DOMUtils.readXml(new 
StringReader(xml)).getDocumentElement());
+        // make sure the direction is OUT since it is a response message.
+        newHeader.setDirection(Direction.DIRECTION_OUT);
+        //newHeader.setMustUnderstand(false);
+        soapHeaders.add(newHeader);
 
-When a route has a CXF endpoint and the developer needs to have
-on-the-wire headers, such as SOAP headers, be relayed along the route to
-be consumed say by another JAXWS endpoint, a `CxfHeaderFilterStrategy`
-instance should be set on the CXF endpoint, then `relayHeaders` property
-of the `CxfHeaderFilterStrategy` instance should be set to `true`, which
-is the default value. Plus, the `CxfHeaderFilterStrategy` instance also
-holds a list of `MessageHeaderFilter` interface, which decides if a specific
-header will be relayed or not.
+    }
 
-Take a look at the tests that show how you'd be able to relay/drop
-headers here:
+}
+----
 
-https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/soap/headers/CxfMessageHeadersRelayTest.java[CxfMessageHeadersRelayTest]
+=== How to get and set SOAP headers in PAYLOAD mode
 
-* The `relayHeaders=true` expresses an intent to relay the headers. The
-actual decision on whether a given header is relayed is delegated to a
-pluggable instance that implements the `MessageHeaderFilter` interface.
-A concrete implementation of `MessageHeaderFilter` will be consulted to
-decide if a header needs to be relayed or not. There is already an
-implementation of `SoapMessageHeaderFilter` which binds itself to
-well-known SOAP name spaces.  If there is a header on the wire whose name space
-is unknown to the runtime, the header will be simply relayed.
+We've already shown how to access the SOAP message as `CxfPayload` object in
+PAYLOAD mode in the section <<How to consume a message from a Camel CXF 
endpoint in PAYLOAD data format>>.
 
-* `POJO` and `PAYLOAD` modes are supported. In `POJO` mode, only
-out-of-band message headers are available for filtering as the in-band
-headers have been processed and removed from the header list by CXF. The
-in-band headers are incorporated into the `MessageContentList` in POJO
-mode. The Camel CXF component does make any attempt to remove the
-in-band headers from the `MessageContentList`. If filtering of in-band
-headers is required, please use `PAYLOAD` mode or plug in a (pretty
-straightforward) CXF interceptor/JAXWS Handler to the CXF endpoint.
- Here is an example of configuring the `CxfHeaderFilterStrategy`.
+Once you obtain a `CxfPayload` object, you can invoke the
+`CxfPayload.getHeaders()` method that returns a List of DOM Elements (SOAP
+headers).
 
+For example, see 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfPayLoadSoapHeaderTest.java#L53[CxfPayLoadSoapHeaderTest]:
 
-[source,xml]
+[source,java]
 ----
-<bean id="dropAllMessageHeadersStrategy" 
class="org.apache.camel.component.cxf.transport.header.CxfHeaderFilterStrategy">
+from(getRouterEndpointURI()).process(new Processor() {
+    @SuppressWarnings("unchecked")
+    public void process(Exchange exchange) throws Exception {
+        CxfPayload<SoapHeader> payload = 
exchange.getIn().getBody(CxfPayload.class);
+        List<Source> elements = payload.getBodySources();
+        assertNotNull(elements, "We should get the elements here");
+        assertEquals(1, elements.size(), "Get the wrong elements size");
 
-    <!--  Set relayHeaders to false to drop all SOAP headers -->
-    <property name="relayHeaders" value="false"/>
+        Element el = new XmlConverter().toDOMElement(elements.get(0));
+        elements.set(0, new DOMSource(el));
+        assertEquals("http://camel.apache.org/pizza/types";,
+                el.getNamespaceURI(), "Get the wrong namespace URI");
 
-</bean>
-----
+        List<SoapHeader> headers = payload.getHeaders();
+        assertNotNull(headers, "We should get the headers here");
+        assertEquals(1, headers.size(), "Get the wrong headers size");
+        assertEquals("http://camel.apache.org/pizza/types";,
+                ((Element) (headers.get(0).getObject())).getNamespaceURI(), 
"Get the wrong namespace URI");
+        // alternatively, you can also get the SOAP header via the camel 
header:
+        headers = exchange.getIn().getHeader(Header.HEADER_LIST, List.class);
+        assertNotNull(headers, "We should get the headers here");
+        assertEquals(1, headers.size(), "Get the wrong headers size");
+        assertEquals("http://camel.apache.org/pizza/types";,
+                ((Element) (headers.get(0).getObject())).getNamespaceURI(), 
"Get the wrong namespace URI");
 
-Then, your endpoint can reference the `CxfHeaderFilterStrategy`:
+    }
 
-[source,xml]
-----
-<route>
-    <from 
uri="cxf:bean:routerNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/>
-    <to 
uri="cxf:bean:serviceNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/>
-</route>
+})
+.to(getServiceEndpointURI());
 ----
 
-* You can plug in your own `MessageHeaderFilter` implementations overriding
-or adding additional ones to the list of relays. To override a
-preloaded relay instance, make sure that your `MessageHeaderFilter`
-implementation services the same name spaces as the one you are looking to
-override.
+You can also use the same way as described in
+subchapter "How to get and set SOAP headers in POJO mode" to set or get
+the SOAP headers. So, you can use the
+header `org.apache.cxf.headers.Header.list` to get and set a list of
+SOAP headers.This does also mean that if you have a route that forwards
+from one Camel CXF endpoint to another (`SOAP Client -> Camel -> CXF
+service`), now also the SOAP headers sent by the SOAP client are
+forwarded to the CXF service. If you do not want that these headers are
+forwarded, you have to remove them in the Camel header
+`org.apache.cxf.headers.Header.list`.
 
-Here is an example of configuring user defined Message Header Filters:
+=== SOAP headers are not available in RAW mode
 
-[source,xml]
+SOAP headers are not available in RAW mode as SOAP processing is
+skipped.
+
+=== How to throw a SOAP Fault from Camel
+
+If you are using a Camel CXF endpoint to consume the SOAP request, you
+may need to throw the SOAP Fault from the camel context. +
+ Basically, you can use the `throwFault` DSL to do that; it works for
+`POJO`, `PAYLOAD` and `RAW` data format. +
+ You can define the soap fault as shown in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfCustomizedExceptionTest.java#L65[CxfCustomizedExceptionTest]:
+
+[source,java]
+----
+SOAP_FAULT = new SoapFault(EXCEPTION_MESSAGE, SoapFault.FAULT_CODE_CLIENT);
+Element detail = SOAP_FAULT.getOrCreateDetail();
+Document doc = detail.getOwnerDocument();
+Text tn = doc.createTextNode(DETAIL_TEXT);
+detail.appendChild(tn);
 ----
-<bean id="customMessageFilterStrategy" 
class="org.apache.camel.component.cxf.transport.header.CxfHeaderFilterStrategy">
-    <property name="messageHeaderFilters">
-        <list>
-            <!--  SoapMessageHeaderFilter is the built-in filter.  It can be 
removed by omitting it. -->
-            <bean 
class="org.apache.camel.component.cxf.common.header.SoapMessageHeaderFilter"/>
 
-            <!--  Add custom filter here -->
-            <bean 
class="org.apache.camel.component.cxf.soap.headers.CustomHeaderFilter"/>
-        </list>
-    </property>
-</bean>
+Then throw it as you like:
+
+[source,java]
+----
+from(routerEndpointURI).setFaultBody(constant(SOAP_FAULT));
 ----
 
-* In addition to `relayHeaders`, the following properties can be
-configured in `CxfHeaderFilterStrategy`.
 
-[width="100%",cols="10%,10%,80%",options="header",]
-|=======================================================================
-|Name |Required |Description
-|`relayHeaders` |No |All message headers will be processed by Message Header 
Filters
- _Type_: `boolean`
- _Default_: `true`
+If your CXF endpoint is working in the `RAW` data format, you could
+set the SOAP Fault message in the message body and set the response
+code in the message header as demonstrated by 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfMessageStreamExceptionTest.java#L43[CxfMessageStreamExceptionTest]:
 
-|`relayAllMessageHeaders` | No |All message headers will be propagated 
(without processing by Message
-Header Filters)
- _Type_: `boolean`
- _Default_: `false`
+[source,java]
+----
+from(routerEndpointURI).process(new Processor() {
 
-|`allowFilterNamespaceClash` |No |If two filters overlap in activation 
namespace, the property controls how
-it should be handled. If the value is `true`, last one wins. If the
-value is `false`, it will throw an exception
- _Type_: `boolean`
- _Default_: `false`
-|=======================================================================
+    public void process(Exchange exchange) throws Exception {
+        Message out = exchange.getMessage();
+        // Set the message body
+        
out.setBody(this.getClass().getResourceAsStream("SoapFaultMessage.xml"));
+        // Set the response code here
+        out.setHeader(org.apache.cxf.message.Message.RESPONSE_CODE, new 
Integer(500));
+    }
 
-== How to make the Camel CXF component use log4j instead of java.util.logging
+});
+----
 
-CXF's default logger is `java.util.logging`. If you want to change it to
-log4j, proceed as follows. Create a file, in the classpath, named
-`META-INF/cxf/org.apache.cxf.logger`. This file should contain the
-fully qualified name of the class,
-`org.apache.cxf.common.logging.Log4jLogger`, with no comments, on a
-single line.
+Same for using POJO data format. You can set the SOAPFault on the _OUT_ body.
 
-== How to let Camel CXF response start with xml processing instruction
+[#propagate-request-response-context]
+=== How to propagate a Camel CXF endpoint's request and response context
 
-If you are using some SOAP client such as PHP, you will get this kind of
-error because CXF doesn't add the XML processing instruction
-`<?xml version="1.0" encoding="utf-8"?>`:
+https://github.com/apache/cxf/blob/master/core/src/main/java/org/apache/cxf/endpoint/Client.java[CXF
 client API] provides a way to invoke the operation with request and
+response context.
+If you are using a Camel CXF endpoint producer to
+invoke the outside web service, you can set the request context and get
+response context with the following code:
 
+[source,java]
 ----
-Error:sendSms: SoapFault exception: [Client] looks like we got no XML document 
in [...]
+CxfExchange exchange = (CxfExchange)template.send(getJaxwsEndpointUri(), new 
Processor() {
+     public void process(final Exchange exchange) {
+         final List<String> params = new ArrayList<String>();
+         params.add(TEST_MESSAGE);
+         // Set the request context to the inMessage
+         Map<String, Object> requestContext = new HashMap<String, Object>();
+         requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
JAXWS_SERVER_ADDRESS);
+         exchange.getIn().setBody(params);
+         exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext);
+         exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, 
GREET_ME_OPERATION);
+     }
+});
+org.apache.camel.Message out = exchange.getMessage();
+// The output is an object array, the first element of the array is the return 
value
+Object\[\] output = out.getBody(Object\[\].class);
+LOG.info("Received output text: " + output\[0\]);
+// Get the response context form outMessage
+Map<String, Object> responseContext = 
CastUtils.cast((Map)out.getHeader(Client.RESPONSE_CONTEXT));
+assertNotNull(responseContext);
+assertEquals("Get the wrong wsdl operation name", 
"{http://apache.org/hello_world_soap_http}greetMe";,
+    responseContext.get("javax.xml.ws.wsdl.operation").toString());
 ----
 
-To resolve this issue, you need to tell `StaxOutInterceptor` to
-write the XML start document for you, as in the 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/WriteXmlDeclarationInterceptor.java[WriteXmlDeclarationInterceptor]
 below:
+=== Attachment Support
+
+=== POJO Mode
+
+Message Transmission Optimization Mechanism (MTOM) is supported if enabled - 
check
+the example in Payload Mode for enabling MTOM.
+Since attachments are marshalled and unmarshalled into POJOs, the attachments 
should be
+retrieved from the Apache Camel message body (as a parameter list), and it 
isn't
+possible to retrieve attachments by Camel Message API
 
 [source,java]
 ----
-public class WriteXmlDeclarationInterceptor extends 
AbstractPhaseInterceptor<SoapMessage> {
-    public WriteXmlDeclarationInterceptor() {
-        super(Phase.PRE_STREAM);
-        addBefore(StaxOutInterceptor.class.getName());
-    }
+DataHandler handler = 
Exchange.getIn(AttachmentMessage.class).getAttachment("id");
+----
 
-    public void handleMessage(SoapMessage message) throws Fault {
-        message.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE);
-    }
+=== Payload Mode
 
-}
-----
+Message Transmission Optimization Mechanism (MTOM) is supported by this Mode.
+Attachments can be retrieved by Camel Message APIs mentioned above.
+SOAP with Attachment (SwA) is supported and attachments can be retrieved.
+SwA is the default (same as setting the CXF endpoint property `mtomEnabled` to 
`false`).
 
-As an alternative, you can add a message header for it as demonstrated in 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-soap/src/test/java/org/apache/camel/component/cxf/jaxws/CxfConsumerTest.java#L62[CxfConsumerTest]:
+To enable MTOM, set the CXF endpoint property `mtomEnabled` to `true`.
 
+[tabs]
+====
+Java (Quarkus)::
++
 [source,java]
 ----
- // set up the response context which force start document
- Map<String, Object> map = new HashMap<String, Object>();
- map.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE);
- exchange.getMessage().setHeader(Client.RESPONSE_CONTEXT, map);
-----
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.common.DataFormat;
+import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.enterprise.inject.Produces;
+import jakarta.inject.Named;
 
-== Configure the CXF endpoints with Spring
+@ApplicationScoped
+public class CxfSoapMtomRoutes extends RouteBuilder {
 
-You can configure the CXF endpoint with the Spring configuration file
-shown below, and you can also embed the endpoint into the `camelContext`
-tags. When you are invoking the service endpoint, you can set the
-`operationName` and `operationNamespace` headers to explicitly state
-which operation you are calling.
+    @Override
+    public void configure() {
+        from("cxf:bean:mtomPayloadModeEndpoint")
+                .process( exchange -> { ... });
+    }
 
+    @Produces
+    @SessionScoped
+    @Named
+    CxfEndpoint mtomPayloadModeEndpoint() {
+        final CxfEndpoint result = new CxfEndpoint();
+        result.setServiceClass(MyMtomService.class);
+        result.setDataFormat(DataFormat.PAYLOAD);
+        result.setMtomEnabled(true);
+        result.setAddress("/mtom/hello");
+        return result;
+    }
+}
+----
+
+XML (Spring)::
++
 [source,xml]
 ----
-<beans xmlns="http://www.springframework.org/schema/beans";
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
-        xmlns:cxf="http://camel.apache.org/schema/cxf";
-        xsi:schemaLocation="
-        http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
-        http://camel.apache.org/schema/cxf 
http://camel.apache.org/schema/cxf/camel-cxf.xsd
-        http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd";>
-     <cxf:cxfEndpoint id="routerEndpoint" 
address="http://localhost:9003/CamelContext/RouterPort";
-            serviceClass="org.apache.hello_world_soap_http.GreeterImpl"/>
-     <cxf:cxfEndpoint id="serviceEndpoint" 
address="http://localhost:9000/SoapContext/SoapPort";
-            wsdlURL="testutils/hello_world.wsdl"
-            serviceClass="org.apache.hello_world_soap_http.Greeter"
-            endpointName="s:SoapPort"
-            serviceName="s:SOAPService"
-        xmlns:s="http://apache.org/hello_world_soap_http"; />
-     <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring";>
-       <route>
-         <from uri="cxf:bean:routerEndpoint" />
-         <to uri="cxf:bean:serviceEndpoint" />
-       </route>
-    </camelContext>
-  </beans>
+<cxf:cxfEndpoint id="mtomPayloadModeEndpoint" 
address="http://localhost:${CXFTestSupport.port1}/CxfMtomRouterPayloadModeTest/mtom";
+        wsdlURL="mtom.wsdl"
+        serviceName="ns:MyMtomService"
+        endpointName="ns:MyMtomPort"
+        xmlns:ns="http://apache.org/camel/cxf/mtom_feature";>
+
+    <cxf:properties>
+        <!--  enable mtom by setting this property to true -->
+        <entry key="mtom-enabled" value="true"/>
+        <!--  set the Camel CXF endpoint data fromat to PAYLOAD mode -->
+        <entry key="dataFormat" value="PAYLOAD"/>
+    </cxf:properties>
+</cxf:cxfEndpoint>
 ----
+====
 
-Be sure to include the JAX-WS `schemaLocation` attribute specified on
-the root `beans` element. This allows CXF to validate the file and is
-required. Also note the namespace declarations at the end of the
-`<cxf:cxfEndpoint/>` tag. These declarations are required because the combined 
`\{namespace}localName` syntax is presently not supported for this tag's
-attribute values.
+You can produce a Camel message with attachment to send to a CXF endpoint in 
Payload mode.
 
-The `cxf:cxfEndpoint` element supports many additional attributes:
+[source,java]
+----
+Exchange exchange = 
context.createProducerTemplate().send("direct:testEndpoint", new Processor() {
 
-[width="100%",cols="50%,50%",options="header",]
-|=======================================================================
-|Name |Value
+    public void process(Exchange exchange) throws Exception {
+        exchange.setPattern(ExchangePattern.InOut);
+        List<Source> elements = new ArrayList<Source>();
+        elements.add(new DOMSource(DOMUtils.readXml(new 
StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement()));
+        CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new 
ArrayList<SoapHeader>(),
+            elements, null);
+        exchange.getIn().setBody(body);
+        
exchange.getIn(AttachmentMessage.class).addAttachment(MtomTestHelper.REQ_PHOTO_CID,
+            new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.REQ_PHOTO_DATA, 
"application/octet-stream")));
 
-|`PortName` |The endpoint name this service is implementing, it maps to the
-`wsdl:port@name`. In the format of `ns:PORT_NAME` where `ns` is a
-namespace prefix valid at this scope.
+        
exchange.getIn(AttachmentMessage.class).addAttachment(MtomTestHelper.REQ_IMAGE_CID,
+            new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.requestJpeg, "image/jpeg")));
 
-|`serviceName` |The service name this service is implementing, it maps to the
-`wsdl:service@name`. In the format of `ns:SERVICE_NAME` where `ns` is a
-namespace prefix valid at this scope.
+    }
 
-|`wsdlURL` |The location of the WSDL. Can be on the classpath, file system, or 
be
-hosted remotely.
+});
 
-|`bindingId` |The `bindingId` for the service model to use.
+// process response
 
-|`address` |The service publish address.
+CxfPayload<SoapHeader> out = exchange.getMessage().getBody(CxfPayload.class);
+assertEquals(1, out.getBody().size());
 
-|`bus` |The bus name that will be used in the JAX-WS endpoint.
+Map<String, String> ns = new HashMap<>();
+ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS);
+ns.put("xop", MtomTestHelper.XOP_NS);
 
-|`serviceClass` |The class name of the SEI (Service Endpoint Interface) class 
which could
-have JSR181 annotation or not.
-|=======================================================================
+XPathUtils xu = new XPathUtils(ns);
+Element oute = new XmlConverter().toDOMElement(out.getBody().get(0));
+Element ele = (Element) 
xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", oute,
+                XPathConstants.NODE);
+String photoId = ele.getAttribute("href").substring(4); // skip "cid:"
 
-It also supports many child elements:
+ele = (Element) xu.getValue("//ns:DetailResponse/ns:image/xop:Include", oute,
+                XPathConstants.NODE);
+String imageId = ele.getAttribute("href").substring(4); // skip "cid:"
 
-[width="100%",cols="50%,50%",options="header",]
-|=======================================================================
-|Name |Value
+DataHandler dr = 
exchange.getMessage(AttachmentMessage.class).getAttachment(decodingReference(photoId));
+assertEquals("application/octet-stream", dr.getContentType());
+assertArrayEquals(MtomTestHelper.RESP_PHOTO_DATA, 
IOUtils.readBytesFromStream(dr.getInputStream()));
 
-|`cxf:inInterceptors` |The incoming interceptors for this endpoint. A list of 
`<bean>` or
-`<ref>`.
+dr = 
exchange.getMessage(AttachmentMessage.class).getAttachment(decodingReference(imageId));
+assertEquals("image/jpeg", dr.getContentType());
 
-|`cxf:inFaultInterceptors` |The incoming fault interceptors for this endpoint. 
A list of `<bean>` or
-`<ref>`.
+BufferedImage image = ImageIO.read(dr.getInputStream());
+assertEquals(560, image.getWidth());
+assertEquals(300, image.getHeight());
+----
 
-|`cxf:outInterceptors` |The outgoing interceptors for this endpoint. A list of 
`<bean>` or
-`<ref>`.
+You can also consume a Camel message received from a CXF endpoint in Payload 
mode.
+The 
https://github.com/apache/camel/blob/main/components/camel-cxf/camel-cxf-spring-soap/src/test/java/org/apache/camel/component/cxf/mtom/CxfMtomConsumerPayloadModeTest.java#L97[CxfMtomConsumerPayloadModeTest]
 illustrates how this works:
 
-|`cxf:outFaultInterceptors` |The outgoing fault interceptors for this 
endpoint. A list of `<bean>` or
-`<ref>`.
+[source,java]
+----
+public static class MyProcessor implements Processor {
 
-|`cxf:properties` | A properties map which should be supplied to the JAX-WS 
endpoint. See
-below.
+    @Override
+    @SuppressWarnings("unchecked")
+    public void process(Exchange exchange) throws Exception {
+        CxfPayload<SoapHeader> in = exchange.getIn().getBody(CxfPayload.class);
 
-|`cxf:handlers` |A JAX-WS handler list which should be supplied to the JAX-WS 
endpoint.
-See below.
+        // verify request
+        assertEquals(1, in.getBody().size());
 
-|`cxf:dataBinding` |You can specify which `DataBinding` will be used in the 
endpoint.
-This can be supplied using the Spring `<bean class="MyDataBinding"/>`
-syntax.
+        Map<String, String> ns = new HashMap<>();
+        ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS);
+        ns.put("xop", MtomTestHelper.XOP_NS);
 
-|`cxf:binding` |You can specify the `BindingFactory` for this endpoint to use. 
This can
-be supplied using the Spring `<bean class="MyBindingFactory"/>` syntax.
+        XPathUtils xu = new XPathUtils(ns);
+        Element body = new XmlConverter().toDOMElement(in.getBody().get(0));
+        Element ele = (Element) 
xu.getValue("//ns:Detail/ns:photo/xop:Include", body,
+                XPathConstants.NODE);
+        String photoId = ele.getAttribute("href").substring(4); // skip "cid:"
+        assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId);
 
-|`cxf:features` |The features that hold the interceptors for this endpoint. A 
list of
-beans or refs
+        ele = (Element) xu.getValue("//ns:Detail/ns:image/xop:Include", body,
+                XPathConstants.NODE);
+        String imageId = ele.getAttribute("href").substring(4); // skip "cid:"
+        assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId);
 
-|`cxf:schemaLocations` |The schema locations for endpoint to use. A list of 
schemaLocations
+        DataHandler dr = 
exchange.getIn(AttachmentMessage.class).getAttachment(photoId);
+        assertEquals("application/octet-stream", dr.getContentType());
+        assertArrayEquals(MtomTestHelper.REQ_PHOTO_DATA, 
IOUtils.readBytesFromStream(dr.getInputStream()));
 
-|`cxf:serviceFactory` |The service factory for this endpoint to use. This can 
be supplied using
-the Spring `<bean class="MyServiceFactory"/>` syntax
-|=======================================================================
+        dr = exchange.getIn(AttachmentMessage.class).getAttachment(imageId);
+        assertEquals("image/jpeg", dr.getContentType());
+        assertArrayEquals(MtomTestHelper.requestJpeg, 
IOUtils.readBytesFromStream(dr.getInputStream()));
 
-You can find more advanced examples that show how to provide
-interceptors, properties and handlers on the CXF
-http://cxf.apache.org/docs/jax-ws-configuration.html[JAX-WS
-Configuration page].
+        // create response
+        List<Source> elements = new ArrayList<>();
+        elements.add(new DOMSource(StaxUtils.read(new 
StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement()));
+        CxfPayload<SoapHeader> sbody = new CxfPayload<>(
+                new ArrayList<SoapHeader>(),
+                elements, null);
+        exchange.getMessage().setBody(sbody);
+        
exchange.getMessage(AttachmentMessage.class).addAttachment(MtomTestHelper.RESP_PHOTO_CID,
+                new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.RESP_PHOTO_DATA, 
"application/octet-stream")));
 
-[NOTE]
-====
-You can use `cxf:properties` to set the Camel CXF endpoint's dataFormat
-and setDefaultBus properties from spring configuration file.
+        
exchange.getMessage(AttachmentMessage.class).addAttachment(MtomTestHelper.RESP_IMAGE_CID,
+                new DataHandler(new 
ByteArrayDataSource(MtomTestHelper.responseJpeg, "image/jpeg")));
 
-[source,xml]
-----
-<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/router";
-     serviceClass="org.apache.camel.component.cxf.HelloService"
-     endpointName="s:HelloPort"
-     serviceName="s:HelloService"
-     xmlns:s="http://www.example.com/test";>
-     <cxf:properties>
-       <entry key="dataFormat" value="RAW"/>
-       <entry key="setDefaultBus" value="true"/>
-     </cxf:properties>
-   </cxf:cxfEndpoint>
+    }
+}
 ----
-====
+
+
 
 include::spring-boot:partial$starter.adoc[]
diff --git a/components/camel-dataset/src/main/docs/dataset-component.adoc 
b/components/camel-dataset/src/main/docs/dataset-component.adoc
index 2bb2d3ebf6f..266f527721d 100644
--- a/components/camel-dataset/src/main/docs/dataset-component.adoc
+++ b/components/camel-dataset/src/main/docs/dataset-component.adoc
@@ -65,7 +65,9 @@ include::partial$component-endpoint-options.adoc[]
 include::partial$component-endpoint-headers.adoc[]
 // component headers: END
 
-== Configuring DataSet
+== Usage
+
+=== Configuring DataSet
 
 Camel will look up in the Registry for a bean implementing the `DataSet` 
interface.
 So you can register your own data set as:
@@ -77,34 +79,12 @@ So you can register your own data set as:
 </bean>
 ----
 
-== Example
-
-For example, to test that a set of messages are sent to a queue and then
-consumed from the queue without losing any messages:
-
-[source,java]
-----
-// send the dataset to a queue
-from("dataset:foo").to("activemq:SomeQueue");
-
-// now lets test that the messages are consumed correctly
-from("activemq:SomeQueue").to("dataset:foo");
-----
-
-The above would look in the Registry to find the
-`foo` `DataSet` instance which is used to create the messages.
-
-Then you create a `DataSet` implementation, such as using the
-`SimpleDataSet` as described below, configuring things like how big the
-data set is and what the messages look like etc.  
- 
-
-== DataSetSupport (abstract class)
+=== DataSetSupport (abstract class)
 
 The `DataSetSupport` abstract class is a nice starting point for new
 data set, and provides some useful features to derived classes.
 
-=== Properties on DataSetSupport
+==== Additional Properties on DataSetSupport
 
 [width="100%",cols="10%,10%,10%,70%",options="header",]
 |===
@@ -124,11 +104,11 @@ Useful for showing the progress of a large load test. If 
smaller than zero (` <
 `size` / 5, if is 0 then `size`, else set to `reportCount` value.
 |===
 
-== SimpleDataSet
+=== SimpleDataSet
 
 The `SimpleDataSet` extends `DataSetSupport`, and adds a default body.
 
-=== Additional Properties on SimpleDataSet
+==== Additional Properties on SimpleDataSet
 
 [width="100%",cols="10%,10%,10%,70%",options="header",]
 |===
@@ -141,12 +121,12 @@ configure the `SimpleDataSet` to use it by setting the
 `outputTransformer` property.
 |===
 
-== ListDataSet
+=== ListDataSet
 
 The List`DataSet` extends `DataSetSupport`, and adds a list of default
 bodies.
 
-=== Additional Properties on ListDataSet
+==== Additional Properties on ListDataSet
 
 [width="100%",cols="10%,10%,10%,70%",options="header",]
 |===
@@ -168,12 +148,12 @@ the payload for the exchange will be selected using the 
modulus of the
 `CamelDataSetIndex % defaultBodies.size()` )
 |===
 
-== FileDataSet
+=== FileDataSet
 
 The `FileDataSet` extends `ListDataSet`, and adds support for loading
 the bodies from a file.
 
-=== Additional Properties on FileDataSet
+==== Additional Properties on FileDataSet
 
 [width="100%",cols="10%,10%,10%,70%",options="header",]
 |===
@@ -185,5 +165,25 @@ the bodies from a file.
 the file into multiple payloads.
 |===
 
+== Example
+
+For example, to test that a set of messages are sent to a queue and then
+consumed from the queue without losing any messages:
+
+[source,java]
+----
+// send the dataset to a queue
+from("dataset:foo").to("activemq:SomeQueue");
+
+// now lets test that the messages are consumed correctly
+from("activemq:SomeQueue").to("dataset:foo");
+----
+
+The above would look in the Registry to find the
+`foo` `DataSet` instance which is used to create the messages.
+
+Then you create a `DataSet` implementation, such as using the
+`SimpleDataSet` as described below, configuring things like how big the
+data set is and what the messages look like etc.
 
 include::spring-boot:partial$starter.adoc[]
diff --git a/components/camel-datasonnet/src/main/docs/datasonnet-language.adoc 
b/components/camel-datasonnet/src/main/docs/datasonnet-language.adoc
index 1011870fae7..27a3f74305a 100644
--- a/components/camel-datasonnet/src/main/docs/datasonnet-language.adoc
+++ b/components/camel-datasonnet/src/main/docs/datasonnet-language.adoc
@@ -33,69 +33,9 @@ datasonnet("someDSExpression");
 include::partial$language-options.adoc[]
 // language options: END
 
-== Example
+== Usage
 
-Here is a simple example using a DataSonnet expression as a predicate in a 
Message Filter:
-
-[tabs]
-====
-Java::
-+
-[source,java]
-------------------------------------------------------------------------------------------------
-// let's route if a line item is over $100
-from("queue:foo")
-    .filter(datasonnet("ds.arrays.firstWith(body.lineItems, function(item) 
item > 100) != null"))
-    .to("queue:bar");
-------------------------------------------------------------------------------------------------
-
-XML::
-+
-[source,xml]
------------------------------------------------------------------------------
-<route>
-    <from uri="queue:foo"/>
-    <filter>
-        <datasonnet>ds.arrays.firstWith(body.lineItems, function(item) item > 
100) != null</datasonnet>
-        <to uri="queue:bar"/>
-    </filter>
-</route>
------------------------------------------------------------------------------
-====
-
-
-Here is an example of a simple DataSonnet expression as a transformation EIP. 
This example will transform an XML body with
-`lineItems` into JSON while filtering out lines that are under 100.
-
-[tabs]
-====
-Java::
-+
-[source,java]
-------------------------------------------------------------------------------------------------
-from("queue:foo")
-    .transform(datasonnet("ds.filter(body.lineItems, function(item) item > 
100)", String.class, "application/xml", "application/json"))
-    .to("queue:bar");
-------------------------------------------------------------------------------------------------
-
-XML::
-+
-[source,xml]
------------------------------------------------------------------------------
-<route>
-    <from uri="queue:foo"/>
-    <filter>
-        <datasonnet bodyMediaType="application/xml" 
outputMediaType="application/json" resultTypeName="java.lang.String" >
-            ds.filter(body.lineItems, function(item) item > 100)
-        </datasonnet>
-        <to uri="queue:bar"/>
-    </filter>
-</route>
------------------------------------------------------------------------------
-====
-
-
-== Setting a result type
+=== Setting a result type
 
 The xref:datasonnet-language.adoc[DataSonnet] expression will return a 
`com.datasonnet.document.Document` by default. The
 document preserves the content type metadata along with the contents of the 
transformation result. In predicates,
@@ -132,7 +72,7 @@ or `Map.class`, respectively. However, you must also set the 
output media type t
 NOTE: The default `Document` object is useful in situations where there are 
intermediate transformation steps, and so
 retaining the content metadata through a route execution is valuable.
 
-== Specifying Media Types
+=== Specifying Media Types
 
 Traditionally, the input and output media types are specified through the
 
https://datasonnet.s3-us-west-2.amazonaws.com/docs-ci/primary/master/datasonnet/1.0-SNAPSHOT/headers.html[DataSonnet
 Header].
@@ -156,7 +96,7 @@ And for output media type:
 4. The DataSonnet Header output media type directive
 5. `application/x-java-object`
 
-== Functions
+=== Functions
 
 Camel adds the following DataSonnet functions that can be used to access the
 exchange:
@@ -202,7 +142,7 @@ XML::
 -----------------------------------------------------------------------------
 ====
 
-== Loading script from external resource
+=== Loading script from external resource
 
 You can externalize the script and have Apache Camel load it from a resource
 such as `"classpath:"`, `"file:"`, or `"http:"`. +
@@ -214,6 +154,69 @@ e.g., to refer to a file on the classpath you can do:
 .setHeader("myHeader").datasonnet("resource:classpath:mydatasonnet.ds");
 -------------------------------------------------------------------
 
+== Examples
+
+Here is a simple example using a DataSonnet expression as a predicate in a 
Message Filter:
+
+[tabs]
+====
+Java::
++
+[source,java]
+------------------------------------------------------------------------------------------------
+// let's route if a line item is over $100
+from("queue:foo")
+    .filter(datasonnet("ds.arrays.firstWith(body.lineItems, function(item) 
item > 100) != null"))
+    .to("queue:bar");
+------------------------------------------------------------------------------------------------
+
+XML::
++
+[source,xml]
+-----------------------------------------------------------------------------
+<route>
+    <from uri="queue:foo"/>
+    <filter>
+        <datasonnet>ds.arrays.firstWith(body.lineItems, function(item) item > 
100) != null</datasonnet>
+        <to uri="queue:bar"/>
+    </filter>
+</route>
+-----------------------------------------------------------------------------
+====
+
+
+Here is an example of a simple DataSonnet expression as a transformation EIP. 
This example will transform an XML body with
+`lineItems` into JSON while filtering out lines that are under 100.
+
+[tabs]
+====
+Java::
++
+[source,java]
+------------------------------------------------------------------------------------------------
+from("queue:foo")
+    .transform(datasonnet("ds.filter(body.lineItems, function(item) item > 
100)", String.class, "application/xml", "application/json"))
+    .to("queue:bar");
+------------------------------------------------------------------------------------------------
+
+XML::
++
+[source,xml]
+-----------------------------------------------------------------------------
+<route>
+    <from uri="queue:foo"/>
+    <filter>
+        <datasonnet bodyMediaType="application/xml" 
outputMediaType="application/json" resultTypeName="java.lang.String" >
+            ds.filter(body.lineItems, function(item) item > 100)
+        </datasonnet>
+        <to uri="queue:bar"/>
+    </filter>
+</route>
+-----------------------------------------------------------------------------
+====
+
+
+
 == Dependencies
 
 To use scripting languages in your camel routes, you need to add a

Reply via email to