Skip to content

Commit 1cb42e0

Browse files
committed
Fixes #2494 : Move to drive the jcache map from the underlying Ehcache manager directly
1 parent b02f2e7 commit 1cb42e0

3 files changed

Lines changed: 112 additions & 76 deletions

File tree

ehcache-107/src/main/java/org/ehcache/jsr107/Eh107CacheManager.java

Lines changed: 86 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import java.io.IOException;
3636
import java.lang.management.ManagementFactory;
3737
import java.net.URI;
38-
import java.util.ArrayList;
3938
import java.util.Collections;
39+
import java.util.HashSet;
4040
import java.util.Map;
4141
import java.util.Properties;
4242
import java.util.concurrent.ConcurrentHashMap;
@@ -51,6 +51,8 @@
5151
import javax.management.InstanceNotFoundException;
5252
import javax.management.MBeanServer;
5353

54+
import org.ehcache.core.events.CacheManagerListener;
55+
import org.ehcache.core.spi.store.InternalCacheManager;
5456
import static org.ehcache.jsr107.CloseUtil.chain;
5557
import static org.ehcache.jsr107.CloseUtil.closeAll;
5658

@@ -83,37 +85,71 @@ class Eh107CacheManager implements CacheManager {
8385
this.configurationMerger = configurationMerger;
8486
this.statisticsService = jsr107Service.getStatistics();
8587

86-
refreshAllCaches();
88+
((InternalCacheManager) ehCacheManager).registerListener(new CacheManagerListener() {
89+
@Override
90+
public void cacheAdded(String alias, org.ehcache.Cache<?, ?> cache) {
91+
loadCache(alias, cache);
92+
}
93+
94+
@Override
95+
public void cacheRemoved(String alias, org.ehcache.Cache<?, ?> cache) {
96+
Eh107Cache<?, ?> jcache = caches.get(alias);
97+
if (jcache != null) {
98+
close(jcache);
99+
}
100+
}
101+
102+
@Override
103+
public void stateTransition(Status from, Status to) {
104+
}
105+
106+
});
107+
loadAllCaches();
87108
}
88109

