allthingssecurity opened a new pull request, #27801: URL: https://github.com/apache/camel/pull/27801
# Description [CAMEL-25614](https://issues.apache.org/jira/browse/CAMEL-25614) With `camel.vault.kubernetes.refreshEnabled=true` (`camel.vault.kubernetescm.refreshEnabled=true` for config maps) camel-main schedules `SecretsReloadTriggerTask` (`ConfigmapsReloadTriggerTask`), which watches the secrets (config maps) of the namespace and reloads the CamelContext when one of the configured ones is updated. The task is scheduled with `PeriodTaskScheduler.scheduledTask`, which submits it once, and `run()` returned as soon as the watch was closed. The Kubernetes client reconnects a watch by itself after transient errors, but it closes the watch for good, with an exception, when the API server answers 410 Gone (the resource version of the watch is too old). How often that happens depends on the cluster: the watch asks for bookmarks, which keep its resource version fresh, so it is an occasional event and not a regular one. It is the same event that CAMEL-25273 fixed for the consumers of the component (`KubernetesHelper.watchAgain`, line 120 on main); the two reload tasks have the same defect, and for them one such close is enough to end the reload for the rest of the run. After the first such close nothing watched the secrets anymore: a rotated secret was not followed by a reload, and nothing was logged. A watch that could not be created (API server not reachable, request refused) ended the task the same way, with the exception kept in a `Future` that nobody reads. Changes, in `SecretsReloadTriggerTask` and `ConfigmapsReloadTriggerTask`: - `run()` watches again until the task is stopped: one second after a closed watch, and with a delay that doubles up to 30 seconds while the watch cannot be created (the first of these delays is one second when the task starts and two seconds after a closed watch). These are the delays that `KubernetesHelper.watchAgain` uses for the consumers. - Both cases are logged with one WARN line without a stack trace; the stack trace of a watch that cannot be created is logged at DEBUG. - `doStop` ends the watch and the wait, so a stopped task does not keep its thread. What users can notice: the reload keeps working after a closed watch, and the new WARN lines. A task whose watch request is always refused (for example missing RBAC permission) now logs one WARN line every 30 seconds instead of nothing at all. No upgrade guide entry: no option, default or API changes. Tests: - New `SecretsReloadTriggerTaskWatchClosedTest` and `ConfigmapsReloadTriggerTaskWatchClosedTest` (3 tests each) with the Kubernetes mock server of the module; the task is scheduled the way camel-main does it, and a `ContextReloadStrategy` records the reload. - The first watch request is answered with a watch event `ERROR` / 410, the next one with a `MODIFIED` event for the configured secret (config map): a reload is expected, after 2 requests. - The same with one more watch request in between that is answered with 403: a reload is expected, after 3 requests. - Stop: the task has a watch (a `MODIFIED` event triggered a reload), then the context is stopped: the thread that runs the task must end (bounded join), and no second watch request is made. - Without the change (main's two tasks, same tests) all six fail after 20 seconds: four with `the update of the secret after the watch was closed did not trigger a reload ==> expected: <true> but was: <false>` (and the same for the config map), the two stop tests with `the stopped task still waits for its watch to be closed ==> expected: <false> but was: <true>`. - With the change, camel-kubernetes tests pass: 179 run, 0 failures, 6 skipped. What is not changed: - Updates made while nothing watches (between the close and the next watch) are still not seen: the task does not list the secrets after it watched again. - The other vault refresh tasks that are scheduled with `scheduledTask` were not looked at. What was not run: no real cluster; the 410 answer comes from the mock server. camel-main itself was not built or tested (it is not changed). Notes: - How it was found: a sweep of the reconnect and re-watch code of the components, and a small TLA+ model of the task (submitted once, watch created or refused, 410, updates). For main the task ends after one 410 or one refused request. The model is only a sketch of the code; the tests above are the evidence. # Target - [x] I checked that the commit is targeting the correct branch (Camel 4 uses the `main` branch) # Tracking - [ ] 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). (The ticket is drafted and not filed yet; CAMEL-25614 is a placeholder until it is.) # 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 camel-kubernetes, 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]
