allthingssecurity opened a new pull request, #27466:
URL: https://github.com/apache/camel/pull/27466

   # Description
   
   [CAMEL-25068](https://issues.apache.org/jira/browse/CAMEL-25068) item 1
   
   Follow-up from the deep review of CAMEL-25048. When the caller binds a bean 
with the same name as a `templateBean` of the template, which of the two beans 
the route gets depended on how the caller bound it and on how the route looks 
it up. Template:
   
   ```java
   routeTemplate("myTemplate").templateParameter("foo")
           .templateBean("greeting", Processor.class, rtc -> ...) // sets the 
body to "template"
           .from("direct:{{foo}}")
           .process("greeting");
   ```
   
   On `main`:
   
   | The caller binds `greeting` with | `process("greeting")` (lookup by 
`Processor`) | `to("bean:{{greeting}}")` (lookup by name) |
   |---|---|---|
   | `TemplatedRouteBuilder...bean("greeting", mine)` | template | caller |
   | `TemplatedRouteBuilder...bean("greeting", Processor.class, mine)` | 
template | template |
   | `TemplatedRouteDefinition.bean("greeting", mine)` (`templatedRoute` in 
Java, XML, YAML) | template | caller |
   | `TemplatedRouteBuilder...configure(rtc -> rtc.bind("greeting", 
Processor.class, mine))` | caller | caller |
   
   The caller's beans are bound in the route template context before 
`DefaultModel.doAddRouteFromTemplate`, which then binds the template beans into 
the same local registry (`addTemplateBeans`). The registry keeps one entry per 
name and type, so a template bean with the same type replaces the caller's 
bean, and one with another type is added next to it; a lookup by type then 
finds the template bean, and a lookup by name finds whichever entry was bound 
first. A configurer runs later, when the route is created, so its bean replaces 
the template bean of the same type.
   
   This change implements option (a) from the JIRA analysis: the caller's bean 
wins. `addTemplateBeans` skips a template bean whose name the caller has 
already bound, so the template bean is not created and every lookup finds the 
caller's bean. This is consistent with:
   - the configurer (and CAMEL-25048 item 6, where the configurer of the 
`TemplatedRouteBuilder` runs after the one of the template, so it can override 
it);
   - template parameters, where the caller's value overrides the default value 
of the template;
   - replacing a template bean with a mock in a test.
   
   Kamelets are not affected: `addRouteFromKamelet` creates a new route 
template context with parameters only, so no template bean is skipped there 
(camel-kamelet suite below).
   
   Other options, for the review:
   - (b) the template bean wins: document it, and bind the template beans after 
the configurers so that the configurer path agrees. The template author keeps 
control; the caller cannot replace a template bean.
   - (c) fail with `FailedToCreateRouteFromTemplateException` on a clash. 
Strict, and it breaks callers that override on purpose.
   
   Behaviour change: the upgrade guide (4.23, "Route templates") gets one more 
item, and `route-template.adoc` (section "Binding Beans to Route Templates") a 
sentence. The javadoc of the three `TemplatedRouteBuilder.bean` methods now 
says that the bean takes precedence over a template bean with the same name.
   
   Not changed:
   - A configurer that binds the name without a type (`rtc.bind("greeting", 
mine)`, keyed by the class of `mine`) after the template bean is bound still 
loses a lookup by the template bean's type, as on `main`. Making that path 
agree too would need `DefaultRouteTemplateContext.bind` to replace every entry 
of the name, which changes the registry semantics; I left it out. Happy to add 
it if you prefer.
   - One `TemplatedRouteBuilder` (or `RouteTemplateContext`) used to add 
several routes: the template beans bound for the first route are in its local 
registry when the next route is added, so they are now kept for the next route 
instead of bound again. Camel itself always uses a new context per route 
(`TemplatedRouteBuilder.builder`, `addRouteFromTemplatedRoute`, the parameter 
map variants of `addRouteFromTemplate`, Kamelets).
   
   The precedence rule was checked with a small Lean 4 model of 
`SimpleRegistry.bind` / `SupplierRegistry.lookupByNameAndType` and the three 
binding steps (caller, template, configurer). It reproduces the four rows 
above, proves that with the change every lookup of a name the caller bound (by 
any type) returns the caller's bean, and that the change binds exactly what 
`main` binds when no template bean has a name the caller bound. It also shows 
the configurer-without-type case above.
   
   Tests: `RouteTemplateCallerBeanTest` (camel-core), one test per binding path:
   - `builderBeanTakesPrecedence`: `TemplatedRouteBuilder.bean` without and 
with a type; also checks that the template bean with the same name is not 
created, and that the other template bean (`suffix`) is still used;
   - `templatedRouteBeanTakesPrecedence`: `TemplatedRouteDefinition.bean` via 
`addRouteFromTemplatedRoute`;
   - `configurerBeanTakesPrecedence`: `configure(rtc -> rtc.bind(...))`.
   
   The first two fail on `main` (two runs each): `expected: "caller!" but was: 
"template!"`. The configurer test passes on `main`: it pins the path the change 
aligns with.
   
   With the change:
   - the camel-core suite passes (8090 tests, 0 failures, 45 skipped; 
`FileConsumerIdempotentKeyNameAndSizeTest` failed once and passed on the 
rerun), and so do the suites of the core modules it is built with (9454 tests 
in total);
   - camel-kamelet (all 64 test classes, 87 tests, 0 failures, 3 skipped);
   - the route template, templated route, Kamelet and reload tests of 
camel-yaml-dsl (12 classes, 56 tests) and camel-xml-io-dsl (6 classes, 16 
tests), 0 failures.
   
   # 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 core modules and the modules listed above, 
including the formatter and import-sort plugins. No generated files change. 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]

Reply via email to