shashank created CAMEL-26739:
--------------------------------
Summary: camel-core - Aggregate EIP: a group completed by its
first exchange is confirmed although it was never stored, and with
JdbcAggregationRepository its id is kept for good
Key: CAMEL-26739
URL: https://issues.apache.org/jira/browse/CAMEL-26739
Project: Camel
Issue Type: Bug
Components: camel-core, camel-sql
Reporter: shashank
Assignee: shashank
A group can be completed by the exchange that creates it, for example with
{{completionSize(1)}}, or with a completion predicate that is true for a group
of one exchange. Such a group is never added to the repository, so
{{AggregateProcessor.doOnCompletion}} does not call {{remove()}} ("only remove
if we have previous added"), and a recoverable repository has nothing in its
completed store for it.
After the exchange is delivered, {{AggregateOnCompletion.onComplete}} still
calls {{confirmWithResult}}. {{JdbcAggregationRepository}} finds no row, logs
{{problem removing row ... DELETE statement did not return 1 but 0}} at ERROR,
and returns {{false}}, so the exchange id is added to
{{unconfirmedCompleteExchanges}}. That set was added in CAMEL-17613 to retry a
confirm whose completed row is not visible yet. Only the recover task removes
ids from it, and only ids it finds in the completed table, so these ids are
never removed: not by later scans, nor by a route stop and start. The set grows
by one id per such group (about 115 bytes of heap each) until the route is
removed, and every such delivery logs a false ERROR.
Found with a TLA+ model of the Aggregate EIP with a recoverable repository.
Short trace: a message arrives, the group has no stored exchange and is
complete, the exchange is submitted and delivered, its confirm finds no
completed row, and its id stays in the unconfirmed set. A route with
{{aggregate(header("id"),
strategy).aggregationRepository(jdbcRepo).completionSize(1)}} on H2 shows it:
500 groups delivered, 500 ERROR lines, 500 ids kept through 15 recover scans
and a route restart; with a 64 MB heap, about 400,000 such groups end in
OutOfMemoryError. Groups of two exchanges keep no id.
Expected: a group that was never stored is not confirmed, so no ERROR is logged
and no id is kept.
Suggested fix: mark the aggregated exchange of a group that was never stored in
{{doOnCompletion}}, and skip the confirm for it in {{AggregateOnCompletion}}.
Groups that were stored, and recovered exchanges, are confirmed as before.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)