allthingssecurity opened a new pull request, #27340: URL: https://github.com/apache/camel/pull/27340
# Description [CAMEL-25299](https://issues.apache.org/jira/browse/CAMEL-25299) With `allowRedeliveryWhileStopping=false`, a redelivery must not be attempted once the stop of the route (or Camel) has been triggered: the exchange gets a `RejectedExecutionException` and goes to the dead letter channel. The synchronous redelivery does this: `RedeliveryTask.sleep()` waits in chunks of one second and checks `preparingShutdown` after each chunk. With `asyncDelayedRedelivery` the delay is a task scheduled on the error handler thread pool, which then called `redeliver()` without looking at the shutdown state. So a route stop waited for the whole redelivery delay (or the shutdown timeout, if the delay is longer), and the message was then redelivered anyway, also after the forced stop. This change: when the redelivery is not allowed while stopping, the scheduled task wakes up every second, like `sleep()`, and once the error handler is preparing to shut down it rejects the redelivery the same way as `runSynchronousRedelivery` does (`RejectedExecutionException("Redelivery not allowed while stopping")`, redelivery exhausted, back to `run()`, which moves the exchange to the dead letter channel or fails it). When the delay is over it redelivers as before. With `allowRedeliveryWhileStopping=true` (the default) nothing changes. If the thread pool rejects a wake-up, the redelivery is rejected instead of losing the callback. The defect was found with a TLA+ model of the redelivery task and the graceful shutdown: "no redelivery starts after its delay ended while the error handler prepares to shut down" is violated with `asyncDelayedRedelivery` (deliver, fail, schedule, prepareShutdown, delay ends, redeliver), holds for the synchronous redelivery (with and without a dead letter channel), and holds with this change. Upgrade guide: a short note in the 4.23 section, as a stop now rejects these messages within a second instead of redelivering them. Tests: new `NotAllowRedeliveryWhileStoppingAsyncDelayedTest`, the asynchronous variant of `NotAllowRedeliveryWhileStoppingDeadLetterChannelTest`. The error handler uses a thread pool that counts down a latch when the redelivery is scheduled; then the test stops the route (shutdown timeout 5 s; the delay is 60 s, the default maximum redelivery delay) and expects the dead letter channel to get the exchange with the rejection, no redelivery, and nothing inflight. A second test stops the CamelContext instead. Without the main-code change both stops run into the timeout and: ``` NotAllowRedeliveryWhileStoppingAsyncDelayedTest.testStopRouteRejectsScheduledRedelivery mock://dead Received message count. Expected: <1> but was: <0> NotAllowRedeliveryWhileStoppingAsyncDelayedTest.testStopCamelContextRejectsScheduledRedelivery mock://dead Received message count. Expected: <1> but was: <0> ``` With the change, `*Redelivery*`, `NotAllowRedelivery*` and `DeadLetterChannel*` tests in camel-core pass: 95 tests, 0 failures. CAMEL-3364, which added the option, already named the delayed tasks in the error handler pool as something the shutdown has to deal with; only `sleep()` was made to check. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [x] If this is a large change, bug fix, or code improvement, I checked there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for the change (usually before you start working on it). # Apache Camel coding standards and style - [x] I checked that each commit in the pull request has a meaningful subject line and body. - [ ] I have run `mvn clean install -DskipTests` locally from root folder and I have committed all auto-generated changes. (I built and tested the affected modules, including the formatter and import-sort plugins. I did not run the full root build.) # AI-assisted contributions - [x] If this PR includes AI-generated code, commits have proper co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR description identifies the AI tool used. This PR was prepared with Claude Code (Claude Opus 5.5). The commit carries a `Co-Authored-By` trailer. _Claude Code on behalf of allthingssecurity_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
