Hello! I would like to resurrect the discussion that I started on this list over a month ago, and if you want to see the roots, you can go here (I don't want to repeat myself ;) ):
http://www.nabble.com/in-out-fault-messages-discussion-to14170013s22882.html#a14170013 Summarizing my point of view: I think, that distinction between in/out/fault messages is not needed and that it makes more problems, than it solves. To actually check it I have prepared very small PoC that simply removes this distinction without changing general interface we have. The patch is attached at the very end of this message if someone is interested. To make it work I had to change only two tests in camel-core (also in the patch) and everything passes. Moreover such patch automatically eliminates some problems that we faced with to early initialization of out messages (getOut() invocation) that caused to loose your body, some strange behaviours of some endpoints that depend on out message being set like from("jetty:http://localhost:1234/test").setBody("response"); <-- doesn't work from("jetty:http://localhost:1234/test").setBody("response").setBody("response"); <-- works (in the second case pipeline creates out message, while the first one doesn't have a pipeline so there is no out message set) Basically it proves (I think) that this distinction (in/out/fault) is not needed at all, and it would simplify the solution if we get rid of it. Moreover our solution gets more powerful, as we can think of defining predicates that stop the pipeline, so it doesn't stop simply on fault (but by default we could stop on 'fault' header set). Of course there are components will require some changes if we go this way - The first one I can think about is servicemix JBI component that sets in, out, and fault messages at the very beginning of the flow. Moreover I found another problem with JMS message that simply ignores setBody() invocations when there is JMSMessage associated with the message. (JIRA issue should be created I think) There was another problem with one of jetty tests that was reading the request stream in the mock endpoint once, and was trying to read it another time when was creating the response (as now body was not changed). Anyway all those problems are pretty small and we can solve them quickly if we would like to. Once again - I know that the change I would like to propose is a huge modification of basic interfaces, and I have really no idea if it could be introduced. Roman Index: src/main/java/org/apache/camel/impl/DefaultExchange.java =================================================================== --- src/main/java/org/apache/camel/impl/DefaultExchange.java (wersja 616530) +++ src/main/java/org/apache/camel/impl/DefaultExchange.java (kopia robocza) @@ -16,6 +16,9 @@ */ package org.apache.camel.impl; +import java.util.HashMap; +import java.util.Map; + import org.apache.camel.CamelContext; import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; @@ -24,9 +27,6 @@ import org.apache.camel.spi.UnitOfWork; import org.apache.camel.util.UuidGenerator; -import java.util.HashMap; -import java.util.Map; - /** * A default implementation of [EMAIL PROTECTED] Exchange} * @@ -37,8 +37,8 @@ protected final CamelContext context; private Map<String, Object> properties; private Message in; - private Message out; - private Message fault; +// private Message out; +// private Message fault; private Throwable exception; private String exchangeId = DefaultExchange.DEFAULT_ID_GENERATOR.generateId(); private UnitOfWork unitOfWork; @@ -174,15 +174,15 @@ } public Message getOut(boolean lazyCreate) { - if (out == null && lazyCreate) { - out = createOutMessage(); - configureMessage(out); - } - return out; + if (lazyCreate) { + in.removeHeader("fault"); + return in; + } + return (in != null && in.getHeader("fault") == null) ? in : null; } public void setOut(Message out) { - this.out = out; + this.in = out; configureMessage(out); } @@ -220,15 +220,16 @@ } public Message getFault(boolean lazyCreate) { - if (fault == null && lazyCreate) { - fault = createFaultMessage(); - configureMessage(fault); + if (lazyCreate) { + in.setHeader("fault", true); + return in; } - return fault; + return ((in == null) || in.getHeader("fault") == null) ? null : in; } public void setFault(Message fault) { - this.fault = fault; + this.in = fault; + in.setHeader("fault", true); configureMessage(fault); } Index: src/test/java/org/apache/camel/processor/SplitterTest.java =================================================================== --- src/test/java/org/apache/camel/processor/SplitterTest.java (wersja 616530) +++ src/test/java/org/apache/camel/processor/SplitterTest.java (kopia robocza) @@ -80,7 +80,7 @@ } }); - assertNull(result.getOut(false)); + assertNull(result.getOut().getBody()); } protected RouteBuilder createRouteBuilder() { Index: src/test/java/org/apache/camel/processor/PipelineTest.java =================================================================== --- src/test/java/org/apache/camel/processor/PipelineTest.java (wersja 616530) +++ src/test/java/org/apache/camel/processor/PipelineTest.java (kopia robocza) @@ -107,7 +107,9 @@ // Check the out Message.. It should have only been processed once. // since the fault should stop it from going to the next process. - assertEquals(1, exchange.getOut().getHeader("copy-counter")); +// We have here out AND fault message at the same time - what is the meaning +// of such response?? +// assertEquals(1, exchange.getOut().getHeader("copy-counter")); } public void testOnlyProperties() {
