Support for TransactionAwareCacheDecorator

This commit makes sure to unwrap any transaction aware cache before
collecting metrics for them.

Closes gh-8984
pull/8796/merge
Stephane Nicoll 8 years ago
parent b73e1d46ae
commit a59000354c

@ -27,7 +27,9 @@ import org.springframework.boot.actuate.cache.CacheStatisticsProvider;
import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
@ -87,7 +89,7 @@ public class CachePublicMetrics implements PublicMetrics {
List<CacheManagerBean> cacheManagerBeans) { List<CacheManagerBean> cacheManagerBeans) {
for (CacheManagerBean cacheManagerBean : cacheManagerBeans) { for (CacheManagerBean cacheManagerBean : cacheManagerBeans) {
CacheManager cacheManager = cacheManagerBean.getCacheManager(); CacheManager cacheManager = cacheManagerBean.getCacheManager();
Cache cache = cacheManager.getCache(cacheName); Cache cache = unwrapIfNecessary(cacheManager.getCache(cacheName));
CacheStatistics statistics = getCacheStatistics(cache, cacheManager); CacheStatistics statistics = getCacheStatistics(cache, cacheManager);
if (statistics != null) { if (statistics != null) {
String prefix = cacheName; String prefix = cacheName;
@ -100,6 +102,14 @@ public class CachePublicMetrics implements PublicMetrics {
} }
} }
private Cache unwrapIfNecessary(Cache cache) {
if (ClassUtils.isPresent("org.springframework.cache.transaction.TransactionAwareCacheDecorator",
getClass().getClassLoader())) {
return TransactionAwareCacheDecoratorHandler.unwrapIfNecessary(cache);
}
return cache;
}
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
private CacheStatistics getCacheStatistics(Cache cache, CacheManager cacheManager) { private CacheStatistics getCacheStatistics(Cache cache, CacheManager cacheManager) {
if (this.statisticsProviders != null) { if (this.statisticsProviders != null) {
@ -140,4 +150,19 @@ public class CachePublicMetrics implements PublicMetrics {
} }
private static class TransactionAwareCacheDecoratorHandler {
private static Cache unwrapIfNecessary(Cache cache) {
try {
if (cache instanceof TransactionAwareCacheDecorator) {
return ((TransactionAwareCacheDecorator) cache).getTargetCache();
}
}
catch (NoClassDefFoundError ex) {
// Ignore
}
return cache;
}
}
} }

@ -18,6 +18,7 @@ package org.springframework.boot.actuate.endpoint;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -29,7 +30,10 @@ import org.springframework.boot.actuate.cache.CaffeineCacheStatisticsProvider;
import org.springframework.boot.actuate.cache.ConcurrentMapCacheStatisticsProvider; import org.springframework.boot.actuate.cache.ConcurrentMapCacheStatisticsProvider;
import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.Metric;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.cache.transaction.TransactionAwareCacheDecorator;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry; import static org.assertj.core.api.Assertions.entry;
@ -78,6 +82,19 @@ public class CachePublicMetricsTests {
entry("cache.anotherCacheManager_foo.size", 0L)); entry("cache.anotherCacheManager_foo.size", 0L));
} }
@Test
public void cacheMetricsWithTransactionAwareCacheDecorator() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Collections.singletonList(
new TransactionAwareCacheDecorator(new ConcurrentMapCache("foo"))));
cacheManager.afterPropertiesSet();
this.cacheManagers.put("cacheManager", cacheManager);
CachePublicMetrics cpm = new CachePublicMetrics(this.cacheManagers,
providers(new ConcurrentMapCacheStatisticsProvider()));
Map<String, Number> metrics = metrics(cpm);
assertThat(metrics).containsOnly(entry("cache.foo.size", 0L));
}
private Map<String, Number> metrics(CachePublicMetrics cpm) { private Map<String, Number> metrics(CachePublicMetrics cpm) {
Collection<Metric<?>> metrics = cpm.metrics(); Collection<Metric<?>> metrics = cpm.metrics();
assertThat(metrics).isNotNull(); assertThat(metrics).isNotNull();

Loading…
Cancel
Save