89-
private void refreshAllCaches() {
110+
private void loadAllCaches() {
90111
for (Map.Entry<String, CacheConfiguration<?, ?>> entry : ehCacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet()) {
91-
String name = entry.getKey();
92112
CacheConfiguration<?, ?> config = entry.getValue();
113+
InternalCache<?, ?> cache = (InternalCache<?, ?>) ehCacheManager.getCache(entry.getKey(), config.getKeyType(), config.getValueType());
93114

94-
if (!caches.containsKey(name)) {
95-
Eh107Cache<?, ?> wrappedCache = wrapEhcacheCache(name, config);
96-
if (caches.putIfAbsent(name, wrappedCache) == null) {
97-
@SuppressWarnings("unchecked")
98-
Eh107Configuration<?, ?> configuration = wrappedCache.getConfiguration(Eh107Configuration.class);
99-
if (configuration.isManagementEnabled()) {
100-
enableManagement(wrappedCache, true);
101-
}
102-
if (configuration.isStatisticsEnabled()) {
103-
enableStatistics(wrappedCache, true);
104-
}
105-
}
106-
}
115+
loadCache(entry.getKey(), cache);
107116
}
108117

109118
for (Eh107Cache<?, ?> wrappedCache : caches.values()) {
110119
wrappedCache.isClosed();
111120
}
112121
}
113122

114-
private <K, V> Eh107Cache<K, V> wrapEhcacheCache(String alias, CacheConfiguration<K, V> ehConfig) {
115-
org.ehcache.Cache<K, V> cache = ehCacheManager.getCache(alias, ehConfig.getKeyType(), ehConfig.getValueType());
116-
return wrapEhcacheCache(alias, (InternalCache<K, V>)cache);
123+
@SuppressWarnings("unchecked")
124+
private <K, V> Cache<K, V> loadCache(String alias, org.ehcache.Cache<K, V> cache) {
125+
return (Cache<K, V>) caches.computeIfAbsent(alias, name -> {
126+
Eh107Cache<?, ?> wrappedCache = wrapEhcacheCache(name, (InternalCache<K, V>) cache);
127+
@SuppressWarnings("unchecked")
128+
Eh107Configuration<?, ?> configuration = wrappedCache.getConfiguration(Eh107Configuration.class);
129+
if (configuration.isManagementEnabled()) {
130+
enableManagement(wrappedCache, true);
131+
}
132+
if (configuration.isStatisticsEnabled()) {
133+
enableStatistics(wrappedCache, true);
134+
}
135+
return wrappedCache;
136+
});
137+
}
138+
139+
@SuppressWarnings("unchecked")
140+
private <K, V> Cache<K, V> reloadCache(String alias, Eh107Cache<K, V> jcache) {
141+
return (Cache<K, V>) caches.computeIfPresent(alias, (name, existing) -> {
142+
@SuppressWarnings("unchecked")
143+
Eh107Configuration<?, ?> oldConfiguration = existing.getConfiguration(Eh107Configuration.class);
144+
Eh107Configuration<?, ?> newConfiguration = jcache.getConfiguration(Eh107Configuration.class);
145+
if (oldConfiguration.isManagementEnabled() != newConfiguration.isManagementEnabled()) {
146+
enableManagement(jcache, newConfiguration.isManagementEnabled());
147+
}
148+
if (oldConfiguration.isStatisticsEnabled() != newConfiguration.isStatisticsEnabled()) {
149+
enableStatistics(jcache, newConfiguration.isStatisticsEnabled());
150+
}
151+
return jcache;
152+
});
117153
}
118154

119155
private <K, V> Eh107Cache<K, V> wrapEhcacheCache(String alias, InternalCache<K, V> cache) {
@@ -176,69 +212,44 @@ public <K, V, C extends Configuration<K, V>> Cache<K, V> createCache(String cach
176212
@SuppressWarnings("unchecked")
177213
Eh107Configuration.Eh107ConfigurationWrapper<K, V> configurationWrapper = (Eh107Configuration.Eh107ConfigurationWrapper<K, V>)config;
178214
CacheConfiguration<K, V> unwrap = configurationWrapper.getCacheConfiguration();
179-
final org.ehcache.Cache<K, V> ehcache;
180215
try {
181-
ehcache = ehCacheManager.createCache(cacheName, unwrap);
216+
ehCacheManager.createCache(cacheName, unwrap);
182217
} catch (IllegalArgumentException e) {
183218
throw new CacheException("A Cache named [" + cacheName + "] already exists");
184219
}
185-
Eh107Cache<K, V> cache = wrapEhcacheCache(cacheName, (InternalCache<K, V>)ehcache);
186-
assert safeCacheRetrieval(cacheName) == null;
187-
caches.put(cacheName, cache);
188-
189-
@SuppressWarnings("unchecked")
190-
Eh107Configuration<?, ?> configuration = cache.getConfiguration(Eh107Configuration.class);
191-
if (configuration.isManagementEnabled()) {
192-
enableManagement(cacheName, true);
193-
}
194-
195-
if (configuration.isStatisticsEnabled()) {
196-
enableStatistics(cacheName, true);
197-
}
198-
199-
return cache;
200-
}
201-
202-
ConfigurationMerger.ConfigHolder<K, V> configHolder = configurationMerger.mergeConfigurations(cacheName, config);
203-
204-
final InternalCache<K, V> ehCache;
205-
try {
206-
ehCache = (InternalCache<K, V>)ehCacheManager.createCache(cacheName, configHolder.cacheConfiguration);
207-
} catch (IllegalArgumentException e) {
208-
throw configHolder.cacheResources.closeResourcesAfter(new CacheException("A Cache named [" + cacheName + "] already exists"));
209-
} catch (Throwable t) {
210-
// something went wrong in ehcache land, make sure to clean up our stuff
211-
throw configHolder.cacheResources.closeResourcesAfter(new CacheException(t));
212-
}
213-
214-
Eh107Cache<K, V> cache = null;
215-
CacheResources<K, V> cacheResources = configHolder.cacheResources;
216-
try {
217-
if (configHolder.useEhcacheLoaderWriter) {
218-
cacheResources = new CacheResources<>(cacheName, wrapCacheLoaderWriter(ehCache.getCacheLoaderWriter()),
219-
cacheResources.getExpiryPolicy(), cacheResources.getListenerResources());
220-
}
221-
cache = new Eh107Cache<>(cacheName, new Eh107CompleteConfiguration<>(configHolder.jsr107Configuration, ehCache
222-
.getRuntimeConfiguration()), cacheResources, ehCache, statisticsService, this);
223-
224-
caches.put(cacheName, cache);
225-
226-
if (configHolder.jsr107Configuration.isManagementEnabled()) {
227-
enableManagement(cacheName, true);
228-
}
220+
} else {
221+
ConfigurationMerger.ConfigHolder<K, V> configHolder = configurationMerger.mergeConfigurations(cacheName, config);
229222

230-
if (configHolder.jsr107Configuration.isStatisticsEnabled()) {
231-
enableStatistics(cacheName, true);
223+
final InternalCache<K, V> ehCache;
224+
try {
225+
ehCache = (InternalCache<K, V>)ehCacheManager.createCache(cacheName, configHolder.cacheConfiguration);
226+
} catch (IllegalArgumentException e) {
227+
throw configHolder.cacheResources.closeResourcesAfter(new CacheException("A Cache named [" + cacheName + "] already exists"));
228+
} catch (Throwable t) {
229+
// something went wrong in ehcache land, make sure to clean up our stuff
230+
throw configHolder.cacheResources.closeResourcesAfter(new CacheException(t));
232231
}
233232

234-
return cache;
235-
} catch (Throwable t) {
236-
if (cache != null) {
237-
throw cache.closeInternalAfter(new CacheException(t));
238-
} else {
239-
throw cacheResources.closeResourcesAfter(new CacheException(t));
233+
Eh107Cache<K, V> cache = null;
234+
CacheResources<K, V> cacheResources = configHolder.cacheResources;
235+
try {
236+
if (configHolder.useEhcacheLoaderWriter) {
237+
cacheResources = new CacheResources<>(cacheName, wrapCacheLoaderWriter(ehCache.getCacheLoaderWriter()),
238+
cacheResources.getExpiryPolicy(), cacheResources.getListenerResources());
239+
}
240+
cache = new Eh107Cache<>(cacheName, new Eh107CompleteConfiguration<>(configHolder.jsr107Configuration, ehCache
241+
.getRuntimeConfiguration()), cacheResources, ehCache, statisticsService, this);
242+
243+
return reloadCache(cacheName, cache);
244+
} catch (Throwable t) {
245+
if (cache != null) {
246+
throw cache.closeInternalAfter(new CacheException(t));
247+
} else {
248+
throw cacheResources.closeResourcesAfter(new CacheException(t));
249+
}
240250
}
241251
}
252+
return safeCacheRetrieval(cacheName);
242253
}
243254
}
244255

@@ -307,8 +318,7 @@ private <K, V> Eh107Cache<K, V> safeCacheRetrieval(final String cacheName) {
307318
@Override
308319
public Iterable<String> getCacheNames() {
309320
checkClosed();
310-
refreshAllCaches();
311-
return Collections.unmodifiableList(new ArrayList<>(caches.keySet()));
321+
return Collections.unmodifiableSet(new HashSet<>(ehCacheManager.getRuntimeConfiguration().getCacheConfigurations().keySet()));
312322
}
313323

314324
@Override

ehcache-107/src/test/java/org/ehcache/jsr107/Eh107XmlIntegrationTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import javax.cache.spi.CachingProvider;
4949

5050
import static org.hamcrest.MatcherAssert.assertThat;
51+
import static org.hamcrest.Matchers.containsInAnyOrder;
5152
import static org.hamcrest.Matchers.empty;
5253
import static org.hamcrest.Matchers.equalTo;
5354
import static org.hamcrest.Matchers.hasItem;
@@ -69,6 +70,11 @@ public void setUp() throws Exception {
6970
.toURI(), cachingProvider.getDefaultClassLoader());
7071
}
7172

73+
@Test
74+
public void testImmediateCacheNames() {
75+
assertThat(cacheManager.getCacheNames(), containsInAnyOrder("customerCache", "productCache"));
76+
}
77+
7278
@Test
7379
public void test107CacheCanReturnCompleteConfigurationWhenNonePassedIn() {
7480
CacheManager cacheManager = cachingProvider.getCacheManager();

ehcache-107/src/test/java/org/ehcache/jsr107/UnwrapTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@
2929
import javax.cache.event.EventType;
3030
import javax.cache.spi.CachingProvider;
3131

32+
import static org.ehcache.config.builders.CacheConfigurationBuilder.newCacheConfigurationBuilder;
33+
import static org.ehcache.config.builders.ResourcePoolsBuilder.heap;
3234
import static org.hamcrest.MatcherAssert.assertThat;
3335
import static org.hamcrest.Matchers.instanceOf;
3436
import static org.hamcrest.Matchers.is;
37+
import static org.hamcrest.Matchers.notNullValue;
38+
import static org.hamcrest.Matchers.nullValue;
3539

3640
/**
3741
* @author rism
@@ -78,6 +82,22 @@ public void testCacheEntryEventUnwrap() {
7882
assertThat(cacheEntryEvent.unwrap(cacheEntryEvent.getClass()), is(instanceOf(Eh107CacheEntryEvent.NormalEvent.class)));
7983
}
8084

85+
@Test
86+
public void testCacheMutationViaUnwrap() {
87+
org.ehcache.CacheManager ehcacheManager = cacheManager.unwrap(org.ehcache.CacheManager.class);
88+
org.ehcache.Cache<Integer, String> cache = ehcacheManager.createCache("jcache", newCacheConfigurationBuilder(Integer.class, String.class, heap(5)));
89+
90+
Cache<Integer, String> javaxCache = cacheManager.getCache("jcache", Integer.class, String.class);
91+
assertThat(javaxCache, is(notNullValue()));
92+
93+
cache.put(1, "one");
94+
95+
assertThat(javaxCache.get(1), is("one"));
96+
97+
ehcacheManager.removeCache("jcache");
98+
assertThat(cacheManager.getCache("jcache", Integer.class, String.class), is(nullValue()));
99+
}
100+
81101
private class EhEvent implements CacheEvent<String,String> {
82102
@Override
83103
public org.ehcache.event.EventType getType() {

0 commit comments

Comments
 (0)