diff --git a/ehcache-107/src/main/java/org/ehcache/jsr107/Eh107CacheManager.java b/ehcache-107/src/main/java/org/ehcache/jsr107/Eh107CacheManager.java index d26bdd791c..853842b1f6 100644 --- a/ehcache-107/src/main/java/org/ehcache/jsr107/Eh107CacheManager.java +++ b/ehcache-107/src/main/java/org/ehcache/jsr107/Eh107CacheManager.java @@ -34,7 +34,10 @@ import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.URI; -import java.util.*; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -47,6 +50,8 @@ import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; +import org.ehcache.core.events.CacheManagerListener; +import org.ehcache.core.spi.store.InternalCacheManager; import static org.ehcache.jsr107.CloseUtil.chain; import static org.ehcache.jsr107.CloseUtil.closeAll; @@ -60,7 +65,7 @@ class Eh107CacheManager implements CacheManager { private static final MBeanServer MBEAN_SERVER = ManagementFactory.getPlatformMBeanServer(); private final Object cachesLock = new Object(); - private final ConcurrentMap> lazilyLoadedCaches = new ConcurrentHashMap<>(); + private final ConcurrentMap> caches = new ConcurrentHashMap<>(); private final org.ehcache.CacheManager ehCacheManager; private final EhcacheCachingProvider cachingProvider; private final ClassLoader classLoader; @@ -79,31 +84,71 @@ class Eh107CacheManager implements CacheManager { this.configurationMerger = configurationMerger; this.statisticsService = jsr107Service.getStatistics(); + ((InternalCacheManager) ehCacheManager).registerListener(new CacheManagerListener() { + @Override + public void cacheAdded(String alias, org.ehcache.Cache cache) { + loadCache(alias, cache); + } + + @Override + public void cacheRemoved(String alias, org.ehcache.Cache cache) { + Eh107Cache jcache = caches.get(alias); + if (jcache != null) { + close(jcache); + } + } + + @Override + public void stateTransition(Status from, Status to) { + } + + }); + loadAllCaches(); } + private void loadAllCaches() { + for (Map.Entry> entry : ehCacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet()) { + CacheConfiguration config = entry.getValue(); + InternalCache cache = (InternalCache) ehCacheManager.getCache(entry.getKey(), config.getKeyType(), config.getValueType()); - private void loadCache(String cacheName) { - Map> cacheConfigurations = ehCacheManager.getRuntimeConfiguration().getCacheConfigurations(); - CacheConfiguration cacheConfiguration; + loadCache(entry.getKey(), cache); + } - if (null != (cacheConfiguration = cacheConfigurations.get(cacheName))) { - Eh107Cache wrappedCache = wrapEhcacheCache(cacheName, cacheConfiguration); - if (lazilyLoadedCaches.putIfAbsent(cacheName, wrappedCache) == null) { - @SuppressWarnings("unchecked") - Eh107Configuration configuration = wrappedCache.getConfiguration(Eh107Configuration.class); - if (configuration.isManagementEnabled()) { - enableManagement(wrappedCache, true); - } - if (configuration.isStatisticsEnabled()) { - enableStatistics(wrappedCache, true); - } - } + for (Eh107Cache wrappedCache : caches.values()) { + wrappedCache.isClosed(); } } - private Eh107Cache wrapEhcacheCache(String alias, CacheConfiguration ehConfig) { - org.ehcache.Cache cache = ehCacheManager.getCache(alias, ehConfig.getKeyType(), ehConfig.getValueType()); - return wrapEhcacheCache(alias, (InternalCache)cache); + @SuppressWarnings("unchecked") + private Cache loadCache(String alias, org.ehcache.Cache cache) { + return (Cache) caches.computeIfAbsent(alias, name -> { + Eh107Cache wrappedCache = wrapEhcacheCache(name, (InternalCache) cache); + @SuppressWarnings("unchecked") + Eh107Configuration configuration = wrappedCache.getConfiguration(Eh107Configuration.class); + if (configuration.isManagementEnabled()) { + enableManagement(wrappedCache, true); + } + if (configuration.isStatisticsEnabled()) { + enableStatistics(wrappedCache, true); + } + return wrappedCache; + }); + } + + @SuppressWarnings("unchecked") + private Cache reloadCache(String alias, Eh107Cache jcache) { + return (Cache) caches.computeIfPresent(alias, (name, existing) -> { + @SuppressWarnings("unchecked") + Eh107Configuration oldConfiguration = existing.getConfiguration(Eh107Configuration.class); + Eh107Configuration newConfiguration = jcache.getConfiguration(Eh107Configuration.class); + if (oldConfiguration.isManagementEnabled() != newConfiguration.isManagementEnabled()) { + enableManagement(jcache, newConfiguration.isManagementEnabled()); + } + if (oldConfiguration.isStatisticsEnabled() != newConfiguration.isStatisticsEnabled()) { + enableStatistics(jcache, newConfiguration.isStatisticsEnabled()); + } + return jcache; + }); } private Eh107Cache wrapEhcacheCache(String alias, InternalCache cache) { @@ -166,67 +211,42 @@ public > Cache createCache(String cach @SuppressWarnings("unchecked") Eh107Configuration.Eh107ConfigurationWrapper configurationWrapper = (Eh107Configuration.Eh107ConfigurationWrapper)config; CacheConfiguration unwrap = configurationWrapper.getCacheConfiguration(); - final org.ehcache.Cache ehcache; try { - ehcache = ehCacheManager.createCache(cacheName, unwrap); + ehCacheManager.createCache(cacheName, unwrap); } catch (IllegalArgumentException e) { throw new CacheException("A Cache named [" + cacheName + "] already exists"); } - Eh107Cache cache = wrapEhcacheCache(cacheName, (InternalCache)ehcache); - assert safeCacheRetrieval(cacheName) == null; - lazilyLoadedCaches.put(cacheName, cache); - - @SuppressWarnings("unchecked") - Eh107Configuration configuration = cache.getConfiguration(Eh107Configuration.class); - if (configuration.isManagementEnabled()) { - enableManagement(cacheName, true); - } - - if (configuration.isStatisticsEnabled()) { - enableStatistics(cacheName, true); - } - - return cache; - } - - ConfigurationMerger.ConfigHolder configHolder = configurationMerger.mergeConfigurations(cacheName, config); - - final InternalCache ehCache; - try { - ehCache = (InternalCache)ehCacheManager.createCache(cacheName, configHolder.cacheConfiguration); - } catch (IllegalArgumentException e) { - throw configHolder.cacheResources.closeResourcesAfter(new CacheException("A Cache named [" + cacheName + "] already exists")); - } catch (Throwable t) { - // something went wrong in ehcache land, make sure to clean up our stuff - throw configHolder.cacheResources.closeResourcesAfter(new CacheException(t)); - } - - Eh107Cache cache = null; - CacheResources cacheResources = configHolder.cacheResources; - try { - if (configHolder.useEhcacheLoaderWriter) { - cacheResources = new CacheResources<>(cacheName, wrapCacheLoaderWriter(ehCache.getCacheLoaderWriter()), - cacheResources.getExpiryPolicy(), cacheResources.getListenerResources()); - } - cache = new Eh107Cache<>(cacheName, new Eh107CompleteConfiguration<>(configHolder.jsr107Configuration, ehCache - .getRuntimeConfiguration()), cacheResources, ehCache, statisticsService, this); - - lazilyLoadedCaches.put(cacheName, cache); - - if (configHolder.jsr107Configuration.isManagementEnabled()) { - enableManagement(cacheName, true); - } + return safeCacheRetrieval(cacheName); + } else { + ConfigurationMerger.ConfigHolder configHolder = configurationMerger.mergeConfigurations(cacheName, config); - if (configHolder.jsr107Configuration.isStatisticsEnabled()) { - enableStatistics(cacheName, true); + final InternalCache ehCache; + try { + ehCache = (InternalCache)ehCacheManager.createCache(cacheName, configHolder.cacheConfiguration); + } catch (IllegalArgumentException e) { + throw configHolder.cacheResources.closeResourcesAfter(new CacheException("A Cache named [" + cacheName + "] already exists")); + } catch (Throwable t) { + // something went wrong in ehcache land, make sure to clean up our stuff + throw configHolder.cacheResources.closeResourcesAfter(new CacheException(t)); } - return cache; - } catch (Throwable t) { - if (cache != null) { - throw cache.closeInternalAfter(new CacheException(t)); - } else { - throw cacheResources.closeResourcesAfter(new CacheException(t)); + Eh107Cache cache = null; + CacheResources cacheResources = configHolder.cacheResources; + try { + if (configHolder.useEhcacheLoaderWriter) { + cacheResources = new CacheResources<>(cacheName, wrapCacheLoaderWriter(ehCache.getCacheLoaderWriter()), + cacheResources.getExpiryPolicy(), cacheResources.getListenerResources()); + } + cache = new Eh107Cache<>(cacheName, new Eh107CompleteConfiguration<>(configHolder.jsr107Configuration, ehCache + .getRuntimeConfiguration()), cacheResources, ehCache, statisticsService, this); + + return reloadCache(cacheName, cache); + } catch (Throwable t) { + if (cache != null) { + throw cache.closeInternalAfter(new CacheException(t)); + } else { + throw cacheResources.closeResourcesAfter(new CacheException(t)); + } } } } @@ -247,7 +267,6 @@ public String toString() { @Override public Cache getCache(String cacheName, Class keyType, Class valueType) { checkClosed(); - loadCache(cacheName); if (cacheName == null || keyType == null || valueType == null) { throw new NullPointerException(); @@ -278,7 +297,6 @@ public Cache getCache(String cacheName, Class keyType, Class @Override public Cache getCache(String cacheName) { checkClosed(); - loadCache(cacheName); if (cacheName == null) { throw new NullPointerException(); @@ -289,7 +307,7 @@ public Cache getCache(String cacheName) { @SuppressWarnings("unchecked") private Eh107Cache safeCacheRetrieval(final String cacheName) { - final Eh107Cache eh107Cache = lazilyLoadedCaches.get(cacheName); + final Eh107Cache eh107Cache = caches.get(cacheName); if(eh107Cache != null && eh107Cache.isClosed()) { return null; } @@ -299,7 +317,7 @@ private Eh107Cache safeCacheRetrieval(final String cacheName) { @Override public Iterable getCacheNames() { checkClosed(); - return Collections.unmodifiableList(new ArrayList<>(lazilyLoadedCaches.keySet())); + return Collections.unmodifiableSet(new HashSet<>(ehCacheManager.getRuntimeConfiguration().getCacheConfigurations().keySet())); } @Override @@ -311,7 +329,7 @@ public void destroyCache(String cacheName) { synchronized (cachesLock) { checkClosed(); - Eh107Cache cache = lazilyLoadedCaches.remove(cacheName); + Eh107Cache cache = caches.remove(cacheName); if (cache == null) { // TCK expects this method to return w/o exception if named cache does // not exist @@ -439,7 +457,7 @@ public void close() { void closeInternal() { synchronized (cachesLock) { try { - closeAll(lazilyLoadedCaches.values(), (Closeable) lazilyLoadedCaches::clear, ehCacheManager); + closeAll(caches.values(), (Closeable) caches::clear, ehCacheManager); } catch (IOException e) { throw new CacheException(e); } @@ -447,7 +465,7 @@ void closeInternal() { } void close(Eh107Cache cache) { - if (lazilyLoadedCaches.remove(cache.getName(), cache)) { + if (caches.remove(cache.getName(), cache)) { try { chain( () -> unregisterObject(cache.getManagementMBean()), diff --git a/ehcache-107/src/test/java/org/ehcache/jsr107/Eh107XmlIntegrationTest.java b/ehcache-107/src/test/java/org/ehcache/jsr107/Eh107XmlIntegrationTest.java index 9e8e55c6cb..665bf48f0d 100644 --- a/ehcache-107/src/test/java/org/ehcache/jsr107/Eh107XmlIntegrationTest.java +++ b/ehcache-107/src/test/java/org/ehcache/jsr107/Eh107XmlIntegrationTest.java @@ -47,6 +47,7 @@ import javax.cache.spi.CachingProvider; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; @@ -68,6 +69,11 @@ public void setUp() throws Exception { .toURI(), cachingProvider.getDefaultClassLoader()); } + @Test + public void testImmediateCacheNames() { + assertThat(cacheManager.getCacheNames(), containsInAnyOrder("customerCache", "productCache")); + } + @Test public void test107CacheCanReturnCompleteConfigurationWhenNonePassedIn() { CacheManager cacheManager = cachingProvider.getCacheManager(); diff --git a/ehcache-107/src/test/java/org/ehcache/jsr107/UnwrapTest.java b/ehcache-107/src/test/java/org/ehcache/jsr107/UnwrapTest.java index 54dc7f9a34..7d06492cf8 100644 --- a/ehcache-107/src/test/java/org/ehcache/jsr107/UnwrapTest.java +++ b/ehcache-107/src/test/java/org/ehcache/jsr107/UnwrapTest.java @@ -15,7 +15,6 @@ */ package org.ehcache.jsr107; -import org.ehcache.config.builders.CacheConfigurationBuilder; import org.ehcache.core.EhcacheManager; import org.ehcache.event.CacheEvent; import org.junit.After; @@ -29,9 +28,13 @@ import javax.cache.event.EventType; import javax.cache.spi.CachingProvider; +import static org.ehcache.config.builders.CacheConfigurationBuilder.newCacheConfigurationBuilder; import static org.ehcache.config.builders.ResourcePoolsBuilder.heap; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; /** * @author rism @@ -79,28 +82,19 @@ public void testCacheEntryEventUnwrap() { } @Test - public void testCacheVisibilityPostUnwrap() { + public void testCacheMutationViaUnwrap() { + org.ehcache.CacheManager ehcacheManager = cacheManager.unwrap(org.ehcache.CacheManager.class); + org.ehcache.Cache cache = ehcacheManager.createCache("jcache", newCacheConfigurationBuilder(Integer.class, String.class, heap(5))); - CacheManager javaxCacheManager = Caching.getCachingProvider().getCacheManager(); - - org.ehcache.CacheManager cacheManager = javaxCacheManager.unwrap(org.ehcache.CacheManager.class); - CacheConfigurationBuilder cacheConfigurationBuilder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, heap(5)); - cacheManager.createCache("jcache", cacheConfigurationBuilder); - - Cache javaxCache = javaxCacheManager.getCache("jcache", Integer.class, String.class); + Cache javaxCache = cacheManager.getCache("jcache", Integer.class, String.class); assertThat(javaxCache, is(notNullValue())); - CacheManager javaxCacheManager1 = javaxCacheManager.unwrap(javax.cache.CacheManager.class); - Cache javaxCache1 = javaxCacheManager1.getCache("jcache", Integer.class, String.class); - assertThat(javaxCache1, is(notNullValue())); - - org.ehcache.Cache cache = cacheManager.getCache("jcache", Integer.class, String.class); - assertThat(cache, is(notNullValue())); + cache.put(1, "one"); - cache.put(1,"one"); assertThat(javaxCache.get(1), is("one")); - assertThat(javaxCache1.get(1), is("one")); + ehcacheManager.removeCache("jcache"); + assertThat(cacheManager.getCache("jcache", Integer.class, String.class), is(nullValue())); } private class EhEvent implements CacheEvent {