1
2
3
4
5
6
7
8
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
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
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
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
156 q.untake(o);
157
158 assertEquals("Queue size", 2, q.size());
159
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
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
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
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
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
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
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
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 }