CAMEL-8829: Do a defensive copy of the message when creating correlated copy, 
to eavoid any ConcurrentModificationException such as routing to logs using 
concurrent threads or if using wire tap EIP etc.


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

Branch: refs/heads/master
Commit: 6d6d1b736e25b139671ba9a652b6b7ac9e524a3b
Parents: d13afd1
Author: Claus Ibsen <davscl...@apache.org>
Authored: Thu Jun 4 10:16:39 2015 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Thu Jun 4 10:16:39 2015 +0200

----------------------------------------------------------------------
 .../org/apache/camel/impl/DefaultExchange.java  | 21 ++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/6d6d1b73/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java 
b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
index d24eed6..6704cdf 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchange.java
@@ -29,6 +29,7 @@ import org.apache.camel.Message;
 import org.apache.camel.MessageHistory;
 import org.apache.camel.spi.Synchronization;
 import org.apache.camel.spi.UnitOfWork;
+import org.apache.camel.util.CaseInsensitiveMap;
 import org.apache.camel.util.EndpointHelper;
 import org.apache.camel.util.ExchangeHelper;
 import org.apache.camel.util.ObjectHelper;
@@ -91,18 +92,18 @@ public final class DefaultExchange implements Exchange {
         DefaultExchange exchange = new DefaultExchange(this);
 
         if (hasProperties()) {
-            exchange.setProperties(safeCopy(getProperties()));
+            exchange.setProperties(safeCopyProperties(getProperties()));
         }
 
         if (safeCopy) {
             exchange.getIn().setBody(getIn().getBody());
             if (getIn().hasHeaders()) {
-                exchange.getIn().setHeaders(safeCopy(getIn().getHeaders()));
+                
exchange.getIn().setHeaders(safeCopyHeaders(getIn().getHeaders()));
             }
             if (hasOut()) {
                 exchange.getOut().setBody(getOut().getBody());
                 if (getOut().hasHeaders()) {
-                    
exchange.getOut().setHeaders(safeCopy(getOut().getHeaders()));
+                    
exchange.getOut().setHeaders(safeCopyHeaders(getOut().getHeaders()));
                 }
             }
         } else {
@@ -118,11 +119,23 @@ public final class DefaultExchange implements Exchange {
     }
 
     @SuppressWarnings("unchecked")
-    private static Map<String, Object> safeCopy(Map<String, Object> 
properties) {
+    private static Map<String, Object> safeCopyHeaders(Map<String, Object> 
headers) {
+        if (headers == null) {
+            return null;
+        }
+
+        Map<String, Object> answer = new CaseInsensitiveMap();
+        answer.putAll(headers);
+        return answer;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Map<String, Object> safeCopyProperties(Map<String, Object> 
properties) {
         if (properties == null) {
             return null;
         }
 
+        // TODO: properties should use same map kind as headers
         Map<String, Object> answer = new ConcurrentHashMap<String, 
Object>(properties);
 
         // safe copy message history using a defensive copy

Reply via email to