Updated Branches:
  refs/heads/master bce6ea8e1 -> 4c9943510

CAMEL-6357: Routing engine avoid clearning headers if end user copied headers 
the wrong way. Improved SetBody EIP to check if OUT message exists when setting 
message.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4c994351
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4c994351
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4c994351

Branch: refs/heads/master
Commit: 4c9943510a46b3a8a372155680eefe6929fc3e67
Parents: bce6ea8
Author: Claus Ibsen <[email protected]>
Authored: Mon May 13 18:49:16 2013 +0200
Committer: Claus Ibsen <[email protected]>
Committed: Mon May 13 18:49:16 2013 +0200

----------------------------------------------------------------------
 .../src/main/java/org/apache/camel/Message.java    |    3 +
 .../java/org/apache/camel/impl/MessageSupport.java |   18 +++-
 .../apache/camel/processor/SetBodyProcessor.java   |   12 ++-
 .../org/apache/camel/impl/MessageSupportTest.java  |   20 ++++
 .../camel/issues/SetBodyTryCatchIssueTest.java     |   73 +++++++++++++++
 5 files changed, 119 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/4c994351/camel-core/src/main/java/org/apache/camel/Message.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/Message.java 
b/camel-core/src/main/java/org/apache/camel/Message.java
index 4018ea1..179871f 100644
--- a/camel-core/src/main/java/org/apache/camel/Message.java
+++ b/camel-core/src/main/java/org/apache/camel/Message.java
@@ -160,6 +160,9 @@ public interface Message {
 
     /**
      * Set all the headers associated with this message
+     * <p/>
+     * <b>Important:</b> If you want to copy headers from another {@link 
Message} to this {@link Message}, then
+     * use <tt>getHeaders().putAll(other)</tt> to copy the headers, where 
<tt>other</tt> is the other headers.
      *
      * @param headers headers to set
      */

http://git-wip-us.apache.org/repos/asf/camel/blob/4c994351/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java 
b/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java
index 3dd2420..c199a15 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/MessageSupport.java
@@ -135,11 +135,21 @@ public abstract class MessageSupport implements Message {
         setBody(that.getBody());
         setFault(that.isFault());
 
-        if (hasHeaders()) {
-            getHeaders().clear();
+        // the headers may be the same instance if the end user has made some 
mistake
+        // and set the OUT message with the same header instance of the IN 
message etc
+        boolean sameHeadersInstance = false;
+        if (hasHeaders() && that.hasHeaders() && getHeaders() == 
that.getHeaders()) {
+            sameHeadersInstance = true;
         }
-        if (that.hasHeaders()) {
-            getHeaders().putAll(that.getHeaders());
+
+        if (!sameHeadersInstance) {
+            if (hasHeaders()) {
+                // okay its safe to clear the headers
+                getHeaders().clear();
+            }
+            if (that.hasHeaders()) {
+                getHeaders().putAll(that.getHeaders());
+            }
         }
         
         if (hasAttachments()) {

http://git-wip-us.apache.org/repos/asf/camel/blob/4c994351/camel-core/src/main/java/org/apache/camel/processor/SetBodyProcessor.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/processor/SetBodyProcessor.java 
b/camel-core/src/main/java/org/apache/camel/processor/SetBodyProcessor.java
index 42ee0f5..23b3995 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/SetBodyProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/SetBodyProcessor.java
@@ -25,7 +25,7 @@ import org.apache.camel.impl.DefaultMessage;
 import org.apache.camel.support.ServiceSupport;
 
 /**
- * A processor which sets the body on the IN message with an {@link Expression}
+ * A processor which sets the body on the IN or OUT message with an {@link 
Expression}
  */
 public class SetBodyProcessor extends ServiceSupport implements Processor, 
Traceable {
     private final Expression expression;
@@ -37,13 +37,19 @@ public class SetBodyProcessor extends ServiceSupport 
implements Processor, Trace
     public void process(Exchange exchange) throws Exception {
         Object newBody = expression.evaluate(exchange, Object.class);
 
-        Message old = exchange.getIn();
+        boolean out = exchange.hasOut();
+        Message old = out ? exchange.getOut() : exchange.getIn();
 
         // create a new message container so we do not drag specialized 
message objects along
         Message msg = new DefaultMessage();
         msg.copyFrom(old);
         msg.setBody(newBody);
-        exchange.setIn(msg);
+
+        if (out) {
+            exchange.setOut(msg);
+        } else {
+            exchange.setIn(msg);
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/4c994351/camel-core/src/test/java/org/apache/camel/impl/MessageSupportTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/MessageSupportTest.java 
b/camel-core/src/test/java/org/apache/camel/impl/MessageSupportTest.java
index 083e8f6..910f95d 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/MessageSupportTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/MessageSupportTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.impl;
 
+import java.util.Map;
+
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.InvalidPayloadException;
@@ -63,4 +65,22 @@ public class MessageSupportTest extends ContextTestSupport {
         
         assertNotNull(in.getMessageId());
     }
+
+    public void testCopyFromSameHeadersInstance() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Message in = exchange.getIn();
+        Map<String, Object> headers = in.getHeaders();
+        headers.put("foo", 123);
+
+        Message out = new DefaultMessage();
+        out.setBody("Bye World");
+        out.setHeaders(headers);
+
+        out.copyFrom(in);
+
+        assertEquals(123, headers.get("foo"));
+        assertEquals(123, in.getHeader("foo"));
+        assertEquals(123, out.getHeader("foo"));
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/4c994351/camel-core/src/test/java/org/apache/camel/issues/SetBodyTryCatchIssueTest.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/test/java/org/apache/camel/issues/SetBodyTryCatchIssueTest.java
 
b/camel-core/src/test/java/org/apache/camel/issues/SetBodyTryCatchIssueTest.java
new file mode 100644
index 0000000..a6f4b7d
--- /dev/null
+++ 
b/camel-core/src/test/java/org/apache/camel/issues/SetBodyTryCatchIssueTest.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.issues;
+
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class SetBodyTryCatchIssueTest extends ContextTestSupport {
+
+    public void testSetBody() throws Exception {
+        getMockEndpoint("mock:bar").expectedBodiesReceived("Hello World");
+        getMockEndpoint("mock:result").expectedBodiesReceived("123");
+
+        Object out = template.requestBody("direct:start", "Hello World");
+        assertEquals("123", out);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .setHeader("foo", constant("123"))
+                    .doTry()
+                        .setHeader("bar", constant("456"))
+                        .to("mock:bar")
+                        .bean(SetBodyTryCatchIssueTest.class, "doSomething")
+                    .doCatch(IllegalArgumentException.class)
+                        // empty block
+                    .end()
+                    .setBody(header("foo"))
+                    .to("mock:result");
+            }
+        };
+    }
+
+    public static void doSomething(Exchange exchange) throws Exception {
+        Map<String, Object> headers = exchange.getIn().getHeaders();
+
+        exchange.getOut().setBody("Bye World");
+        // we copy the headers by mistake by setting it as a reference from 
the IN
+        // but we should ideally do as below instead
+        // but we want to let Camel handle this situation as well, otherwise 
headers may appear as lost
+        // exchange.getOut().getHeaders().putAll(headers);
+        exchange.getOut().setHeaders(headers);
+
+        throw new IllegalArgumentException("Forced");
+    }
+
+}

Reply via email to