1 7 package org.jboss.cache.loader; 8 9 import org.apache.commons.logging.Log; 10 import org.apache.commons.logging.LogFactory; 11 import org.jboss.cache.CacheImpl; 12 import org.jboss.cache.CacheSPI; 13 import org.jboss.cache.Fqn; 14 import org.jboss.cache.config.CacheLoaderConfig; 15 import org.jboss.cache.config.Configuration; 16 import org.jboss.cache.factories.XmlConfigurationParser; 17 import org.jboss.cache.xml.XmlHelper; 18 import org.w3c.dom.Element ; 19 20 25 public class SingletonStoreCacheLoaderTest extends AbstractCacheLoaderTestBase 26 { 27 private CacheSPI cache1, cache2, cache3; 28 private static final Log log = LogFactory.getLog(SingletonStoreCacheLoaderTest.class); 29 30 protected void setUp() throws Exception 31 { 32 log.info("*** test:" + getName() + " ***"); 33 34 cache1 = new CacheImpl(); 35 cache2 = new CacheImpl(); 36 cache3 = new CacheImpl(); 37 38 cache1.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC); 39 cache2.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC); 40 cache3.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC); 41 } 42 43 public void testPutCacheLoaderWithNoPush() throws Exception 44 { 45 initSingletonNonPushCache(cache1); 46 initSingletonNonPushCache(cache2); 47 initSingletonNonPushCache(cache3); 48 49 createCaches(); 50 statCaches(); 51 52 cache1.put(fqn("/test1"), "key", "value"); 53 cache2.put(fqn("/test2"), "key", "value"); 54 cache3.put(fqn("/test3"), "key", "value"); 55 56 CacheLoader cl1 = getDelegatingCacheLoader(cache1); 57 CacheLoader cl2 = getDelegatingCacheLoader(cache2); 58 CacheLoader cl3 = getDelegatingCacheLoader(cache3); 59 60 assertTrue("/test1 should have been entered in cl1", cl1.exists(fqn("/test1"))); 61 assertTrue("/test2 should have been entered in cl1", cl1.exists(fqn("/test2"))); 62 assertTrue("/test3 should have been entered in cl1", cl1.exists(fqn("/test3"))); 63 64 assertFalse("/test1 should not be in cl2", cl2.exists(fqn("/test1"))); 65 assertFalse("/test2 should not be in cl2", cl2.exists(fqn("/test2"))); 66 assertFalse("/test3 should not be in cl2", cl2.exists(fqn("/test3"))); 67 68 assertFalse("/test1 should not be in cl3", cl3.exists(fqn("/test1"))); 69 assertFalse("/test2 should not be in cl3", cl3.exists(fqn("/test2"))); 70 assertFalse("/test3 should not be in cl3", cl3.exists(fqn("/test3"))); 71 72 stopCache1(); 73 74 cache2.put(fqn("/test4"), "key", "value"); 75 cache3.put(fqn("/test5"), "key", "value"); 76 77 assertTrue("/test4 should have been entered in cl2", cl2.exists(fqn("/test4"))); 78 assertTrue("/test5 should have been entered in cl2", cl2.exists(fqn("/test5"))); 79 80 assertFalse("/test4 should not be in cl3", cl3.exists(fqn("/test4"))); 81 assertFalse("/test5 should not be in cl3", cl3.exists(fqn("/test5"))); 82 83 stopCache2(); 84 85 cache3.put(fqn("/test6"), "key", "value"); 86 assertTrue("/test5 should have been entered in cl3", cl3.exists(Fqn.fromString("/test6"))); 87 } 88 89 public void testPutCacheLoaderWithPush() throws Exception 90 { 91 initSingletonWithPushCache(cache1); 92 initSingletonWithPushCache(cache2); 93 initSingletonWithPushCache(cache3); 94 95 createCaches(); 96 statCaches(); 97 98 cache1.put(fqn("/a"), "a-key", "a-value"); 99 cache1.put(fqn("/a"), "aa-key", "aa-value"); 100 cache1.put(fqn("/a/b"), "b-key", "b-value"); 101 cache1.put(fqn("/a/b"), "bb-key", "bb-value"); 102 cache1.put(fqn("/a/b/c"), "c-key", "c-value"); 103 cache1.put(fqn("/a/b/d"), "d-key", "d-value"); 104 cache1.put(fqn("/e"), "e-key", "e-value"); 105 cache1.put(fqn("/e/f/g"), "g-key", "g-value"); 106 107 CacheLoader cl1 = getDelegatingCacheLoader(cache1); 108 CacheLoader cl2 = getDelegatingCacheLoader(cache2); 109 CacheLoader cl3 = getDelegatingCacheLoader(cache3); 110 111 assertTrue(cl1.get(fqn("/a")).containsKey("a-key")); 112 assertTrue(cl1.get(fqn("/a")).containsKey("aa-key")); 113 assertTrue(cl1.get(fqn("/a/b")).containsKey("b-key")); 114 assertTrue(cl1.get(fqn("/a/b")).containsKey("bb-key")); 115 assertTrue(cl1.get(fqn("/a/b/c")).containsKey("c-key")); 116 assertTrue(cl1.get(fqn("/a/b/d")).containsKey("d-key")); 117 assertTrue(cl1.get(fqn("/e")).containsKey("e-key")); 118 assertTrue(cl1.get(fqn("/e/f/g")).containsKey("g-key")); 119 120 assertFalse(cl2.exists(fqn("/a"))); 121 assertFalse(cl2.exists(fqn("/a"))); 122 assertFalse(cl2.exists(fqn("/a/b"))); 123 assertFalse(cl2.exists(fqn("/a/b"))); 124 assertFalse(cl2.exists(fqn("/a/b/c"))); 125 assertFalse(cl2.exists(fqn("/a/b/d"))); 126 assertFalse(cl2.exists(fqn("/e"))); 127 assertFalse(cl2.exists(fqn("/e/f/g"))); 128 129 assertFalse(cl3.exists(fqn("/a"))); 130 assertFalse(cl3.exists(fqn("/a"))); 131 assertFalse(cl3.exists(fqn("/a/b"))); 132 assertFalse(cl3.exists(fqn("/a/b"))); 133 assertFalse(cl3.exists(fqn("/a/b/c"))); 134 assertFalse(cl3.exists(fqn("/a/b/d"))); 135 assertFalse(cl3.exists(fqn("/e"))); 136 assertFalse(cl3.exists(fqn("/e/f/g"))); 137 138 stopCache1(); 139 Thread.sleep(1000); 140 141 SingletonStoreCacheLoader scl2 = (SingletonStoreCacheLoader) cache2.getCacheLoaderManager().getCacheLoader(); 142 joinPushThread(scl2.getPushStateThread()); 143 144 assertTrue(cl2.get(fqn("/a")).containsKey("a-key")); 145 assertTrue(cl2.get(fqn("/a")).containsKey("aa-key")); 146 assertTrue(cl2.get(fqn("/a/b")).containsKey("b-key")); 147 assertTrue(cl2.get(fqn("/a/b")).containsKey("bb-key")); 148 assertTrue(cl2.get(fqn("/a/b/c")).containsKey("c-key")); 149 assertTrue(cl2.get(fqn("/a/b/d")).containsKey("d-key")); 150 assertTrue(cl2.get(fqn("/e")).containsKey("e-key")); 151 assertTrue(cl2.get(fqn("/e/f/g")).containsKey("g-key")); 152 153 cache2.put(fqn("/e/f/h"), "h-key", "h-value"); 154 cache3.put(fqn("/i"), "i-key", "i-value"); 155 156 assertTrue(cl2.get(fqn("/e/f/h")).containsKey("h-key")); 157 assertTrue(cl2.get(fqn("/i")).containsKey("i-key")); 158 159 assertFalse(cl3.exists(fqn("/a"))); 160 assertFalse(cl3.exists(fqn("/a"))); 161 assertFalse(cl3.exists(fqn("/a/b"))); 162 assertFalse(cl3.exists(fqn("/a/b"))); 163 assertFalse(cl3.exists(fqn("/a/b/c"))); 164 assertFalse(cl3.exists(fqn("/a/b/d"))); 165 assertFalse(cl3.exists(fqn("/e"))); 166 assertFalse(cl3.exists(fqn("/e/f/g"))); 167 assertFalse(cl3.exists(fqn("/e/f/h"))); 168 assertFalse(cl3.exists(fqn("/i"))); 169 170 stopCache2(); 171 Thread.sleep(1000); 172 173 SingletonStoreCacheLoader scl3 = (SingletonStoreCacheLoader) cache3.getCacheLoaderManager().getCacheLoader(); 174 joinPushThread(scl3.getPushStateThread()); 175 176 assertTrue(cl3.get(fqn("/a")).containsKey("a-key")); 177 assertTrue(cl3.get(fqn("/a")).containsKey("aa-key")); 178 assertTrue(cl3.get(fqn("/a/b")).containsKey("b-key")); 179 assertTrue(cl3.get(fqn("/a/b")).containsKey("bb-key")); 180 assertTrue(cl3.get(fqn("/a/b/c")).containsKey("c-key")); 181 assertTrue(cl3.get(fqn("/a/b/d")).containsKey("d-key")); 182 assertTrue(cl3.get(fqn("/e")).containsKey("e-key")); 183 assertTrue(cl3.get(fqn("/e/f/g")).containsKey("g-key")); 184 assertTrue(cl3.get(fqn("/e/f/h")).containsKey("h-key")); 185 assertTrue(cl3.get(fqn("/i")).containsKey("i-key")); 186 187 cache3.put(fqn("/a"), "aaa-key", "aaa-value"); 188 189 assertTrue(cl3.get(fqn("/a")).containsKey("aaa-key")); 190 191 stopCache3(); 192 } 193 194 public void testAvoidConcurrentStatePush() throws InterruptedException 195 { 196 MockSingletonStoreCacheLoader mscl = new MockSingletonStoreCacheLoader(null, true, 3000); 197 198 Thread t1 = new Thread (createActiveStatusChanger(mscl)); 199 Thread t2 = new Thread (createActiveStatusChanger(mscl)); 200 201 t1.start(); 202 Thread.sleep(1000); 203 t2.start(); 204 205 t1.join(); 206 t2.join(); 207 208 assertEquals(1, mscl.getNumberCreatedThreads()); 209 } 210 211 private void createCaches() throws Exception 212 { 213 cache1.create(); 214 cache2.create(); 215 cache3.create(); 216 } 217 218 private void statCaches() throws Exception 219 { 220 cache1.start(); 221 cache2.start(); 222 cache3.start(); 223 } 224 225 private void joinPushThread(Thread pushThread) throws InterruptedException 226 { 227 if (pushThread != null) 228 { 229 pushThread.join(); 230 } 231 } 232 233 private Runnable createActiveStatusChanger(SingletonStoreCacheLoader mscl) 234 { 235 return new ActiveStatusModifier(mscl); 236 } 237 238 protected CacheLoaderConfig getSingletonStoreCacheLoaderConfig(String cacheloaderClass, boolean singleton, 239 boolean pushStateWhenCoordinator) throws Exception 240 { 241 String xml = "<config>\n" + 242 "<passivation>false</passivation>\n" + 243 "<preload></preload>\n" + 244 "<cacheloader>\n" + 245 "<class>" + cacheloaderClass + "</class>\n" + 246 "<properties></properties>\n" + 247 "<singletonStore pushStateWhenCoordinator=\"" + pushStateWhenCoordinator + "\">" + singleton + "</singletonStore>\n" + 252 "</cacheloader>\n" + 253 "</config>"; 254 Element element = XmlHelper.stringToElement(xml); 255 return XmlConfigurationParser.parseCacheLoaderConfig(element); 256 } 257 258 private void initSingletonNonPushCache(CacheSPI cache) throws Exception 259 { 260 cache.getConfiguration().setCacheLoaderConfig(getSingletonStoreCacheLoaderConfig( 261 DummyInMemoryCacheLoader.class.getName(), true, false)); 262 } 263 264 private void initSingletonWithPushCache(CacheSPI cache) throws Exception 265 { 266 cache.getConfiguration().setCacheLoaderConfig(getSingletonStoreCacheLoaderConfig( 267 DummyInMemoryCacheLoader.class.getName(), true, true)); 268 } 269 270 private CacheLoader getDelegatingCacheLoader(CacheSPI cache) 271 { 272 AbstractDelegatingCacheLoader acl = (AbstractDelegatingCacheLoader) cache.getCacheLoaderManager().getCacheLoader(); 273 return acl.getCacheLoader(); 274 } 275 276 private Fqn fqn(String fqn) 277 { 278 return Fqn.fromString(fqn); 279 } 280 281 private void stopCache1() 282 { 283 if (cache1 != null) 284 { 285 cache1.stop(); 286 } 287 288 cache1 = null; 289 } 290 291 private void stopCache2() 292 { 293 if (cache2 != null) 294 { 295 cache2.stop(); 296 } 297 298 cache2 = null; 299 } 300 301 private void stopCache3() 302 { 303 if (cache3 != null) 304 { 305 cache3.stop(); 306 } 307 308 cache3 = null; 309 } 310 311 protected void tearDown() 312 { 313 stopCache1(); 314 stopCache2(); 315 stopCache3(); 316 } 317 318 class MockSingletonStoreCacheLoader extends SingletonStoreCacheLoader 319 { 320 private int numberCreatedThreads = 0; 321 private long busyPeriod; 322 323 public MockSingletonStoreCacheLoader(CacheLoader loader, boolean pushConfiguration, long busyPeriodTime) 324 { 325 super(loader, pushConfiguration); 326 busyPeriod = busyPeriodTime; 327 } 328 329 public int getNumberCreatedThreads() 330 { 331 return numberCreatedThreads; 332 } 333 334 public void setNumberCreatedThreads(int numberCreatedThreads) 335 { 336 this.numberCreatedThreads = numberCreatedThreads; 337 } 338 339 protected Thread createPushStateThread() 340 { 341 return new Thread (new Runnable () 342 { 343 public void run() 344 { 345 numberCreatedThreads++; 346 try 347 { 348 Thread.sleep(busyPeriod); 349 } 350 catch (InterruptedException e) 351 { 352 fail("ActiveStatusModifier interrupted"); 353 } 354 } 355 }); 356 } 357 } 358 359 class ActiveStatusModifier implements Runnable 360 { 361 private SingletonStoreCacheLoader scl; 362 363 public ActiveStatusModifier(SingletonStoreCacheLoader singleton) 364 { 365 scl = singleton; 366 } 367 368 public void run() 369 { 370 scl.activeStatusChanged(true); 371 try 372 { 373 scl.getPushStateThread().join(); 374 } 375 catch (InterruptedException e) 376 { 377 throw new RuntimeException (e); 378 } 379 } 380 } 381 } 382 | Popular Tags |