[
https://issues.apache.org/jira/browse/CAMEL-26856?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-26856:
--------------------------------
Fix Version/s: 4.24.0
> camel-kafka - exactlyOnce: a Kafka send whose retry was rejected, in a route
> called from a doTry, is replayed after the doCatch instead of skipped
> --------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26856
> URL: https://issues.apache.org/jira/browse/CAMEL-26856
> Project: Camel
> Issue Type: Bug
> Components: camel-kafka
> Reporter: shashank
> Assignee: shashank
> Priority: Major
> Fix For: 4.24.0
>
>
> With {{exactlyOnce}} on a Kafka consumer, the route calls another route from
> a {{doTry}} block (for example with {{direct}}), and that route sends to
> Kafka with an error handler that redelivers ({{maximumRedeliveries}} > 0).
> When the send fails, its retry is rejected inside the open transaction:
> {{KafkaProducer}} (around line 709-726) sets {{rollbackOnly}} and the
> {{CamelKafkaExactlyOnceRetryRollback}} property, and throws. The called route
> fails unhandled, the {{doCatch}} of the calling route catches the failure,
> and {{CatchProcessor}} sets {{rollbackOnly}} again after the {{doCatch}}
> block.
> {{KafkaTransactionSynchronization.onDone}} skips the rollback of such a
> rejected retry only when the exchange is failure handled
> ({{handledRedeliveryRejection}}, lines 123-125 and 142-143). Since
> CAMEL-26447 the exchange is no longer marked failure handled after a
> {{doCatch}} caught the failure of a called route, as when the {{doTry}} fails
> in the route itself. So the source transaction is aborted and the source
> record is replayed, where before CAMEL-26447 it took the offsets-only path
> (abort the output, commit the source offsets, skip the record). For a send
> that keeps failing (for example a record that is too large), every replay
> ends the same way, so the consumer does not get past that record.
> A {{doTry}} that fails in the route itself is not affected: no redelivery
> runs inside the {{doTry}}, so no retry is rejected, and the recorded send
> failure takes the offsets-only path.
> Expected: a rejected retry whose failure was handled, by an error handler or
> by a {{doCatch}}, takes the offsets-only path, as before CAMEL-26447 and as
> for a {{doTry}} that fails in the route.
> Possible fix, in camel-kafka: treat the rejected retry as handled when the
> exchange has no exception left, instead of requiring the failure handled mark:
> {code:java}
> boolean handledRedeliveryRejection = exchange.getException() == null
> &&
> Boolean.TRUE.equals(exchange.getProperty(KafkaExactlyOnceMetadata.RETRY_ROLLBACK_PROPERTY));
> {code}
> A rejection that nothing handled keeps its exception and is still rolled back
> by the branch on {{exchange.getException() != null}}. A rollback that the
> route asks for itself after the rejection ({{markRollbackOnly}}) is not told
> apart from the rejection, which is already the case today when an error
> handler handled it.
> Test: a variant of
> {{KafkaTransactionSynchronizationTest.handledInTransactionRedeliveryRejectionCommitsOffsetsAfterAbortingOutput}}
> with {{isFailureHandled()}} returning false (the {{doCatch}} case), and if
> practical a case in {{KafkaExactlyOnceIT}} with the {{doTry}} calling a route
> that redelivers a failing send.
> CAMEL-26447 exposes this, so it should be fixed in the same release (4.24.0).
> Found in the review of CAMEL-26447 (apache/camel#29584), from reading the
> code; not reproduced with a broker.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)