Search code examples
javaapache-camelcxfjbossfuseblueprint-osgi

How are SOAP headers processed in Camel-CXF?


I'm trying to wrap my head around Apache Camel using Jboss Fuse 6.2.1 and I don't understand how SOAP headers are being processed.

I have a WSDL from which I have generated classes for my input and output messages. The input consists of a header and a body while the output only consists of a body.

WSDL

<wsdl:types>
    <xs:schema targetNamespace="http://cxftestserver.blueprint.me.com">
        <xs:element name="input">
            <xs:complexType>
                <xs:sequence>
                    <xs:element type="xs:string" name="Id" />
                    <xs:element type="xs:string" name="Name" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:element name="output">
            <xs:complexType>
                <xs:sequence>
                    <xs:element type="xs:string" name="Code" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    <xs:schema targetNamespace="http://cxftestserver.blueprint.me.com/authentication">
        <xs:element name="authHeader">
            <xs:complexType>
                <xs:sequence>
                    <xs:element type="xs:string" name="username" />
                    <xs:element type="xs:string" name="password" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
</wsdl:types>

<wsdl:message name="inputTest">
    <wsdl:part name="header" element="tns1:authHeader" />
    <wsdl:part name="body" element="tns:input" />
</wsdl:message>
<wsdl:message name="outputTest">
    <wsdl:part name="out" element="tns:output" />
</wsdl:message>

Blueprint

<bean id="myProcessor" class="com.me.blueprint.cxftestserver.MyProcessor" />

<cxf:cxfEndpoint id="test-ws" address="/Test" serviceClass="com.me.blueprint.cxftestserver.TestEndpoint" />

<camel:camelContext>
    <camel:route>
        <camel:from uri="cxf:bean:test-ws" />
        <camel:process ref="myProcessor" />
    </camel:route>
</camel:camelContext>

What I don't understand now is why the Message-body inside of the Exchange contains both the authHeader and the input? Every example I've read in the docs suggest that I should be able to extract the header by doing:

exchange.getIn().getHeaders(//insert your favorite parameter here);

but whenever I've tried that it would always return null. I wasted several hours looking in all the wrong places when I finally found that the Message-body contained the MessageContentsList-object holding both my SOAP-header and my SOAP-body.

Message inMessage = e.getIn();
AuthHeader header = inMessage.getBody(AuthHeader.class);
Input body = inMessage.getBody(Input.class);

Can someone please explain to me why and when this happens?


Solution

  • I believe I've found the answer to my initial question:

    According to the documentation I've now come to understand that, when using POJO as data format, the consumer-endpoint looks at what parameters the requested method has in my SEI (Service Endpoint Interface (to which the serviceClass-attribute points.))

    These parameters are then invoked into the Message-body (MessageContentsList-object) which would explain why both the header and the body are present.