|
1 | 1 | package com.rabbitmq.client.test.functional; |
2 | 2 |
|
3 | 3 | import com.rabbitmq.client.*; |
4 | | -import com.rabbitmq.client.impl.recovery.AutorecoveringChannel; |
5 | | -import com.rabbitmq.client.impl.recovery.AutorecoveringConnection; |
| 4 | +import com.rabbitmq.client.impl.AMQConnection; |
| 5 | +import com.rabbitmq.client.impl.recovery.*; |
6 | 6 | import com.rabbitmq.client.Recoverable; |
7 | 7 | import com.rabbitmq.client.RecoveryListener; |
8 | | -import com.rabbitmq.client.impl.recovery.ConsumerRecoveryListener; |
9 | | -import com.rabbitmq.client.impl.recovery.QueueRecoveryListener; |
10 | 8 | import com.rabbitmq.client.test.BrokerTestCase; |
11 | 9 | import com.rabbitmq.tools.Host; |
12 | 10 |
|
|
21 | 19 | import java.util.concurrent.atomic.AtomicInteger; |
22 | 20 | import java.util.concurrent.atomic.AtomicReference; |
23 | 21 |
|
| 22 | +@SuppressWarnings("ThrowFromFinallyBlock") |
24 | 23 | public class ConnectionRecovery extends BrokerTestCase { |
25 | | - public static final long RECOVERY_INTERVAL = 2000; |
| 24 | + private static final long RECOVERY_INTERVAL = 2000; |
26 | 25 |
|
27 | 26 | public void testConnectionRecovery() throws IOException, InterruptedException { |
28 | 27 | assertTrue(connection.isOpen()); |
@@ -89,6 +88,44 @@ public void testConnectionRecoveryWithDisabledTopologyRecovery() |
89 | 88 | } |
90 | 89 | } |
91 | 90 |
|
| 91 | + // see https://github.com/rabbitmq/rabbitmq-java-client/issues/135 |
| 92 | + public void testThatShutdownHooksOnConnectionFireBeforeRecoveryStarts() throws IOException, InterruptedException { |
| 93 | + final List<String> events = new ArrayList<String>(); |
| 94 | + final CountDownLatch latch = new CountDownLatch(1); |
| 95 | + connection.addShutdownListener(new ShutdownListener() { |
| 96 | + public void shutdownCompleted(ShutdownSignalException cause) { |
| 97 | + events.add("shutdown hook 1"); |
| 98 | + } |
| 99 | + }); |
| 100 | + connection.addShutdownListener(new ShutdownListener() { |
| 101 | + public void shutdownCompleted(ShutdownSignalException cause) { |
| 102 | + events.add("shutdown hook 2"); |
| 103 | + } |
| 104 | + }); |
| 105 | + // note: we do not want to expose RecoveryCanBeginListener so this |
| 106 | + // test does not use it |
| 107 | + ((AutorecoveringConnection)connection).getDelegate().addRecoveryCanBeginListener(new RecoveryCanBeginListener() { |
| 108 | + @Override |
| 109 | + public void recoveryCanBegin(ShutdownSignalException cause) { |
| 110 | + events.add("recovery start hook 1"); |
| 111 | + } |
| 112 | + }); |
| 113 | + ((AutorecoveringConnection)connection).addRecoveryListener(new RecoveryListener() { |
| 114 | + @Override |
| 115 | + public void handleRecovery(Recoverable recoverable) { |
| 116 | + latch.countDown(); |
| 117 | + } |
| 118 | + }); |
| 119 | + assertTrue(connection.isOpen()); |
| 120 | + closeAndWaitForRecovery(); |
| 121 | + assertTrue(connection.isOpen()); |
| 122 | + assertEquals("shutdown hook 1", events.get(0)); |
| 123 | + assertEquals("shutdown hook 2", events.get(1)); |
| 124 | + assertEquals("recovery start hook 1", events.get(2)); |
| 125 | + connection.close(); |
| 126 | + wait(latch); |
| 127 | + } |
| 128 | + |
92 | 129 | public void testShutdownHooksRecoveryOnConnection() throws IOException, InterruptedException { |
93 | 130 | final CountDownLatch latch = new CountDownLatch(2); |
94 | 131 | connection.addShutdownListener(new ShutdownListener() { |
@@ -211,7 +248,7 @@ public void testClientNamedQueueRecoveryWithNoWait() throws IOException, Interru |
211 | 248 | testClientNamedQueueRecoveryWith("java-client.test.recovery.q1-nowait", true); |
212 | 249 | } |
213 | 250 |
|
214 | | - protected void testClientNamedQueueRecoveryWith(String q, boolean noWait) throws IOException, InterruptedException, TimeoutException { |
| 251 | + private void testClientNamedQueueRecoveryWith(String q, boolean noWait) throws IOException, InterruptedException, TimeoutException { |
215 | 252 | Channel ch = connection.createChannel(); |
216 | 253 | if(noWait) { |
217 | 254 | declareClientNamedQueueNoWait(ch, q); |
@@ -750,20 +787,20 @@ private ConnectionFactory buildConnectionFactoryWithRecoveryEnabled(boolean disa |
750 | 787 | } |
751 | 788 |
|
752 | 789 | private static void wait(CountDownLatch latch) throws InterruptedException { |
753 | | - // Very very generous amount of time to wait, just make sure we never |
754 | | - // hang forever |
755 | | - assertTrue(latch.await(1800, TimeUnit.SECONDS)); |
| 790 | + // we want to wait for recovery to complete for a reasonable amount of time |
| 791 | + // but still make recovery failures easy to notice in development environments |
| 792 | + assertTrue(latch.await(90, TimeUnit.SECONDS)); |
756 | 793 | } |
757 | 794 |
|
758 | 795 | private void waitForConfirms(Channel ch) throws InterruptedException, TimeoutException { |
759 | 796 | ch.waitForConfirms(30 * 60 * 1000); |
760 | 797 | } |
761 | 798 |
|
762 | | - protected void assertRecordedQueues(Connection conn, int size) { |
| 799 | + private void assertRecordedQueues(Connection conn, int size) { |
763 | 800 | assertEquals(size, ((AutorecoveringConnection)conn).getRecordedQueues().size()); |
764 | 801 | } |
765 | 802 |
|
766 | | - protected void assertRecordedExchanges(Connection conn, int size) { |
| 803 | + private void assertRecordedExchanges(Connection conn, int size) { |
767 | 804 | assertEquals(size, ((AutorecoveringConnection)conn).getRecordedExchanges().size()); |
768 | 805 | } |
769 | 806 | } |
0 commit comments