You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Ton Swieb <to...@finalist.nl> on 2014/10/15 17:25:58 UTC

soapAction HTTP header not set by CXF client in POJO mode

Hi,

I am using the CXF component in my Camel route to send soap messages.
The WSDL I am using specifies a non-empty soapAction attribute. So
according to the basic profile specification the soapAction must be present
as a HTTP header in the HTTP request. I would expect CXF to handle this,
but that does not always appear to be the case. In payload mode the
behaviour is as expected. In pojo mode the behaviour is not as expected,
because I have to manually add the soapAction in the Camel route.

I have tested this with the following combination:
- Camel 2.12.3 and CXF 2.7.10.
- Camel 2.12.4 and CXF 2.7.12.
- Camel 2.14.0 and CXF 3.0.1.

Is this a bug or a missing feature? Or should I configure my CXF client
differently?

I created a couple of tests to verify the above behaviour. With 2 camel
routes per test. One route sending a soap message using the CXF client. One
route receiving the soap message using CXF and which verifies if the
soapAction is present.
I included the test code inline and as a complete runnable Maven project in
the ZIP.

Thanks in advance for any thoughts.

package nl.finalist.ai.camel.test;


import java.io.File;

import org.apache.camel.CamelExecutionException;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.cxf.binding.soap.SoapBindingConstants;
import org.junit.Test;

/**
 * Verify that the SoapAction HTTP header is set by CXF when called from a
Camel route.
 * Behaviour between CXF in POJO mode differs from CXF in PAYLOAD mode
 * @author ton.swieb
 */
public class CamelCxfSoapActionTest extends CamelTestSupport {

    public static final String SOAP_ACTON = "
http://finalist.nl/ai/ICamelCxfTestService/CamelCxfTest";
    public static final String OPERATON_NAME = "CamelCxfTest";
    public static final String OPERATION_NAMESPACE = "http://finalist.nl/ai/
";

    public static final String ENDPOINT_CXF = "cxf://
http://localhost:8080?wsdlURL=CamelCxfTestService.wsdl&loggingFeatureEnabled=true
";
    private static final String ENDPOINT_PAYLOAD_MODE = "direct:payload";
    private static final String ENDPOINT_POJO_MODE = "direct:pojo";
    private static final String ENDPOINT_POJO_MODE_WITH_SOAP_ACTION =
"direct:pojoWithSoapAction";

    @Test
    public void testsoapActionIsSetByCxfInPayloadMode() {

        //See the asserts in the mockRoute
        String response = template.requestBody(ENDPOINT_PAYLOAD_MODE,new
File("src/test/resources/request.xml"),String.class);
        assertNotNull(response);
    }

    @Test(expected=CamelExecutionException.class)
    public void testsoapActionIsNotSetByCxfInPojoMode() {

        //See the asserts in the mockRoute
        template.requestBody(ENDPOINT_POJO_MODE,null,Boolean.class);
    }

    @Test
    public void testSetSoapActionManuallyIsHonoredByCxfInPojoMode() {

        //See the asserts in the mockRoute
        String response =
template.requestBody(ENDPOINT_POJO_MODE_WITH_SOAP_ACTION,null,String.class);
        assertNotNull(response);
    }

    @Override
    protected RouteBuilder createRouteBuilder() {

        return new RouteBuilder() {

            @Override
            public void configure() {

                from(ENDPOINT_POJO_MODE)
                .setHeader(CxfConstants.OPERATION_NAME,
constant(OPERATON_NAME))
                .setHeader(CxfConstants.OPERATION_NAMESPACE,
constant(OPERATION_NAMESPACE))
                .to(ENDPOINT_CXF +
"&serviceClass=nl.finalist.ai.ICamelCxfTestService");

                from(ENDPOINT_POJO_MODE_WITH_SOAP_ACTION)

.setHeader(SoapBindingConstants.SOAP_ACTION,constant(SOAP_ACTON))
                .setHeader(CxfConstants.OPERATION_NAME,
constant(OPERATON_NAME))
                .setHeader(CxfConstants.OPERATION_NAMESPACE,
constant(OPERATION_NAMESPACE))
                .to(ENDPOINT_CXF +
"&serviceClass=nl.finalist.ai.ICamelCxfTestService");

                from(ENDPOINT_PAYLOAD_MODE)
                .setHeader(CxfConstants.OPERATION_NAME,
constant(OPERATON_NAME))
                .setHeader(CxfConstants.OPERATION_NAMESPACE,
constant(OPERATION_NAMESPACE))
                .to(ENDPOINT_CXF + "&dataFormat=PAYLOAD");

                //The CXF server endpoint which is used to assert the
presence of the soapAction HTTP header for all routes
                from(ENDPOINT_CXF + "&dataFormat=PAYLOAD")
                .process(new Processor() {

                    @Override
                    public void process(Exchange arg0) throws Exception {
                        String soapAction =
arg0.getIn().getHeader(SoapBindingConstants.SOAP_ACTION,String.class);
                        assertEquals(SOAP_ACTON,soapAction);
                    }
                })

.pollEnrich("file://src/test/resources?fileName=response.xml&noop=true&initialDelay=0");
            }
        };
    }
}
-- 

Met vriendelijke groet,

Ton Swieb
Senior Software Consultant / Architect

Finalist -  open *IT* oplossingen
Rotterdam - Amsterdam - Eindhoven
*www.finalist.nl* <http://www.finalist.nl/>

Telefoon 088 217 08 15
Mobiel    06 14 680 172