Claus Ibsen created CAMEL-26734:
-----------------------------------
Summary: camel-core - a step after one that was redelivered gets
fewer redeliveries, as the redelivery counter stays on the message
Key: CAMEL-26734
URL: https://issues.apache.org/jira/browse/CAMEL-26734
Project: Camel
Issue Type: Bug
Components: camel-core
Reporter: Claus Ibsen
Fix For: 4.24.0
When the error handler redelivers a step and the step then succeeds, the
{{CamelRedeliveryCounter}} header (and {{CamelRedelivered}},
{{CamelRedeliveryMaxCounter}}) stays on the message. A later failure, at
another step of the route or in another route (also a copy sent over seda),
starts counting from that header:
{{RedeliveryErrorHandler.incrementRedeliveryCounter}} takes {{Math.max(field,
header) + 1}}. So with {{maximumRedeliveries=2}}, a step after one that needed
2 redeliveries is not redelivered at all, and the message goes to the dead
letter channel at its first failure.
h3. Reproducer
Route {{two-steps}} calls {{direct:one}} (fails twice, succeeds at the second
redelivery), then {{direct:two}} (fails once). Both called routes have
{{noErrorHandler}}; the route has a dead letter channel with
{{maximumRedeliveries: 2}}.
{code:yaml}
- errorHandler:
deadLetterChannel:
deadLetterUri: "log:dead"
redeliveryPolicy:
maximumRedeliveries: 2
redeliveryDelay: 100
retryAttemptedLogLevel: WARN
- route:
id: two-steps
from:
uri: timer:once?repeatCount=1
steps:
- to:
uri: direct:one
- log:
message: "step one done,
CamelRedeliveryCounter=${header.CamelRedeliveryCounter}"
- to:
uri: direct:two
- log:
message: "step two done"
- route:
id: one
errorHandler:
noErrorHandler: {}
from:
uri: direct:one
steps:
- filter:
expression:
simple:
expression: "${header.CamelRedeliveryCounter} == null ||
${header.CamelRedeliveryCounter} < 2"
steps:
- throwException:
exceptionType: java.lang.IllegalStateException
message: "step one fails"
- route:
id: two
errorHandler:
noErrorHandler: {}
from:
uri: direct:two
steps:
- filter:
expression:
simple:
expression: "${exchangeProperty.stepTwoFailed} == null"
steps:
- setProperty:
name: stepTwoFailed
expression:
constant:
expression: "true"
- throwException:
exceptionType: java.lang.IllegalStateException
message: "step two fails once"
{code}
{{camel run redeliv.camel.yaml}} logs:
{noformat}
WARN DeadLetterChannel : Failed delivery ... at two-steps[throwException1] ...
On delivery attempt: 0 caught: java.lang.IllegalStateException: step one fails
WARN DeadLetterChannel : Failed delivery ... at two-steps[throwException1] ...
On delivery attempt: 1 caught: java.lang.IllegalStateException: step one fails
INFO : step one done, CamelRedeliveryCounter=2
WARN DeadLetterChannel : Failed delivery ... at two-steps[throwException2] ...
On delivery attempt: 0 caught: java.lang.IllegalStateException: step two fails
once
INFO dead : Exchange[ExchangePattern: InOnly, BodyType: null, Body: [Body is
null]]
{noformat}
Expected: step two is redelivered, and attempt 1 succeeds. Actual: it goes to
the dead letter channel at its first failure. The same happens on 4.8.0, 4.23.0
and 4.24.0-SNAPSHOT, so it is long-standing.
h3. How it was found
camel-chaos found it while the chaos example of camel-jbang-examples was being
written (apache/camel-jbang-examples#134). In that shop, an order whose payment
needed two redeliveries in route {{orders}} was parked by route {{shipping}},
after a seda hand-off, at its first failure.
h3. Where
{{RedeliveryErrorHandler.incrementRedeliveryCounter}} (and
{{decrementRedeliveryCounter}}). Respecting a higher header value was kept on
purpose for a nested error handler, such as per-endpoint redelivery in a
routing slip (CAMEL-23469). So a fix must keep that case. Two options:
* remove the redelivery headers when a redelivered step succeeds;
* only honour a header that a nested error handler set while this redelivery
task runs.
_Claude Code on behalf of Claus Ibsen_
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)