camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Willem Jiang <willem.ji...@gmail.com>
Subject Re: CXF consumer: fault handling
Date Thu, 05 Aug 2010 03:47:24 GMT
S. Ali Tokmen wrote:
> Hello
> 
> I use the CAMEL-CXF component to create Web Service based on a 
> preexisting WSDL. The CXF codegen plugin generates for me all classes 
> with everything annotated correctly, in particular WSDL fault classes 
> annotated correctly.
> 
> Now, here's my issue: if I do as described in 
> http://camel.apache.org/cxf.html#CXF-HowtothrowaSOAPFaultfromCamel and 
> throw the exception generated by CXF codegen in a processor, CXF returns:
> 
>    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
>    <soap:Body>
>    <soap:Fault>
>    <faultcode>soap:Server</faultcode>
>    <faultstring>Failed searching for address: Could not send
>    Message.</faultstring>
>    </soap:Fault>
>    </soap:Body>
>    </soap:Envelope>
> 
> It therefore copies the exception message from the thrown exception, 
> which is nice, but one important thing is missing: the fault detail is 
> not set. Because of this, when I call my Web Service with a JAX-WS 
> client, it throws me back a Fault instead of an 
> AddressNotFoundFault_Exception (generated by CXF codegen).
> 
> In order to overcome this issue, I've created a CAMEL exception handler 
> that ends with the following processor:
> 
>    Throwable cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT,
>    Throwable.class);
>    WebFault faultAnnotation =
>    cause.getClass().getAnnotation(WebFault.class);
>    if (faultAnnotation == null) {
>         // The thrown exception is not a WebFault.
>         // Let the CAMEL CXF classic error return handle this.
>         return;
>    }
> 
>    Fault fault = new Fault(cause);
>    if (cause.getMessage() != null) {
>         fault.setMessage(cause.getMessage());
>    } else {
>         fault.setMessage(cause.getClass().getSimpleName());
>    }
> 
>    Element detail = fault.getOrCreateDetail();
>    Element faultDetails = detail.getOwnerDocument().createElementNS(
>         faultAnnotation.targetNamespace(), faultAnnotation.name());
>    detail.appendChild(faultDetails);
> 
>    exchange.getOut().setFault(true);
>    exchange.getOut().setBody(fault);
> 
> With that modification, the CAMEL CXF component returns:
> 
>    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
>    <soap:Body>
>    <soap:Fault>
>    <faultcode>soap:Server</faultcode>
>    <faultstring>Failed searching for address: Could not send
>    Message.</faultstring>
>    <detail>
>    <AddressNotFoundFault xmlns="http://soap-test.camel.jonas.ow2.org/"/>
>    </detail>
>    </soap:Fault>
>    </soap:Body>
>    </soap:Envelope>
> 
> ... and the JAX-WS client throws the AddressNotFoundFault_Exception. 
> Marvellous.
> 
> Now, is this an expected behavior? If no, and that the patch is correct, 
> could it be integrated into (I guess) 
> org.apache.camel.component.cxf.CxfConsumer.java 's checkFailure method?
> 
> Cheers
> 
CXF FaultOutInterceptor will take care of it if you just throw the Fault 
message out from CxfConsumer.
If you just put the Fault into the out message of exchange, you need to 
set the fault detail yourself.
Why can't you just throw the fault out from CxfConsumer?
Can configure your error handler to ignore the WebFault :)

Willem
----------------------------------
Apache Camel, Apache CXF committer
Open Source Integration http://www.fusesource.com
Blog http://willemjiang.blogspot.com
Tiwtter http://twitter.com/willemjiang

Mime
View raw message