camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject camel git commit: CAMEL-8415: DefaultExchangeHolder - Only transfer primitive headers/properties
Date Tue, 08 Sep 2015 08:06:37 GMT
Repository: camel
Updated Branches:
  refs/heads/master 345203a12 -> 6e18ca3ee


CAMEL-8415: DefaultExchangeHolder - Only transfer primitive headers/properties


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

Branch: refs/heads/master
Commit: 6e18ca3ee11aeb4fb43fe8f50954592bfb567ca7
Parents: 345203a
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Tue Sep 8 10:07:31 2015 +0200
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Tue Sep 8 10:07:31 2015 +0200

----------------------------------------------------------------------
 .../camel/impl/DefaultExchangeHolder.java       | 68 ++++++++++++++++++--
 .../camel/impl/DefaultExchangeHolderTest.java   | 25 +++++++
 ...eadLetterQueueUsingTransferExchangeTest.java | 15 +----
 3 files changed, 91 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/6e18ca3e/camel-core/src/main/java/org/apache/camel/impl/DefaultExchangeHolder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchangeHolder.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchangeHolder.java
index 0605649..ea9713c 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultExchangeHolder.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultExchangeHolder.java
@@ -52,7 +52,7 @@ import org.slf4j.LoggerFactory;
  * <li>exception</li>
  * </ul>
  * The body is serialized and stored as serialized bytes. The header and exchange properties
only include
- * primitive, and String types. Any other type is skipped.
+ * primitive, and String types (and Exception types for exchange properties). Any other type
is skipped.
  * <p/>
  * Any object that is not serializable will be skipped and Camel will log this at WARN level.
  *
