View Javadoc

1   /*
2    * $Id: AbstractTransactionQueueManagerTestCase.java 22387 2011-07-12 03:53:36Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.util.queue;
12  
13  import org.mule.tck.junit4.AbstractMuleContextTestCase;
14  import org.mule.util.concurrent.Latch;
15  import org.mule.util.store.SimpleMemoryObjectStore;
16  import org.mule.util.xa.AbstractResourceManager;
17  
18  import java.io.Serializable;
19  import java.util.Random;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.junit.Test;
24  
25  import static org.junit.Assert.assertEquals;
26  import static org.junit.Assert.assertFalse;
27  import static org.junit.Assert.assertNotNull;
28  import static org.junit.Assert.assertNull;
29  import static org.junit.Assert.assertTrue;
30  
31  public abstract class AbstractTransactionQueueManagerTestCase extends AbstractMuleContextTestCase
32  {
33  
34      /**
35       * logger used by this class
36       */
37      protected transient Log logger = LogFactory.getLog(getClass());
38  
39      protected abstract TransactionalQueueManager createQueueManager() throws Exception;
40  
41      protected abstract boolean isPersistent();
42  
43      @Test
44      public void testPutTake() throws Exception
45      {
46          TransactionalQueueManager mgr = createQueueManager();
47          mgr.start();
48  
49          QueueSession s = mgr.getQueueSession();
50          Queue q = s.getQueue("queue1");
51  
52          assertEquals("Queue size", 0, q.size());
53          q.put("String1");
54          assertEquals("Queue size", 1, q.size());
55          Object o = q.take();
56          assertNotNull(o);
57          assertEquals("Queue content", "String1", o);
58          assertEquals("Queue size", 0, q.size());
59  
60          purgeQueue(q);
61  
62          mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
63      }
64  
65      @Test
66      public void testTakePut() throws Exception
67      {
68          final TransactionalQueueManager mgr = createQueueManager();
69          mgr.start();
70  
71          final Latch latch = new Latch();
72  
73          Thread t = new Thread()
74          {
75              @Override
76              public void run()
77              {
78                  try
79                  {
80                      latch.countDown();
81                      Thread.sleep(200);
82                      QueueSession s = mgr.getQueueSession();
83                      Queue q = s.getQueue("queue1");
84                      assertEquals("Queue size", 0, q.size());
85                      q.put("String1");
86                  }
87                  catch (Exception e)
88                  {
89                      // ignore, let test fail
90                  }
91              }
92          };
93          t.start();
94          latch.await();
95          long t0 = System.currentTimeMillis();
96          QueueSession s = mgr.getQueueSession();
97          Queue q = s.getQueue("queue1");
98          assertEquals("Queue size", 0, q.size());
99          Object o = q.take();
100         long t1 = System.currentTimeMillis();
101         t.join();
102         assertNotNull(o);
103         assertEquals("Queue content", "String1", o);
104         assertEquals("Queue size", 0, q.size());
105         assertTrue(t1 - t0 > 100);
106 
107         purgeQueue(q);
108 
109         mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
110     }
111 
112     @Test
113     public void testPutTakeUntake() throws Exception
114     {
115         final TransactionalQueueManager mgr = createQueueManager();
116         mgr.start();
117 
118         final Latch latch = new Latch();
119 
120         Thread t = new Thread()
121         {
122             @Override
123             public void run()
124             {
125                 try
126                 {
127                     latch.countDown();
128                     Thread.sleep(200);
129                     QueueSession s = mgr.getQueueSession();
130                     Queue q = s.getQueue("queue1");
131                     assertEquals("Queue size", 0, q.size());
132                     q.put("String1");
133                     q.put("String2");
134                 }
135                 catch (Exception e)
136                 {
137                     // ignore, let test fail
138                 }
139             }
140         };
141         t.start();
142         latch.await();
143         long t0 = System.currentTimeMillis();
144         QueueSession s = mgr.getQueueSession();
145         Queue q = s.getQueue("queue1");
146         assertEquals("Queue size", 0, q.size());
147         Serializable o = q.take();
148         long t1 = System.currentTimeMillis();
149         t.join();
150         assertNotNull(o);
151         assertEquals("Queue content", "String1", o);
152         assertEquals("Queue size", 1, q.size());
153         assertTrue(t1 - t0 > 100);
154 
155         // Same as put/take until now, but now we do an untake
156         q.untake(o);
157         // Ensure queue size is now 2
158         assertEquals("Queue size", 2, q.size());
159         // Take to ensure order is correct
160         Object o2 = q.take();
161         assertEquals("Queue content", "String1", o2);
162         assertEquals("Queue size", 1, q.size());
163 
164         purgeQueue(q);
165 
166         mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
167 
168     }
169 
170     @Test
171     public void testTakePutRollbackPut() throws Exception
172     {
173         final TransactionalQueueManager mgr = createQueueManager();
174         mgr.start();
175 
176         final Latch latch = new Latch();
177 
178         Thread t = new Thread()
179         {
180             @Override
181             public void run()
182             {
183                 try
184                 {
185                     latch.countDown();
186                     Thread.sleep(200);
187                     QueueSession s = mgr.getQueueSession();
188                     Queue q = s.getQueue("queue1");
189                     assertEquals("Queue size", 0, q.size());
190                     s.begin();
191                     q.put("String1");
192                     s.rollback();
193                     s.begin();
194                     q.put("String2");
195                     s.commit();
196                 }
197                 catch (Exception e)
198                 {
199                     // ignore, let test fail
200                 }
201             }
202         };
203         t.start();
204         latch.await();
205         long t0 = System.currentTimeMillis();
206         QueueSession s = mgr.getQueueSession();
207         Queue q = s.getQueue("queue1");
208         assertEquals("Queue size", 0, q.size());
209         Object o = q.take();
210         long t1 = System.currentTimeMillis();
211         t.join();
212         assertNotNull(o);
213         assertEquals("Queue content", "String2", o);
214         assertEquals("Queue size", 0, q.size());
215         assertTrue(t1 - t0 > 100);
216 
217         purgeQueue(q);
218 
219         mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
220     }
221 
222     @Test
223     public void testPutTakeUntakeRollbackUntake() throws Exception
224     {
225         final TransactionalQueueManager mgr = createQueueManager();
226         mgr.start();
227 
228         final Latch latch = new Latch();
229 
230         final Serializable object1 = "string1";
231         final Serializable object2 = "string2";
232 
233         Thread t = new Thread()
234         {
235             @Override
236             public void run()
237             {
238                 try
239                 {
240                     latch.countDown();
241                     Thread.sleep(200);
242                     QueueSession s = mgr.getQueueSession();
243                     Queue q = s.getQueue("queue1");
244                     assertEquals("Queue size", 0, q.size());
245 
246                     s.begin();
247                     q.put(object1);
248                     q.put(object2);
249                     q.take();
250                     q.take();
251                     s.commit();
252 
253                     s.begin();
254                     q.untake(object1);
255                     s.commit();
256 
257                     s.begin();
258                     q.untake(object2);
259                     s.rollback();
260                 }
261                 catch (Exception e)
262                 {
263                     // ignore, let test fail
264                 }
265             }
266         };
267         t.start();
268         latch.await();
269         long t0 = System.currentTimeMillis();
270         QueueSession s = mgr.getQueueSession();
271         Queue q = s.getQueue("queue1");
272         assertEquals("Queue size", 0, q.size());
273         Object o = q.take();
274         long t1 = System.currentTimeMillis();
275         t.join();
276         assertNotNull(o);
277         assertEquals("Queue content", object1, o);
278         assertEquals("Queue size", 0, q.size());
279         assertTrue(t1 - t0 > 100);
280 
281         purgeQueue(q);
282 
283         mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
284     }
285 
286     @Test
287     public void testTakePutOverCapacity() throws Exception
288     {
289         final TransactionalQueueManager mgr = createQueueManager();
290         mgr.start();
291         mgr.setDefaultQueueConfiguration(new QueueConfiguration(2, new SimpleMemoryObjectStore()));
292 
293         final Latch latch = new Latch();
294 
295         Thread t = new Thread()
296         {
297             @Override
298             public void run()
299             {
300                 try
301                 {
302                     latch.await();
303                     Thread.sleep(200);
304                     QueueSession s = mgr.getQueueSession();
305                     Queue q = s.getQueue("queue1");
306                     Object o = q.take();
307                     assertEquals("Queue content", "String1", o);
308                 }
309                 catch (Exception e)
310                 {
311                     // ignore, let test fail
312                 }
313             }
314         };
315         t.start();
316 
317         QueueSession s = mgr.getQueueSession();
318         Queue q = s.getQueue("queue1");
319         assertEquals("Queue size", 0, q.size());
320         q.put("String1");
321         q.put("String2");
322 
323         latch.countDown();
324 
325         long t0 = System.currentTimeMillis();
326         q.put("String3");
327         long t1 = System.currentTimeMillis();
328 
329         t.join();
330 
331         assertEquals("Queue size", 2, q.size());
332         assertTrue(t1 - t0 > 100);
333 
334         purgeQueue(q);
335 
336         mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
337     }
338 
339     @Test
340     public void testPutWithPersistence() throws Exception
341     {
342         if (isPersistent())
343         {
344             TransactionalQueueManager mgr = createQueueManager();
345 
346             try
347             {
348                 QueueSession s = mgr.getQueueSession();
349                 Queue q = s.getQueue("queue1");
350                 mgr.start();
351                 q.put("String1");
352                 assertEquals("Queue size", 1, q.size());
353 
354                 q = s.getQueue("queue1");
355                 assertEquals("Queue size", 1, q.size());
356             }
357             finally
358             {
359                 mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
360             }
361 
362             mgr = createQueueManager();
363             try
364             {
365                 QueueSession s = mgr.getQueueSession();
366                 Queue q = s.getQueue("queue1");
367                 mgr.start();
368                 assertEquals("Queue size", 1, q.size());
369 
370                 purgeQueue(q);
371             }
372             finally
373             {
374                 mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
375             }
376         }
377         else
378         {
379             logger.info("Ignoring test because queue manager is not persistent");
380         }
381     }
382 
383     @Test
384     public void testTransactedPutCommitWithPersistence() throws Exception
385     {
386         if (isPersistent())
387         {
388             TransactionalQueueManager mgr = createQueueManager();
389 
390             try
391             {
392                 QueueSession s = mgr.getQueueSession();
393                 Queue q = s.getQueue("queue1");
394                 mgr.start();
395                 s.begin();
396                 q.put("String1");
397                 assertEquals("Queue size", 1, q.size());
398                 s.commit();
399                 assertEquals("Queue size", 1, q.size());
400 
401                 s = mgr.getQueueSession();
402                 q = s.getQueue("queue1");
403                 assertEquals("Queue size", 1, q.size());
404 
405                 mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
406 
407                 mgr = createQueueManager();
408                 s = mgr.getQueueSession();
409                 q = s.getQueue("queue1");
410                 mgr.start();
411                 assertEquals("Queue size", 1, q.size());
412 
413                 purgeQueue(q);
414             }
415             finally
416             {
417                 mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
418             }
419         }
420         else
421         {
422             logger.info("Ignoring test because queue manager is not persistent");
423         }
424     }
425 
426     @Test
427     public void testTransactedPutRollbackWithPersistence() throws Exception
428     {
429         if (isPersistent())
430         {
431             TransactionalQueueManager mgr = createQueueManager();
432 
433             try
434             {
435                 mgr.start();
436 
437                 QueueSession s = mgr.getQueueSession();
438                 Queue q = s.getQueue("queue1");
439                 s.begin();
440                 q.put("String1");
441                 assertEquals("Queue size", 1, q.size());
442                 s.rollback();
443                 assertEquals("Queue size", 0, q.size());
444 
445                 s = mgr.getQueueSession();
446                 q = s.getQueue("queue1");
447                 assertEquals("Queue size", 0, q.size());
448 
449                 mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
450 
451                 mgr = createQueueManager();
452                 mgr.start();
453                 s = mgr.getQueueSession();
454                 q = s.getQueue("queue1");
455                 assertEquals("Queue size", 0, q.size());
456 
457                 purgeQueue(q);
458             }
459             finally
460             {
461 
462                 mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
463 
464             }
465         }
466         else
467         {
468             logger.info("Ignoring test because queue manager is not persistent");
469         }
470     }
471 
472     @Test
473     public void testPutTake_RespectsOrderOnPersistence() throws Exception
474     {
475         if (isPersistent())
476         {
477             TransactionalQueueManager mgr1 = createQueueManager();
478 
479             QueueSession s1 = mgr1.getQueueSession();
480             Queue q1 = s1.getQueue("queue1");
481             mgr1.start();
482             assertEquals("Queue size", 0, q1.size());
483             final int numberOfElements = 10;
484             for (int i = 1; i <= numberOfElements; i++)
485             {
486                 q1.put("String" + i);
487                 assertEquals("Queue size", i, q1.size());
488             }
489 
490             mgr1.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
491 
492             TransactionalQueueManager mgr2 = createQueueManager();
493 
494             QueueSession s2 = mgr2.getQueueSession();
495             Queue q2 = s2.getQueue("queue1");
496             mgr2.start();
497             for (int i = 1; i <= numberOfElements; i++)
498             {
499                 Object o = q2.take();
500                 assertNotNull(o);
501                 assertEquals("Queue content", "String" + i, o);
502             }
503             assertEquals("Queue size", 0, q2.size());
504 
505             purgeQueue(q2);
506 
507             mgr2.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
508         }
509     }
510 
511     @Test
512     public void testTransactionsOnMultipleQueues() throws Exception
513     {
514 
515         TransactionalQueueManager mgr = createQueueManager();
516 
517         try
518         {
519             mgr.start();
520 
521             QueueSession s1 = mgr.getQueueSession();
522             QueueSession s2 = mgr.getQueueSession();
523 
524             Queue q1s1 = s1.getQueue("queue1");
525             Queue q1s2 = s2.getQueue("queue1");
526             Queue q2s1 = s1.getQueue("queue2");
527             Queue q2s2 = s2.getQueue("queue2");
528 
529             q1s1.put("String1");
530             assertEquals("Queue size", 1, q1s1.size());
531             assertEquals("Queue size", 1, q1s2.size());
532 
533             s1.begin();
534 
535             Object o = q1s1.take();
536             assertNotNull(o);
537             assertEquals("String1", o);
538             assertEquals("Queue size", 0, q1s1.size());
539             assertEquals("Queue size", 0, q1s2.size());
540             q2s1.put("String2");
541             assertEquals("Queue size", 1, q2s1.size());
542             assertEquals("Queue size", 0, q2s2.size());
543 
544             s1.commit();
545 
546             assertEquals("Queue size", 0, q1s1.size());
547             assertEquals("Queue size", 0, q1s2.size());
548             assertEquals("Queue size", 1, q2s1.size());
549             assertEquals("Queue size", 1, q2s2.size());
550 
551             s1.begin();
552 
553             o = q2s1.take();
554             assertNotNull(o);
555             assertEquals("String2", o);
556             assertEquals("Queue size", 0, q1s1.size());
557             assertEquals("Queue size", 0, q1s2.size());
558             assertEquals("Queue size", 0, q2s1.size());
559             assertEquals("Queue size", 0, q2s2.size());
560 
561             q1s1.put("String1");
562 
563             assertEquals("Queue size", 1, q1s1.size());
564             assertEquals("Queue size", 0, q1s2.size());
565             assertEquals("Queue size", 0, q2s1.size());
566             assertEquals("Queue size", 0, q2s2.size());
567 
568             s1.rollback();
569 
570             assertEquals("Queue size", 0, q1s1.size());
571             assertEquals("Queue size", 0, q1s2.size());
572             assertEquals("Queue size", 1, q2s1.size());
573             assertEquals("Queue size", 1, q2s2.size());
574 
575             purgeQueue(q1s1);
576             purgeQueue(q1s2);
577             purgeQueue(q2s1);
578             purgeQueue(q2s2);
579         }
580         finally
581         {
582             mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
583         }
584     }
585 
586     @Test
587     public void testPoll() throws Exception
588     {
589         final TransactionalQueueManager mgr = createQueueManager();
590 
591         try
592         {
593             mgr.start();
594 
595             QueueSession s = mgr.getQueueSession();
596             Queue q = s.getQueue("queue1");
597 
598             assertEquals("Queue size", 0, q.size());
599             Object o = q.poll(0);
600             assertEquals("Queue size", 0, q.size());
601             assertNull(o);
602             o = q.poll(1000);
603             assertEquals("Queue size", 0, q.size());
604             assertNull(o);
605             q.put("String1");
606             assertEquals("Queue size", 1, q.size());
607             o = q.poll(0);
608             assertEquals("Queue size", 0, q.size());
609             assertEquals("Queue content", "String1", o);
610 
611             new Thread(new Runnable()
612             {
613                 public void run()
614                 {
615                     try
616                     {
617                         Thread.sleep(500);
618                         QueueSession s = mgr.getQueueSession();
619                         Queue q = s.getQueue("queue1");
620                         q.put("String1");
621                     }
622                     catch (Exception e)
623                     {
624                         e.printStackTrace();
625                     }
626                 }
627             }).start();
628             o = q.poll(1000);
629             assertEquals("Queue size", q.size(), 0);
630             assertEquals("Queue content", "String1", o);
631 
632             purgeQueue(q);
633         }
634         finally
635         {
636             mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
637         }
638     }
639 
640     @Test
641     public void testPeek() throws Exception
642     {
643 
644         TransactionalQueueManager mgr = createQueueManager();
645 
646         try
647         {
648             mgr.start();
649 
650             QueueSession s = mgr.getQueueSession();
651             Queue q = s.getQueue("queue1");
652 
653             assertEquals("Queue size", 0, q.size());
654             Object o = q.peek();
655             assertEquals("Queue size", 0, q.size());
656             assertNull(o);
657             q.put("String1");
658             assertEquals("Queue size", 1, q.size());
659             o = q.peek();
660             assertEquals("Queue size", 1, q.size());
661             assertEquals("Queue content", "String1", o);
662             o = q.poll(1000);
663             assertEquals("Queue size", 0, q.size());
664             assertEquals("Queue content", "String1", o);
665 
666             purgeQueue(q);
667         }
668         finally
669         {
670             mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
671         }
672     }
673 
674     @Test
675     public void testOffer() throws Exception
676     {
677 
678         final TransactionalQueueManager mgr = createQueueManager();
679         mgr.setDefaultQueueConfiguration(new QueueConfiguration(1, new SimpleMemoryObjectStore()));
680         try
681         {
682             mgr.start();
683 
684             QueueSession s = mgr.getQueueSession();
685             Queue q = s.getQueue("queue1");
686 
687             assertEquals("Queue size", 0, q.size());
688             assertTrue(q.offer("String1", 0L));
689             assertEquals("Queue size", 1, q.size());
690             assertFalse(q.offer("String2", 1000));
691             assertEquals("Queue size", 1, q.size());
692 
693             new Thread(new Runnable()
694             {
695                 public void run()
696                 {
697                     try
698                     {
699                         Thread.sleep(500);
700                         QueueSession s = mgr.getQueueSession();
701                         Queue q = s.getQueue("queue1");
702                         assertEquals("Queue content", "String1", q.take());
703                     }
704                     catch (Exception e)
705                     {
706                         e.printStackTrace();
707                     }
708                 }
709             }).start();
710             assertTrue(q.offer("String2", 1000));
711             assertEquals("Queue size", 1, q.size());
712 
713             purgeQueue(q);
714         }
715         finally
716         {
717             mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
718         }
719     }
720 
721     @Test
722     public void testBench() throws Exception
723     {
724 
725         TransactionalQueueManager mgr = createQueueManager();
726 
727         try
728         {
729             mgr.start();
730 
731             QueueSession s = mgr.getQueueSession();
732             Queue q = s.getQueue("queue1");
733 
734             Random rnd = new Random();
735             long t0 = System.currentTimeMillis();
736             for (int i = 0; i < 1; i++)
737             {
738                 for (int j = 0; j < 500; j++)
739                 {
740                     byte[] o = new byte[2048];
741                     rnd.nextBytes(o);
742                     q.put(o);
743                 }
744                 while (q.size() > 0)
745                 {
746                     q.take();
747                 }
748             }
749             long t1 = System.currentTimeMillis();
750 
751             logger.info("Time: " + (t1 - t0) + " ms");
752 
753             purgeQueue(q);
754         }
755         finally
756         {
757             mgr.stop(AbstractResourceManager.SHUTDOWN_MODE_NORMAL);
758         }
759     }
760 
761     protected void purgeQueue(Queue queue) throws InterruptedException
762     {
763         while (queue.size() > 0)
764         {
765             queue.poll(1000);
766         }
767         assertEquals("Queue must be fully consumed after successful test run. Queue size:", 0, queue.size());
768     }
769 
770     @Test
771     public void testRecoverWarmRestart() throws Exception
772     {
773         TransactionalQueueManager mgr = createQueueManager();
774         mgr.start();
775         QueueSession s = mgr.getQueueSession();
776         Queue q = s.getQueue("warmRecoverQueue");
777 
778         int toPopulate = 500;
779 
780         // Populate queue
781         Random rnd = new Random();
782         for (int j = 0; j < toPopulate; j++)
783         {
784             byte[] o = new byte[2048];
785             rnd.nextBytes(o);
786             q.put(o);
787         }
788         assertEquals(q.size(), toPopulate);
789 
790         // Stop and start TransactionalQueueManager
791         mgr.stop();
792         mgr.start();
793 
794         assertEquals(toPopulate, q.size());
795     }
796 
797     @Test
798     public void testRecoverColdRestart() throws Exception
799     {
800         TransactionalQueueManager mgr = createQueueManager();
801         QueueSession s = mgr.getQueueSession();
802         Queue q = s.getQueue("warmRecoverQueue");
803         mgr.start();
804 
805         int toPopulate = 500;
806 
807         // Populate queue
808         Random rnd = new Random();
809         for (int j = 0; j < toPopulate; j++)
810         {
811             byte[] o = new byte[2048];
812             rnd.nextBytes(o);
813             q.put(o);
814         }
815         assertEquals(toPopulate, q.size());
816 
817         // Stop and recreate TransactionalQueueManager simulating a cold restart
818         mgr.stop();
819         mgr = createQueueManager();
820         s = mgr.getQueueSession();
821         q = s.getQueue("warmRecoverQueue");
822         mgr.start();
823         if (isPersistent())
824         {
825             assertEquals(toPopulate, q.size());
826         }
827         else
828         {
829             assertEquals(0, q.size());
830         }
831 
832     }
833 
834 }