cacheManagerSupplier = cacheManagerRecorder.resolveCacheInfo(
+ infos.stream().map(CacheManagerInfoBuildItem::get).collect(toList()), cacheNames.getNames(),
+ micrometerSupported);
return SyntheticBeanBuildItem.configure(CacheManager.class)
.scope(ApplicationScoped.class)
diff --git a/extensions/cache/pom.xml b/extensions/cache/pom.xml
index 092198414e79cd..a7f580a571601f 100644
--- a/extensions/cache/pom.xml
+++ b/extensions/cache/pom.xml
@@ -19,5 +19,6 @@
deployment
deployment-spi
runtime
+ runtime-spi
diff --git a/extensions/cache/runtime-spi/pom.xml b/extensions/cache/runtime-spi/pom.xml
new file mode 100644
index 00000000000000..19619b5e24a5fc
--- /dev/null
+++ b/extensions/cache/runtime-spi/pom.xml
@@ -0,0 +1,40 @@
+
+
+
+ io.quarkus
+ quarkus-cache-parent
+ 999-SNAPSHOT
+
+ 4.0.0
+
+ quarkus-cache-runtime-spi
+ Quarkus - Cache - Runtime SPI
+
+
+
+ io.smallrye.reactive
+ mutiny
+
+
+
+
+
+
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${project.version}
+
+
+
+
+
+
+
+
+
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/Cache.java b/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/Cache.java
similarity index 89%
rename from extensions/cache/runtime/src/main/java/io/quarkus/cache/Cache.java
rename to extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/Cache.java
index a7d7b3e9b2637b..baba8744869a7d 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/Cache.java
+++ b/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/Cache.java
@@ -7,7 +7,7 @@
/**
* Use this interface to interact with a cache programmatically e.g. store, retrieve or delete cache values. The cache can be
- * injected using the {@link CacheName} annotation or retrieved using {@link CacheManager#getCache(String)}.
+ * injected using the {@code @io.quarkus.cache.CacheName} annotation or retrieved using {@link CacheManager#getCache(String)}.
*/
public interface Cache {
@@ -20,7 +20,8 @@ public interface Cache {
/**
* Returns the unique and immutable default key for the current cache. This key is used by the annotations caching API when
- * a no-args method annotated with {@link CacheResult} or {@link CacheInvalidate} is invoked. It can also be used with the
+ * a no-args method annotated with {@code @io.quarkus.cache.CacheResult} or {@code @io.quarkus.cache.CacheInvalidate} is
+ * invoked. It can also be used with the
* programmatic caching API.
*
* @return default cache key
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/CacheManager.java b/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/CacheManager.java
similarity index 91%
rename from extensions/cache/runtime/src/main/java/io/quarkus/cache/CacheManager.java
rename to extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/CacheManager.java
index ffedd8ad288e19..c62628ca1e0893 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/CacheManager.java
+++ b/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/CacheManager.java
@@ -7,7 +7,7 @@
*
* Use this interface to retrieve all existing {@link Cache} names and interact with any cache programmatically e.g. store,
* retrieve or delete cache values. It shares the same caches collection the Quarkus caching annotations use. The
- * {@link CacheName} annotation can also be used to inject and access a specific cache from its name.
+ * {@code @io.quarkus.cache.CacheName} annotation can also be used to inject and access a specific cache from its name.
*
*
* Code example:
diff --git a/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/CacheManagerInfo.java b/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/CacheManagerInfo.java
new file mode 100644
index 00000000000000..cd46de05491848
--- /dev/null
+++ b/extensions/cache/runtime-spi/src/main/java/io/quarkus/cache/CacheManagerInfo.java
@@ -0,0 +1,27 @@
+package io.quarkus.cache;
+
+import java.util.Set;
+import java.util.function.Supplier;
+
+public interface CacheManagerInfo {
+
+ boolean supports(Context context);
+
+ Supplier get(Context context);
+
+ interface Context {
+
+ boolean cacheEnabled();
+
+ Metrics metrics();
+
+ String cacheType();
+
+ Set cacheNames();
+
+ enum Metrics {
+ NONE,
+ MICROMETER
+ }
+ }
+}
diff --git a/extensions/cache/runtime/pom.xml b/extensions/cache/runtime/pom.xml
index c87ec82e4e0ef6..70993637b709a0 100644
--- a/extensions/cache/runtime/pom.xml
+++ b/extensions/cache/runtime/pom.xml
@@ -27,6 +27,10 @@
io.quarkus
quarkus-mutiny
+
+ io.quarkus
+ quarkus-cache-runtime-spi
+
io.vertx
vertx-web
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheBuildConfig.java b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheBuildConfig.java
new file mode 100644
index 00000000000000..be01933b30a96c
--- /dev/null
+++ b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheBuildConfig.java
@@ -0,0 +1,20 @@
+package io.quarkus.cache.runtime;
+
+import static io.quarkus.runtime.annotations.ConfigPhase.BUILD_AND_RUN_TIME_FIXED;
+
+import io.quarkus.runtime.annotations.ConfigRoot;
+import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithDefault;
+
+@ConfigRoot(phase = BUILD_AND_RUN_TIME_FIXED)
+@ConfigMapping(prefix = "quarkus.cache")
+public interface CacheBuildConfig {
+
+ String CAFFEINE_CACHE_TYPE = "caffeine";
+
+ /**
+ * Cache type.
+ */
+ @WithDefault(CAFFEINE_CACHE_TYPE)
+ String type();
+}
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheConfig.java b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheConfig.java
index 56d46a8870da16..0ac4f0bad8331e 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheConfig.java
+++ b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheConfig.java
@@ -10,60 +10,50 @@
import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigDocSection;
-import io.quarkus.runtime.annotations.ConfigGroup;
-import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigRoot;
+import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithDefault;
+import io.smallrye.config.WithParentName;
@ConfigRoot(phase = RUN_TIME)
-public class CacheConfig {
-
- public static final String CAFFEINE_CACHE_TYPE = "caffeine";
+@ConfigMapping(prefix = "quarkus.cache")
+public interface CacheConfig {
/**
* Whether or not the cache extension is enabled.
*/
- @ConfigItem(defaultValue = "true")
- public boolean enabled;
-
- /**
- * Cache type.
- */
- @ConfigItem(defaultValue = CAFFEINE_CACHE_TYPE)
- public String type;
+ @WithDefault("true")
+ boolean enabled();
/**
* Caffeine configuration.
*/
- @ConfigItem
- public CaffeineConfig caffeine;
+ CaffeineConfig caffeine();
- @ConfigGroup
- public static class CaffeineConfig {
+ interface CaffeineConfig {
/**
* Default configuration applied to all Caffeine caches (lowest precedence)
*/
- @ConfigItem(name = ConfigItem.PARENT)
+ @WithParentName
@ConfigDocSection
- public CaffeineCacheConfig defaultConfig;
+ CaffeineCacheConfig defaultConfig();
/**
* Additional configuration applied to a specific Caffeine cache (highest precedence)
*/
- @ConfigItem(name = ConfigItem.PARENT)
+ @WithParentName
@ConfigDocMapKey("cache-name")
@ConfigDocSection
- public Map cachesConfig;
+ Map cachesConfig();
- @ConfigGroup
- public static class CaffeineCacheConfig {
+ interface CaffeineCacheConfig {
/**
* Minimum total size for the internal data structures. Providing a large enough estimate at construction time
* avoids the need for expensive resizing operations later, but setting this value unnecessarily high wastes memory.
*/
- @ConfigItem
- public OptionalInt initialCapacity;
+ OptionalInt initialCapacity();
/**
* Maximum number of entries the cache may contain. Note that the cache may evict an entry before this limit is
@@ -71,29 +61,25 @@ public static class CaffeineCacheConfig {
* the cache evicts entries that are less likely to be used again. For example, the cache may evict an entry because
* it hasn't been used recently or very often.
*/
- @ConfigItem
- public OptionalLong maximumSize;
+ OptionalLong maximumSize();
/**
* Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after
* the entry's creation, or the most recent replacement of its value.
*/
- @ConfigItem
- public Optional expireAfterWrite;
+ Optional expireAfterWrite();
/**
* Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after
* the entry's creation, the most recent replacement of its value, or its last read.
*/
- @ConfigItem
- public Optional expireAfterAccess;
+ Optional expireAfterAccess();
/**
* Whether or not metrics are recorded if the application depends on the Micrometer extension. Setting this
* value to {@code true} will enable the accumulation of cache stats inside Caffeine.
*/
- @ConfigItem
- public Optional metricsEnabled;
+ Optional metricsEnabled();
}
}
}
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheManagerRecorder.java b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheManagerRecorder.java
index 8350ca55c6b280..2e2621edc114f7 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheManagerRecorder.java
+++ b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/CacheManagerRecorder.java
@@ -1,57 +1,105 @@
package io.quarkus.cache.runtime;
-import static io.quarkus.cache.runtime.CacheConfig.CAFFEINE_CACHE_TYPE;
+import static io.quarkus.cache.runtime.CacheBuildConfig.CAFFEINE_CACHE_TYPE;
+import java.util.Collection;
import java.util.Set;
import java.util.function.Supplier;
import jakarta.enterprise.inject.spi.DeploymentException;
import io.quarkus.cache.CacheManager;
+import io.quarkus.cache.CacheManagerInfo;
import io.quarkus.cache.runtime.caffeine.CaffeineCacheManagerBuilder;
import io.quarkus.cache.runtime.noop.NoOpCacheManagerBuilder;
+import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
@Recorder
public class CacheManagerRecorder {
- private final CacheConfig cacheConfig;
+ private final CacheBuildConfig cacheBuildConfig;
+ private final RuntimeValue cacheConfigRV;
- public CacheManagerRecorder(CacheConfig cacheConfig) {
- this.cacheConfig = cacheConfig;
+ public CacheManagerRecorder(CacheBuildConfig cacheBuildConfig, RuntimeValue cacheConfigRV) {
+ this.cacheBuildConfig = cacheBuildConfig;
+ this.cacheConfigRV = cacheConfigRV;
}
- public Supplier getCacheManagerSupplierWithMicrometerMetrics(Set cacheNames) {
- Supplier> caffeineCacheManagerSupplier = new Supplier>() {
+ public Supplier resolveCacheInfo(Collection infos, Set cacheNames,
+ boolean micrometerMetricsEnabled) {
+ CacheConfig cacheConfig = cacheConfigRV.getValue();
+ CacheManagerInfo.Context context = new CacheManagerInfo.Context() {
@Override
- public Supplier get() {
- return CaffeineCacheManagerBuilder.buildWithMicrometerMetrics(cacheNames, cacheConfig);
+ public boolean cacheEnabled() {
+ return cacheConfig.enabled();
+ }
+
+ @Override
+ public Metrics metrics() {
+ return micrometerMetricsEnabled ? Metrics.MICROMETER : Metrics.NONE;
+ }
+
+ @Override
+ public String cacheType() {
+ return cacheBuildConfig.type();
+ }
+
+ @Override
+ public Set cacheNames() {
+ return cacheNames;
}
};
- return getCacheManagerSupplier(cacheNames, caffeineCacheManagerSupplier);
+ for (CacheManagerInfo info : infos) {
+ if (info.supports(context)) {
+ return info.get(context);
+ }
+ }
+ throw new DeploymentException("Unknown cache type: " + context.cacheType());
}
- public Supplier getCacheManagerSupplierWithoutMetrics(Set cacheNames) {
- Supplier> caffeineCacheManagerSupplier = new Supplier>() {
+ public CacheManagerInfo noOpCacheManagerInfo() {
+ return new CacheManagerInfo() {
@Override
- public Supplier get() {
- return CaffeineCacheManagerBuilder.buildWithoutMetrics(cacheNames, cacheConfig);
+ public boolean supports(Context context) {
+ return !context.cacheEnabled();
+ }
+
+ @Override
+ public Supplier get(Context context) {
+ return NoOpCacheManagerBuilder.build(context.cacheNames());
}
};
- return getCacheManagerSupplier(cacheNames, caffeineCacheManagerSupplier);
}
- private Supplier getCacheManagerSupplier(Set cacheNames,
- Supplier> caffeineCacheManagerSupplier) {
- if (cacheConfig.enabled) {
- switch (cacheConfig.type) {
- case CAFFEINE_CACHE_TYPE:
- return caffeineCacheManagerSupplier.get();
- default:
- throw new DeploymentException("Unknown cache type: " + cacheConfig.type);
- }
- } else {
- return NoOpCacheManagerBuilder.build(cacheNames);
- }
+ public CacheManagerInfo getCacheManagerInfoWithMicrometerMetrics() {
+ return new CacheManagerInfo() {
+ @Override
+ public boolean supports(Context context) {
+ return context.cacheEnabled() && context.cacheType().equals(CAFFEINE_CACHE_TYPE)
+ && (context.metrics() == Context.Metrics.MICROMETER);
+ }
+
+ @Override
+ public Supplier get(Context context) {
+ return CaffeineCacheManagerBuilder.buildWithMicrometerMetrics(context.cacheNames(), cacheConfigRV.getValue());
+ }
+ };
}
+
+ public CacheManagerInfo getCacheManagerInfoWithoutMetrics() {
+ return new CacheManagerInfo() {
+ @Override
+ public boolean supports(Context context) {
+ return context.cacheEnabled() && context.cacheType().equals(CAFFEINE_CACHE_TYPE)
+ && (context.metrics() == Context.Metrics.NONE);
+ }
+
+ @Override
+ public Supplier get(Context context) {
+ return CaffeineCacheManagerBuilder.buildWithoutMetrics(context.cacheNames(), cacheConfigRV.getValue());
+ }
+ };
+ }
+
}
diff --git a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheInfoBuilder.java b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheInfoBuilder.java
index e324300052acba..c5af6931e29d3c 100644
--- a/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheInfoBuilder.java
+++ b/extensions/cache/runtime/src/main/java/io/quarkus/cache/runtime/caffeine/CaffeineCacheInfoBuilder.java
@@ -14,7 +14,7 @@ public static Set build(Set cacheNames, CacheConfig c
if (cacheNames.isEmpty()) {
return Collections.emptySet();
} else {
- CaffeineCacheConfig defaultConfig = cacheConfig.caffeine.defaultConfig;
+ CaffeineCacheConfig defaultConfig = cacheConfig.caffeine().defaultConfig();
Set cacheInfos = HashSetFactory. getInstance().apply(cacheNames.size());
for (String cacheName : cacheNames) {
@@ -22,36 +22,36 @@ public static Set build(Set cacheNames, CacheConfig c
CaffeineCacheInfo cacheInfo = new CaffeineCacheInfo();
cacheInfo.name = cacheName;
- CaffeineCacheConfig namedCacheConfig = cacheConfig.caffeine.cachesConfig.get(cacheInfo.name);
+ CaffeineCacheConfig namedCacheConfig = cacheConfig.caffeine().cachesConfig().get(cacheInfo.name);
- if (namedCacheConfig != null && namedCacheConfig.initialCapacity.isPresent()) {
- cacheInfo.initialCapacity = namedCacheConfig.initialCapacity.getAsInt();
- } else if (defaultConfig.initialCapacity.isPresent()) {
- cacheInfo.initialCapacity = defaultConfig.initialCapacity.getAsInt();
+ if (namedCacheConfig != null && namedCacheConfig.initialCapacity().isPresent()) {
+ cacheInfo.initialCapacity = namedCacheConfig.initialCapacity().getAsInt();
+ } else if (defaultConfig.initialCapacity().isPresent()) {
+ cacheInfo.initialCapacity = defaultConfig.initialCapacity().getAsInt();
}
- if (namedCacheConfig != null && namedCacheConfig.maximumSize.isPresent()) {
- cacheInfo.maximumSize = namedCacheConfig.maximumSize.getAsLong();
- } else if (defaultConfig.maximumSize.isPresent()) {
- cacheInfo.maximumSize = defaultConfig.maximumSize.getAsLong();
+ if (namedCacheConfig != null && namedCacheConfig.maximumSize().isPresent()) {
+ cacheInfo.maximumSize = namedCacheConfig.maximumSize().getAsLong();
+ } else if (defaultConfig.maximumSize().isPresent()) {
+ cacheInfo.maximumSize = defaultConfig.maximumSize().getAsLong();
}
- if (namedCacheConfig != null && namedCacheConfig.expireAfterWrite.isPresent()) {
- cacheInfo.expireAfterWrite = namedCacheConfig.expireAfterWrite.get();
- } else if (defaultConfig.expireAfterWrite.isPresent()) {
- cacheInfo.expireAfterWrite = defaultConfig.expireAfterWrite.get();
+ if (namedCacheConfig != null && namedCacheConfig.expireAfterWrite().isPresent()) {
+ cacheInfo.expireAfterWrite = namedCacheConfig.expireAfterWrite().get();
+ } else if (defaultConfig.expireAfterWrite().isPresent()) {
+ cacheInfo.expireAfterWrite = defaultConfig.expireAfterWrite().get();
}
- if (namedCacheConfig != null && namedCacheConfig.expireAfterAccess.isPresent()) {
- cacheInfo.expireAfterAccess = namedCacheConfig.expireAfterAccess.get();
- } else if (defaultConfig.expireAfterAccess.isPresent()) {
- cacheInfo.expireAfterAccess = defaultConfig.expireAfterAccess.get();
+ if (namedCacheConfig != null && namedCacheConfig.expireAfterAccess().isPresent()) {
+ cacheInfo.expireAfterAccess = namedCacheConfig.expireAfterAccess().get();
+ } else if (defaultConfig.expireAfterAccess().isPresent()) {
+ cacheInfo.expireAfterAccess = defaultConfig.expireAfterAccess().get();
}
- if (namedCacheConfig != null && namedCacheConfig.metricsEnabled.isPresent()) {
- cacheInfo.metricsEnabled = namedCacheConfig.metricsEnabled.get();
- } else if (defaultConfig.metricsEnabled.isPresent()) {
- cacheInfo.metricsEnabled = defaultConfig.metricsEnabled.get();
+ if (namedCacheConfig != null && namedCacheConfig.metricsEnabled().isPresent()) {
+ cacheInfo.metricsEnabled = namedCacheConfig.metricsEnabled().get();
+ } else if (defaultConfig.metricsEnabled().isPresent()) {
+ cacheInfo.metricsEnabled = defaultConfig.metricsEnabled().get();
}
cacheInfos.add(cacheInfo);