View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
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  
17  package net.sf.ehcache.writer;
18  
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertFalse;
21  import static org.junit.Assert.assertNotNull;
22  import static org.junit.Assert.assertNull;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.fail;
25  
26  import java.util.Properties;
27  
28  import net.sf.ehcache.AbstractCacheTest;
29  import net.sf.ehcache.Cache;
30  import net.sf.ehcache.CacheManager;
31  import net.sf.ehcache.Element;
32  import net.sf.ehcache.Status;
33  import net.sf.ehcache.config.CacheConfiguration;
34  import net.sf.ehcache.config.CacheWriterConfiguration;
35  import net.sf.ehcache.event.CountingCacheEventListener;
36  
37  import org.junit.After;
38  import org.junit.Before;
39  import org.junit.Test;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  /***
44   * Tests for a CacheWriters
45   *
46   * @author Geert Bevin
47   * @version $Id: CacheWriterTest.java 2521 2010-06-23 10:53:48Z gbevin $
48   */
49  public class CacheWriterTest extends AbstractCacheTest {
50  
51      private static final Logger LOG = LoggerFactory.getLogger(CacheWriterTest.class.getName());
52  
53      protected CacheManager manager;
54  
55      @Override
56      @Before
57      public void setUp() throws Exception {
58          manager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache-writer.xml");
59      }
60  
61      @Override
62      @After
63      public void tearDown() throws Exception {
64          if (!manager.getStatus().equals(Status.STATUS_SHUTDOWN)) {
65              manager.shutdown();
66          }
67      }
68  
69      @Test
70      public void testWriteThroughXml() {
71          Cache cache = manager.getCache("writeThroughCacheXml");
72          assertNotNull(cache.getRegisteredCacheWriter());
73  
74          TestCacheWriter writer = (TestCacheWriter) cache.getRegisteredCacheWriter();
75          assertTrue(writer.isInitialized());
76  
77          Element el1 = new Element("key1", "value1");
78          Element el2 = new Element("key2", "value2");
79          Element el3 = new Element("key3", "value3");
80          assertEquals(0, writer.getWrittenElements().size());
81          cache.putWithWriter(el1);
82          assertEquals(1, writer.getWrittenElements().size());
83          cache.putWithWriter(el2);
84          assertEquals(2, writer.getWrittenElements().size());
85          cache.putWithWriter(el3);
86          assertEquals(3, writer.getWrittenElements().size());
87          assertEquals("value1", writer.getWrittenElements().get("key1").getValue());
88          assertEquals("value2", writer.getWrittenElements().get("key2").getValue());
89          assertEquals("value3", writer.getWrittenElements().get("key3").getValue());
90          cache.removeWithWriter(el2.getKey());
91          assertEquals(3, writer.getWrittenElements().size());
92          assertNotNull(writer.getWrittenElements().get("key1"));
93          assertNotNull(writer.getWrittenElements().get("key2"));
94          assertNotNull(writer.getWrittenElements().get("key3"));
95          assertEquals(1, writer.getDeletedElements().size());
96          assertTrue(writer.getDeletedElements().containsKey("key2"));
97      }
98  
99      @Test
100     public void testWriteThroughXmlProperties() {
101         Cache cache = manager.getCache("writeThroughCacheXmlProperties");
102         assertNotNull(cache.getRegisteredCacheWriter());
103 
104         TestCacheWriter writer = (TestCacheWriter) cache.getRegisteredCacheWriter();
105         assertTrue(writer.isInitialized());
106 
107         Element el1 = new Element("key1", "value1");
108         Element el2 = new Element("key2", "value2");
109         Element el3 = new Element("key3", "value3");
110         assertEquals(0, writer.getWrittenElements().size());
111         cache.putWithWriter(el1);
112         assertEquals(1, writer.getWrittenElements().size());
113         cache.putWithWriter(el2);
114         assertEquals(2, writer.getWrittenElements().size());
115         cache.putWithWriter(el3);
116         assertEquals(3, writer.getWrittenElements().size());
117         assertNull(writer.getWrittenElements().get("key1"));
118         assertNull(writer.getWrittenElements().get("key2"));
119         assertNull(writer.getWrittenElements().get("key3"));
120         assertEquals("value1", writer.getWrittenElements().get("prekey1suff").getValue());
121         assertEquals("value2", writer.getWrittenElements().get("prekey2suff").getValue());
122         assertEquals("value3", writer.getWrittenElements().get("prekey3suff").getValue());
123         cache.removeWithWriter(el1.getKey());
124         assertEquals(3, writer.getWrittenElements().size());
125         assertNotNull(writer.getWrittenElements().get("prekey1suff"));
126         assertNotNull(writer.getWrittenElements().get("prekey2suff"));
127         assertNotNull(writer.getWrittenElements().get("prekey3suff"));
128         assertEquals(1, writer.getDeletedElements().size());
129         assertTrue(writer.getDeletedElements().containsKey("prekey1suff"));
130     }
131 
132     @Test
133     public void testWriteThroughJavaRegistration() {
134         Cache cache = manager.getCache("writeThroughCacheJavaRegistration");
135         assertNull(cache.getRegisteredCacheWriter());
136 
137         TestCacheWriter writer = new TestCacheWriter(new Properties());
138         cache.registerCacheWriter(writer);
139         assertTrue(writer.isInitialized());
140 
141         Element el1 = new Element("key1", "value1");
142         Element el2 = new Element("key2", "value2");
143         Element el3 = new Element("key3", "value3");
144         Element el4 = new Element("key4", "value4");
145         assertEquals(0, writer.getWrittenElements().size());
146         cache.putWithWriter(el1);
147         assertEquals(1, writer.getWrittenElements().size());
148         cache.putWithWriter(el2);
149         assertEquals(2, writer.getWrittenElements().size());
150         cache.putWithWriter(el3);
151         assertEquals(3, writer.getWrittenElements().size());
152         cache.putWithWriter(el4);
153         assertEquals(4, writer.getWrittenElements().size());
154         assertEquals("value1", writer.getWrittenElements().get("key1").getValue());
155         assertEquals("value2", writer.getWrittenElements().get("key2").getValue());
156         assertEquals("value3", writer.getWrittenElements().get("key3").getValue());
157         assertEquals("value4", writer.getWrittenElements().get("key4").getValue());
158         cache.removeWithWriter(el1.getKey());
159         cache.removeWithWriter(el2.getKey());
160         cache.removeWithWriter(el3.getKey());
161         assertEquals(4, writer.getWrittenElements().size());
162         assertNotNull(writer.getWrittenElements().get("key1"));
163         assertNotNull(writer.getWrittenElements().get("key2"));
164         assertNotNull(writer.getWrittenElements().get("key3"));
165         assertNotNull(writer.getWrittenElements().get("key4"));
166         assertEquals(3, writer.getDeletedElements().size());
167         assertTrue(writer.getDeletedElements().containsKey("key1"));
168         assertTrue(writer.getDeletedElements().containsKey("key2"));
169         assertTrue(writer.getDeletedElements().containsKey("key3"));
170     }
171 
172     @Test
173     public void testWriteThroughNotifyListeners() {
174         Cache cache = new Cache(new CacheConfiguration("writeThroughCacheOnly", 10)
175                 .cacheEventListenerFactory(new CacheConfiguration.CacheEventListenerFactoryConfiguration().className("net.sf.ehcache.event.CountingCacheEventListenerFactory")));
176         assertNull(cache.getRegisteredCacheWriter());
177 
178         CacheManager.getInstance().addCache(cache);
179 
180         TestCacheWriterException writer = new TestCacheWriterException();
181         cache.registerCacheWriter(writer);
182         assertTrue(writer.isInitialized());
183 
184         // without listeners notification
185         cache.getCacheConfiguration().getCacheWriterConfiguration().setNotifyListenersOnException(false);
186 
187         CountingCacheEventListener.resetCounters();
188 
189         try {
190             cache.putWithWriter(new Element("key1", "value1"));
191             fail("Expected UnsupportedOperationException");
192         } catch (UnsupportedOperationException e) {
193             // expected
194             assertEquals(0, CountingCacheEventListener.getCacheElementsPut(cache).size());
195         }
196 
197         CountingCacheEventListener.resetCounters();
198 
199         try {
200             cache.putWithWriter(new Element("key1", "value1"));
201             fail("Expected UnsupportedOperationException");
202         } catch (UnsupportedOperationException e) {
203             // expected
204             assertEquals(0, CountingCacheEventListener.getCacheElementsUpdated(cache).size());
205         }
206 
207         CountingCacheEventListener.resetCounters();
208 
209         try {
210             cache.removeWithWriter("key1");
211             fail("Expected UnsupportedOperationException");
212         } catch (UnsupportedOperationException e) {
213             // expected
214             assertEquals(0, CountingCacheEventListener.getCacheElementsRemoved(cache).size());
215         }
216 
217         // with listeners notification
218         cache.getCacheConfiguration().getCacheWriterConfiguration().setNotifyListenersOnException(true);
219 
220         CountingCacheEventListener.resetCounters();
221 
222         try {
223             cache.putWithWriter(new Element("key1", "value1"));
224             fail("Expected UnsupportedOperationException");
225         } catch (UnsupportedOperationException e) {
226             // expected
227             assertEquals(0, CountingCacheEventListener.getCacheElementsUpdated(cache).size());
228             assertEquals(1, CountingCacheEventListener.getCacheElementsPut(cache).size());
229         }
230 
231         CountingCacheEventListener.resetCounters();
232 
233         try {
234             assertNotNull(cache.get("key1"));
235             cache.putWithWriter(new Element("key1", "value1"));
236             fail("Expected UnsupportedOperationException");
237         } catch (UnsupportedOperationException e) {
238             // expected
239             assertEquals(0, CountingCacheEventListener.getCacheElementsPut(cache).size());
240             assertEquals(1, CountingCacheEventListener.getCacheElementsUpdated(cache).size());
241         }
242 
243         CountingCacheEventListener.resetCounters();
244 
245         try {
246             cache.removeWithWriter("key1");
247             fail("Expected UnsupportedOperationException");
248         } catch (UnsupportedOperationException e) {
249             // expected
250             assertEquals(1, CountingCacheEventListener.getCacheElementsRemoved(cache).size());
251         }
252     }
253 
254     @Test
255     public void testWriteBehindSolelyJava() throws InterruptedException {
256         Cache cache = new Cache(
257                 new CacheConfiguration("writeBehindSolelyJava", 10)
258                         .cacheWriter(new CacheWriterConfiguration()
259                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
260                         .minWriteDelay(2)
261                         .maxWriteDelay(8)
262                         .cacheWriterFactory(new CacheWriterConfiguration.CacheWriterFactoryConfiguration()
263                         .className("net.sf.ehcache.writer.TestCacheWriterFactory"))));
264         assertNotNull(cache.getRegisteredCacheWriter());
265 
266         CacheManager.getInstance().addCache(cache);
267         TestCacheWriter writer = (TestCacheWriter) cache.getRegisteredCacheWriter();
268         assertTrue(writer.isInitialized());
269         assertEquals(0, writer.getWrittenElements().size());
270 
271         Element el1 = new Element("key1", "value1");
272         Element el2 = new Element("key2", "value2");
273         Element el3 = new Element("key3", "value3");
274         cache.putWithWriter(el1);
275         cache.putWithWriter(el2);
276         cache.putWithWriter(el3);
277 
278         Thread.sleep(3000);
279 
280         assertEquals(3, writer.getWrittenElements().size());
281         assertNotNull(writer.getWrittenElements().get("key1"));
282         assertNotNull(writer.getWrittenElements().get("key2"));
283         assertNotNull(writer.getWrittenElements().get("key3"));
284         assertEquals(0, writer.getDeletedElements().size());
285 
286         cache.removeWithWriter(el2.getKey());
287         cache.removeWithWriter(el3.getKey());
288 
289         assertEquals(3, writer.getWrittenElements().size());
290         assertEquals(0, writer.getDeletedElements().size());
291 
292         Thread.sleep(3000);
293 
294         assertEquals(3, writer.getWrittenElements().size());
295         assertEquals(2, writer.getDeletedElements().size());
296         assertTrue(writer.getDeletedElements().containsKey("key2"));
297         assertTrue(writer.getDeletedElements().containsKey("key3"));
298     }
299 
300     @Test
301     public void testWriteBehindStopWaitsForEmptyQueue() throws InterruptedException {
302         Cache cache = new Cache(
303                 new CacheConfiguration("writeBehindSolelyJavaStopWaitsForEmptyQueue", 10)
304                         .cacheWriter(new CacheWriterConfiguration()
305                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
306                         .minWriteDelay(2)
307                         .maxWriteDelay(8)));
308         TestCacheWriterSlow writer = new TestCacheWriterSlow();
309         cache.registerCacheWriter(writer);
310         assertNotNull(cache.getRegisteredCacheWriter());
311 
312         CacheManager.getInstance().addCache(cache);
313         assertTrue(writer.isInitialized());
314         assertEquals(0, writer.getWrittenElements().size());
315 
316         Element el1 = new Element("key1", "value1");
317         Element el2 = new Element("key2", "value2");
318         Element el3 = new Element("key3", "value3");
319         cache.putWithWriter(el1);
320         cache.putWithWriter(el2);
321         cache.putWithWriter(el3);
322         cache.removeWithWriter(el2.getKey());
323         cache.removeWithWriter(el3.getKey());
324         cache.dispose();
325 
326         Thread.sleep(3000);
327 
328         assertEquals(3, writer.getWrittenElements().size());
329         assertNotNull(writer.getWrittenElements().get("key1"));
330         assertNotNull(writer.getWrittenElements().get("key2"));
331         assertNotNull(writer.getWrittenElements().get("key3"));
332         assertEquals(3, writer.getWrittenElements().size());
333         assertEquals(2, writer.getDeletedElements().size());
334         assertTrue(writer.getDeletedElements().containsKey("key2"));
335         assertTrue(writer.getDeletedElements().containsKey("key3"));
336     }
337 
338     @Test
339     public void testWriteBehindBatched() throws InterruptedException {
340         Cache cache = new Cache(
341                 new CacheConfiguration("writeBehindBatched", 10)
342                         .cacheWriter(new CacheWriterConfiguration()
343                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
344                         .minWriteDelay(1)
345                         .maxWriteDelay(4)
346                         .writeBatching(true)
347                         .writeBatchSize(10)
348                         .cacheWriterFactory(new CacheWriterConfiguration.CacheWriterFactoryConfiguration()
349                         .className("net.sf.ehcache.writer.TestCacheWriterFactory")
350                         .properties("key.prefix=pre2; key.suffix=suff2")
351                         .propertySeparator(";"))));
352         assertNotNull(cache.getRegisteredCacheWriter());
353 
354         CacheManager.getInstance().addCache(cache);
355         TestCacheWriter writer = (TestCacheWriter) cache.getRegisteredCacheWriter();
356         assertTrue(writer.isInitialized());
357         assertEquals(0, writer.getWrittenElements().size());
358 
359         Element el1 = new Element("key1", "value1");
360         Element el2 = new Element("key2", "value2");
361         Element el3 = new Element("key3", "value3");
362         cache.putWithWriter(el1);
363         cache.putWithWriter(el2);
364         cache.putWithWriter(el3);
365 
366         Thread.sleep(3000);
367 
368         assertEquals(0, writer.getWrittenElements().size());
369 
370         Thread.sleep(2000);
371 
372         assertEquals(3, writer.getWrittenElements().size());
373         assertFalse(writer.getWrittenElements().containsKey("key1"));
374         assertFalse(writer.getWrittenElements().containsKey("key2"));
375         assertFalse(writer.getWrittenElements().containsKey("key3"));
376         assertFalse(writer.getWrittenElements().containsKey("pre2key1suff2"));
377         assertFalse(writer.getWrittenElements().containsKey("pre2key2suff2"));
378         assertFalse(writer.getWrittenElements().containsKey("pre2key3suff2"));
379         assertTrue(writer.getWrittenElements().containsKey("pre2key1suff2-batched"));
380         assertTrue(writer.getWrittenElements().containsKey("pre2key2suff2-batched"));
381         assertTrue(writer.getWrittenElements().containsKey("pre2key3suff2-batched"));
382 
383         assertEquals(0, writer.getDeletedElements().size());
384 
385         cache.removeWithWriter(el2.getKey());
386         cache.removeWithWriter(el3.getKey());
387 
388         Thread.sleep(2000);
389 
390         assertEquals(3, writer.getWrittenElements().size());
391         assertEquals(0, writer.getDeletedElements().size());
392 
393         Thread.sleep(3000);
394 
395         assertEquals(3, writer.getWrittenElements().size());
396         assertEquals(2, writer.getDeletedElements().size());
397         assertTrue(writer.getDeletedElements().containsKey("pre2key2suff2-batched"));
398         assertTrue(writer.getDeletedElements().containsKey("pre2key3suff2-batched"));
399     }
400 
401     @Test
402     public void testWriteBehindBatchedCoalescing() throws InterruptedException {
403         Cache cache = new Cache(
404                 new CacheConfiguration("writeBehindBatchedCoalescing", 10)
405                         .cacheWriter(new CacheWriterConfiguration()
406                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
407                         .minWriteDelay(1)
408                         .maxWriteDelay(1)
409                         .writeBatching(true)
410                         .writeBatchSize(10)
411                         .writeCoalescing(true)
412                         .cacheWriterFactory(new CacheWriterConfiguration.CacheWriterFactoryConfiguration()
413                         .className("net.sf.ehcache.writer.TestCacheWriterFactory"))));
414         assertNotNull(cache.getRegisteredCacheWriter());
415 
416         CacheManager.getInstance().addCache(cache);
417         TestCacheWriter writer = (TestCacheWriter) cache.getRegisteredCacheWriter();
418         assertTrue(writer.isInitialized());
419         assertEquals(0, writer.getWrittenElements().size());
420 
421         Element el1 = new Element("key1", "value1");
422         Element el2a = new Element("key2", "value2a");
423         Element el2b = new Element("key2", "value2b");
424         Element el3 = new Element("key3", "value3");
425         cache.putWithWriter(el1);
426         cache.putWithWriter(el2a);
427         cache.putWithWriter(el3);
428         cache.putWithWriter(el2b);
429         cache.removeWithWriter("key1");
430 
431         Thread.sleep(2000);
432 
433         assertEquals(2, writer.getWrittenElements().size());
434 
435         assertFalse(writer.getWrittenElements().containsKey("key1-batched"));
436         assertTrue(writer.getWrittenElements().containsKey("key2-batched"));
437         assertTrue(writer.getWrittenElements().containsKey("key3-batched"));
438         assertEquals("value2b", writer.getWrittenElements().get("key2-batched").getObjectValue());
439         assertEquals("value3", writer.getWrittenElements().get("key3-batched").getObjectValue());
440 
441         assertEquals(1, writer.getDeletedElements().size());
442 
443         assertTrue(writer.getDeletedElements().containsKey("key1-batched"));
444     }
445 
446     @Test
447     public void testWriteBehindExceptionWithoutRetrying() throws InterruptedException {
448         Cache cache = new Cache(
449                 new CacheConfiguration("writeBehindExceptionWithoutRetrying", 10)
450                         .cacheWriter(new CacheWriterConfiguration()
451                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
452                         .minWriteDelay(0)
453                         .maxWriteDelay(0)
454                         .retryAttempts(0)
455                         .retryAttemptDelaySeconds(0)));
456         TestCacheWriterRetries writer = new TestCacheWriterRetries(3);
457         cache.registerCacheWriter(writer);
458 
459         CacheManager.getInstance().addCache(cache);
460         assertTrue(writer.isInitialized());
461         assertEquals(0, writer.getWrittenElements().size());
462 
463         cache.putWithWriter(new Element("key1", "value1"));
464         cache.putWithWriter(new Element("key2", "value1"));
465         cache.putWithWriter(new Element("key3", "value1"));
466         cache.removeWithWriter("key2");
467 
468         Thread.sleep(2000);
469 
470         assertEquals(0, writer.getWrittenElements().size());
471     }
472 
473     @Test
474     public void testWriteBehindRetryWithoutExceptions() throws InterruptedException {
475         Cache cache = new Cache(
476                 new CacheConfiguration("writeBehindRetryWithoutExceptions", 10)
477                         .cacheWriter(new CacheWriterConfiguration()
478                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
479                         .minWriteDelay(0)
480                         .maxWriteDelay(0)
481                         .retryAttempts(3)
482                         .retryAttemptDelaySeconds(0)));
483         TestCacheWriterRetries writer = new TestCacheWriterRetries(0);
484         cache.registerCacheWriter(writer);
485 
486         CacheManager.getInstance().addCache(cache);
487         assertTrue(writer.isInitialized());
488         assertEquals(0, writer.getWrittenElements().size());
489 
490         cache.putWithWriter(new Element("key1", "value1"));
491         cache.putWithWriter(new Element("key2", "value1"));
492         cache.putWithWriter(new Element("key3", "value1"));
493         cache.removeWithWriter("key2");
494 
495         Thread.sleep(2000);
496 
497         assertEquals(2, writer.getWrittenElements().size());
498         assertEquals(1, (long) writer.getWriteCount().get("key1"));
499         assertEquals(1, (long) writer.getWriteCount().get("key2"));
500         assertEquals(1, (long) writer.getWriteCount().get("key3"));
501         assertFalse(writer.getDeleteCount().containsKey("key1"));
502         assertEquals(1, (long) writer.getDeleteCount().get("key2"));
503         assertFalse(writer.getDeleteCount().containsKey("key3"));
504     }
505 
506     @Test
507     public void testWriteBehindRetryWithoutDelay() throws InterruptedException {
508         Cache cache = new Cache(
509                 new CacheConfiguration("writeBehindRetryWithoutDelay", 10)
510                         .cacheWriter(new CacheWriterConfiguration()
511                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
512                         .minWriteDelay(0)
513                         .maxWriteDelay(0)
514                         .retryAttempts(3)
515                         .retryAttemptDelaySeconds(0)));
516         TestCacheWriterRetries writer = new TestCacheWriterRetries(3);
517         cache.registerCacheWriter(writer);
518 
519         CacheManager.getInstance().addCache(cache);
520         assertTrue(writer.isInitialized());
521         assertEquals(0, writer.getWrittenElements().size());
522 
523         cache.putWithWriter(new Element("key1", "value1"));
524         cache.putWithWriter(new Element("key2", "value2"));
525         cache.putWithWriter(new Element("key3", "value3"));
526         cache.removeWithWriter("key2");
527 
528         Thread.sleep(2000);
529 
530         assertEquals(2, writer.getWrittenElements().size());
531         assertEquals(1, (long) writer.getWriteCount().get("key1"));
532         assertEquals(1, (long) writer.getWriteCount().get("key2"));
533         assertEquals(1, (long) writer.getWriteCount().get("key3"));
534         assertEquals(1, (long) writer.getDeleteCount().get("key2"));
535     }
536 
537     @Test
538     public void testWriteBehindRetryWithDelay() throws InterruptedException {
539         Cache cache = new Cache(
540                 new CacheConfiguration("writeBehindRetryWithDelay", 10)
541                         .cacheWriter(new CacheWriterConfiguration()
542                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
543                         .minWriteDelay(0)
544                         .maxWriteDelay(0)
545                         .retryAttempts(3)
546                         .retryAttemptDelaySeconds(1)));
547         TestCacheWriterRetries writer = new TestCacheWriterRetries(3);
548         cache.registerCacheWriter(writer);
549 
550         CacheManager.getInstance().addCache(cache);
551         assertTrue(writer.isInitialized());
552         assertEquals(0, writer.getWrittenElements().size());
553 
554         cache.putWithWriter(new Element("key1", "value1"));
555         cache.putWithWriter(new Element("key2", "value2"));
556         cache.putWithWriter(new Element("key3", "value3"));
557         cache.removeWithWriter("key2");
558 
559         Thread.sleep(3000);
560 
561         assertEquals(0, writer.getWrittenElements().size());
562         assertFalse(writer.getWriteCount().containsKey("key1"));
563         assertFalse(writer.getWriteCount().containsKey("key2"));
564         assertFalse(writer.getWriteCount().containsKey("key3"));
565         assertFalse(writer.getDeleteCount().containsKey("key2"));
566 
567         Thread.sleep(1000);
568 
569         assertEquals(1, writer.getWrittenElements().size());
570         assertEquals(1, (long) writer.getWriteCount().get("key1"));
571         assertFalse(writer.getWriteCount().containsKey("key2"));
572         assertFalse(writer.getWriteCount().containsKey("key3"));
573         assertFalse(writer.getDeleteCount().containsKey("key2"));
574 
575         Thread.sleep(2000);
576 
577         assertEquals(1, writer.getWrittenElements().size());
578 
579         Thread.sleep(1000);
580 
581         assertEquals(2, writer.getWrittenElements().size());
582         assertEquals(1, (long) writer.getWriteCount().get("key1"));
583         assertEquals(1, (long) writer.getWriteCount().get("key2"));
584         assertFalse(writer.getWriteCount().containsKey("key3"));
585         assertFalse(writer.getDeleteCount().containsKey("key2"));
586 
587         Thread.sleep(2000);
588 
589         assertEquals(2, writer.getWrittenElements().size());
590 
591         Thread.sleep(1000);
592 
593         assertEquals(3, writer.getWrittenElements().size());
594         assertEquals(1, (long) writer.getWriteCount().get("key1"));
595         assertEquals(1, (long) writer.getWriteCount().get("key2"));
596         assertEquals(1, (long) writer.getWriteCount().get("key3"));
597         assertFalse(writer.getDeleteCount().containsKey("key2"));
598 
599         Thread.sleep(2000);
600 
601         assertEquals(3, writer.getWrittenElements().size());
602 
603         Thread.sleep(1000);
604 
605         assertEquals(2, writer.getWrittenElements().size());
606         assertEquals(1, (long) writer.getWriteCount().get("key1"));
607         assertEquals(1, (long) writer.getWriteCount().get("key2"));
608         assertEquals(1, (long) writer.getWriteCount().get("key3"));
609         assertEquals(1, (long) writer.getDeleteCount().get("key2"));
610     }
611 
612     @Test
613     public void testWriteBehindExceptionWithoutRetryingBatched() throws InterruptedException {
614         Cache cache = new Cache(
615                 new CacheConfiguration("writeBehindExceptionWithoutRetryingBatched", 10)
616                         .cacheWriter(new CacheWriterConfiguration()
617                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
618                         .minWriteDelay(1)
619                         .maxWriteDelay(1)
620                         .writeBatching(true)
621                         .writeBatchSize(10)
622                         .retryAttempts(0)
623                         .retryAttemptDelaySeconds(0)));
624         TestCacheWriterRetries writer = new TestCacheWriterRetries(3);
625         cache.registerCacheWriter(writer);
626 
627         CacheManager.getInstance().addCache(cache);
628         assertTrue(writer.isInitialized());
629         assertEquals(0, writer.getWrittenElements().size());
630 
631         cache.putWithWriter(new Element("key1", "value1"));
632         cache.putWithWriter(new Element("key2", "value1"));
633         cache.putWithWriter(new Element("key3", "value1"));
634         cache.removeWithWriter("key2");
635 
636         Thread.sleep(2000);
637 
638         assertEquals(2, writer.getWrittenElements().size());
639         assertEquals(1, (long) writer.getWriteCount().get("key1"));
640         assertEquals(1, (long) writer.getWriteCount().get("key2"));
641         assertFalse(writer.getWriteCount().containsKey("key3"));
642         assertFalse(writer.getDeleteCount().containsKey("key1"));
643         assertFalse(writer.getDeleteCount().containsKey("key2"));
644         assertFalse(writer.getDeleteCount().containsKey("key3"));
645     }
646 
647     @Test
648     public void testWriteBehindRetryWithoutExceptionsBatched() throws InterruptedException {
649         Cache cache = new Cache(
650                 new CacheConfiguration("writeBehindRetryWithoutExceptionsBatched", 10)
651                         .cacheWriter(new CacheWriterConfiguration()
652                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
653                         .minWriteDelay(1)
654                         .maxWriteDelay(1)
655                         .writeBatching(true)
656                         .writeBatchSize(10)
657                         .retryAttempts(3)
658                         .retryAttemptDelaySeconds(0)));
659         TestCacheWriterRetries writer = new TestCacheWriterRetries(0);
660         cache.registerCacheWriter(writer);
661 
662         CacheManager.getInstance().addCache(cache);
663         assertTrue(writer.isInitialized());
664         assertEquals(0, writer.getWrittenElements().size());
665 
666         cache.putWithWriter(new Element("key1", "value1"));
667         cache.putWithWriter(new Element("key2", "value2"));
668         cache.putWithWriter(new Element("key3", "value3"));
669         cache.removeWithWriter("key2");
670 
671         Thread.sleep(2000);
672 
673         assertEquals(2, writer.getWrittenElements().size());
674         assertEquals(1, (long) writer.getWriteCount().get("key1"));
675         assertEquals(1, (long) writer.getWriteCount().get("key2"));
676         assertEquals(1, (long) writer.getWriteCount().get("key3"));
677         assertFalse(writer.getDeleteCount().containsKey("key1"));
678         assertEquals(1, (long) writer.getDeleteCount().get("key2"));
679         assertFalse(writer.getDeleteCount().containsKey("key3"));
680     }
681 
682     @Test
683     public void testWriteBehindRetryWithoutDelayBatched() throws InterruptedException {
684         Cache cache = new Cache(
685                 new CacheConfiguration("writeBehindRetryWithoutDelayBatched", 10)
686                         .cacheWriter(new CacheWriterConfiguration()
687                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
688                         .minWriteDelay(1)
689                         .maxWriteDelay(1)
690                         .writeBatching(true)
691                         .writeBatchSize(10)
692                         .retryAttempts(3)
693                         .retryAttemptDelaySeconds(0)));
694         TestCacheWriterRetries writer = new TestCacheWriterRetries(3);
695         cache.registerCacheWriter(writer);
696 
697         CacheManager.getInstance().addCache(cache);
698         assertTrue(writer.isInitialized());
699         assertEquals(0, writer.getWrittenElements().size());
700 
701         cache.putWithWriter(new Element("key1", "value1"));
702         cache.putWithWriter(new Element("key2", "value2"));
703         cache.putWithWriter(new Element("key3", "value3"));
704         cache.removeWithWriter("key2");
705 
706         Thread.sleep(2000);
707 
708         assertEquals(2, writer.getWrittenElements().size());
709         assertEquals(4, (long) writer.getWriteCount().get("key1"));
710         assertEquals(4, (long) writer.getWriteCount().get("key2"));
711         assertEquals(1, (long) writer.getWriteCount().get("key3"));
712         assertEquals(1, (long) writer.getDeleteCount().get("key2"));
713     }
714 
715     @Test
716     public void testWriteBehindRetryWithDelayBatched() throws InterruptedException {
717         Cache cache = new Cache(
718                 new CacheConfiguration("writeBehindRetryWithDelayBatched", 10)
719                         .cacheWriter(new CacheWriterConfiguration()
720                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
721                         .minWriteDelay(1)
722                         .maxWriteDelay(1)
723                         .writeBatching(true)
724                         .writeBatchSize(10)
725                         .retryAttempts(3)
726                         .retryAttemptDelaySeconds(1)));
727         TestCacheWriterRetries writer = new TestCacheWriterRetries(3);
728         cache.registerCacheWriter(writer);
729 
730         CacheManager.getInstance().addCache(cache);
731         assertTrue(writer.isInitialized());
732         assertEquals(0, writer.getWrittenElements().size());
733 
734         cache.putWithWriter(new Element("key1", "value1"));
735         cache.putWithWriter(new Element("key2", "value2"));
736         cache.putWithWriter(new Element("key3", "value3"));
737         cache.removeWithWriter("key2");
738 
739         Thread.sleep(3000);
740 
741         assertEquals(2, writer.getWrittenElements().size());
742         assertTrue(writer.getWriteCount().containsKey("key1"));
743         assertTrue(writer.getWriteCount().containsKey("key2"));
744         assertFalse(writer.getWriteCount().containsKey("key3"));
745         assertFalse(writer.getDeleteCount().containsKey("key1"));
746         assertFalse(writer.getDeleteCount().containsKey("key2"));
747         assertFalse(writer.getDeleteCount().containsKey("key3"));
748 
749         Thread.sleep(3000);
750 
751         assertEquals(3, writer.getWrittenElements().size());
752         assertEquals(4, (long) writer.getWriteCount().get("key1"));
753         assertEquals(4, (long) writer.getWriteCount().get("key2"));
754         assertEquals(1, (long) writer.getWriteCount().get("key3"));
755         assertFalse(writer.getDeleteCount().containsKey("key1"));
756         assertFalse(writer.getDeleteCount().containsKey("key2"));
757         assertFalse(writer.getDeleteCount().containsKey("key3"));
758 
759         Thread.sleep(5000);
760 
761         assertEquals(2, writer.getWrittenElements().size());
762         assertEquals(4, (long) writer.getWriteCount().get("key1"));
763         assertEquals(4, (long) writer.getWriteCount().get("key2"));
764         assertEquals(1, (long) writer.getWriteCount().get("key3"));
765         assertFalse(writer.getDeleteCount().containsKey("key1"));
766         assertEquals(1, (long) writer.getDeleteCount().get("key2"));
767         assertFalse(writer.getDeleteCount().containsKey("key3"));
768     }
769 
770     @Test
771     public void testWriteBehindRateLimitBatched() throws InterruptedException {
772         Cache cache = new Cache(
773                 new CacheConfiguration("writeBehindRetryWithDelayBatched", 100)
774                         .cacheWriter(new CacheWriterConfiguration()
775                         .writeMode(CacheWriterConfiguration.WriteMode.WRITE_BEHIND)
776                         .minWriteDelay(1)
777                         .writeBatching(true)
778                         .writeBatchSize(10)
779                         .rateLimitPerSecond(5)));
780         TestCacheWriter writer = new TestCacheWriter(new Properties());
781         cache.registerCacheWriter(writer);
782 
783         CacheManager.getInstance().addCache(cache);
784         assertTrue(writer.isInitialized());
785         assertEquals(0, writer.getWrittenElements().size());
786 
787         for (int i = 0; i < 30; i++) {
788             cache.putWithWriter(new Element("key" + i, "value" + i));
789         }
790 
791         Thread.sleep(1000);
792 
793         assertEquals(0, writer.getWrittenElements().size());
794 
795         Thread.sleep(1500);
796 
797         assertEquals(10, writer.getWrittenElements().size());
798 
799         Thread.sleep(1000);
800 
801         assertEquals(10, writer.getWrittenElements().size());
802 
803         Thread.sleep(1000);
804 
805         assertEquals(20, writer.getWrittenElements().size());
806 
807         Thread.sleep(1000);
808 
809         assertEquals(20, writer.getWrittenElements().size());
810 
811         Thread.sleep(1000);
812 
813         assertEquals(30, writer.getWrittenElements().size());
814     }
815 }