Details
-
Bug
-
Resolution: Done
-
Major
-
2.6.0-fuse-00-00
-
None
-
None
Description
The attached test case demonstrates a failure when a jms endpoint is added to a route which ultimately throws a custom exception, UknownPersonFault. The following correct output when the jms end point is not used:
ID: 1 Response-Code: 500 Encoding: UTF-8 Content-Type: text/xml;charset=UTF-8 Headers: {content-type=[text/xml;charset=UTF-8], Content-Length=[353], Server=[Jetty(7.2.2.v20101205)]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>CXF-JMS Fault</faultstring> <detail><UnknownPersonFault xmlns="http://servicemix.apache.org/samples/wsdl-first/types"> <personId>BEAN</personId></UnknownPersonFault></detail></soap:Fault></soap:Body> </soap:Envelope>
The following is when a simple, dummy jms route is added (AfterJmsEndpointProcessor in route):
ID: 2
Response-Code: 500
Encoding: UTF-8
Content-Type: text/xml;charset=UTF-8
Headers: {content-type=[text/xml;charset=UTF-8], Content-Length=[229], Server=[Jetty(7.2.2.v20101205)]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>
<soap:Fault><faultcode>soap:Server</faultcode><faultstring>AfterJmsEndpointProcessor</faultstring>
<detail/></soap:Fault></soap:Body></soap:Envelope>
As you can see we didn't get our fault back. The route in question looks as follows;
from("cxf:bean:requestRouterEndpoint?dataFormat=PAYLOAD") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { CxfPayload payload = exchange.getIn().getBody(CxfPayload.class); List<Element> message = payload.getBody(); XmlConverter xmlConverter = new XmlConverter(); String inMessage = xmlConverter.toString(message.get(0), null);; exchange.getIn().setBody(inMessage); System.out.println("inMessage " +inMessage); } }) .choice() .when().xpath("string(/ns:GetPerson/ns:personId/text())='1'", ns) .to("bean:service?method=serviceException") .when().xpath("string(/ns:GetPerson/ns:personId/text())='2'", ns) .inOut("activemq:queue:request.queue") .process(new AfterJmsEndpointProcessor()); from("activemq:queue:request.queue") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { System.out.println("Hello"); exchange.getOut().setBody("ERROR"); } });
If I either comment out " .inOut("activemq:queue:request.queue")" or make it inOnly, the correct exception is returned.
Jon A. dug into the code a bit for me. There is something going wrong between the camel-jms thread that is returning a response and the thread than is waiting for a reply in camel-cxf. The fault gets set to true in SoapFaultProcessor, but in the case where the JmsProducer is used in the mix, when the response eventually makes it to CxfConsumer...checkFailure, the fault value is set back to false for some reason. If a SEDA queue is used instead of a JMS queue there is no issue.
to run the test case:
1. run mvn clean install -Dmaven.test.skip=true
2. deploy bundle into fuse esb install mvn:com.fusesource/soap-fault-issue/0.0.1-SNAPSHOT
3. run mvn test