You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/03/29 19:07:06 UTC

svn commit: r1086641 - in /camel/trunk: camel-core/src/main/java/org/apache/camel/ camel-core/src/main/java/org/apache/camel/impl/ camel-core/src/test/java/org/apache/camel/processor/ camel-core/src/test/java/org/apache/camel/processor/interceptor/ cam...

Author: davsclaus
Date: Tue Mar 29 17:07:04 2011
New Revision: 1086641

URL: http://svn.apache.org/viewvc?rev=1086641&view=rev
Log:
CAMEL-3817: Added breadcrumb to Camel to track messages accross transports. There is an option to disable breadcrumb if you want that.

Added:
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbDisabledTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCWithBreadcrumbTest.java
      - copied, changed from r1086145, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCTest.java
    camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.java
    camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.java
      - copied, changed from r1086145, camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCTest.java
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.xml
    camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.xml
      - copied, changed from r1086145, camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCTest.xml
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/PipelineTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersExcludeTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/DefaultTraceEventMessageTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorDestinationTest.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TracerTest.java
    camel/trunk/camel-core/src/test/resources/log4j.properties
    camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
    camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
    camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerSlowResponseTest.java
    camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
    camel/trunk/components/camel-spring/src/test/resources/log4j.properties

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java Tue Mar 29 17:07:04 2011
@@ -992,4 +992,20 @@ public interface CamelContext extends Su
      */
     void setUseMDCLogging(Boolean useMDCLogging);
 
+    /**
+     * Whether or not breadcrumb is enabled.
+     *
+     * @return <tt>true</tt> if breadcrumb is enabled
+     */
+    Boolean isUseBreadcrumb();
+
+    /**
+     * Set whether breadcrumb is enabled.
+     *
+     * @param useBreadcrumb <tt>true</tt> to enable breadcrumb, <tt>false</tt> to disable
+     */
+    void setUseBreadcrumb(Boolean useBreadcrumb);
+
+
+
 }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Exchange.java Tue Mar 29 17:07:04 2011
@@ -85,6 +85,9 @@ public interface Exchange {
     String BEAN_METHOD_NAME           = "CamelBeanMethodName";
     String BEAN_MULTI_PARAMETER_ARRAY = "CamelBeanMultiParameterArray";
     String BINDING                    = "CamelBinding";
+    // do not prefix with Camel and use lower-case starting letter as its a shared key
+    // used across other Apache products such as AMQ, SMX etc.
+    String BREADCRUMB_ID              = "breadcrumbId";
 
     String CHARSET_NAME      = "CamelCharsetName";
     String CREATED_TIMESTAMP = "CamelCreatedTimestamp";

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Tue Mar 29 17:07:04 2011
@@ -167,6 +167,7 @@ public class DefaultCamelContext extends
     private Boolean disableJMX = Boolean.FALSE;
     private Boolean lazyLoadTypeConverters = Boolean.FALSE;
     private Boolean useMDCLogging = Boolean.FALSE;
+    private Boolean useBreadcrumb = Boolean.TRUE;
     private Long delay;
     private ErrorHandlerBuilder errorHandlerBuilder;
     private Map<String, DataFormatDefinition> dataFormats = new HashMap<String, DataFormatDefinition>();
@@ -2177,6 +2178,14 @@ public class DefaultCamelContext extends
         this.useMDCLogging = useMDCLogging;
     }
 
+    public Boolean isUseBreadcrumb() {
+        return useBreadcrumb != null && useBreadcrumb;
+    }
+
+    public void setUseBreadcrumb(Boolean useBreadcrumb) {
+        this.useBreadcrumb = useBreadcrumb;
+    }
+
     public ClassLoader getApplicationContextClassLoader() {
         return applicationContextClassLoader;
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultUnitOfWork.java Tue Mar 29 17:07:04 2011
@@ -78,6 +78,17 @@ public class DefaultUnitOfWork implement
             exchange.setProperty(Exchange.CREATED_TIMESTAMP, new Date());
         }
 