@@ -184,7 +184,7 @@ public class DefaultExchangeHolder implements Serializable {
 
     private Map<String, Object> safeSetInHeaders(Exchange exchange) {
         if (exchange.getIn().hasHeaders()) {
-            Map<String, Object> map = checkValidMapObjects("in headers", exchange,
exchange.getIn().getHeaders());
+            Map<String, Object> map = checkValidHeaderObjects("in headers", exchange,
exchange.getIn().getHeaders());
             if (map != null && !map.isEmpty()) {
                 inHeaders = new LinkedHashMap<String, Object>(map);
             }
@@ -194,7 +194,7 @@ public class DefaultExchangeHolder implements Serializable {
 
     private Map<String, Object> safeSetOutHeaders(Exchange exchange) {
         if (exchange.hasOut() && exchange.getOut().hasHeaders()) {
-            Map<String, Object> map = checkValidMapObjects("out headers", exchange,
exchange.getOut().getHeaders());
+            Map<String, Object> map = checkValidHeaderObjects("out headers", exchange,
exchange.getOut().getHeaders());
             if (map != null && !map.isEmpty()) {
                 outHeaders = new LinkedHashMap<String, Object>(map);
             }
@@ -204,7 +204,7 @@ public class DefaultExchangeHolder implements Serializable {
 
     private Map<String, Object> safeSetProperties(Exchange exchange) {
         if (exchange.hasProperties()) {
-            Map<String, Object> map = checkValidMapObjects("properties", exchange,
exchange.getProperties());
+            Map<String, Object> map = checkValidExchangePropertyObjects("properties",
exchange, exchange.getProperties());
             if (map != null && !map.isEmpty()) {
                 properties = new LinkedHashMap<String, Object>(map);
             }
@@ -226,7 +226,7 @@ public class DefaultExchangeHolder implements Serializable {
         }
     }
 
-    private static Map<String, Object> checkValidMapObjects(String type, Exchange exchange,
Map<String, Object> map) {
+    private static Map<String, Object> checkValidHeaderObjects(String type, Exchange
exchange, Map<String, Object> map) {
         if (map == null) {
             return null;
         }
@@ -251,6 +251,31 @@ public class DefaultExchangeHolder implements Serializable {
         return result;
     }
 
+    private static Map<String, Object> checkValidExchangePropertyObjects(String type,
Exchange exchange, Map<String, Object> map) {
+        if (map == null) {
+            return null;
+        }
+
+        Map<String, Object> result = new LinkedHashMap<String, Object>();
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+
+            // silently skip any values which is null
+            Object value = getValidExchangePropertyValue(entry.getKey(), entry.getValue());
+            if (value != null) {
+                Serializable converted = exchange.getContext().getTypeConverter().convertTo(Serializable.class,
exchange, value);
+                if (converted != null) {
+                    result.put(entry.getKey(), converted);
+                } else {
+                    logCannotSerializeObject(type, entry.getKey(), entry.getValue());
+                }
+            } else {
+                logInvalidExchangePropertyValue(type, entry.getKey(), entry.getValue());
+            }
+        }
+
+        return result;
+    }
+
     /**
      * We only want to store header values of primitive and String related types.
      * <p/>
@@ -288,6 +313,25 @@ public class DefaultExchangeHolder implements Serializable {
         return null;
     }
 
+    /**
+     * We only want to store exchange property values of primitive and String related types,
and
+     * as well any caught exception that Camel routing engine has caught.
+     * <p/>
+     * This default implementation will allow the same values as {@link #getValidHeaderValue(String,
Object)}
+     * and in addition any value of type {@link Throwable}.
+     *
+     * @param propertyName   the property name
+     * @param propertyValue  the property value
+     * @return  the value to use, <tt>null</tt> to ignore this header
+     */
+    protected static Object getValidExchangePropertyValue(String propertyName, Object propertyValue)
{
+        // for exchange properties we also allow exception to be transferred so people can
store caught exception
+        if (propertyValue instanceof Throwable) {
+            return propertyValue;
+        }
+        return getValidHeaderValue(propertyName, propertyValue);
+    }
+
     private static void logCannotSerializeObject(String type, String key, Object value) {
         if (key.startsWith("Camel")) {
             // log Camel at DEBUG level
@@ -316,4 +360,18 @@ public class DefaultExchangeHolder implements Serializable {
         }
     }
 
+    private static void logInvalidExchangePropertyValue(String type, String key, Object value)
{
+        if (key.startsWith("Camel")) {
+            // log Camel at DEBUG level
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Exchange {} containing key: {} with object: {} of type: {} is
not valid exchange property type, it will be excluded by the holder."
+                          , new Object[]{type, key, value, ObjectHelper.classCanonicalName(value)});
+            }
+        } else {
+            // log regular at WARN level
+            LOG.warn("Exchange {} containing key: {} with object: {} of type: {} is not valid
exchange property type, it will be excluded by the holder."
+                     , new Object[]{type, key, value, ObjectHelper.classCanonicalName(value)});
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/6e18ca3e/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
b/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
index f5150b8..cdb6ddc 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
@@ -127,6 +127,31 @@ public class DefaultExchangeHolderTest extends ContextTestSupport {
         assertNull(exchange.getIn().getHeader("Foo"));
     }
 
+    public void testCaughtException() throws Exception {
+        // use a mixed list, the MyFoo is not serializable so the entire list should be skipped
+        List<Object> list = new ArrayList<Object>();
+        list.add("I am okay");
+        list.add(new MyFoo("Tiger"));
+
+        Exchange exchange = new DefaultExchange(context);
+        exchange.getIn().setBody("Hello World");
+        exchange.getIn().setHeader("Foo", list);
+        exchange.getIn().setHeader("Bar", 123);
+        exchange.setProperty(Exchange.EXCEPTION_CAUGHT, new IllegalArgumentException("Forced"));
+
+        DefaultExchangeHolder holder = DefaultExchangeHolder.marshal(exchange);
+
+        exchange = new DefaultExchange(context);
+        DefaultExchangeHolder.unmarshal(exchange, holder);
+
+        // the caught exception should be included
+        assertEquals("Hello World", exchange.getIn().getBody());
+        assertEquals(123, exchange.getIn().getHeader("Bar"));
+        assertNull(exchange.getIn().getHeader("Foo"));
+        assertNotNull(exchange.getProperty(Exchange.EXCEPTION_CAUGHT));
+        assertEquals("Forced", exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class).getMessage());
+    }
+
     public void testFileNotSupported() throws Exception {
         Exchange exchange = new DefaultExchange(context);
         exchange.getIn().setBody(new File("src/test/resources/log4j.properties"));

http://git-wip-us.apache.org/repos/asf/camel/blob/6e18ca3e/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsDeadLetterQueueUsingTransferExchangeTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsDeadLetterQueueUsingTransferExchangeTest.java
b/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsDeadLetterQueueUsingTransferExchangeTest.java
index fff728b..2128eed 100644
--- a/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsDeadLetterQueueUsingTransferExchangeTest.java
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/JmsDeadLetterQueueUsingTransferExchangeTest.java
@@ -58,9 +58,8 @@ public class JmsDeadLetterQueueUsingTransferExchangeTest extends CamelTestSuppor
         assertMockEndpointsSatisfied();
 
         Exchange dead = mock.getReceivedExchanges().get(0);
-        // caused exception details is stored as headers
-        assertEquals("Kabom", dead.getIn().getHeader("CausedExceptionMessage", String.class));
-        assertEquals("java.lang.IllegalArgumentException", dead.getIn().getHeader("CausedExceptionType",
String.class));
+        // caused exception is stored as a property
+        assertEquals("Kabom", dead.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class).getMessage());
     }
 
     protected CamelContext createCamelContext() throws Exception {
@@ -77,15 +76,7 @@ public class JmsDeadLetterQueueUsingTransferExchangeTest extends CamelTestSuppor
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                errorHandler(deadLetterChannel(getUri()).onPrepareFailure(new Processor()
{
-                    @Override
-                    public void process(Exchange exchange) throws Exception {
-                        // store exception as a string
-                        Exception cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT,
Exception.class);
-                        exchange.getIn().setHeader("CausedExceptionMessage", cause.getMessage());
-                        exchange.getIn().setHeader("CausedExceptionType", cause.getClass().getName());
-                    }
-                }).disableRedelivery());
+                errorHandler(deadLetterChannel(getUri()).disableRedelivery());
 
                 from("direct:start").process(new Processor() {
                     public void process(Exchange exchange) throws Exception {


Mime
View raw message