View Javadoc

1   /*
2    * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.spi.config.cache.infinispan;
17  
18  import java.util.HashSet;
19  import java.util.Set;
20  import java.util.concurrent.locks.Lock;
21  import java.util.concurrent.locks.ReentrantReadWriteLock;
22  
23  import org.infinispan.configuration.cache.Configuration;
24  import org.infinispan.manager.EmbeddedCacheManager;
25  
26  import de.smartics.properties.spi.config.cache.Cache;
27  import de.smartics.properties.spi.config.cache.CacheManager;
28  import de.smartics.properties.spi.config.cache.UnawareCache;
29  import de.smartics.properties.spi.config.cache.guava.GuavaCacheManager;
30  import de.smartics.util.lang.StaticAnalysis;
31  
32  /**
33   * The base implementation to connect to Infinispan caches.
34   */
35  public abstract class AbstractInfinispanCompoundKeyCacheManager implements
36      CacheManager
37  { // NOPMD
38    // ********************************* Fields *********************************
39  
40    // --- constants ------------------------------------------------------------
41  
42    /**
43     * The name for the cache.
44     */
45    private static final String CACHE_NAME = "smartics-properties-cache";
46  
47    // --- members --------------------------------------------------------------
48  
49    /**
50     * The lock for synchronized access.
51     *
52     * @serial
53     */
54    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
55  
56    /**
57     * The read lock for synchronized access.
58     *
59     * @serial
60     */
61    private final Lock readLock = lock.readLock();
62  
63    /**
64     * The write lock for synchronized access.
65     *
66     * @serial
67     */
68    private final Lock writeLock = lock.writeLock();
69  
70    /**
71     * The infinispan cache manager for property keys.
72     */
73    @SuppressWarnings("unused")
74    private final EmbeddedCacheManager manager; // NOPMD
75  
76    /**
77     * The in memory cache manager for configurations / management.
78     */
79    private final GuavaCacheManager configManager;
80  
81    /**
82     * The underlaying cache.
83     */
84    private final org.infinispan.Cache<Object, Object> cache;
85  
86    // ****************************** Initializer *******************************
87  
88    // ****************************** Constructors ******************************
89  
90    /**
91     * Default constructor.
92     *
93     * @param manager the Infinispan cache manager.
94     */
95    public AbstractInfinispanCompoundKeyCacheManager(
96        final EmbeddedCacheManager manager)
97    {
98      this.manager = manager;
99      configManager = new GuavaCacheManager();
100 
101     manager.getDefaultCacheConfiguration().jmxStatistics();
102 
103     this.cache = manager.getCache(CACHE_NAME);
104     if (!manager.isRunning(CACHE_NAME))
105     {
106       final Configuration cacheConfig = this.cache.getCacheConfiguration();
107       cacheConfig.jmxStatistics();
108       cacheConfig.indexing().indexLocalOnly();
109       cache.start();
110     }
111     // cache.addListener(new CompoundKeyHandlingCacheListener());
112     cache.clear();
113   }
114 
115   // ****************************** Inner Classes *****************************
116 
117   // ********************************* Methods ********************************
118 
119   // --- init -----------------------------------------------------------------
120 
121   // --- get&set --------------------------------------------------------------
122 
123   // --- business -------------------------------------------------------------
124 
125   /**
126    * Removes all keys from all caches.
127    */
128   @Override
129   public final void clearAll()
130   {
131     writeLock.lock();
132     try
133     {
134       internalClearAll();
135     }
136     finally
137     {
138       writeLock.unlock();
139     }
140   }
141 
142   /**
143    * Clears the cache with the given name.
144    *
145    * @param cacheName the name of the cache to be cleared.
146    */
147   @Override
148   public final void clear(final String cacheName)
149   {
150     writeLock.lock();
151     try
152     {
153       internalClear(cacheName);
154     }
155     finally
156     {
157       writeLock.unlock();
158     }
159   }
160 
161   /**
162    * Clears and stops the cache.
163    *
164    * @param cacheName the name of the cache to be cleared and stopped.
165    */
166   @Override
167   public final void discard(final String cacheName)
168   {
169     writeLock.lock();
170     try
171     {
172       if (isManagementCache(cacheName))
173       {
174         configManager.discard(cacheName);
175       }
176       internalClear(cacheName);
177       internalStop(cacheName);
178     }
179     finally
180     {
181       writeLock.unlock();
182     }
183 
184   }
185 
186   /**
187    * Stops all caches, rendering the manager in a stopped state.
188    */
189   @Override
190   public final void stopAll()
191   {
192     writeLock.lock();
193     try
194     {
195       internalStopAll();
196     }
197     finally
198     {
199       writeLock.unlock();
200     }
201   }
202 
203   /**
204    * Stops the cache with the given name.
205    *
206    * @param cacheName the name of the cache to stop.
207    */
208   @Override
209   public final void stop(final String cacheName)
210   {
211     writeLock.lock();
212     try
213     {
214       internalStop(cacheName);
215     }
216     finally
217     {
218       writeLock.unlock();
219     }
220   }
221 
222   /**
223    * Returns the properties cache with the given name. The cache is already
224    * started.
225    *
226    * @param cacheName the name of the cache to fetch.
227    * @return the requested cache already started.
228    */
229   @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
230   public final UnawareCache getPropertiesCache(final String cacheName)
231   {
232     writeLock.lock();
233     try
234     {
235       final UnawareCache propertiesCache =
236           internalGetPropertiesCache(cacheName);
237       return propertiesCache;
238     }
239     finally
240     {
241       writeLock.unlock();
242     }
243   }
244 
245   /**
246    * Returns the configurations cache with the given name. The cache is already
247    * started.
248    *
249    * @param cacheName the name of the cache to fetch.
250    * @return the requested cache already started.
251    */
252   @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
253   public final Cache getConfigurationsCache(final String cacheName)
254   {
255     writeLock.lock();
256     try
257     {
258       return configManager.getConfigurationsCache(cacheName);
259     }
260     finally
261     {
262       writeLock.unlock();
263     }
264   }
265 
266   /**
267    * Returns the set of cache names.
268    *
269    * @return the set of cache names.
270    */
271   @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
272   @Override
273   public final Set<String> getCacheNames()
274   {
275     readLock.lock();
276     try
277     {
278       final Cache infinispanDelegatingCacheCache =
279           configManager.getInfinispanDelegatingCache();
280       final Set<String> cacheNames = infinispanDelegatingCacheCache.keySet();
281 
282       final HashSet allCacheNames = new HashSet<String>();
283       if (cacheNames != null)
284       {
285         allCacheNames.addAll(cacheNames);
286       }
287       final Set inMemoryCacheNames = configManager.getCacheNames();
288       if (inMemoryCacheNames != null)
289       {
290         allCacheNames.addAll(inMemoryCacheNames);
291       }
292       return allCacheNames;
293     }
294     finally
295     {
296       readLock.unlock();
297     }
298   }
299 
300   // --- private -------------------------------------------------------------
301 
302   /**
303    * Removes all keys from all caches.
304    */
305   private void internalClearAll()
306   {
307     configManager.clearAll();
308     cache.clear();
309   }
310 
311   /**
312    * Clears the cache with the given name.
313    *
314    * @param cacheName the name of the cache to be cleared.
315    */
316   private void internalClear(final String cacheName)
317   {
318     if (isManagementCache(cacheName))
319     {
320       configManager.clear(cacheName);
321     }
322     else if (isInfinispanDelegatingCache(cacheName))
323     {
324       internalClearAll();
325     }
326     else
327     {
328       // TODO TK clear only the properties for this cache
329       cache.clear();
330     }
331   }
332 
333   private boolean isInfinispanDelegatingCache(final String cacheName)
334   {
335     return GuavaCacheManager.INFINISPAN_DELEGATING_CACHE_CACHE_NAME
336         .equals(cacheName);
337   }
338 
339   private boolean isManagementCache(final String cacheName)
340   {
341     return cacheName.startsWith("Management");
342   }
343 
344   /**
345    * Stops all caches, rendering the manager in a stopped state.
346    */
347   private void internalStopAll()
348   {
349     configManager.stopAll();
350     cache.stop();
351   }
352 
353   /**
354    * Stops the cache with the given name.
355    *
356    * @param cacheName the name of the cache to stop.
357    */
358   private void internalStop(final String cacheName)
359   {
360     if (isManagementCache(cacheName))
361     {
362       configManager.stop(cacheName);
363     }
364   }
365 
366   /**
367    * Returns the properties cache with the given name. The cache is already
368    * started.
369    *
370    * @param cacheName the name of the cache to fetch.
371    * @return the requested cache already started.
372    */
373   @SuppressWarnings({ StaticAnalysis.RAWTYPES, StaticAnalysis.UNCHECKED })
374   private UnawareCache<?, ?> internalGetPropertiesCache(final String cacheName)
375   {
376     final Cache infinispanCacheCache =
377         configManager.getInfinispanDelegatingCache();
378     InfinispanCompoundKeyDelegatingCache infinispanCache =
379         (InfinispanCompoundKeyDelegatingCache) infinispanCacheCache
380             .get(cacheName);
381 
382     if (infinispanCache == null)
383     {
384       infinispanCache =
385           new InfinispanCompoundKeyDelegatingCache(cacheName, this.cache);
386       infinispanCacheCache.put(cacheName, infinispanCache);
387     }
388     return infinispanCache;
389   }
390 
391   // --- object basics --------------------------------------------------------
392 
393 }