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

SimpleLanguage cache issue

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 3.19.0, 3.20.1, 3.20.2, 4.0-M1
    • 3.21.0, 4.0-M3, 4.0.0
    • camel-core
    • None
    • Unknown

    Description

      Hi guys, I'm attaching a test class that will reproduce the issue that I'm experiencing.
      As summary: The cache inside the SimpleLanguage class looks like it's going to be affected by the evaluation of the simple expression, producing unexpected results.
      When the method resolveTemplate is used the result is not the expected one.
      To make it work I have to simulate a new entry in the cache making use of the method resolveTemplateNoCache.
      Thanks in advance

      public class SimpleLanguageTest extends CamelTestSupport {
          @EndpointInject("mock:result")
          private MockEndpoint mockResult;
      
          @EndpointInject("mock:fail")
          private MockEndpoint mockWithFailure;
      
          @Test
          public void whenSimpleLanguageNotUseCachedEntriesItWillNotFail() throws Exception {
      
              mockResult.await(20, TimeUnit.SECONDS);
              mockResult.expectedMessageCount(102);
              assertMockEndpointsSatisfied();
              List<Exchange> exchanges = mockResult.getExchanges();
              exchanges.stream()
                      .forEach(exchange -> assertTrue(exchange.getMessage().getHeader("#CustomHeader", String.class).equals("This is a test a with startLabel: `Document` endLabel: `Document` and label: `ALabel`")));
      
      
          }
      
          @Test
          public void whenSimpleLanguageUseCachedEntriesItWillFail() throws Exception {
              mockWithFailure.expectedMessageCount(102);
              assertMockEndpointsSatisfied();
              List<Exchange> exchanges = mockWithFailure.getExchanges();
              exchanges.stream()
                      .forEach(exchange -> assertTrue(exchange.getMessage().getHeader("#CustomHeader", String.class).equals("This is a test a with startLabel: `Document` endLabel: `Document` and label: `ALabel`")));
      
      
          }
      
          @Override
          protected RoutesBuilder createRouteBuilder() throws Exception {
      
              return new RouteBuilder() {
                  Map body = new HashMap() {{
                      put("label", "ALabel");
                      put("startLabel", "Document");
                      put("endLabel", "Document");
                  }};
      
      
                  String simpleTemplate = "This is a test a with startLabel: `${body.get('startLabel')}` endLabel: `${body.get('endLabel')}` and label: `${body.get('label')}`";
      
      
                  @Override
                  public void configure() throws Exception {
                      from("timer://test-timer?fixedRate=true&period=10&delay=1")
                              .process(new Processor() {
                                  @Override
                                  public void process(Exchange exchange) throws Exception {
                                      exchange.getMessage().setBody(body);
                                      exchange.getMessage().setHeader("#CustomHeader", resolveTemplateNoCache(simpleTemplate, exchange));
                                  }
                              })
                              .to("mock:result");
      
                      from("timer://test-timer1?fixedRate=true&period=10&delay=1")
      
                              .process(new Processor() {
                                  @Override
                                  public void process(Exchange exchange) throws Exception {
                                      exchange.getMessage().setBody(body);
                                      exchange.getMessage().setHeader("#CustomHeader", resolveTemplateNoCache(simpleTemplate, exchange));
                                  }
                              })
                              .to("mock:result");
      
                      from("timer://test-timer2?fixedRate=true&period=10&delay=1")
                              .process(new Processor() {
                                  @Override
                                  public void process(Exchange exchange) throws Exception {
                                      exchange.getMessage().setBody(body);
                                      exchange.getMessage().setHeader("#CustomHeader", resolveTemplateNoCache(simpleTemplate, exchange));
                                  }
                              })
                              .to("mock:result");
      
                      from("timer://test-timer3?fixedRate=true&period=10&delay=1")
                              .process(new Processor() {
                                  @Override
                                  public void process(Exchange exchange) throws Exception {
                                      exchange.getMessage().setBody(body);
                                      exchange.getMessage().setHeader("#CustomHeader", resolveTemplate(simpleTemplate, exchange));
                                  }
                              })
                              .to("mock:fail");
      
                      from("timer://test-timer4?fixedRate=true&period=10&delay=1")
      
                              .process(new Processor() {
                                  @Override
                                  public void process(Exchange exchange) throws Exception {
                                      exchange.getMessage().setBody(body);
                                      exchange.getMessage().setHeader("#CustomHeader", resolveTemplate(simpleTemplate, exchange));
                                  }
                              })
                              .to("mock:fail");
      
                      from("timer://test-timer5?fixedRate=true&period=10&delay=1")
                              .process(new Processor() {
                                  @Override
                                  public void process(Exchange exchange) throws Exception {
                                      exchange.getMessage().setBody(body);
                                      exchange.getMessage().setHeader("#CustomHeader", resolveTemplate(simpleTemplate, exchange));
                                  }
                              })
                              .to("mock:fail");
                  }
      
              };
          }
      
          public String resolveTemplate(String template, Exchange exchange) {
              var simpleExpression = new SimpleExpression();
              simpleExpression.setExpression(template);
              return simpleExpression.evaluate(exchange, String.class);
      
          }
      
          public String resolveTemplateNoCache(String template, Exchange exchange) {
              var simpleExpression = new SimpleExpression();
              //This will force to create a new entry in the cache in the SimpleLanguage class
              String nocache = String.join("-", "-nocache", UUID.randomUUID().toString());
              simpleExpression.setExpression("%s%s".formatted(template, nocache));
              return simpleExpression.evaluate(exchange, String.class).replace(nocache, "");
      
          }
      }
       

      Attachments

        Issue Links

          Activity

            People

              rhuanrocha Rhuan Rocha
              andrea81 Andrea Evangelista
              Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: