Polish cache code

This commit is contained in:
Phillip Webb
2015-06-04 00:51:20 -07:00
parent 412b7b9e50
commit d2f11c465e
22 changed files with 234 additions and 175 deletions

View File

@@ -18,11 +18,9 @@ package org.springframework.boot.actuate.autoconfigure;
import javax.cache.Caching;
import com.hazelcast.core.IMap;
import com.hazelcast.spring.cache.HazelcastCache;
import net.sf.ehcache.Ehcache;
import org.infinispan.spring.provider.SpringCache;
import org.infinispan.spring.provider.SpringCache;
import org.springframework.boot.actuate.cache.CacheStatistics;
import org.springframework.boot.actuate.cache.CacheStatisticsProvider;
import org.springframework.boot.actuate.cache.ConcurrentMapCacheStatisticsProvider;
@@ -45,6 +43,9 @@ import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.hazelcast.core.IMap;
import com.hazelcast.spring.cache.HazelcastCache;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link CacheStatisticsProvider}
* beans.
@@ -81,7 +82,7 @@ public class CacheStatisticsAutoConfiguration {
}
@Configuration
@ConditionalOnClass({ IMap.class, HazelcastCache.class} )
@ConditionalOnClass({ IMap.class, HazelcastCache.class })
static class HazelcastCacheStatisticsConfiguration {
@Bean

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.cache;
import java.lang.management.ManagementFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
@@ -29,37 +30,32 @@ import javax.management.ReflectionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
/**
* Base {@link CacheStatisticsProvider} implementation that uses JMX to
* retrieve the cache statistics.
* Base {@link CacheStatisticsProvider} implementation that uses JMX to retrieve the cache
* statistics.
*
* @author Stephane Nicoll
* @since 1.3.0
* @param <C> The cache type
*/
public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
implements CacheStatisticsProvider<C> {
public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache> implements
CacheStatisticsProvider<C> {
private static final Logger logger = LoggerFactory
.getLogger(AbstractJmxCacheStatisticsProvider.class);
private MBeanServer mBeanServer;
private Map<String, ObjectNameWrapper> caches =
new ConcurrentHashMap<String, ObjectNameWrapper>();
private Map<String, ObjectNameWrapper> caches = new ConcurrentHashMap<String, ObjectNameWrapper>();
@Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, C cache) {
try {
ObjectName objectName = internalGetObjectName(cache);
if (objectName != null) {
return getCacheStatistics(objectName);
}
return null;
return (objectName == null ? null : getCacheStatistics(objectName));
}
catch (MalformedObjectNameException ex) {
throw new IllegalStateException(ex);
@@ -71,20 +67,20 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
* {@code null} if none is found.
* @param cache the cache to handle
* @return the object name of the cache statistics MBean
* @throws MalformedObjectNameException
*/
protected abstract ObjectName getObjectName(C cache) throws MalformedObjectNameException;
protected abstract ObjectName getObjectName(C cache)
throws MalformedObjectNameException;
/**
* Return the current {@link CacheStatistics} snapshot from the MBean identified by the
* specified {@link ObjectName}.
* Return the current {@link CacheStatistics} snapshot from the MBean identified by
* the specified {@link ObjectName}.
* @param objectName the object name of the cache statistics MBean
* @return the current cache statistics
*/
protected abstract CacheStatistics getCacheStatistics(ObjectName objectName);
private ObjectName internalGetObjectName(C cache)
throws MalformedObjectNameException {
private ObjectName internalGetObjectName(C cache) throws MalformedObjectNameException {
String cacheName = cache.getName();
ObjectNameWrapper value = this.caches.get(cacheName);
if (value != null) {
@@ -102,7 +98,8 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
return this.mBeanServer;
}
protected <T> T getAttribute(ObjectName objectName, String attributeName, Class<T> type) {
protected <T> T getAttribute(ObjectName objectName, String attributeName,
Class<T> type) {
try {
Object attribute = getMBeanServer().getAttribute(objectName, attributeName);
return type.cast(attribute);
@@ -111,8 +108,8 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
throw new IllegalStateException(ex);
}
catch (AttributeNotFoundException ex) {
throw new IllegalStateException("Unexpected: MBean with name '" + objectName + "' " +
"does not expose attribute with name " + attributeName, ex);
throw new IllegalStateException("Unexpected: MBean with name '" + objectName
+ "' " + "does not expose attribute with name " + attributeName, ex);
}
catch (ReflectionException ex) {
throw new IllegalStateException(ex);
@@ -123,13 +120,14 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
}
}
private static class ObjectNameWrapper {
private final ObjectName objectName;
public ObjectNameWrapper(ObjectName objectName) {
this.objectName = objectName;
}
}
}

View File

@@ -86,4 +86,5 @@ public class DefaultCacheStatistics implements CacheStatistics {
metrics.add(new Metric<T>(name, value));
}
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.boot.actuate.cache;
import java.util.Set;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
@@ -29,35 +30,43 @@ import org.infinispan.spring.provider.SpringCache;
* @author Stephane Nicoll
* @since 1.3.0
*/
public class InfinispanCacheStatisticsProvider extends AbstractJmxCacheStatisticsProvider<SpringCache> {
public class InfinispanCacheStatisticsProvider extends
AbstractJmxCacheStatisticsProvider<SpringCache> {
@Override
protected ObjectName getObjectName(SpringCache cache) throws MalformedObjectNameException {
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(
new ObjectName("org.infinispan:component=Statistics,type=Cache," +
"name=\"" + cache.getName() + "(local)\",*"), null);
protected ObjectName getObjectName(SpringCache cache)
throws MalformedObjectNameException {
ObjectName name = new ObjectName(
"org.infinispan:component=Statistics,type=Cache,name=\""
+ cache.getName() + "(local)\",*");
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null);
if (instances.size() == 1) {
return instances.iterator().next().getObjectName();
}
return null; // None or more than one
// None or more than one
return null;
}
@Override
protected CacheStatistics getCacheStatistics(ObjectName objectName) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics();
Integer size = getAttribute(objectName, "numberOfEntries",
Integer.class);
Integer size = getAttribute(objectName, "numberOfEntries", Integer.class);
if (size != null) {
statistics.setSize((long) size);
if (size > 0) { // Let's initialize the stats if we have some data
Double hitRatio = getAttribute(objectName, "hitRatio",
Double.class);
if ((hitRatio != null)) {
statistics.setHitRatio(hitRatio);
statistics.setMissRatio(1 - hitRatio);
}
if (size > 0) {
// Let's initialize the stats if we have some data
initalizeStats(objectName, statistics);
}
}
return statistics;
}
private void initalizeStats(ObjectName objectName, DefaultCacheStatistics statistics) {
Double hitRatio = getAttribute(objectName, "hitRatio", Double.class);
if ((hitRatio != null)) {
statistics.setHitRatio(hitRatio);
statistics.setMissRatio(1 - hitRatio);
}
}
}

View File

@@ -17,6 +17,7 @@
package org.springframework.boot.actuate.cache;
import java.util.Set;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
@@ -29,27 +30,28 @@ import org.springframework.cache.jcache.JCacheCache;
* @author Stephane Nicoll
* @since 1.3.0
*/
public class JCacheCacheStatisticsProvider extends AbstractJmxCacheStatisticsProvider<JCacheCache> {
public class JCacheCacheStatisticsProvider extends
AbstractJmxCacheStatisticsProvider<JCacheCache> {
@Override
protected ObjectName getObjectName(JCacheCache cache)
throws MalformedObjectNameException {
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(
new ObjectName("javax.cache:type=CacheStatistics,Cache="
+ cache.getName() + ",*"), null);
ObjectName name = new ObjectName("javax.cache:type=CacheStatistics,Cache="
+ cache.getName() + ",*");
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null);
if (instances.size() == 1) {
return instances.iterator().next().getObjectName();
}
return null; // None or more than one
// None or more than one
return null;
}
@Override
protected CacheStatistics getCacheStatistics(ObjectName objectName) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics();
Float hitPercentage = getAttribute(objectName, "CacheHitPercentage",
Float hitPercentage = getAttribute(objectName, "CacheHitPercentage", Float.class);
Float missPercentage = getAttribute(objectName, "CacheMissPercentage",
Float.class);
Float missPercentage = getAttribute(objectName,
"CacheMissPercentage", Float.class);
if ((hitPercentage != null && missPercentage != null)
&& (hitPercentage > 0 || missPercentage > 0)) {
statistics.setHitRatio(hitPercentage / (double) 100);

View File

@@ -19,22 +19,15 @@ package org.springframework.boot.actuate.autoconfigure;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import com.google.common.cache.CacheBuilder;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.spring.provider.SpringEmbeddedCacheManager;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.actuate.cache.CacheStatistics;
import org.springframework.boot.actuate.cache.CacheStatisticsProvider;
import org.springframework.cache.Cache;
@@ -52,6 +45,14 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import com.google.common.cache.CacheBuilder;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;