diff --git a/docs/src/main/asciidoc/cache-redis-reference.adoc b/docs/src/main/asciidoc/cache-redis-reference.adoc index 09b38a27154e1..79f3049ef99c4 100644 --- a/docs/src/main/asciidoc/cache-redis-reference.adoc +++ b/docs/src/main/asciidoc/cache-redis-reference.adoc @@ -21,7 +21,7 @@ include::{includes}/extension-status.adoc[] When using Redis as the backend for Quarkus cache, each cached item will be stored in Redis: - The backend uses the __ Redis client (if not configured otherwise), so make sure it's configured (or use the xref:redis-dev-services.adoc[Redis Dev Service]) -- the Redis key is built as follows: `cache:$cache-name:$cache-key`, where `cache-key` is the key the application uses. +- the Redis key is built as follows: `cache:{cache-name}:{cache-key}`, where `cache-key` is the key the application uses and `cache:{cache-name}` the prefix. - the value is encoded to JSON if needed @@ -118,10 +118,11 @@ include::{generated-dir}/config/quarkus-redis-cache.adoc[opts=optional, leveloff == Configure the Redis key -By default, the Redis backend stores the entry using the following keys: `cache:$cache-name:$cache-key`, where `cache-key` is the key the application uses. -So, you can find all the entries for a single cache using the Redis `KEYS` command: `KEYS cache:$cache-name:*` +By default, the Redis backend stores the entry using the following keys pattern: `cache:{cache-name}:{cache-key}`, where `cache-key` is the key the application uses and `cache:{cache-name}` the prefix. The variable `{cache-name}` is resolved from the value set in the cache annotations. +So, you can find all the entries for a single cache using the Redis `KEYS` command: `KEYS cache:{cache-name}:*` + +The prefix can be configured by using the `prefix` property: -The `cache:$cache-name:` segment can be configured using the `prefix` property: [source, properties] @@ -135,6 +136,16 @@ quarkus.cache.redis.expensiveResourceCache.prefix=my-expensive-cache In these cases, you can find all the keys managed by the default cache using `KEYS my-cache:*`, and all the keys managed by the `expensiveResourceCache` cache using: `KEYS my-expensive-cache:*`. + +---- +# Default configuration +# The variable "{cache-name}" is resolved from the value set in the cache annotations. +quarkus.cache.redis.prefix=my-cache-{cache-name} +---- + +In this latest example, you can find all the keys managed by the default cache using `KEYS my-cache-{cache-name}:*`. + + == Enable optimistic locking The access to the cache can be _direct_ or use https://redis.io/docs/manual/transactions/#optimistic-locking-using-check-and-set[optimistic locking]. diff --git a/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheImpl.java b/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheImpl.java index d8fb126fbadac..fc9d3460f26b1 100644 --- a/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheImpl.java +++ b/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheImpl.java @@ -397,15 +397,11 @@ public Uni apply(List listOfKeys) { } String computeActualKey(String key) { - if (cacheInfo.prefix != null) { - return cacheInfo.prefix + ":" + key; - } else { - return "cache:" + getName() + ":" + key; - } + return getKeyPrefix() + ":" + key; } Object computeUserKey(String key) { - String prefix = cacheInfo.prefix != null ? cacheInfo.prefix : "cache:" + getName(); + String prefix = getKeyPrefix(); if (!key.startsWith(prefix + ":")) { return null; // Not a key handle by the cache. } @@ -414,10 +410,14 @@ Object computeUserKey(String key) { } private String getKeyPattern() { + return getKeyPrefix() + ":*"; + } + + private String getKeyPrefix() { if (cacheInfo.prefix != null) { - return cacheInfo.prefix + ":" + "*"; + return cacheInfo.prefix.replace("{cache-name}", getName()); } else { - return "cache:" + getName() + ":" + "*"; + return "cache:" + getName(); } } diff --git a/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheRuntimeConfig.java b/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheRuntimeConfig.java index e08c9a48b4523..a82902c308a74 100644 --- a/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheRuntimeConfig.java +++ b/extensions/redis-cache/runtime/src/main/java/io/quarkus/cache/redis/runtime/RedisCacheRuntimeConfig.java @@ -32,8 +32,9 @@ public class RedisCacheRuntimeConfig { Optional expireAfterAccess; /** - * the key prefix allowing to identify the keys belonging to the cache. - * If not set, use "cache:$cache-name" + * The key prefix allowing to identify the keys belonging to the cache. + * If not set, the value "{@code cache:{cache-name}}" will be used. The variable + * "{@code {cache-name}}" is resolved from the value set in the cache annotations. */ @ConfigItem public Optional prefix; diff --git a/extensions/redis-cache/runtime/src/test/java/io/quarkus/cache/redis/runtime/RedisCacheImplTest.java b/extensions/redis-cache/runtime/src/test/java/io/quarkus/cache/redis/runtime/RedisCacheImplTest.java index 3362bf8e7bc9b..b4c8583c0d77e 100644 --- a/extensions/redis-cache/runtime/src/test/java/io/quarkus/cache/redis/runtime/RedisCacheImplTest.java +++ b/extensions/redis-cache/runtime/src/test/java/io/quarkus/cache/redis/runtime/RedisCacheImplTest.java @@ -41,6 +41,39 @@ void clear() { } } + @Test + public void testComputeActualKey() { + RedisCacheInfo info = new RedisCacheInfo(); + info.name = "foo"; + info.prefix = null; + info.expireAfterWrite = Optional.of(Duration.ofSeconds(2)); + + RedisCacheImpl cache = new RedisCacheImpl(info, vertx, redis, BLOCKING_ALLOWED); + assertThat(cache.computeActualKey("keyname")).isEqualTo("cache:foo:keyname"); + } + + @Test + public void testComputeActualKeyWithCustomPrefix() { + RedisCacheInfo info = new RedisCacheInfo(); + info.name = "foo"; + info.prefix = "my-prefix"; + info.expireAfterWrite = Optional.of(Duration.ofSeconds(2)); + + RedisCacheImpl cache = new RedisCacheImpl(info, vertx, redis, BLOCKING_ALLOWED); + assertThat(cache.computeActualKey("keyname")).isEqualTo("my-prefix:keyname"); + } + + @Test + public void testComputeActualKeyWithCustomPrefixUsingCacheNameVariable() { + RedisCacheInfo info = new RedisCacheInfo(); + info.name = "foo"; + info.prefix = "my-prefix:{cache-name}"; + info.expireAfterWrite = Optional.of(Duration.ofSeconds(2)); + + RedisCacheImpl cache = new RedisCacheImpl(info, vertx, redis, BLOCKING_ALLOWED); + assertThat(cache.computeActualKey("keyname")).isEqualTo("my-prefix:foo:keyname"); + } + @Test public void testPutInTheCache() { String k = UUID.randomUUID().toString();