This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new e7cbc864f98 Bypass (#10808)
e7cbc864f98 is described below

commit e7cbc864f98c265cdd336f927f9071f33e7e928e
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Tue Jul 25 08:50:23 2023 +0200

    Bypass (#10808)
    
    * CAMEL-14467: camel-jcache - Dynamically bypass the cache for lookups. 
Thanks to Jens Kleine-Herzbruch for the patch.
---
 .../src/main/docs/jcache-component.adoc            |  6 +++
 .../component/jcache/policy/JCachePolicy.java      | 11 ++++-
 .../jcache/policy/JCachePolicyProcessor.java       | 40 ++++++++++++-----
 .../jcache/policy/JCachePolicyProcessorTest.java   | 52 ++++++++++++++++++++++
 4 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/components/camel-jcache/src/main/docs/jcache-component.adoc 
b/components/camel-jcache/src/main/docs/jcache-component.adoc
index 0a33957fca7..8f879fbbc63 100644
--- a/components/camel-jcache/src/main/docs/jcache-component.adoc
+++ b/components/camel-jcache/src/main/docs/jcache-component.adoc
@@ -177,6 +177,12 @@ from("direct:get-orders")
     .bean(OrderService.class,"findOrderById(${header.orderId})");
 ----------------------------
 
+== BypassExpression
+
+The `JCachePolicy` can be configured with an `Expression` that can per 
`Exchange` determine whether
+to look up the value from the cache or bypass. If the expression is evaluated 
to `false` then the route
+is executed as normal, and the returned value is inserted into the cache for 
future lookup.
+
 == Camel XML DSL examples
 
 == Use JCachePolicy in an XML route
diff --git 
a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicy.java
 
b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicy.java
index 87d82d8626c..e764e13862e 100644
--- 
a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicy.java
+++ 
b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicy.java
@@ -53,6 +53,7 @@ public class JCachePolicy implements Policy {
     private String cacheName;
     private Configuration cacheConfiguration;
     private Expression keyExpression;
+    private Expression bypassExpression;
     private boolean enabled = true;
 
     @Override
@@ -105,7 +106,7 @@ public class JCachePolicy implements Policy {
 
         }
 
-        return new JCachePolicyProcessor(route.getCamelContext(), cache, 
keyExpression, processor);
+        return new JCachePolicyProcessor(route.getCamelContext(), cache, 
keyExpression, bypassExpression, processor);
     }
 
     public Cache getCache() {
@@ -148,6 +149,14 @@ public class JCachePolicy implements Policy {
         this.keyExpression = keyExpression;
     }
 
+    public Expression getBypassExpression() {
+        return bypassExpression;
+    }
+
+    public void setBypassExpression(Expression bypassExpression) {
+        this.bypassExpression = bypassExpression;
+    }
+
     public boolean isEnabled() {
         return enabled;
     }
diff --git 
a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessor.java
 
b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessor.java
index d561d8518ab..08d8bc22a5b 100644
--- 
a/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessor.java
+++ 
b/components/camel-jcache/src/main/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessor.java
@@ -33,12 +33,15 @@ public class JCachePolicyProcessor extends 
DelegateAsyncProcessor {
     private final CamelContext camelContext;
     private Cache cache;
     private Expression keyExpression;
+    private Expression bypassExpression;
 
-    public JCachePolicyProcessor(CamelContext camelContext, Cache cache, 
Expression keyExpression, Processor processor) {
+    public JCachePolicyProcessor(CamelContext camelContext, Cache cache, 
Expression keyExpression, Expression bypassExpression,
+                                 Processor processor) {
         super(processor);
         this.camelContext = camelContext;
         this.cache = cache;
         this.keyExpression = keyExpression;
+        this.bypassExpression = bypassExpression;
     }
 
     @Override
@@ -59,21 +62,26 @@ public class JCachePolicyProcessor extends 
DelegateAsyncProcessor {
                 return super.process(exchange, callback);
             }
 
-            //Check if cache contains the key
-            Object value = cache.get(key);
-            if (value != null) {
-                // use the cached object in the Exchange without calling the 
rest of the route
-                LOG.debug("Cached object is found, skipping the route - 
key:{}, exchange:{}", key, exchange.getExchangeId());
+            Boolean bypass = bypassExpression != null ? 
bypassExpression.evaluate(exchange, Boolean.class) : Boolean.FALSE;
+            if (!Boolean.TRUE.equals(bypass)) {
+                //Check if cache contains the key
+                Object value = cache.get(key);
+                if (value != null) {
+                    // use the cached object in the Exchange without calling 
the rest of the route
+                    LOG.debug("Cached object is found, skipping the route - 
key:{}, exchange:{}", key,
+                            exchange.getExchangeId());
 
-                exchange.getMessage().setBody(value);
+                    exchange.getMessage().setBody(value);
 
-                callback.done(true);
-                return true;
+                    callback.done(true);
+                    return true;
+                }
+                //Not found in cache. Continue route.
+                LOG.debug("No cached object is found, continue route - key:{}, 
exchange:{}", key, exchange.getExchangeId());
+            } else {
+                LOG.debug("Bypassing cache - key:{}, exchange:{}", key, 
exchange.getExchangeId());
             }
 
-            //Not found in cache. Continue route.
-            LOG.debug("No cached object is found, continue route - key:{}, 
exchange:{}", key, exchange.getExchangeId());
-
             return super.process(exchange, new AsyncCallback() {
                 @Override
                 public void done(boolean doneSync) {
@@ -136,4 +144,12 @@ public class JCachePolicyProcessor extends 
DelegateAsyncProcessor {
     public void setKeyExpression(Expression keyExpression) {
         this.keyExpression = keyExpression;
     }
+
+    public Expression getBypassExpression() {
+        return bypassExpression;
+    }
+
+    public void setBypassExpression(Expression bypassExpression) {
+        this.bypassExpression = bypassExpression;
+    }
 }
diff --git 
a/components/camel-jcache/src/test/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessorTest.java
 
b/components/camel-jcache/src/test/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessorTest.java
index 1a3cfca32ff..24f1e8b91e3 100644
--- 
a/components/camel-jcache/src/test/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessorTest.java
+++ 
b/components/camel-jcache/src/test/java/org/apache/camel/component/jcache/policy/JCachePolicyProcessorTest.java
@@ -16,6 +16,9 @@
  */
 package org.apache.camel.component.jcache.policy;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import javax.cache.Cache;
 import javax.cache.CacheManager;
 import javax.cache.Caching;
@@ -245,6 +248,45 @@ public class JCachePolicyProcessorTest extends 
JCachePolicyTestBase {
 
     }
 
+    //Use a bypass expression ${header.mybypass}
+    @Test
+    public void testBypassExpression() throws Exception {
+        final String key = randomString();
+        final String body = randomString();
+        MockEndpoint mock = getMockEndpoint("mock:value");
+        Cache cache = lookupCache("simple");
+
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("mykey", key);
+        headers.put("mybypass", Boolean.TRUE);
+
+        //Send first, key is not in cache
+        Object responseBody = 
this.template().requestBodyAndHeaders("direct:cached-bypass", body, headers);
+
+        //We got back the value, mock was called once, value got cached.
+        assertEquals(generateValue(body), cache.get(key));
+        assertEquals(generateValue(body), responseBody);
+        assertEquals(1, mock.getExchanges().size());
+
+        //Send again, use another body, but the same key
+        final String body2 = randomString();
+        responseBody = 
this.template().requestBodyAndHeaders("direct:cached-bypass", body2, headers);
+
+        //We got back the value, the mock was called again, value got cached
+        assertEquals(generateValue(body2), cache.get(key));
+        assertEquals(generateValue(body2), responseBody);
+        assertEquals(2, mock.getExchanges().size());
+
+        //Send again, use another body, but the same key; disable bypass
+        headers.put("mybypass", Boolean.FALSE);
+        responseBody = 
this.template().requestBodyAndHeaders("direct:cached-bypass", body, headers);
+
+        //We got back the cached value, the mock was not called again
+        assertEquals(generateValue(body2), cache.get(key));
+        assertEquals(generateValue(body2), responseBody);
+        assertEquals(2, mock.getExchanges().size());
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
@@ -299,6 +341,16 @@ public class JCachePolicyProcessorTest extends 
JCachePolicyTestBase {
                 from("direct:cached-byheader")
                         .policy(jcachePolicy)
                         .to("mock:value");
+
+                //Use ${header.mykey} as the key, ${header.mybypass} as bypass
+                jcachePolicy = new JCachePolicy();
+                jcachePolicy.setCache(cacheManager.getCache("simple"));
+                jcachePolicy.setKeyExpression(simple("${header.mykey}"));
+                jcachePolicy.setBypassExpression(simple("${header.mybypass}"));
+
+                from("direct:cached-bypass")
+                        .policy(jcachePolicy)
+                        .to("mock:value");
             }
         };
     }

Reply via email to