Claus Ibsen created CAMEL-25140:
-----------------------------------

             Summary: camel-core - interceptSendToEndpoint: the interceptor 
belongs to one route, so removing that route breaks the other routes, and the 
interception is lost on a CamelContext restart
                 Key: CAMEL-25140
                 URL: https://issues.apache.org/jira/browse/CAMEL-25140
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: Claus Ibsen


An interceptSendToEndpoint that applies to several routes (defined in a 
RouteBuilder or a route configuration) is reified once per route. Each route 
builds its own before/after processors (wrapped in that route's error handler) 
and registers its own InterceptSendToEndpointCallback. But the endpoint is 
wrapped only once, by whichever callback runs first (the callbacks are kept in 
an unordered set), and the other callbacks see an already wrapped endpoint and 
do nothing. The wrapped endpoint, and every producer created from it, uses that 
one route's processors.

h3. Problems

# *Removing a route breaks the other routes.* Two routes in one RouteBuilder 
with interceptSendToEndpoint("mock:target"), both sending to mock:target. After 
removing the route whose processors wrap the endpoint, every send from the 
other route fails with RejectedExecutionException (the error handler of the 
removed route is shut down). Stopping the route without removing it is fine. 
Putting the original endpoint back in the registry would not help, as the other 
route's producer is already created from the wrapped endpoint.
# *The interception is lost on a CamelContext restart.* After stop() and 
start() on the same CamelContext, nothing is intercepted anymore: the reifier 
removes the intercept definition from the route outputs, so the routes created 
again on start no longer have it.
# *Callbacks are never unregistered.* Every route add or reload registers more 
callbacks (with the processors of routes that may be gone). When one of them 
wraps a new endpoint, the processors of a removed route are started again and 
used.
# *Only one interceptor per endpoint.* Two interceptSendToEndpoint for the same 
endpoint (from different RouteBuilders or route configurations), or 
mockEndpoints/InterceptSendToMockEndpointStrategy together with an 
interceptSendToEndpoint, do not combine: only the first one to wrap the 
endpoint applies.
# The intercepted route id was the one of the route that wrapped the endpoint 
(fixed in CAMEL-25067 by taking it from the exchange).

Route reload (removing and adding all the routes of a file) happened to work in 
a probe, because the unused endpoint is removed from the registry together with 
the routes and wrapped again, but it depends on the callback order.

h3. Proposed redesign

Wrap each endpoint once in a dispatching interceptor that holds the registered 
interceptors, and let each route register and unregister its interceptor 
(before/after processors, skip, onWhen) with its route lifecycle. At send time 
the dispatcher uses the interceptor of the sending route (from the exchange), 
falling back to the registered interceptors when the exchange is not routed by 
a route with one (such as a ProducerTemplate). Existing producers keep working 
when a route is removed, as the wrapper stays the same and only its 
registrations change. Callbacks are unregistered when the route is removed, and 
the intercepts are applied again on a CamelContext restart.

Found while fixing CAMEL-25067.

_Claude Code on behalf of davsclaus_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to