[
https://issues.apache.org/jira/browse/CAMEL-24062?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-24062.
---------------------------------
Resolution: Fixed
Fixed on main via https://github.com/apache/camel/pull/24697
Backported to camel-4.18.x via https://github.com/apache/camel/pull/24699
> UseOriginalAggregationStrategy silently ignored under Multicast (original
> never bound) — inconsistent with Splitter
> -------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24062
> URL: https://issues.apache.org/jira/browse/CAMEL-24062
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Affects Versions: 4.18.2
> Reporter: Eduard Gomoliako
> Assignee: Claus Ibsen
> Priority: Minor
> Fix For: 4.18.4, 4.22.0
>
>
> {{UseOriginalAggregationStrategy}} works as documented under the Splitter EIP
> but is silently ignored under Multicast. {{Splitter.process(...)}} binds the
> per-invocation _original_ exchange onto the strategy; {{MulticastProcessor}}
> does not — even though the shared base already contains the mechanism to
> honor it. So {{multicast().aggregationStrategy(new
> UseOriginalAggregationStrategy())}} does *not* restore the original
> pre-multicast exchange; it degrades to "use latest" with no error or warning.
> Please unify the two EIPs, or document why they differ.
> h3. Current behavior (4.18.2)
> * *{{Splitter.process(Exchange, AsyncCallback)}}* — if the strategy is a
> {{{}UseOriginalAggregationStrategy{}}}, creates a per-invocation instance via
> {{{}newInstance(exchange){}}}, optionally wraps in
> {{ShareUnitOfWorkAggregationStrategy}} when {{{}isShareUnitOfWork(){}}}, and
> installs it via {{{}setAggregationStrategyOnExchange(...){}}}; also falls
> back to {{new UseOriginalAggregationStrategy(exchange, true)}} when no
> strategy is set.
> * *{{MulticastProcessor}}* — overrides {{process(...)}} but has *no*
> {{UseOriginalAggregationStrategy}} handling. Yet its own
> {{getAggregationStrategy(Exchange)}} already reads the per-exchange,
> per-processor {{AGGREGATION_STRATEGY}} map ({{{}map.get(this){}}}) before the
> shared field — so the binding hook lives in the shared base and is
> functional; only {{Splitter}} ever writes to it.
> * *{{UseOriginalAggregationStrategy}}* — holds {{original}} (set via
> constructor / {{{}newInstance{}}}), implements only the 2-arg
> {{{}aggregate(old, new){}}}, does *not* override the 3-arg {{aggregate(old,
> new, inputExchange)}} from CAMEL-13287 (so the forwarded {{inputExchange}} is
> dropped), and returns the accumulated exchange when {{original}} is null.
> *Root cause:* Multicast never binds {{{}original{}}}, so it stays {{null}}
> and the strategy returns the last/aggregated exchange instead of the original
> — silently. CAMEL-13287's {{inputExchange}} doesn't help because this
> strategy never consults it.
> h3. Reproduce
>
>
> {code:java}
> // A) Splitter — works: mock:out receives the ORIGINAL body
> from("direct:split")
> .split(constant(java.util.List.of("only-element")))
> .aggregationStrategy(new UseOriginalAggregationStrategy())
> .setBody(constant("MUTATED"))
> .end()
> .to("mock:out");{code}
> {code:java}
> // B) Multicast — broken: mock:out receives "MUTATED", not the original
> from("direct:multicast")
> .multicast()
> .aggregationStrategy(new UseOriginalAggregationStrategy())
> .to("direct:mutate")
> .end()
> .to("mock:out");from("direct:mutate").setBody(constant("MUTATED"));
> // Send body "ORIGINAL" to each entry point. {code}
> *Expected:* route (B) {{mock:out}} receives the original
> ({{{}"ORIGINAL"{}}}), like (A). *Actual:* (B) receives the aggregated/last
> exchange; the strategy is a no-op.
> h3. Suggested resolutions (any one)
> # *Unify* — move the {{UseOriginalAggregationStrategy}} binding block from
> {{Splitter.process}} into {{MulticastProcessor.process}} (the base already
> reads what would be written). Don't copy Splitter's null-strategy fallback
> verbatim — Multicast's non-aggregating default differs.
> # *Alternative* — have {{UseOriginalAggregationStrategy}} override the 3-arg
> {{aggregate(old, new, inputExchange)}} to fall back to {{inputExchange}} when
> {{original}} is null; that fixes every EIP that forwards the input exchange,
> no per-EIP {{process()}} change.
> # *Document / fail fast* — if intentional, say so in the Multicast docs +
> Javadoc and error when it's configured on a multicast.
> h3. Question
> Is this divergence intentional? If so, what's the rationale and can it be
> documented / made to fail fast? If not, can the behavior be unified?
> h3. Related
> CAMEL-13287 (added 3-arg {{aggregate}} with {{{}inputExchange{}}}) — related
> but does not resolve this.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)