Federico Mariani created CAMEL-24143:
----------------------------------------
Summary: camel-core - Split & Aggregate EIP review follow-ups
(medium findings)
Key: CAMEL-24143
URL: https://issues.apache.org/jira/browse/CAMEL-24143
Project: Camel
Issue Type: Bug
Components: camel-core, eip
Affects Versions: 4.21.0, 4.22.0
Reporter: Federico Mariani
Umbrella for the medium findings from a code review of the
Split/Multicast/Aggregate EIP processors in {{camel-core-processor}} (July
2026). The high findings are tracked separately: CAMEL-24138 (nested-split
failure swallow), CAMEL-24139 (watermark data loss on abort), CAMEL-24140
(UseOriginal + shareUnitOfWork), CAMEL-24141 (recovery/interval task death),
CAMEL-24142 (lost multicast timeout). Full review document attached.
Items new in CAMEL-23264 (unreleased 4.22.0-SNAPSHOT — can be fixed before
release):
# *M1 — errorThreshold ratio wrong under parallelProcessing*
({{Splitter.java:557-563}}): {{ratio = failureCount / (index + 1)}} uses the
completing item's _original index_ as denominator, not the number of items
completed so far. With out-of-order parallel completion a 1%-failure run can
abort at {{errorThreshold(0.5)}} (low-index item failing late), or badly
under-count. Use a completed-items counter as denominator.
# *M2 — non-failure stop conditions recorded as "failures"*
({{Splitter.java:543-570}}): with thresholds configured,
{{shouldContinueOnFailure}} records a {{SplitResult.Failure}} for any
{{continueProcessing=false}} condition — including exceptions already handled
by the error handler ({{Failure(index, null)}}), {{rollbackOnly}}, and a
deliberate {{.stop()}} (routeStop) in the child route, whose semantics are
silently overridden to "continue".
# *M3 — SplitResult.getSuccessCount() counts never-attempted items as successes
after an abort* ({{SplitResult.java:63-67}}): {{totalItems}} counts
prepared/drained items, so after an abort {{totalItems - failureCount}}
includes unprocessed items; can even go negative combined with CAMEL-24138.
# *M7 — unguarded Integer.parseInt of the stored watermark*
({{Splitter.java:316-318}}): a non-numeric value under the watermark key (key
previously used with {{watermarkExpression}}, shared key, corrupted store)
fails every exchange with a bare {{NumberFormatException}}.
Longstanding:
# *M4 — optimistic-lock async retry can leak the callback*
({{AggregateProcessor.java:404-410}}): retries scheduled on the
optimistic-locking executor have no try/catch; an unexpected
(non-OptimisticLocking) exception from {{doProcess}} on the retry thread
escapes and the {{AsyncCallback}} is never invoked — the exchange hangs. The
first attempt is guarded by {{process()}}'s try/catch, the retry path is not.
# *M5 — Statistics.reset() does not reset completedByInterval*
({{AggregateProcessor.java:207-218}}).
# *M6 — aggregateCompletionCounter NPE on null CamelAggregatedCompletedBy*
({{AggregateProcessor.java:924-952}}) — also feeds the recovery-task death in
CAMEL-24141.
Low findings (L1-L6: timeout strategy lookup ignoring per-exchange strategies,
watermark late-completion NPE, LRU'd error handlers never stopped — a {{Map}}
is not {{Iterable}} so {{ServiceHelper.stopService}} skips it,
StringAggregationStrategy delimiter edge, forceCompletionOfAllGroups count,
errorThreshold first-item-abort docs) are described in the attached review
document.
_Filed by Claude Code on behalf of Federico Mariani (fmariani)_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)