+        // inject breadcrumb header if enabled
+        if (exchange.getContext().isUseBreadcrumb()) {
+            // create or use existing breadcrumb
+            String breadcrumbId = exchange.getIn().getHeader(Exchange.BREADCRUMB_ID, String.class);
+            if (breadcrumbId == null) {
+                // no existing breadcrumb, so create a new one based on the message id
+                breadcrumbId = exchange.getIn().getMessageId();
+                exchange.getIn().setHeader(Exchange.BREADCRUMB_ID, breadcrumbId);
+            }
+        }
+
         // fire event
         EventHelper.notifyExchangeCreated(exchange.getContext(), exchange);
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/MDCUnitOfWork.java Tue Mar 29 17:07:04 2011
@@ -29,6 +29,7 @@ import org.slf4j.MDC;
  */
 public class MDCUnitOfWork extends DefaultUnitOfWork {
 
+    public static final String MDC_BREADCRUMB_ID = "breadcrumbId";
     public static final String MDC_EXCHANGE_ID = "exchangeId";
     public static final String MDC_CORRELATION_ID = "correlationId";
     public static final String MDC_ROUTE_ID = "routeId";
@@ -43,6 +44,11 @@ public class MDCUnitOfWork extends Defau
         if (corrId != null) {
             MDC.put(MDC_CORRELATION_ID, corrId);
         }
+        // and add optional breadcrumb id
+        String breadcrumbId = exchange.getIn().getHeader(Exchange.BREADCRUMB_ID, String.class);
+        if (breadcrumbId != null) {
+            MDC.put(MDC_BREADCRUMB_ID, breadcrumbId);
+        }
     }
 
     @Override
@@ -94,9 +100,11 @@ public class MDCUnitOfWork extends Defau
      * Clears information put on the MDC by this {@link MDCUnitOfWork}
      */
     public void clear() {
+        MDC.remove(MDC_BREADCRUMB_ID);
         MDC.remove(MDC_EXCHANGE_ID);
         MDC.remove(MDC_CORRELATION_ID);
         MDC.remove(MDC_ROUTE_ID);
+        MDC.remove(MDC_TRANSACTION_KEY);
     }
 
     @Override
@@ -111,6 +119,7 @@ public class MDCUnitOfWork extends Defau
     private static final class MDCCallback implements AsyncCallback {
 
         private final AsyncCallback delegate;
+        private final String breadcrumbId;
         private final String exchangeId;
         private final String correlationId;
         private final String routeId;
@@ -118,6 +127,7 @@ public class MDCUnitOfWork extends Defau
         private MDCCallback(AsyncCallback delegate) {
             this.delegate = delegate;
             this.exchangeId = MDC.get(MDC_EXCHANGE_ID);
+            this.breadcrumbId = MDC.get(MDC_BREADCRUMB_ID);
             this.correlationId = MDC.get(MDC_CORRELATION_ID);
 
             String routeId = MDC.get(MDC_ROUTE_ID);
@@ -130,19 +140,26 @@ public class MDCUnitOfWork extends Defau
         }
 
         public void done(boolean doneSync) {
-            if (!doneSync) {
-                // when done asynchronously then restore information from previous thread
-                if (exchangeId != null) {
-                    MDC.put(MDC_EXCHANGE_ID, exchangeId);
-                }
-                if (correlationId != null) {
-                    MDC.put(MDC_CORRELATION_ID, correlationId);
-                }
-                if (routeId != null) {
-                    MDC.put(MDC_ROUTE_ID, routeId);
+            try {
+                if (!doneSync) {
+                    // when done asynchronously then restore information from previous thread
+                    if (breadcrumbId != null) {
+                        MDC.put(MDC_BREADCRUMB_ID, breadcrumbId);
+                    }
+                    if (exchangeId != null) {
+                        MDC.put(MDC_EXCHANGE_ID, exchangeId);
+                    }
+                    if (correlationId != null) {
+                        MDC.put(MDC_CORRELATION_ID, correlationId);
+                    }
+                    if (routeId != null) {
+                        MDC.put(MDC_ROUTE_ID, routeId);
+                    }
                 }
+            } finally {
+                // muse ensure delegate is invoked
+                delegate.done(doneSync);
             }
-            delegate.done(doneSync);
         }
 
         @Override

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbDisabledTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbDisabledTest.java?rev=1086641&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbDisabledTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbDisabledTest.java Tue Mar 29 17:07:04 2011
@@ -0,0 +1,55 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version 
+ */
+public class BreadcrumbDisabledTest extends MDCTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // MDC and breadcrumb disabled
+                context.setUseMDCLogging(false);
+                context.setUseBreadcrumb(false);
+
+                from("direct:a").routeId("route-a")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                assertNull("Should not have breadcrumb", exchange.getIn().getHeader("breadcrumbId"));
+                            }
+                        })
+                        .to("log:foo").to("direct:b");
+
+                from("direct:b").routeId("route-b")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                assertNull("Should not have breadcrumb", exchange.getIn().getHeader("breadcrumbId"));
+                            }
+                        })
+                        .to("log:bar").to("mock:result");
+            }
+        };
+    }
+}

