etzel-mes opened a new pull request, #28789:
URL: https://github.com/apache/camel/pull/28789

   # Description
   
   JIRA: CAMEL-26444 (filed by me as mardonius; follow-up to CAMEL-24899).
   
   **What went wrong.** CAMEL-24899 keeps the content of the route files that 
loaded (`lastGoodContent`) and, when a reload fails, loads the failed file from 
that content. `RouteWatcherReloadStrategy` filled it only after a successful 
`updateRoutes` in `onRouteReload`, never with the routes loaded at startup. 
Until the first successful reload since start, a failed reload therefore had 
nothing to go back to:
   
   - `camel run only.camel.yaml --dev`: the first broken save logs "Reload 
failed and there are no previous routes to restore" and the route stops. After 
one good save, a broken save keeps the previous version running.
   - The on-demand reload (`camel run --source-dir`, `/q/dev/reload`) passes 
every file as changed, so the first failed reload since start restored no file 
at all.
   - When nothing was restored, the routes that the partial load had added 
before the failure kept running (`m1` of a file whose `m2` failed), although 
the warning says that the application runs without routes.
   
   **The change** (`RouteWatcherReloadStrategy`):
   
   - When the strategy starts, it remembers the content of the sources of the 
routes that run, collected as `onRouteReload` collects them (that selection is 
now one method, `addRouteSources`). The context starts the strategy, a deferred 
service, after the routes. The supervising route controller starts the routes 
after the context, and the strategy together with the first route it starts, so 
the routes it has yet to start are taken from `getControlledRoutes()`.
   - With no routes at startup, the supervising route controller starts the 
strategy with the first route a reload adds, in the middle of that reload. A 
flag set at the beginning of `onRouteReload` keeps those routes out of the 
startup content; otherwise a file that fails after its first route was added 
would be "restored" from its broken content.
   - `restorePreviousRoutes` removes what a partial load left (routes, route 
templates, endpoints) also when there is nothing to restore, as it already did 
before a restore, so nothing of the failed file runs.
   - `route-reload.adoc` gets a short section on what a failed reload keeps 
running; the user manual did not describe it yet.
   
   **Existing tests.** Two assertions change.
   
   - `RouteReloadRollbackTest#aFailedReloadRestoresThePreviousRoutes` asserted 
that route `bad` is gone after its file failed to reload. It was written for 
CAMEL-24860, a day before CAMEL-24899, when a failed reload loaded only the 
other files again from disk and a failed file could not come back. CAMEL-24899 
kept the content in memory, but only after a successful reload, so the 
assertion still held.
   - `RouteReloadBatchTest#aBatchWithOneBrokenFileStillLoadsTheOthers` 
(CAMEL-25032) checks that the good file of a failed batch gets through. Its 
last line, that `shop` is gone, records the same gap.
   
   On main, with one successful reload before the broken save, both flows keep 
the previous version of the broken file running; I checked both. Both tests now 
expect the version loaded at startup. That is what CAMEL-24860 asks for ("keep 
the old ones when the new fail"), and what CAMEL-24899 asks for ("keep the last 
successfully loaded route definitions").
   
   Three tests began with a successful reload only to get around the gap ("one 
successful reload, so the content that runs is remembered"):
   
   - 
`RouteReloadRollbackTest#theOnlyRouteFileKeepsItsPreviousVersionWhenTheSaveIsBroken`
 (CAMEL-24899)
   - `RouteReloadOnDemandRemovedFileTest#aFileRestoredFromMemoryCanBeRemoved` 
(CAMEL-25427)
   - 
`RouteReloadPropertiesRetryTest#aReloadThatFailedOnAMissingPropertyLoadsWhenThePropertyArrives`
 (CAMEL-25032)
   
   That reload is removed, so they start from the content loaded at startup, 
and each of them fails on main. With the startup content kept, those tests no 
longer check what a successful reload remembers. The last step of the new 
single-file test now checks it: a broken save after a good one goes back to the 
good one, not to the version loaded at startup.
   
   No upgrade guide entry: there is nothing to migrate, and a failed reload in 
dev mode keeps more running than before.
   
   **Verification.**
   
   - Three new tests in `RouteReloadRollbackTest`, each red on main and green 
with the change:
     - `theFirstBrokenSaveAfterStartGoesBackToTheVersionLoadedAtStartup`: the 
four steps of the JIRA reproduction, with the strategy added to the context 
before it starts, as Camel Main adds it.
     - 
`theFirstFailedOnDemandReloadAfterStartGoesBackToEveryFileLoadedAtStartup`: 
`RouteOnDemandReloadStrategy` as `camel run --source-dir` sets it up, with the 
supervising route controller.
     - `aFailedReloadWithNothingToGoBackToLeavesNoneOfItsRoutesRunning`: the 
first route file fails after its first route was added, with the supervising 
route controller.
   - The three tests without their first reload fail on main as well.
   - Mutants: without `getControlledRoutes()` the on-demand test fails. Without 
the flag, or without the cleanup, the last test fails. If the content of a 
successful reload is not remembered, the last step of the single-file test 
fails; before that step was added, every reload test passed with this mutant.
   - `*Reload*Test` of camel-core (50), camel-xml-io-dsl (4) and camel-yaml-dsl 
(20), and `SemanticDeclarationDslTest` of camel-semantic, which subclasses the 
strategy. The four changed test classes five runs in a row with 
`-Dsurefire.rerunFailingTestsCount=0`.
   - End to end with Camel Main, the file watcher (500 ms) and timer routes, 
with the default and the supervising route controller (`initialDelay` 1000): 
the first broken save logs "The previous routes were restored (1 route(s) 
running, 1 from the last loaded content of the changed file)" and v1 keeps 
ticking; with a two-route file whose second route breaks, both routes keep 
ticking. On main the same runs log "there are no previous routes to restore", 
v1 stops, and in the two-route case `m1` keeps ticking while `m2` stops.
   - `-Psourcecheck` on camel-support and camel-yaml-dsl; the formatter and 
impsort leave no changes. No root build.
   
   @davsclaus @gnodet could you have a look? (I cannot request reviewers.)
   
   # 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.
   
   # 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.
   
   The code and tests were written with Claude Code (Claude Opus 5.5) under my 
direction; the commit carries the `Co-authored-by` trailer.
   
   _Claude Code on behalf of etzel-mes_
   
   🤖 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]

Reply via email to