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