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)

Reply via email to