[
https://issues.apache.org/jira/browse/CAMEL-26453?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Work on CAMEL-26453 started by shashank.
----------------------------------------
> camel-dynamic-router - a route that sends to a Dynamic Router channel cannot
> be added again after it was removed
> ----------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-26453
> URL: https://issues.apache.org/jira/browse/CAMEL-26453
> Project: Camel
> Issue Type: Bug
> Components: camel-core
> Reporter: shashank
> Assignee: shashank
> Priority: Major
>
> {{DynamicRouterEndpoint.doInit()}} creates the {{DynamicRouterProcessor}} of
> its channel and adds it to the component with
> {{DynamicRouterComponent.addRoutingProcessor(channel, processor)}}, which
> fails when the channel already has a processor ({noformat}Dynamic Router can
> have only one processor per channel; channel 'orders' already has a
> processor{noformat}). Nothing ever removes the processor again, except the
> {{doShutdown}} of the component (when the CamelContext shuts down).
> When a route that sends to {{dynamic-router:orders}} is removed, Camel stops
> and removes the endpoints that only that route used, so the endpoint is gone
> but its processor stays in the component. Then:
> * adding the route again fails with {{FailedToCreateRouteException}} ...
> {{already has a processor}} (a route reload in development mode replaces the
> routes of a changed file by removing and adding them, and fails the same way);
> * a {{toD("dynamic-router:${header.channel}")}} in another route, which used
> the same endpoint while the removed route existed (a {{toD}} endpoint does
> not keep an endpoint in use), creates the endpoint again on its next message
> and fails every exchange with {{ResolveEndpointFailedException}};
> * the same happens when the producer cache of a {{toD}} evicts the endpoint
> and a later message creates it again.
> The subscriptions of the channel are kept by the component (filter service),
> so the channel would work again as soon as the new endpoint can register its
> processor.
> Reproducer (on main 4ab42b192b26):
> {code:java}
> from("direct:subscribe").to("dynamic-router-control:subscribe?subscribeChannel=orders&subscriptionId=all&destinationUri=mock:result&priority=1&predicate=true");
> from("direct:start").routeId("router").to("dynamic-router:orders");
> context.getRouteController().stopRoute("router");
> context.removeRoute("router");
> context.addRoutes(sameRouterRoute); // FailedToCreateRouteException: ...
> channel 'orders' already has a processor
> {code}
> The same check makes an endpoint that is stopped and started again fail, as
> {{BaseService.start}} runs {{init}} again after a stop.
> *Proposal*
> * The component keeps one processor per channel, with the endpoint that uses
> it. An endpoint with the same URI takes the same processor (a route removed
> and added again, a reload, a {{toD}} re-creating the endpoint, an endpoint
> started again); an endpoint with another URI still fails while the endpoint
> that uses the processor is in use, and replaces the processor once that
> endpoint is stopped (the new processor is created first; the old
> {{RecipientList}} is stopped, and its thread pool is only shut down with the
> component so that exchanges another route still has in flight in it are not
> interrupted; replaced processors are kept until the component shuts down).
> * Nothing is stopped when an endpoint stops, so a send that still uses a
> removed or evicted endpoint keeps routing, and no processor or
> {{parallelProcessing}} pool is created per re-creation.
> * The producer fails the exchange with a clear exception naming the channel
> when the channel has no processor, instead of a {{NullPointerException}};
> {{doShutdown}} of the component stops the processors (it passes the map
> itself to {{ServiceHelper.stopAndShutdownService}} today, which stops
> nothing).
> * Tests: remove the route and add it again (with the same and with other
> options), a {{toD}} after the route was removed, a stop and start of the
> endpoint, a second endpoint for the channel, a send through a removed
> endpoint, an exchange in flight with {{parallelProcessing}}.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)