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)