[
https://issues.apache.org/jira/browse/CAMEL-19456?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
byungkyu.han updated CAMEL-19456:
---------------------------------
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.
{code:java}
@Test
public void testRemoveRoute() throws Exception {
DefaultCamelContext ctx = new DefaultCamelContext(false);
ctx.disableJMX();
ctx.getRegistry().bind("UtilBean", UtilBean.class);
ctx.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").routeId("rawRoute").to("bean:UtilBean?method=RAW(convertToJson('aa
a',${body}))")
.to("bean:UtilBean?method=RAW(convertToJson(*,'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
}
}
// 코드 자리 표시자
{code}
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.
{code:java}
@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;
}
// 코드 자리 표시자
{code}
was:
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.
{code:java}
@Test
public void testRemoveRoute() throws Exception {
DefaultCamelContext ctx = new DefaultCamelContext(false);
ctx.disableJMX();
ctx.getRegistry().bind("UtilBean", UtilBean.class);
ctx.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").routeId("coolRoute").to("bean:UtilBean?method=RAW(convertToJson('aa
a',${body}))")
.to("bean:UtilBean?method=RAW(convertToJson(*,'aa
a',${body}))");
}
});
ctx.start();
EndpointRegistry<NormalizedUri> endpoints = ctx.getEndpointRegistry();
Map<String, RouteService> routeServices = ctx.getRouteServices();
Set<Endpoint> routeEndpoints =
routeServices.get("coolRoute").gatherEndpoints();
for(Endpoint endpoint : routeEndpoints) {
Endpoint oldEndpoint =
endpoints.remove(ctx.getEndpointKey(endpoint.getEndpointUri()));
assertNotNull(oldEndpoint); //fail
}
}
// 코드 자리 표시자
{code}
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.
> The invocation of the removeRoute() method is too slow when using RAW().
> ------------------------------------------------------------------------
>
> Key: CAMEL-19456
> URL: https://issues.apache.org/jira/browse/CAMEL-19456
> Project: Camel
> Issue Type: Bug
> Components: came-core
> Affects Versions: 3.7.5, 3.20.5
> Reporter: byungkyu.han
> Priority: Major
>
> 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.
> {code:java}
> @Test
> public void testRemoveRoute() throws Exception {
> DefaultCamelContext ctx = new DefaultCamelContext(false);
> ctx.disableJMX();
> ctx.getRegistry().bind("UtilBean", UtilBean.class);
> ctx.addRoutes(new RouteBuilder() {
> @Override
> public void configure() throws Exception {
>
> from("direct:start").routeId("rawRoute").to("bean:UtilBean?method=RAW(convertToJson('aa
> a',${body}))")
> .to("bean:UtilBean?method=RAW(convertToJson(*,'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
> }
> }
> // 코드 자리 표시자
> {code}
>
> 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.
> {code:java}
> @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;
> }
> // 코드 자리 표시자
> {code}
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)