Added: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbTest.java?rev=1086641&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/BreadcrumbTest.java Tue Mar 29 17:07:04 2011
@@ -0,0 +1,56 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.slf4j.MDC;
+
+/**
+ * @version 
+ */
+public class BreadcrumbTest extends MDCTest {
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // breadcrumb should also work without MDC
+                context.setUseMDCLogging(false);
+                context.setUseBreadcrumb(true);
+
+                from("direct:a").routeId("route-a")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                assertEquals(exchange.getIn().getMessageId(), exchange.getIn().getHeader("breadcrumbId"));
+                            }
+                        })
+                        .to("log:foo").to("direct:b");
+
+                from("direct:b").routeId("route-b")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                assertEquals(exchange.getIn().getMessageId(), exchange.getIn().getHeader("breadcrumbId"));
+                            }
+                        })
+                        .to("log:bar").to("mock:result");
+            }
+        };
+    }
+}

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCWithBreadcrumbTest.java (from r1086145, camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCWithBreadcrumbTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCWithBreadcrumbTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCTest.java&r1=1086145&r2=1086641&rev=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/MDCWithBreadcrumbTest.java Tue Mar 29 17:07:04 2011
@@ -16,50 +16,31 @@
  */
 package org.apache.camel.processor;
 
-import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
 import org.slf4j.MDC;
 
 /**
  * @version 
  */
-public class MDCTest extends ContextTestSupport {
-
-    public void testMDC() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedBodiesReceived("Hello World");
-
-        template.sendBody("direct:a", "Hello World");
-
-        assertMockEndpointsSatisfied();
-    }
-
-    public void testMDCTwoMessages() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedBodiesReceived("Hello World", "Bye World");
-
-        template.sendBody("direct:a", "Hello World");
-        template.sendBody("direct:a", "Bye World");
-
-        assertMockEndpointsSatisfied();
-    }
+public class MDCWithBreadcrumbTest extends MDCTest {
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                // enable MDC
+                // enable MDC and breadcrumb
                 context.setUseMDCLogging(true);
+                context.setUseBreadcrumb(true);
 
                 from("direct:a").routeId("route-a")
                         .process(new Processor() {
                             public void process(Exchange exchange) throws Exception {
                                 assertEquals("route-a", MDC.get("routeId"));
                                 assertEquals(exchange.getExchangeId(), MDC.get("exchangeId"));
+                                assertEquals(exchange.getIn().getMessageId(), MDC.get("breadcrumbId"));
                             }
                         })
                         .to("log:foo").to("direct:b");
@@ -69,6 +50,7 @@ public class MDCTest extends ContextTest
                             public void process(Exchange exchange) throws Exception {
                                 assertEquals("route-b", MDC.get("routeId"));
                                 assertEquals(exchange.getExchangeId(), MDC.get("exchangeId"));
+                                assertEquals(exchange.getIn().getMessageId(), MDC.get("breadcrumbId"));
                             }
                         })
                         .to("log:bar").to("mock:result");

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/PipelineTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/PipelineTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/PipelineTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/PipelineTest.java Tue Mar 29 17:07:04 2011
@@ -130,7 +130,8 @@ public class PipelineTest extends Contex
                 exchange.getIn().setBody("test");
             }
         });
