Uploaded image for project: 'Camel'
  1. Camel
  2. CAMEL-19456

The invocation of the removeRoute() method is too slow when using RAW().

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 3.7.5, 3.20.5
    • 4.0-RC1, 4.0.0
    • came-core
    • None
    • Unknown

    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

          Activity

            People

              Unassigned Unassigned
              luke.me byungkyu.han
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: