Details
Description
When the removeRoute() method is called on AbstractCamelContext, it attempts to remove the endpoints from the EndpointRegistry. However, if the keys do not match, it invokes the matchEndpoint() method. The more endpoints there are, and the larger the number of endpoints that need to be removed, the slower the process becomes.
@Test public void testRemoveRoute() throws Exception { DefaultCamelContext ctx = new DefaultCamelContext(false); ctx.disableJMX(); ctx.getRegistry().bind("MyBean", UtilBean.class); ctx.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").routeId("rawRoute").to("MyBean?method=RAW(addString('aa a',${body}))"); } }); ctx.start(); EndpointRegistry<NormalizedUri> endpoints = ctx.getEndpointRegistry(); Map<String, RouteService> routeServices = ctx.getRouteServices(); Set<Endpoint> routeEndpoints = routeServices.get("rawRoute").gatherEndpoints(); for(Endpoint endpoint : routeEndpoints) { Endpoint oldEndpoint = endpoints.remove(ctx.getEndpointKey(endpoint.getEndpointUri())); assertNotNull(oldEndpoint); //fail } } // 코드 자리 표시자
The reason for the mismatch in keys is that when creating the NormalizeUri, the RAW() syntax is used, which does not apply the UnsafeUriCharactersEncoder.encode. However, during Endpoint creation, the UnsafeUriCharactersEncoder.encode is used. This inconsistency in the encoding process leads to different keys being generated for the endpoints between the NormalizeUri and Endpoint creation. As a result, when removing routes, the keys used for removal may not match exactly with the keys stored in the EndpointRegistry.
To address the issue, one possible solution is to perform the removal operation using a decoded URI. By decoding the URI before removing it, you can ensure that the keys match accurately in the EndpointRegistry.
@Override public Collection<Endpoint> removeEndpoints(String uri) throws Exception { Collection<Endpoint> answer = new ArrayList<>(); Endpoint oldEndpoint = endpoints.remove(getEndpointKey(uri)); if (oldEndpoint != null) { answer.add(oldEndpoint); stopServices(oldEndpoint); } else { String encode = unsafeUriCharactersDecodeWithOutPercent(uri); oldEndpoint = endpoints.remove(getEndpointKey(encode)); if(oldEndpoint != null){ answer.add(oldEndpoint); stopServices(oldEndpoint); }else { List<NormalizedUri> toRemove = new ArrayList<>(); for (Map.Entry<NormalizedUri, Endpoint> entry : endpoints.entrySet()) { oldEndpoint = entry.getValue(); if (EndpointHelper.matchEndpoint(this, oldEndpoint.getEndpointUri(), uri)) { try { stopServices(oldEndpoint); } catch (Exception e) { LOG.warn("Error stopping endpoint " + oldEndpoint + ". This exception will be ignored.", e); } answer.add(oldEndpoint); toRemove.add(entry.getKey()); } } for (NormalizedUri key : toRemove) { endpoints.remove(key); } } } // notify lifecycle its being removed for (Endpoint endpoint : answer) { for (LifecycleStrategy strategy : lifecycleStrategies) { strategy.onEndpointRemove(endpoint); } } return answer; } // 코드 자리 표시자
Attachments
Issue Links
- links to