-        assertEquals("There should have no message header", 0, exchange.getOut().getHeaders().size());
+        // there is always breadcrumb header
+        assertEquals("There should have no message header", 1, exchange.getOut().getHeaders().size());
         assertEquals("There should have no attachments", 0, exchange.getOut().getAttachments().size());
         assertEquals("Get a wrong message body", "test", exchange.getOut().getBody());
         assertNull(exchange.getOut().getHeader("test"));

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersExcludeTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersExcludeTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersExcludeTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersExcludeTest.java Tue Mar 29 17:07:04 2011
@@ -40,7 +40,8 @@ public class RemoveHeadersExcludeTest ex
 
         assertMockEndpointsSatisfied();
 
-        assertEquals(1, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
+        // there is also a breadcrumb header
+        assertEquals(2, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
     }
 
     public void testRemoveHeadersRegEx() throws Exception {
@@ -62,7 +63,8 @@ public class RemoveHeadersExcludeTest ex
 
         assertMockEndpointsSatisfied();
 
-        assertEquals(3, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
+        // there is also a breadcrumb header
+        assertEquals(4, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
     }
 
     protected RouteBuilder createRouteBuilder() {

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/RemoveHeadersTest.java Tue Mar 29 17:07:04 2011
@@ -40,7 +40,8 @@ public class RemoveHeadersTest extends C
 
         assertMockEndpointsSatisfied();
 
-        assertEquals(1, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
+        // breadcrumb is a header added as well so we expect 2
+        assertEquals(2, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
     }
 
     public void testRemoveHeadersRegEx() throws Exception {
@@ -61,7 +62,8 @@ public class RemoveHeadersTest extends C
 
         assertMockEndpointsSatisfied();
 
-        assertEquals(2, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
+        // breadcrumb is a header added as well so we expect 3
+        assertEquals(3, mock.getReceivedExchanges().get(0).getIn().getHeaders().size());
     }
 
     protected RouteBuilder createRouteBuilder() {

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/DefaultTraceEventMessageTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/DefaultTraceEventMessageTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/DefaultTraceEventMessageTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/DefaultTraceEventMessageTest.java Tue Mar 29 17:07:04 2011
@@ -61,7 +61,7 @@ public class DefaultTraceEventMessageTes
         assertTrue(em.getProperties().contains("foo=123"));
         assertTrue(em.getProperties().contains("CamelToEndpoint=direct://start"));
         assertTrue(em.getProperties().contains("CamelCreatedTimestamp"));
-        assertEquals("{bar=456}", em.getHeaders());
+        assertTrue(em.getHeaders().contains("bar=456"));
         assertEquals("Hello World", em.getBody());
         assertEquals("String", em.getBodyType());
         assertEquals("Bye World", em.getOutBody());

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorDestinationTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorDestinationTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorDestinationTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TraceInterceptorDestinationTest.java Tue Mar 29 17:07:04 2011
@@ -71,12 +71,10 @@ public class TraceInterceptorDestination
         assertEquals("Foo World", tracedBodies.get(7));
 
         // assert headers as well
-        assertEquals("{to=James}", tracedHeaders.get(0));
-        assertEquals("{to=Hello}", tracedHeaders.get(1));
-        assertEquals("{to=Goodday}", tracedHeaders.get(2));
-        assertEquals("{to=Bye}", tracedHeaders.get(3));
-        assertEquals("{to=Foo}", tracedHeaders.get(4));
-        assertEquals("{to=Foo}", tracedHeaders.get(5));
+        assertTrue(tracedHeaders.get(0), tracedHeaders.get(0).contains("to=James"));
+        assertTrue(tracedHeaders.get(1), tracedHeaders.get(1).contains("to=Hello"));
+        assertTrue(tracedHeaders.get(2), tracedHeaders.get(2).contains("to=Goodday"));
+        assertTrue(tracedHeaders.get(3), tracedHeaders.get(3).contains("to=Bye"));
     }
 
     protected RouteBuilder createRouteBuilder() throws Exception {

Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TracerTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TracerTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TracerTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/processor/interceptor/TracerTest.java Tue Mar 29 17:07:04 2011
@@ -83,7 +83,8 @@ public class TracerTest extends ContextT
         assertNotNull(em.getShortExchangeId());
         assertNotNull(em.getExchangePattern());
         assertEquals("direct://start", em.getFromEndpointUri());
-        assertNull(em.getHeaders());
+        // there is always a breadcrumb header
+        assertNotNull(em.getHeaders());
         assertNotNull(em.getProperties());
         assertNull(em.getOutBody());
         assertNull(em.getOutBodyType());

Modified: camel/trunk/camel-core/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/resources/log4j.properties?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/resources/log4j.properties (original)
+++ camel/trunk/camel-core/src/test/resources/log4j.properties Tue Mar 29 17:07:04 2011
@@ -55,7 +55,7 @@ log4j.appender.out=org.apache.log4j.Cons
 log4j.appender.out.layout=org.apache.log4j.PatternLayout
 log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
 # MDC
-#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{exchangeId} - %-10.10X{correlationId} - %-10.10X{routeId} - %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{breadcrumbId} - %-10.10X{exchangeId} - %-10.10X{correlationId} - %-10.10X{routeId} - %m%n
 
 # File appender
 log4j.appender.file=org.apache.log4j.FileAppender
@@ -64,6 +64,6 @@ log4j.appender.file.file=target/camel-co
 log4j.appender.file.append=true
 log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
 # MDC
-#log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{exchangeId} - %-10.10X{correlationId} - %-10.10X{routeId} - %m%n
+#log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{breadcrumbId} - %-10.10X{exchangeId} - %-10.10X{correlationId} - %-10.10X{routeId} - %m%n
 
 log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
\ No newline at end of file

Modified: camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java (original)
+++ camel/trunk/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java Tue Mar 29 17:07:04 2011
@@ -90,6 +90,8 @@ public class CamelContextFactoryBean ext
     @XmlAttribute(required = false)
     private String useMDCLogging;
     @XmlAttribute(required = false)
+    private String useBreadcrumb;
+    @XmlAttribute(required = false)
     private Boolean useBlueprintPropertyResolver;
     @XmlAttribute(required = false)
     private ShutdownRoute shutdownRoute;
@@ -293,6 +295,14 @@ public class CamelContextFactoryBean ext
         this.useMDCLogging = useMDCLogging;
     }
 
+    public String getUseBreadcrumb() {
+        return useBreadcrumb;
+    }
+
+    public void setUseBreadcrumb(String useBreadcrumb) {
+        this.useBreadcrumb = useBreadcrumb;
+    }
+
     public Boolean getLazyLoadTypeConverters() {
         return lazyLoadTypeConverters;
     }

Modified: camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java (original)
+++ camel/trunk/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java Tue Mar 29 17:07:04 2011
@@ -453,6 +453,8 @@ public abstract class AbstractCamelConte
 
     public abstract String getUseMDCLogging();
 
+    public abstract String getUseBreadcrumb();
+
     public abstract Boolean getLazyLoadTypeConverters();
 
     public abstract CamelJMXAgentDefinition getCamelJMXAgent();
@@ -508,6 +510,9 @@ public abstract class AbstractCamelConte
         if (getUseMDCLogging() != null) {
             ctx.setUseMDCLogging(CamelContextHelper.parseBoolean(getContext(), getUseMDCLogging()));
         }
+        if (getUseBreadcrumb() != null) {
+            ctx.setUseBreadcrumb(CamelContextHelper.parseBoolean(getContext(), getUseBreadcrumb()));
+        }
         if (getShutdownRoute() != null) {
             ctx.setShutdownRoute(getShutdownRoute());
         }

Modified: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerSlowResponseTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerSlowResponseTest.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerSlowResponseTest.java (original)
+++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerSlowResponseTest.java Tue Mar 29 17:07:04 2011
@@ -54,7 +54,7 @@ public class JettyHttpProducerSlowRespon
         String reply = exchange.getOut().getBody(String.class);
         assertEquals("Bye World", reply);
 
-        assertEquals(4, exchange.getOut().getHeaders().size());
+        assertEquals(5, exchange.getOut().getHeaders().size());
     }
 
     @Override

Modified: camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java (original)
+++ camel/trunk/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java Tue Mar 29 17:07:04 2011
@@ -97,6 +97,8 @@ public class CamelContextFactoryBean ext
     @XmlAttribute(required = false)
     private String useMDCLogging;
     @XmlAttribute(required = false)
+    private String useBreadcrumb;
+    @XmlAttribute(required = false)
     private ShutdownRoute shutdownRoute;
     @XmlAttribute(required = false)
     private ShutdownRunningTask shutdownRunningTask;
@@ -460,6 +462,14 @@ public class CamelContextFactoryBean ext
         this.useMDCLogging = useMDCLogging;
     }
 
+    public String getUseBreadcrumb() {
+        return useBreadcrumb;
+    }
+
+    public void setUseBreadcrumb(String useBreadcrumb) {
+        this.useBreadcrumb = useBreadcrumb;
+    }
+
     public Boolean getLazyLoadTypeConverters() {
         return lazyLoadTypeConverters;
     }

Added: camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.java?rev=1086641&view=auto
==============================================================================
--- camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.java (added)
+++ camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.java Tue Mar 29 17:07:04 2011
@@ -0,0 +1,51 @@
+/**
+ * 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.spring;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.slf4j.MDC;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @version 
+ */
+public class SpringMDCWithBreadcrumbDisabledTest extends SpringMDCTest {
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.xml");
+    }
+
+    public static class ProcessorA implements Processor {
+
+        public void process(Exchange exchange) throws Exception {
+            assertEquals("route-a", MDC.get("routeId"));
+            assertNull("Should not have breadcrumb", exchange.getIn().getHeader("breadcrumbId"));
+        }
+    }
+
+    public static class ProcessorB implements Processor {
+
+        public void process(Exchange exchange) throws Exception {
+            assertEquals("route-b", MDC.get("routeId"));
+            assertNull("Should not have breadcrumb", exchange.getIn().getHeader("breadcrumbId"));
+        }
+    }
+
+}

Copied: camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.java (from r1086145, camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.java?p2=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.java&p1=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCTest.java&r1=1086145&r2=1086641&rev=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCTest.java (original)
+++ camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.java Tue Mar 29 17:07:04 2011
@@ -18,7 +18,6 @@ package org.apache.camel.spring;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.apache.camel.component.mock.MockEndpoint;
 import org.slf4j.MDC;
 import org.springframework.context.support.AbstractXmlApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -26,30 +25,11 @@ import org.springframework.context.suppo
 /**
  * @version 
  */
-public class SpringMDCTest extends SpringTestSupport {
+public class SpringMDCWithBreadcrumbTest extends SpringMDCTest {
 
     @Override
     protected AbstractXmlApplicationContext createApplicationContext() {
-        return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringMDCTest.xml");
-    }
-
-    public void testMDC() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedBodiesReceived("Hello World");
-
-        template.sendBody("direct:a", "Hello World");
-
-        assertMockEndpointsSatisfied();
-    }
-
-    public void testMDCTwoMessages() throws Exception {
-        MockEndpoint mock = getMockEndpoint("mock:result");
-        mock.expectedBodiesReceived("Hello World", "Bye World");
-
-        template.sendBody("direct:a", "Hello World");
-        template.sendBody("direct:a", "Bye World");
-
-        assertMockEndpointsSatisfied();
+        return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringMDCWithBreadcrumbTest.xml");
     }
 
     public static class ProcessorA implements Processor {
@@ -57,6 +37,7 @@ public class SpringMDCTest extends Sprin
         public void process(Exchange exchange) throws Exception {
             assertEquals("route-a", MDC.get("routeId"));
             assertEquals(exchange.getExchangeId(), MDC.get("exchangeId"));
+            assertEquals(exchange.getIn().getMessageId(), MDC.get("breadcrumbId"));
         }
     }
 
@@ -64,7 +45,7 @@ public class SpringMDCTest extends Sprin
 
         public void process(Exchange exchange) throws Exception {
             assertEquals("route-b", MDC.get("routeId"));
-            assertEquals(exchange.getExchangeId(), MDC.get("exchangeId"));
+            assertEquals(exchange.getIn().getMessageId(), MDC.get("breadcrumbId"));
         }
     }
 

Modified: camel/trunk/components/camel-spring/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/log4j.properties?rev=1086641&r1=1086640&r2=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/log4j.properties (original)
+++ camel/trunk/components/camel-spring/src/test/resources/log4j.properties Tue Mar 29 17:07:04 2011
@@ -35,7 +35,7 @@ log4j.appender.out=org.apache.log4j.Cons
 log4j.appender.out.layout=org.apache.log4j.PatternLayout
 log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
 # MDC
-#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{exchangeId} - %-10.10X{correlationId} - %-10.10X{transactionKey} - %-10.10X{routeId} - %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{breadcrumbId} - %-10.10X{exchangeId} - %-10.10X{correlationId} - %-10.10X{transactionKey} - %-10.10X{routeId} - %m%n
 
 # File appender
 log4j.appender.file=org.apache.log4j.FileAppender

Added: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.xml?rev=1086641&view=auto
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.xml (added)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbDisabledTest.xml Tue Mar 29 17:07:04 2011
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+    <bean id="processorA" class="org.apache.camel.spring.SpringMDCWithBreadcrumbDisabledTest$ProcessorA"/>
+    <bean id="processorB" class="org.apache.camel.spring.SpringMDCWithBreadcrumbDisabledTest$ProcessorB"/>
+
+    <camelContext xmlns="http://camel.apache.org/schema/spring" useMDCLogging="true" useBreadcrumb="false">
+
+        <route id="route-a">
+            <from uri="direct:a"/>
+            <process ref="processorA"/>
+            <to uri="log:foo"/>
+            <to uri="direct:b"/>
+        </route>
+
+        <route id="route-b">
+            <from uri="direct:b"/>
+            <process ref="processorB"/>
+            <to uri="log:bar"/>
+            <to uri="mock:result"/>
+        </route>
+
+    </camelContext>
+
+</beans>

Copied: camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.xml (from r1086145, camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCTest.xml)
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.xml?p2=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.xml&p1=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCTest.xml&r1=1086145&r2=1086641&rev=1086641&view=diff
==============================================================================
--- camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCTest.xml (original)
+++ camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringMDCWithBreadcrumbTest.xml Tue Mar 29 17:07:04 2011
@@ -22,10 +22,10 @@
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
     ">
 
-    <bean id="processorA" class="org.apache.camel.spring.SpringMDCTest$ProcessorA"/>
-    <bean id="processorB" class="org.apache.camel.spring.SpringMDCTest$ProcessorB"/>
+    <bean id="processorA" class="org.apache.camel.spring.SpringMDCWithBreadcrumbTest$ProcessorA"/>
+    <bean id="processorB" class="org.apache.camel.spring.SpringMDCWithBreadcrumbTest$ProcessorB"/>
 
-    <camelContext xmlns="http://camel.apache.org/schema/spring" useMDCLogging="true">
+    <camelContext xmlns="http://camel.apache.org/schema/spring" useMDCLogging="true" useBreadcrumb="true">
 
         <route id="route-a">
             <from uri="direct:a"/>