[ 
https://issues.apache.org/jira/browse/CAMEL-25253?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25253.
---------------------------------
    Resolution: Fixed

Merged via https://github.com/apache/camel/pull/27250

> camel-dynamic-router - updating a subscription is ignored when the priority 
> is unchanged, and duplicates the subscription when the priority changes
> ---------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25253
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25253
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Minor
>             Fix For: 4.23.0
>
>
> The control endpoint and the JMX operations can update an existing 
> subscription ({{update=true}}: "update the subscription (true), or add a new 
> one (false)"). {{DynamicRouterFilterService.addFilterForChannel}} checks that 
> a filter with the id exists and then only does
> {code:java}
> filters.add(filter);                         // ConcurrentSkipListSet ordered 
> by FILTER_COMPARATOR (priority, then id)
> filterStatistics.add(filter.statistics());
> {code}
> The set compares filters by priority and id only, so:
> * *same priority:* the new filter is "equal" to the existing one, {{add}} 
> returns false and the old filter stays. The update (new predicate, new 
> destination) is silently ignored, while the operation returns the 
> subscription id as if it had succeeded;
> * *other priority:* both filters stay in the set. The subscription now routes 
> with its old and its new definition: in {{allMatch}} mode messages go to both 
> destinations (duplicates), in {{firstMatch}} mode the old definition can 
> still win; and {{getFilterById}} returns either.
> In addition, {{filterExists}} is computed with 
> {{filterMap.get(channel).stream()}} as soon as any channel has filters, so a 
> subscription for a channel that has none yet fails with a 
> {{NullPointerException}}.
> The existing unit test of the update passes only because its factory returns 
> the same mock for the old and the new filter, whose priority it changes in 
> place.
> h3. Reproduction
> With the default filter factory:
> {code:java}
> DynamicRouterFilterService service = new DynamicRouterFilterService();
> service.initializeChannelFilters("test");
> service.addFilterForChannel("sub", 1, PredicateBuilder.constant(true), 
> "mock:old", "test", false);
> service.addFilterForChannel("sub", 1, PredicateBuilder.constant(true), 
> "mock:new", "test", true);   // returns "sub"
> service.getFilterById("sub", "test").endpoint();                              
>                       // "mock:old"
> service.addFilterForChannel("sub", 10, PredicateBuilder.constant(true), 
> "mock:new", "test", true);
> service.getFiltersForChannel("test").size();                                  
>                       // 2
> service.addFilterForChannel("other", 1, PredicateBuilder.constant(true), 
> "mock:other", "other", false); // NullPointerException
> {code}
> A unit test with these three cases fails on main.
> h3. Proposed fix
> Get (or create) the channel's filter set and statistics list first; on an 
> update remove the existing filter with that id, then add the new filter. The 
> statistics of the replaced filter stay in the list, as {{removeFilterById}} 
> keeps those of a removed filter on purpose ("the statistics still represent 
> actions that happened"), so after an update the list looks as after an 
> unsubscribe and a subscribe with the same id. With the fix the new test and 
> the camel-dynamic-router suite pass (137 unit tests, 21 integration tests).
> Affected: 4.14.x, 4.18.x and main (same code since CAMEL-20302, 4.4).
> Duplicate check (2026-10-01): JIRA text "dynamic-router" (54 issues) and 
> "dynamic router" with "update": CAMEL-21407 (unsubscribe), CAMEL-23735 
> (aggregation), CAMEL-24576 (control predicate), none about update. GitHub 
> pull requests: none open on the component.
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to