org.redisson.jcache.JCacheManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redisson Show documentation
Show all versions of redisson Show documentation
Redis Java client with features of In-Memory Data Grid
/**
* Copyright (c) 2013-2022 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.jcache;
import java.lang.management.ManagementFactory;
import java.net.URI;
import java.util.Collections;
import java.util.HashSet;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;
import javax.cache.configuration.CompleteConfiguration;
import javax.cache.configuration.Configuration;
import javax.cache.spi.CachingProvider;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import org.redisson.Redisson;
import org.redisson.jcache.bean.EmptyStatisticsMXBean;
import org.redisson.jcache.bean.JCacheManagementMXBean;
import org.redisson.jcache.bean.JCacheStatisticsMXBean;
import org.redisson.jcache.configuration.JCacheConfiguration;
import org.redisson.jcache.configuration.RedissonConfiguration;
/**
*
* @author Nikita Koksharov
*
*/
public class JCacheManager implements CacheManager {
private static final EmptyStatisticsMXBean EMPTY_INSTANCE = new EmptyStatisticsMXBean();
private static final MBeanServer MBEAN_SERVER = ManagementFactory.getPlatformMBeanServer();
private final ClassLoader classLoader;
private final CachingProvider cacheProvider;
private final Properties properties;
private final URI uri;
private final ConcurrentMap> caches = new ConcurrentHashMap<>();
private final ConcurrentMap, JCacheStatisticsMXBean> statBeans = new ConcurrentHashMap<>();
private final ConcurrentMap, JCacheManagementMXBean> managementBeans = new ConcurrentHashMap<>();
private final AtomicBoolean closed = new AtomicBoolean();
private final Redisson redisson;
public JCacheManager(Redisson redisson, ClassLoader classLoader, CachingProvider cacheProvider, Properties properties, URI uri) {
super();
this.classLoader = classLoader;
this.cacheProvider = cacheProvider;
this.properties = properties;
this.uri = uri;
this.redisson = redisson;
}
@Override
public CachingProvider getCachingProvider() {
return cacheProvider;
}
@Override
public URI getURI() {
return uri;
}
@Override
public ClassLoader getClassLoader() {
return classLoader;
}
@Override
public Properties getProperties() {
return properties;
}
private void checkNotClosed() {
if (closed.get()) {
throw new IllegalStateException();
}
}
@Override
public > Cache createCache(String cacheName, C configuration)
throws IllegalArgumentException {
checkNotClosed();
Redisson cacheRedisson = redisson;
if (cacheName == null) {
throw new NullPointerException();
}
if (configuration == null) {
throw new NullPointerException();
}
if (cacheRedisson == null && !(configuration instanceof RedissonConfiguration)) {
throw new IllegalStateException("Default configuration hasn't been specified!");
}
boolean hasOwnRedisson = false;
if (configuration instanceof RedissonConfiguration) {
RedissonConfiguration rc = (RedissonConfiguration) configuration;
if (rc.getConfig() != null) {
cacheRedisson = (Redisson) Redisson.create(rc.getConfig());
hasOwnRedisson = true;
} else {
cacheRedisson = (Redisson) rc.getRedisson();
}
}
JCacheConfiguration cfg = new JCacheConfiguration(configuration);
JCache cache = new JCache<>(this, cacheRedisson, cacheName, cfg, hasOwnRedisson);
JCache, ?> oldCache = caches.putIfAbsent(cacheName, cache);
if (oldCache != null) {
throw new CacheException("Cache " + cacheName + " already exists");
}
if (cfg.isStatisticsEnabled()) {
enableStatistics(cacheName, true);
}
if (cfg.isManagementEnabled()) {
enableManagement(cacheName, true);
}
return cache;
}
@Override
public Cache getCache(String cacheName, Class keyType, Class valueType) {
checkNotClosed();
if (cacheName == null) {
throw new NullPointerException();
}
if (keyType == null) {
throw new NullPointerException();
}
if (valueType == null) {
throw new NullPointerException();
}
JCache, ?> cache = caches.get(cacheName);
if (cache == null) {
return null;
}
if (!keyType.isAssignableFrom(cache.getConfiguration(CompleteConfiguration.class).getKeyType())) {
throw new ClassCastException("Wrong type of key for " + cacheName);
}
if (!valueType.isAssignableFrom(cache.getConfiguration(CompleteConfiguration.class).getValueType())) {
throw new ClassCastException("Wrong type of value for " + cacheName);
}
return (Cache) cache;
}
@Override
public Cache getCache(String cacheName) {
checkNotClosed();
Cache cache = (Cache) getCache(cacheName, Object.class, Object.class);
if (cache != null) {
if (cache.getConfiguration(CompleteConfiguration.class).getKeyType() != Object.class) {
throw new IllegalArgumentException("Wrong type of key for " + cacheName);
}
if (cache.getConfiguration(CompleteConfiguration.class).getValueType() != Object.class) {
throw new IllegalArgumentException("Wrong type of value for " + cacheName);
}
}
return cache;
}
@Override
public Iterable getCacheNames() {
return Collections.unmodifiableSet(new HashSet<>(caches.keySet()));
}
@Override
public void destroyCache(String cacheName) {
checkNotClosed();
if (cacheName == null) {
throw new NullPointerException();
}
JCache, ?> cache = caches.get(cacheName);
if (cache != null) {
cache.clear();
cache.close();
}
}
public void closeCache(JCache, ?> cache) {
caches.remove(cache.getRawName());
unregisterStatisticsBean(cache);
unregisterManagementBean(cache);
}
@Override
public void enableManagement(String cacheName, boolean enabled) {
checkNotClosed();
if (cacheName == null) {
throw new NullPointerException();
}
JCache, ?> cache = caches.get(cacheName);
if (cache == null) {
throw new NullPointerException();
}
if (enabled) {
JCacheManagementMXBean statBean = managementBeans.get(cache);
if (statBean == null) {
statBean = new JCacheManagementMXBean(cache);
JCacheManagementMXBean oldBean = managementBeans.putIfAbsent(cache, statBean);
if (oldBean != null) {
statBean = oldBean;
}
}
try {
ObjectName objectName = queryNames("Configuration", cache);
if (MBEAN_SERVER.queryNames(objectName, null).isEmpty()) {
MBEAN_SERVER.registerMBean(statBean, objectName);
}
} catch (MalformedObjectNameException e) {
throw new CacheException(e);
} catch (InstanceAlreadyExistsException e) {
throw new CacheException(e);
} catch (MBeanRegistrationException e) {
throw new CacheException(e);
} catch (NotCompliantMBeanException e) {
throw new CacheException(e);
}
} else {
unregisterManagementBean(cache);
}
cache.getConfiguration(JCacheConfiguration.class).setManagementEnabled(enabled);
}
private ObjectName queryNames(String baseName, JCache, ?> cache) throws MalformedObjectNameException {
String name = getName(baseName, cache);
return new ObjectName(name);
}
private void unregisterManagementBean(JCache, ?> cache) {
JCacheManagementMXBean statBean = managementBeans.remove(cache);
if (statBean != null) {
try {
ObjectName name = queryNames("Configuration", cache);
for (ObjectName objectName : MBEAN_SERVER.queryNames(name, null)) {
MBEAN_SERVER.unregisterMBean(objectName);
}
} catch (MalformedObjectNameException e) {
throw new CacheException(e);
} catch (MBeanRegistrationException e) {
throw new CacheException(e);
} catch (InstanceNotFoundException e) {
throw new CacheException(e);
}
}
}
public JCacheStatisticsMXBean getStatBean(JCache, ?> cache) {
JCacheStatisticsMXBean bean = statBeans.get(cache);
if (bean != null) {
return bean;
}
return EMPTY_INSTANCE;
}
private String getName(String name, JCache, ?> cache) {
return "javax.cache:type=Cache" + name + ",CacheManager="
+ cache.getCacheManager().getURI().toString().replaceAll(",|:|=|\n", ".")
+ ",Cache=" + cache.getRawName().replaceAll(",|:|=|\n", ".");
}
@Override
public void enableStatistics(String cacheName, boolean enabled) {
checkNotClosed();
if (cacheName == null) {
throw new NullPointerException();
}
JCache, ?> cache = caches.get(cacheName);
if (cache == null) {
throw new NullPointerException();
}
if (enabled) {
JCacheStatisticsMXBean statBean = statBeans.get(cache);
if (statBean == null) {
statBean = new JCacheStatisticsMXBean();
JCacheStatisticsMXBean oldBean = statBeans.putIfAbsent(cache, statBean);
if (oldBean != null) {
statBean = oldBean;
}
}
try {
ObjectName objectName = queryNames("Statistics", cache);
if (!MBEAN_SERVER.isRegistered(objectName)) {
MBEAN_SERVER.registerMBean(statBean, objectName);
}
} catch (MalformedObjectNameException e) {
throw new CacheException(e);
} catch (InstanceAlreadyExistsException e) {
throw new CacheException(e);
} catch (MBeanRegistrationException e) {
throw new CacheException(e);
} catch (NotCompliantMBeanException e) {
throw new CacheException(e);
}
} else {
unregisterStatisticsBean(cache);
}
cache.getConfiguration(JCacheConfiguration.class).setStatisticsEnabled(enabled);
}
private void unregisterStatisticsBean(JCache, ?> cache) {
JCacheStatisticsMXBean statBean = statBeans.remove(cache);
if (statBean != null) {
try {
ObjectName name = queryNames("Statistics", cache);
for (ObjectName objectName : MBEAN_SERVER.queryNames(name, null)) {
MBEAN_SERVER.unregisterMBean(objectName);
}
} catch (MalformedObjectNameException e) {
throw new CacheException(e);
} catch (MBeanRegistrationException e) {
throw new CacheException(e);
} catch (InstanceNotFoundException e) {
throw new CacheException(e);
}
}
}
@Override
public void close() {
if (closed.compareAndSet(false, true)) {
if (cacheProvider != null) {
cacheProvider.close(uri, classLoader);
}
for (Cache, ?> cache : caches.values()) {
try {
cache.close();
} catch (Exception e) {
// skip
}
}
if (redisson != null) {
redisson.shutdown();
}
}
}
@Override
public boolean isClosed() {
return closed.get();
}
@Override
public T unwrap(Class clazz) {
if (clazz.isAssignableFrom(getClass())) {
return clazz.cast(this);
}
throw new IllegalArgumentException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy