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 2021/10/26 10:50:40 UTC

[camel] branch main updated: CAMEL-17009: MDC is not cleared when UoW is done.

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new a9aa1fe  CAMEL-17009: MDC is not cleared when UoW is done.
a9aa1fe is described below

commit a9aa1fea7b2c5c3dc304589c892f14f992a2d57c
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Oct 26 11:36:35 2021 +0200

    CAMEL-17009: MDC is not cleared when UoW is done.
---
 .../main/java/org/apache/camel/spi/UnitOfWork.java  |  4 ++--
 .../apache/camel/impl/engine/DefaultUnitOfWork.java |  8 ++++++++
 .../org/apache/camel/impl/engine/MDCUnitOfWork.java |  6 ++++++
 .../org/apache/camel/processor/MDCClearingTest.java | 21 +++++++++++++++------
 .../camel-core/src/test/resources/log4j2.properties |  3 +++
 5 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java b/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java
index a6f118e..1d37e24 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java
@@ -40,7 +40,7 @@ public interface UnitOfWork {
     String MDC_TRANSACTION_KEY = "camel.transactionKey";
 
     /**
-     * Clears the unit of work from user data so it may be reused.
+     * Clears the unit of work from user data, so it may be reused.
      * <p/>
      * <b>Important:</b> This API is NOT intended for Camel end users, but used internally by Camel itself.
      */
@@ -196,7 +196,7 @@ public interface UnitOfWork {
     boolean isBeforeAfterProcess();
 
     /**
-     * Strategy for work to be execute before processing.
+     * Strategy for work to be executed before processing.
      * <p/>
      * For example the MDCUnitOfWork leverages this to ensure MDC is handled correctly during routing exchanges using
      * the asynchronous routing engine.
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
index 10b4d21..a68d058a 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
@@ -256,15 +256,23 @@ public class DefaultUnitOfWork implements UnitOfWork {
 
         // the exchange is now done
         if (exchange instanceof PooledExchange) {
+            // pooled exchange has its own done logic which will reset this uow for reuse
+            // so do not call onDone
             try {
                 ((PooledExchange) exchange).done(false);
             } catch (Throwable e) {
                 // must catch exceptions to ensure synchronizations is also invoked
                 log.warn("Exception occurred during exchange done. This exception will be ignored.", e);
             }
+        } else {
+            onDone();
         }
     }
 
+    protected void onDone() {
+        // optimized to do nothing
+    }
+
     @Override
     public void beforeRoute(Exchange exchange, Route route) {
         if (log.isTraceEnabled()) {
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/MDCUnitOfWork.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/MDCUnitOfWork.java
index a8e1683..db7d5d1 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/MDCUnitOfWork.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/MDCUnitOfWork.java
@@ -196,6 +196,12 @@ public class MDCUnitOfWork extends DefaultUnitOfWork {
     }
 
     @Override
+    protected void onDone() {
+        // clear MDC, so we do not leak as Camel is done using this UoW
+        clear();
+    }
+
+    @Override
     public void reset() {
         super.reset();
         clear();
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/MDCClearingTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/MDCClearingTest.java
index c32c90d..acf37f0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/MDCClearingTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/MDCClearingTest.java
@@ -35,7 +35,6 @@ import org.slf4j.MDC;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
 
-@Disabled("TODO: CAMEL-17009")
 public class MDCClearingTest extends ContextTestSupport {
 
     public static final String CAMEL_BREADCRUMB_ID = "camel.breadcrumbId";
@@ -43,7 +42,7 @@ public class MDCClearingTest extends ContextTestSupport {
     public static final String MY_BREADCRUMB = "my breadcrumb";
 
     private static final Logger LOG = LoggerFactory.getLogger(MDCClearingTest.class);
-    private final ExecutorService executorService = Executors.newFixedThreadPool(16);
+    private final ExecutorService executorService = Executors.newFixedThreadPool(1);
 
     @Test
     public void shouldPropagateAndClearMdcInSyncRoute() {
@@ -58,6 +57,7 @@ public class MDCClearingTest extends ContextTestSupport {
     }
 
     @Test
+    @Disabled
     public void shouldPropagateAndClearMdcInAsyncRoute() {
         // given
         MDC.remove(CAMEL_BREADCRUMB_ID);
@@ -70,6 +70,7 @@ public class MDCClearingTest extends ContextTestSupport {
     }
 
     @Test
+    @Disabled
     public void shouldPropagateAndClearMdcInMixedRoute() {
         // given
         MDC.remove(CAMEL_BREADCRUMB_ID);
@@ -98,11 +99,11 @@ public class MDCClearingTest extends ContextTestSupport {
                         .process(new MySyncProcessor("STEP 1"));
 
                 from("direct:test-async")
-                        .process(new MySyncProcessor("STEP 1"));
+                        .process(new MyAsyncProcessor("STEP 2"));
 
                 from("direct:test-mixed")
-                        .process(new MyAsyncProcessor("STEP 1"))
-                        .process(new MySyncProcessor("STEP 2"));
+                        .process(new MyAsyncProcessor("STEP 3"))
+                        .process(new MySyncProcessor("STEP 4"));
             }
         };
     }
@@ -134,7 +135,15 @@ public class MDCClearingTest extends ContextTestSupport {
             LOG.info(msg);
             assertEquals(MY_BREADCRUMB, MDC.get(CAMEL_BREADCRUMB_ID));
 
-            executorService.execute(() -> callback.done(false));
+            executorService.execute(() -> {
+                // wait a little to simulate later async completion
+                try {
+                    Thread.sleep(10);
+                } catch (InterruptedException e) {
+                    // ignore
+                }
+                callback.done(false);
+            });
             return false;
         }
     }
diff --git a/core/camel-core/src/test/resources/log4j2.properties b/core/camel-core/src/test/resources/log4j2.properties
index a5b53e0..8bee7af 100644
--- a/core/camel-core/src/test/resources/log4j2.properties
+++ b/core/camel-core/src/test/resources/log4j2.properties
@@ -19,6 +19,9 @@ appender.console.name = console
 appender.console.layout.type = PatternLayout
 appender.console.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
 
+## MDC layout
+### appender.console.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %X{camel.exchangeId} %X{camel.breadcrumbId} - %m%n
+
 appender.file.type = File
 appender.file.name = file
 appender.file.fileName = target/camel-core-test.log