+\r
+ @Test\r
+ public void clusterContainerAndGlobalTest() throws CacheExistException, CacheConfigException,\r
+ CacheListenerAddException, InterruptedException {\r
+ String cache1 = "Cache1";\r
+ String cache2 = "Cache2";\r
+ // Lets test the case of caches with same name in different\r
+ // containers (actually global an container case)\r
+ String cache3 = "Cache2";\r
+\r
+ HashSet<cacheMode> cacheModeSet = new HashSet<cacheMode>();\r
+ cacheModeSet.add(cacheMode.NON_TRANSACTIONAL);\r
+ ConcurrentMap cm11 = this.clusterDefaultServices.createCache(cache1, cacheModeSet);\r
+ assertNotNull(cm11);\r
+\r
+ assertTrue(this.clusterDefaultServices.existCache(cache1));\r
+ assertEquals(cm11, this.clusterDefaultServices.getCache(cache1));\r
+\r
+ ConcurrentMap cm12 = this.clusterDefaultServices.createCache(cache2, cacheModeSet);\r
+ ConcurrentMap cm23 = this.clusterGlobalServices.createCache(cache3, cacheModeSet);\r
+\r
+ // Now given cahe2 and cache3 have same name lets make sure\r
+ // they don't return the same reference\r
+ assertNotNull(this.clusterGlobalServices.getCache(cache2));\r
+ // cm12 reference must be different than cm23\r
+ assertTrue(cm12 != cm23);\r
+\r
+ HashSet<String> cacheList = (HashSet<String>) this.clusterDefaultServices\r
+ .getCacheList();\r
+ assertEquals(2, cacheList.size());\r
+ assertTrue(cacheList.contains(cache1));\r
+ assertTrue(cacheList.contains(cache2));\r
+\r
+ assertNotNull(this.clusterDefaultServices.getCacheProperties(cache1));\r
+\r
+ {\r
+ /***********************************/\r
+ /* Testing cacheAware in Container */\r
+ /***********************************/\r
+ Dictionary<String, Object> props = new Hashtable<String, Object>();\r
+ Set<String> propSet = new HashSet<String>();\r
+ propSet.add(cache1);\r
+ propSet.add(cache2);\r
+ props.put("cachenames", propSet);\r
+ CacheAware listener = new CacheAware();\r
+ CacheAware listenerRepeated = new CacheAware();\r
+ ServiceRegistration updateServiceReg = ServiceHelper.registerServiceWReg(ICacheUpdateAware.class, "default",\r
+ listener, props);\r
+ assertNotNull(updateServiceReg);\r
+\r
+ // Register another service for the same caches, this\r
+ // should not get any update because we don't allow to\r
+ // override the existing unless before unregistered\r
+ ServiceRegistration updateServiceRegRepeated = ServiceHelper.registerServiceWReg(ICacheUpdateAware.class,\r
+ "default",\r
+ listenerRepeated, props);\r
+ assertNotNull(updateServiceRegRepeated);\r
+ CountDownLatch res = null;\r
+ List<Update> ups = null;\r
+ Update up = null;\r
+ Integer k1 = new Integer(10);\r
+ Long k2 = new Long(100L);\r
+\r
+ /***********************/\r
+ /* CREATE NEW KEY CASE */\r
+ /***********************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(2);\r
+ // modify the cache\r
+ cm11.put(k1, "foo");\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 2);\r
+ // Validate that first we get an update (yes even in case of a\r
+ // new value added)\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertTrue(up.value.equals("foo"));\r
+ assertTrue(up.cacheName.equals(cache1));\r
+ // Validate that we then get a create\r
+ up = ups.get(1);\r
+ assertTrue(up.t.equals(UpdateType.ADDED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertNull(up.value);\r
+ assertTrue(up.cacheName.equals(cache1));\r
+\r
+ /*******************************/\r
+ /* UPDATE AN EXISTING KEY CASE */\r
+ /*******************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm11.put(k1, "baz");\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get an update with expect fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertTrue(up.value.equals("baz"));\r
+ assertTrue(up.cacheName.equals(cache1));\r
+\r
+ /**********************************/\r
+ /* RE-UPDATE AN EXISTING KEY CASE */\r
+ /**********************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm11.put(k1, "baz");\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get an update with expect fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertTrue(up.value.equals("baz"));\r
+ assertTrue(up.cacheName.equals(cache1));\r
+\r
+ /********************************/\r
+ /* REMOVAL OF EXISTING KEY CASE */\r
+ /********************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm11.remove(k1);\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get a delete with expected fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.REMOVED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertNull(up.value);\r
+ assertTrue(up.cacheName.equals(cache1));\r
+\r
+ /***********************/\r
+ /* CREATE NEW KEY CASE */\r
+ /***********************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(2);\r
+ // modify the cache\r
+ cm12.put(k2, new Short((short)15));\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 2);\r
+ // Validate that first we get an update (yes even in case of a\r
+ // new value added)\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k2));\r
+ assertTrue(up.value.equals(new Short((short)15)));\r
+ assertTrue(up.cacheName.equals(cache2));\r
+ // Validate that we then get a create\r
+ up = ups.get(1);\r
+ assertTrue(up.t.equals(UpdateType.ADDED));\r
+ assertTrue(up.key.equals(k2));\r
+ assertNull(up.value);\r
+ assertTrue(up.cacheName.equals(cache2));\r
+\r
+ /*******************************/\r
+ /* UPDATE AN EXISTING KEY CASE */\r
+ /*******************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm12.put(k2, "BAZ");\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get an update with expect fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k2));\r
+ assertTrue(up.value.equals("BAZ"));\r
+ assertTrue(up.cacheName.equals(cache2));\r
+\r
+ /********************************/\r
+ /* REMOVAL OF EXISTING KEY CASE */\r
+ /********************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm12.remove(k2);\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get a delete with expected fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.REMOVED));\r
+ assertTrue(up.key.equals(k2));\r
+ assertNull(up.value);\r
+ assertTrue(up.cacheName.equals(cache2));\r
+\r
+ /******************************************************************/\r
+ /* NOW LETS REMOVE THE REGISTRATION AND MAKE SURE NO UPDATS COMES */\r
+ /******************************************************************/\r
+ updateServiceReg.unregister();\r
+ // Start monitoring the updates, noone should come in\r
+ res = listener.restart(1);\r
+\r
+ /***********************/\r
+ /* CREATE NEW KEY CASE */\r
+ /***********************/\r
+ // modify the cache\r
+ cm11.put(k1, "foo");\r
+\r
+ /*******************************/\r
+ /* UPDATE AN EXISTING KEY CASE */\r
+ /*******************************/\r
+ // modify the cache\r
+ cm11.put(k1, "baz");\r
+\r
+ /********************************/\r
+ /* REMOVAL OF EXISTING KEY CASE */\r
+ /********************************/\r
+ // modify the cache\r
+ cm11.remove(k1);\r
+\r
+ /***********************/\r
+ /* CREATE NEW KEY CASE */\r
+ /***********************/\r
+ // modify the cache\r
+ cm12.put(k2, new Short((short)15));\r
+\r
+ /*******************************/\r
+ /* UPDATE AN EXISTING KEY CASE */\r
+ /*******************************/\r
+ // modify the cache\r
+ cm12.put(k2, "BAZ");\r
+\r
+ /********************************/\r
+ /* REMOVAL OF EXISTING KEY CASE */\r
+ /********************************/\r
+ // modify the cache\r
+ cm12.remove(k2);\r
+\r
+\r
+ // Wait to make sure no updates came in, clearly this is\r
+ // error prone as logic, but cannot find a better way than\r
+ // this to make sure updates didn't get in\r
+ res.await(1L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 0);\r
+ }\r
+\r
+ {\r
+ /***********************************/\r
+ /* Testing cacheAware in Global */\r
+ /***********************************/\r
+ Dictionary<String, Object> props = new Hashtable<String, Object>();\r
+ Set<String> propSet = new HashSet<String>();\r
+ propSet.add(cache3);\r
+ props.put("cachenames", propSet);\r
+ CacheAware listener = new CacheAware();\r
+ ServiceRegistration updateServiceReg = ServiceHelper.registerGlobalServiceWReg(ICacheUpdateAware.class,\r
+ listener, props);\r
+ assertNotNull(updateServiceReg);\r
+\r
+ CountDownLatch res = null;\r
+ List<Update> ups = null;\r
+ Update up = null;\r
+ Integer k1 = new Integer(10);\r
+\r
+ /***********************/\r
+ /* CREATE NEW KEY CASE */\r
+ /***********************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(2);\r
+ // modify the cache\r
+ cm23.put(k1, "foo");\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 2);\r
+ // Validate that first we get an update (yes even in case of a\r
+ // new value added)\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertTrue(up.value.equals("foo"));\r
+ assertTrue(up.cacheName.equals(cache3));\r
+ // Validate that we then get a create\r
+ up = ups.get(1);\r
+ assertTrue(up.t.equals(UpdateType.ADDED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertNull(up.value);\r
+ assertTrue(up.cacheName.equals(cache3));\r
+\r
+ /*******************************/\r
+ /* UPDATE AN EXISTING KEY CASE */\r
+ /*******************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm23.put(k1, "baz");\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get an update with expect fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.CHANGED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertTrue(up.value.equals("baz"));\r
+ assertTrue(up.cacheName.equals(cache3));\r
+\r
+ /********************************/\r
+ /* REMOVAL OF EXISTING KEY CASE */\r
+ /********************************/\r
+ // Start monitoring the updates\r
+ res = listener.restart(1);\r
+ // modify the cache\r
+ cm23.remove(k1);\r
+ // Wait\r
+ res.await(100L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 1);\r
+ // Validate we get a delete with expected fields\r
+ up = ups.get(0);\r
+ assertTrue(up.t.equals(UpdateType.REMOVED));\r
+ assertTrue(up.key.equals(k1));\r
+ assertNull(up.value);\r
+ assertTrue(up.cacheName.equals(cache3));\r
+\r
+ /******************************************************************/\r
+ /* NOW LETS REMOVE THE REGISTRATION AND MAKE SURE NO UPDATS COMES */\r
+ /******************************************************************/\r
+ updateServiceReg.unregister();\r
+ // Start monitoring the updates, noone should come in\r
+ res = listener.restart(1);\r
+\r
+ /***********************/\r
+ /* CREATE NEW KEY CASE */\r
+ /***********************/\r
+ // modify the cache\r
+ cm23.put(k1, "foo");\r
+\r
+ /*******************************/\r
+ /* UPDATE AN EXISTING KEY CASE */\r
+ /*******************************/\r
+ // modify the cache\r
+ cm23.put(k1, "baz");\r
+\r
+ /********************************/\r
+ /* REMOVAL OF EXISTING KEY CASE */\r
+ /********************************/\r
+ // modify the cache\r
+ cm23.remove(k1);\r
+\r
+ // Wait to make sure no updates came in, clearly this is\r
+ // error prone as logic, but cannot find a better way than\r
+ // this to make sure updates didn't get in\r
+ res.await(1L, TimeUnit.SECONDS);\r
+ // Analyze the updates\r
+ ups = listener.getUpdates();\r
+ assertTrue(ups.size() == 0);\r
+ }\r
+\r
+ InetAddress addr = this.clusterDefaultServices.getMyAddress();\r
+ assertNotNull(addr);\r
+\r
+ List<InetAddress> addrList = this.clusterDefaultServices\r
+ .getClusteredControllers();\r
+\r
+ this.clusterDefaultServices.destroyCache(cache1);\r
+ assertFalse(this.clusterDefaultServices.existCache(cache1));\r
+ }\r
+\r
+ private class Update {\r
+ Object key;\r
+ Object value;\r
+ String cacheName;\r
+ UpdateType t;\r
+\r
+ Update (UpdateType t, Object key, Object value, String cacheName) {\r
+ this.t = t;\r
+ this.key = key;\r
+ this.value = value;\r
+ this.cacheName = cacheName;\r
+ }\r
+ }\r
+\r
+ private class CacheAware implements ICacheUpdateAware {\r
+ private CopyOnWriteArrayList<Update> gotUpdates;\r
+ private CountDownLatch latch = null;\r
+\r
+ CacheAware() {\r
+ this.gotUpdates = new CopyOnWriteArrayList<Update>();\r
+ }\r
+\r
+\r
+ /**\r
+ * Restart the monitor of the updates on the CacheAware object\r
+ *\r
+ * @param expectedOperations Number of expected updates\r
+ *\r
+ * @return a countdown latch which will be used to wait till the updates are done\r
+ */\r
+ CountDownLatch restart(int expectedOperations) {\r
+ this.gotUpdates.clear();\r
+ this.latch = new CountDownLatch(expectedOperations);\r
+ return this.latch;\r
+ }\r
+\r
+ List<Update> getUpdates() {\r
+ return this.gotUpdates;\r
+ }\r
+\r
+ @Override\r
+ public void entryCreated(Object key, String cacheName, boolean originLocal) {\r
+ log.debug("CACHE[{}] Got an entry created for key:{}", cacheName, key);\r
+ Update u = new Update(UpdateType.ADDED, key, null, cacheName);\r
+ this.gotUpdates.add(u);\r
+ this.latch.countDown();\r
+ }\r
+\r
+ @Override\r
+ public void entryUpdated(Object key, Object newValue, String cacheName, boolean originLocal) {\r
+ log.debug("CACHE[{}] Got an entry updated for key:{} newValue:{}", cacheName, key, newValue);\r
+ Update u = new Update(UpdateType.CHANGED, key, newValue, cacheName);\r
+ this.gotUpdates.add(u);\r
+ this.latch.countDown();\r
+ }\r
+\r
+ @Override\r
+ public void entryDeleted(Object key, String cacheName, boolean originLocal) {\r
+ log.debug("CACHE[{}] Got an entry delete for key:{}", cacheName, key);\r
+ Update u = new Update(UpdateType.REMOVED, key, null, cacheName);\r
+ this.gotUpdates.add(u);\r
+ this.latch.countDown();\r
+ }\r
+ }\r