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

   Fixes CAMEL-25140 (found while fixing CAMEL-25067, #27076).
   
   ## Problem
   An `interceptSendToEndpoint` that applies to several routes (in a 
`RouteBuilder` or route configuration) is reified per route, and each route 
registered its own `InterceptSendToEndpointCallback`. The endpoint was wrapped 
once, by whichever callback ran first (they are in an unordered set), and the 
other callbacks did nothing. So:
   - the wrapped endpoint used one route's before/after processors, wrapped in 
that route's error handler. Removing that route made every other route that 
sends to the endpoint fail with `RejectedExecutionException` (reproduced).
   - the interception was lost on a CamelContext restart, as the reifier 
removed the definition from the route outputs.
   - callbacks were never unregistered and piled up with route add/reload.
   - only one interceptor could apply per endpoint: two `RouteBuilder`s, or 
`mockEndpoints` together with an intercept, did not combine.
   
   ## Design
   - **Wrapped once, chosen per send.** `DefaultInterceptSendToEndpoint` keeps 
a list of route interceptors (`Interceptor` record: route id, before, after, 
skip). `InterceptSendToEndpointProcessor` builds the chain on each send: the 
interceptors of the sending route. If that route has none (another route, a 
`ProducerTemplate`), it uses those of the first route that registered one, 
which keeps today's scope. The endpoint's own interceptor (such as a mock) runs 
last. Each interceptor only sees the result of its own `onWhen`. Existing 
producers keep working, as the wrapper never changes.
   - **`InterceptSendToEndpointManager`** (one per CamelContext, a context 
plugin) is the single endpoint callback. The reifier adds the uri pattern when 
the route is created, because the route resolves its endpoints then. The 
interceptor is registered and unregistered by an 
`InterceptSendToEndpointService` added to the route, so it follows the route 
start/stop/removal.
   - **Restart:** the definition stays in the route (it is abstract), so the 
interceptor is created again when the routes are created again.
   - **Mocks:** `InterceptSendToMockEndpointStrategy` joins an endpoint that is 
already wrapped for route interceptors (instead of skipping it).
   - **`DefaultRoute`:** a service added with `Route.addService(service)` was 
dropped when the route gathered its services again (`initializeServices` clears 
the list). Nothing else used it (the only other caller uses 
`addService(service, true)`), and such services are now kept.
   - `InterceptSendToEndpointCallback` is deprecated (no longer used anywhere 
in Camel).
   
   Decisions (see the JIRA): keep the current scope for now (worth revisiting, 
as the docs describe builder/route-configuration scope); a fixed order when 
several interceptors apply; main only, no backport.
   
   The intercept EIP docs (and the catalog copy) and the 4.23 upgrade guide 
describe the changes.
   
   ## Tests
   `InterceptSendToEndpointRouteLifecycleTest` covers: removing a route, 
stopping/starting a route, removing all routes, a `ProducerTemplate` send, a 
CamelContext restart, two `RouteBuilder`s, and `mockEndpoints` plus an 
intercept. 6 of 7 fail on the old code; the `ProducerTemplate` one already 
worked.
   
   Full suites pass: camel-core (7972), camel-management (509), 
camel-spring-xml (1163), camel-test-junit5 (77), camel-mock. One timing flake 
in `FileConsumerInterceptEmptyFileTest` (`interceptFrom`, not touched) passed 
on rerun and in 5 more runs.
   
   _Claude Code on behalf of davsclaus_
   
   🤖 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