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

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


The following commit(s) were added to refs/heads/camel-4.18.x by this push:
     new 8f4eb37bc5ca CAMEL-24062: Fix Multicast EIP to honor 
UseOriginalAggregationStrategy
8f4eb37bc5ca is described below

commit 8f4eb37bc5caec3dae5eab482ead113a3d1c1a66
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jul 15 09:56:51 2026 +0200

    CAMEL-24062: Fix Multicast EIP to honor UseOriginalAggregationStrategy
    
    Move the UseOriginalAggregationStrategy binding from Splitter and
    RecipientListProcessor into MulticastProcessor (their shared base class),
    so all three EIPs consistently bind the original exchange on the strategy.
    Previously Multicast never called newInstance(exchange), making the strategy
    silently ineffective in error scenarios where the aggregated result could
    overwrite the original exchange body.
    
    Closes #24699
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../apache/camel/processor/MulticastProcessor.java   | 14 ++++++++++++++
 .../camel/processor/RecipientListProcessor.java      | 20 --------------------
 .../java/org/apache/camel/processor/Splitter.java    | 10 ----------
 ...icastUseOriginalPropagateExceptionCaughtTest.java |  2 ++
 .../ROOT/pages/camel-4x-upgrade-guide-4_18.adoc      |  9 +++++++++
 5 files changed, 25 insertions(+), 30 deletions(-)

diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/MulticastProcessor.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/MulticastProcessor.java
index 1066873a6331..f21b73704c20 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/MulticastProcessor.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/MulticastProcessor.java
@@ -52,6 +52,8 @@ import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.StreamCache;
 import org.apache.camel.Traceable;
+import org.apache.camel.processor.aggregate.ShareUnitOfWorkAggregationStrategy;
+import org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy;
 import org.apache.camel.processor.errorhandler.ErrorHandlerSupport;
 import org.apache.camel.spi.AsyncProcessorAwaitManager;
 import org.apache.camel.spi.ErrorHandlerAware;
@@ -308,6 +310,18 @@ public class MulticastProcessor extends 
BaseProcessorSupport
 
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
+        AggregationStrategy strategy = getAggregationStrategy();
+
+        // set original exchange if not already pre-configured
+        if (strategy instanceof UseOriginalAggregationStrategy original) {
+            // need to create a new private instance, as we can also have 
concurrency issue so we cannot store state
+            AggregationStrategy clone = original.newInstance(exchange);
+            if (isShareUnitOfWork()) {
+                clone = new ShareUnitOfWorkAggregationStrategy(clone);
+            }
+            setAggregationStrategyOnExchange(exchange, clone);
+        }
+
         if (synchronous) {
             try {
                 // force synchronous processing using await manager
diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
index f946becd4634..a67cee877818 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
@@ -26,7 +26,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 
 import org.apache.camel.AggregationStrategy;
-import org.apache.camel.AsyncCallback;
 import org.apache.camel.AsyncProducer;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
@@ -38,8 +37,6 @@ import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.Route;
-import org.apache.camel.processor.aggregate.ShareUnitOfWorkAggregationStrategy;
-import org.apache.camel.processor.aggregate.UseOriginalAggregationStrategy;
 import org.apache.camel.spi.NormalizedEndpointUri;
 import org.apache.camel.spi.ProducerCache;
 import org.apache.camel.support.AsyncProcessorConverterHelper;
@@ -191,23 +188,6 @@ public class RecipientListProcessor extends 
MulticastProcessor {
         this.ignoreInvalidEndpoints = ignoreInvalidEndpoints;
     }
 
-    @Override
-    public boolean process(Exchange exchange, final AsyncCallback callback) {
-        AggregationStrategy strategy = getAggregationStrategy();
-
-        // set original exchange if not already pre-configured
-        if (strategy instanceof UseOriginalAggregationStrategy original) {
-            // need to create a new private instance, as we can also have 
concurrency issue so we cannot store state
-            AggregationStrategy clone = original.newInstance(exchange);
-            if (isShareUnitOfWork()) {
-                clone = new ShareUnitOfWorkAggregationStrategy(clone);
-            }
-            setAggregationStrategyOnExchange(exchange, clone);
-        }
-
-        return super.process(exchange, callback);
-    }
-
     @Override
     protected Iterable<ProcessorExchangePair> 
createProcessorExchangePairs(Exchange exchange)
             throws Exception {
diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/Splitter.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/Splitter.java
index 4620ecf945f4..d746813b1d36 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/Splitter.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/Splitter.java
@@ -102,16 +102,6 @@ public class Splitter extends MulticastProcessor {
     public boolean process(Exchange exchange, final AsyncCallback callback) {
         AggregationStrategy strategy = getAggregationStrategy();
 
-        // set original exchange if not already pre-configured
-        if (strategy instanceof UseOriginalAggregationStrategy original) {
-            // need to create a new private instance, as we can also have 
concurrency issue so we cannot store state
-            AggregationStrategy clone = original.newInstance(exchange);
-            if (isShareUnitOfWork()) {
-                clone = new ShareUnitOfWorkAggregationStrategy(clone);
-            }
-            setAggregationStrategyOnExchange(exchange, clone);
-        }
-
         // if no custom aggregation strategy is being used then fallback to 
keep the original
         // and propagate exceptions which is done by a per exchange specific 
aggregation strategy
         // to ensure it supports async routing
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/MulticastUseOriginalPropagateExceptionCaughtTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/MulticastUseOriginalPropagateExceptionCaughtTest.java
index 0cf9ed2b3892..4d8eb952a6c3 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/MulticastUseOriginalPropagateExceptionCaughtTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/MulticastUseOriginalPropagateExceptionCaughtTest.java
@@ -45,6 +45,8 @@ public class MulticastUseOriginalPropagateExceptionCaughtTest 
extends ContextTes
 
         assertEquals(1, 
getMockEndpoint("mock:result").getReceivedExchanges().size());
         Exchange exchange = 
getMockEndpoint("mock:result").getReceivedExchanges().get(0);
+        // verify original body is preserved
+        assertEquals(body, exchange.getIn().getBody(String.class));
         Exception exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, 
Exception.class);
         assertNotNull(exception);
         Throwable rootCause = exception;
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
index 88002166e0b9..1aea803fd6f9 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_18.adoc
@@ -13,6 +13,15 @@ See the xref:camel-upgrade-recipes-tool.adoc[documentation] 
page for details.
 
 == Upgrading from 4.18.3 to 4.18.4
 
+=== camel-core - Multicast EIP honors UseOriginalAggregationStrategy
+
+The `UseOriginalAggregationStrategy` binding has been moved from `Splitter` 
and `RecipientListProcessor`
+into `MulticastProcessor` (their shared base class), so all three EIPs 
(Multicast, Splitter,
+RecipientList) now consistently bind the original exchange on the strategy. 
Previously, Multicast
+never called `newInstance(exchange)`, which made the strategy silently 
ineffective — especially in
+error scenarios where the aggregated result could overwrite the original 
exchange body instead of
+preserving it.
+
 === camel-azure-servicebus - Camel-managed message lock renewal
 
 When consuming from Azure Service Bus in `PEEK_LOCK` mode with 
`maxAutoLockRenewDuration > 0`, Camel now

Reply via email to