shashank created CAMEL-26707:
--------------------------------
Summary: camel-core - Idempotent Consumer: an exchange marked
rollback only keeps its message id, so the redelivered message is dropped as a
duplicate
Key: CAMEL-26707
URL: https://issues.apache.org/jira/browse/CAMEL-26707
Project: Camel
Issue Type: Bug
Components: camel-core
Reporter: shashank
Assignee: shashank
{{markRollbackOnly()}} and {{markRollbackOnlyLast()}} mark the exchange for
rollback without setting an exception, so the unit of work runs the on
completions as successful ({{exchange.isFailed()}} only checks the exception).
{{IdempotentOnCompletion.onComplete}} then confirms the message id (or adds it,
with {{eager=false}}) instead of removing it, and {{removeOnFailure}} has no
effect. {{completionEager}} goes through the same {{onComplete}}.
A consumer that does not commit a rollback only exchange (such as the SQL
consumer, which then skips {{onConsume}} since CAMEL-25527, or a transacted JMS
consumer) redelivers the message. The Idempotent Consumer finds its message id
and drops the redelivery as a duplicate, and the consumer then commits it: the
message was never processed, and the dropped duplicate is only logged at DEBUG.
This happens with the default options, with any idempotent repository that is
not enlisted in the transaction that is rolled back.
{code:java}
from("sql:select * from inbox where consumed = false?onConsume=update inbox set
consumed = true where id = :#id")
.idempotentConsumer(simple("${body[msgid]}"), repository)
.choice().when(dependencyNotReady).markRollbackOnly().end()
.to("direct:process");
// first poll: rolled back, the row stays unconsumed, but the message id is
confirmed
// second poll: "Ignoring duplicate message", and onConsume marks the row
consumed
{code}
The SQL consumer already treats a rollback only exchange as failed
({{SqlConsumer}}: "a rollback only exchange (without an exception) did not
complete successfully either" (CAMEL-25527, CAMEL-25588));
{{PipelineHelper.continueProcessing}} also stops on {{isRollbackOnly() ||
isRollbackOnlyLast()}}.
Expected: with {{removeOnFailure=true}} (the default) the message id of a
rollback only exchange is removed, as for a failed one, so the redelivered
message is processed.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)