1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.spi.config.cache.guava;
17
18 import java.util.HashSet;
19 import java.util.Iterator;
20 import java.util.Map.Entry;
21 import java.util.Set;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.TimeUnit;
24 import java.util.concurrent.locks.Lock;
25 import java.util.concurrent.locks.ReentrantReadWriteLock;
26 import java.util.logging.Logger;
27
28 import com.google.common.cache.Cache;
29 import com.google.common.cache.CacheBuilder;
30 import com.google.common.cache.CacheLoader;
31 import com.google.common.cache.LoadingCache;
32 import com.google.common.cache.RemovalListener;
33 import com.google.common.cache.RemovalNotification;
34
35 import de.smartics.properties.api.config.domain.Property;
36 import de.smartics.properties.api.config.domain.PropertyCollection;
37 import de.smartics.properties.impl.config.cache.CacheConfigurationPropertiesManagement;
38 import de.smartics.properties.spi.config.cache.infinispan.InfinispanCompoundKeyDelegatingCache;
39 import de.smartics.util.lang.StaticAnalysis;
40
41
42
43
44
45
46 public final class GuavaCacheManager
47 {
48
49
50
51
52
53
54
55 private static final Logger LOGGER = Logger.getLogger(GuavaCacheManager.class
56 .getName());
57
58
59
60
61 public static final String INFINISPAN_DELEGATING_CACHE_CACHE_NAME =
62 "INFINISPAN_DELEGATING_CACHE_CACHE";
63
64
65
66
67
68
69 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
70
71
72
73
74
75
76 private final Lock readLock = lock.readLock();
77
78
79
80
81
82
83 private final Lock writeLock = lock.writeLock();
84
85
86
87
88
89 @SuppressWarnings(StaticAnalysis.RAWTYPES)
90 private final RemovalListener<Object, Object> configurationCacheCacheEntryRemovalListener =
91 new RemovalListener<Object, Object>()
92 {
93 public void onRemoval(final RemovalNotification<Object, Object> removal)
94 {
95 final String key = removal.getKey().toString();
96 LOGGER.fine("REMOVED: Confiurations cache removed cache with key: "
97 + key);
98 final Object value = removal.getValue();
99 if (value instanceof CacheConfigurationPropertiesManagement)
100 {
101 removeFromInfinispanCache((CacheConfigurationPropertiesManagement) value);
102 }
103 }
104
105 private void removeFromInfinispanCache(
106 final CacheConfigurationPropertiesManagement management)
107 {
108 final PropertyCollection collection =
109 management.getPropertyStoreAccessor()
110 .getPropertyCollectionFromStore();
111 final String configurationKeyString = management.getKey().toString();
112 final InfinispanCompoundKeyDelegatingCache ic =
113 fetchInfinispanCompuondKeyDelegatingCache(configurationKeyString);
114
115 for (final Iterator iterator = collection.iterator(); iterator
116 .hasNext();)
117 {
118 final Property property = (Property) iterator.next();
119 final String propertyKey = property.getName();
120 ic.remove(propertyKey);
121 LOGGER.finest("REMOVED from infinispan cache: key:" + propertyKey);
122 }
123 }
124
125 @SuppressWarnings("unchecked")
126 private InfinispanCompoundKeyDelegatingCache fetchInfinispanCompuondKeyDelegatingCache(
127 final String configurationKeyString)
128 {
129 final de.smartics.properties.spi.config.cache.Cache infinispanDelegatingCache =
130 getInfinispanDelegatingCache();
131 final InfinispanCompoundKeyDelegatingCache ic =
132 (InfinispanCompoundKeyDelegatingCache) infinispanDelegatingCache
133 .get(configurationKeyString);
134 return ic;
135 }
136 };
137
138
139
140
141
142
143 @SuppressWarnings(StaticAnalysis.RAWTYPES)
144 private final RemovalListener<Object, Cache> infinispanCacheCacheEntryRemovalListener =
145 new RemovalListener<Object, Cache>()
146 {
147 public void onRemoval(final RemovalNotification<Object, Cache> removal)
148 {
149 final String key = removal.getKey().toString();
150 LOGGER.fine("REMOVED: Infinispan cache removed cache with key: "
151 + key);
152 }
153 };
154
155
156
157
158 @SuppressWarnings(StaticAnalysis.RAWTYPES)
159 private final RemovalListener<Object, Cache> mainCacheCacheEntryRemovalListener =
160 new RemovalListener<Object, Cache>()
161 {
162 public void onRemoval(final RemovalNotification<Object, Cache> removal)
163 {
164 final Object key = removal.getKey().toString();
165 LOGGER.fine("REMOVED: Main cache removed cache with key: " + key);
166 }
167 };
168
169
170
171
172
173 @SuppressWarnings(StaticAnalysis.RAWTYPES)
174 private final CacheBuilder configurationsCacheCacheBuilder = CacheBuilder
175 .newBuilder().expireAfterWrite(30, TimeUnit.MINUTES)
176 .removalListener(configurationCacheCacheEntryRemovalListener);
177
178
179
180
181
182 @SuppressWarnings(StaticAnalysis.RAWTYPES)
183 private final CacheBuilder infinispanCacheCacheBuilder = CacheBuilder
184 .newBuilder().expireAfterWrite(30, TimeUnit.MINUTES)
185 .removalListener(infinispanCacheCacheEntryRemovalListener);
186
187
188
189
190
191
192 @SuppressWarnings(StaticAnalysis.RAWTYPES)
193 private final CacheBuilder mainCacheBuilder = CacheBuilder.newBuilder()
194 .removalListener(mainCacheCacheEntryRemovalListener);
195
196
197
198
199 @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
200 private final LoadingCache<String, Cache> configurationCacheCache =
201 mainCacheBuilder.build(new CacheLoader<String, Cache>()
202 {
203 public Cache load(final String key)
204 {
205 LOGGER.fine("BUILDING: Building config cache cache for key: " + key);
206 return configurationsCacheCacheBuilder.build();
207 }
208 });
209
210
211
212
213 @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
214 private final LoadingCache<String, Cache> infinispanCacheCache =
215 mainCacheBuilder.build(new CacheLoader<String, Cache>()
216 {
217 public Cache load(final String key)
218 {
219 LOGGER
220 .fine("BUILDING: Building guava (infinispanCacheCache) cache for key: "
221 + key);
222 return infinispanCacheCacheBuilder.build();
223 }
224 });
225
226
227
228
229 @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
230 private final GuavaDelegatingCache guavaBasedInfinispanCacheCache =
231 new GuavaDelegatingCache(infinispanCacheCache);
232
233
234
235
236
237
238
239
240
241
242 public GuavaCacheManager()
243 {
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 public void clearAll()
260 {
261 writeLock.lock();
262 try
263 {
264 internalClearAll(configurationCacheCache);
265 internalClearAll(infinispanCacheCache);
266 }
267 finally
268 {
269 writeLock.unlock();
270 }
271
272 }
273
274 @SuppressWarnings("rawtypes")
275 private void internalClearAll(final LoadingCache<String, Cache> cache)
276 {
277 for (final Entry<String, Cache> entry : cache.asMap().entrySet())
278 {
279 entry.getValue().cleanUp();
280 }
281 cache.cleanUp();
282 }
283
284
285
286
287
288
289 @SuppressWarnings(StaticAnalysis.RAWTYPES)
290 public void clear(final String cacheName)
291 {
292 writeLock.lock();
293 try
294 {
295 final Cache current = findCache(cacheName);
296 if (current != null)
297 {
298 current.cleanUp();
299 }
300 }
301 finally
302 {
303 writeLock.unlock();
304 }
305 }
306
307 @SuppressWarnings("rawtypes")
308 private Cache findCache(final String cacheName)
309 {
310 Cache current = configurationCacheCache.getIfPresent(cacheName);
311 if (current == null)
312 {
313 current = infinispanCacheCache.getIfPresent(cacheName);
314 }
315 return current;
316 }
317
318
319
320
321
322
323 public void discard(final String cacheName)
324 {
325 clear(cacheName);
326 }
327
328
329
330
331 public void stopAll()
332 {
333 clearAll();
334 }
335
336
337
338
339
340
341 public void stop(final String cacheName)
342 {
343 clear(cacheName);
344 }
345
346
347
348
349
350
351
352 @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
353 public de.smartics.properties.spi.config.cache.Cache getConfigurationsCache(
354 final String cacheName)
355 {
356 writeLock.lock();
357 try
358 {
359 LOGGER.finest("GETTING: gCC: " + cacheName);
360 final Cache currentCache = configurationCacheCache.get(cacheName);
361 return new GuavaDelegatingCache(currentCache);
362 }
363 catch (final ExecutionException e)
364 {
365
366 return null;
367 }
368 finally
369 {
370 writeLock.unlock();
371 }
372 }
373
374
375
376
377
378
379 @SuppressWarnings(StaticAnalysis.RAWTYPES)
380 public de.smartics.properties.spi.config.cache.Cache getInfinispanDelegatingCache()
381 {
382 LOGGER.finest("GETTING: idc");
383 return guavaBasedInfinispanCacheCache;
384 }
385
386
387
388
389
390
391 public Set<String> getCacheNames()
392 {
393 readLock.lock();
394 try
395 {
396 final Set<String> cacheNames = new HashSet<String>();
397 cacheNames.addAll(configurationCacheCache.asMap().keySet());
398 cacheNames.addAll(infinispanCacheCache.asMap().keySet());
399 return cacheNames;
400 }
401 finally
402 {
403 readLock.unlock();
404 }
405 }
406
407
408 }