allthingssecurity opened a new pull request, #29784: URL: https://github.com/apache/camel/pull/29784
# Description [CAMEL-26880](https://issues.apache.org/jira/browse/CAMEL-26880) Follow-up of #29666 (CAMEL-26865, `ClusteredRoutePolicy` starts and stops each route on its own, and retries a failed start), #29589 (CAMEL-26799) and #29529 (CAMEL-26754), all merged; one commit on top of main. A leadership change while the CamelContext is suspended (from JMX, for example) was not applied after the resume: - **taken while suspended**: the policy started its routes with `startRoute`, which does nothing while the CamelContext is suspended (`shouldStartRoutes()` is false), and recorded them as started. The resume only resumes the routes that were started before the suspend, so the leader did not run them, until the leadership changed again; - **lost while suspended**: a route whose consumer does not support suspension is stopped by the suspend; the policy skipped it (not stoppable) and kept it recorded as started, and the resume started it again, so a node that is no longer the leader ran the route next to the new leader. Change, in `ClusteredRoutePolicy`: - `doStartManagedRoutes` returns while the CamelContext is suspending or suspended (the routes stay with the stopped routes); - the listener of the policy also takes `CamelContextResumedEvent` and hands it to the policy thread, which applies the leadership again (the re-apply added in #29666): on the leader it starts the stopped routes, on a node that is not the leader it stops the started routes that run (the resume starts them before the event, so such a route runs for the time the hand-over takes); - the resumed event comes while the CamelContext status is still starting (`BaseService.resume` sets started only after `doResume`, which fires the event), so a re-apply that finds the CamelContext starting after its first start, or after a resume (a policy attached after the start never gets the started event), schedules a retry (the retry delay of #29666) instead of waiting for a started event that does not come again. This also closes the "routes added while the CamelContext is suspended" item named in #29666. Not changed here (follow-ups): a suspend that begins between the policy's check and its `startRoute` still records the route as started (narrow; `doSuspend` takes no route lock); a route stopped or removed while the CamelContext is suspended stays in the CamelContext's list of suspended routes, so the resume starts it again (core; the re-apply above stops it again for the clustered routes); a leadership lost while the CamelContext is suspending runs a stop next to the suspend (as before); `CamelContextResumeFailedEvent` is not handled. `MasterRoutePolicy` (camel-zookeeper-master) starts and stops the consumer rather than the route, and is not looked at here. Tests, in `ClusteredEdgeCasesTest` (in-JVM test cluster view, no sleeps): - `testLeadershipTakenWhileTheCamelContextIsSuspended`: suspend, the node becomes the leader, resume: the route must start; - `testLeadershipTakenWhileTheCamelContextIsSuspendedAndASlowResume`: the same, with an event notifier after the one of the policy that holds the resume for 500 ms (so the CamelContext is still starting when the policy thread applies the leadership): the route must start; - `testRouteAddedAfterStartAndASlowResume`: the same with a route (and its policy) added after the CamelContext started; - `testLeadershipLostWhileTheCamelContextIsSuspended`: a route with a consumer that does not support suspension runs on the leader; suspend, the node loses the leadership, resume: the route must end stopped; - `testLeadershipLostWhileTheCamelContextIsSuspendedWithASuspendableConsumer`: the same with a SEDA consumer (a control: it already worked). On main's code the first four fail; the first version of this change (without the retry while resuming) fails both slow-resume tests, the second version (retry only for a policy that saw the started event) fails the one with the route added after start. With the change the camel-core cluster tests pass (72, 0 failures, with the tests of #29529, #29589, #29666 and #29670), the camel-file cluster tests too (16, 0 failures), and `ClusteredEdgeCasesTest` (17 tests) passes 340/340 over 20 runs in one JVM. Found with Specula (TLA+ model checked against traces of the real code) and code review, and confirmed with the tests above. # 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): [CAMEL-26880](https://issues.apache.org/jira/browse/CAMEL-26880). # 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 the core modules with the formatter and import-sort plugins and ran the camel-core cluster tests; no generated file changes. 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]
