Details
-
Enhancement
-
Resolution: Done
-
Major
-
1.4.1.0-fuse
-
None
-
None
Description
If you have a camel flow that starts with a JBI endpoint, such that a JbiExchange is used before the routing slip, as a result of the routing slip we get a DefaultExchange with a JbiMessages inside.
This causes a ClassCastException to be thrown as folows:
ERROR - DeadLetterChannel - Failed delivery for exchangeId: ID-S206035J4463581/1100-1212402361227/0-0. On delivery attempt: 0 caught: java.lang.ClassCastException: org.apache.camel.impl.DefaultExchange
java.lang.ClassCastException: org.apache.camel.impl.DefaultExchange
at org.apache.servicemix.camel.JbiMessage.getExchange(JbiMessage.java:55)
at org.apache.servicemix.camel.JbiMessage.getExchange(JbiMessage.java:34)
at org.apache.camel.impl.MessageSupport.getBody(MessageSupport.java:49)
at org.apache.camel.builder.xml.XPathBuilder.getDocument(XPathBuilder.java:537)
at org.apache.camel.builder.xml.XPathBuilder.evaluateAs(XPathBuilder.java:420)
at org.apache.camel.builder.xml.XPathBuilder.evaluate(XPathBuilder.java:110)
at org.apache.camel.processor.Splitter.createProcessorExchangePairs(Splitter.java:70)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:147)
...
This is an enhancement request to allow for a jbi exhange before the routing slip. Possible options on the fix:
1) Preserve the exchange type
2) Possibly change the way messages are copied to the newly created exchange?
In RoutingSlip.process(Exchange exchange) after processing is finished the result is copied to the orginal exchange using:
ExchangeHelper.copyResults(exchange, current);
which delegates copying to the copyFrom(Message that) method of the MessageSupport class:
result.getOut(true).copyFrom(out); public void copyFrom(Message that) { setMessageId(that.getMessageId()); setBody(that.getBody()); getHeaders().putAll(that.getHeaders()); getAttachments().putAll(that.getAttachments()); }
This way a new out message is created if it's null. Message id, body, headers, and attachments are then copied to this message. We do not copy the whole original message.
We could employ similar mechanisms when copying out the message of one exchange to the in message of the exchange sent to the next recipient. Currently the copyOutToIn(Exchange result, Exchange source) method is used.
private void copyOutToIn(Exchange result, Exchange source) { result.setException(source.getException()); Message fault = source.getFault(false); if (fault != null) { result.getFault(true).copyFrom(fault); } result.setIn(getResultMessage(source)); result.getProperties().clear(); result.getProperties().putAll(source.getProperties()); }
Using this mechanism faults are copied properly. We can use similar mechanisms to copy the result message to 'in' of the next exchange.