13
13
// If you have any questions regarding licensing, please contact us at
14
14
// info@rabbitmq.com.
15
15
16
-
17
16
package com .rabbitmq .client .test ;
18
17
19
- import com .rabbitmq .client .*;
18
+ import com .rabbitmq .client .AMQP ;
19
+ import com .rabbitmq .client .Channel ;
20
+ import com .rabbitmq .client .Connection ;
21
+ import com .rabbitmq .client .ConnectionFactory ;
22
+ import com .rabbitmq .client .QueueingConsumer ;
23
+ import com .rabbitmq .client .Recoverable ;
24
+ import com .rabbitmq .client .RecoveryListener ;
25
+ import com .rabbitmq .client .RpcClient ;
26
+ import com .rabbitmq .client .RpcServer ;
27
+ import com .rabbitmq .client .ShutdownSignalException ;
20
28
import com .rabbitmq .client .impl .NetworkConnection ;
21
29
import com .rabbitmq .client .impl .recovery .AutorecoveringConnection ;
30
+ import com .rabbitmq .client .impl .recovery .RecordedBinding ;
31
+ import com .rabbitmq .client .impl .recovery .RecordedConsumer ;
32
+ import com .rabbitmq .client .impl .recovery .RecordedExchange ;
33
+ import com .rabbitmq .client .impl .recovery .RecordedQueue ;
34
+ import com .rabbitmq .client .impl .recovery .TopologyRecoveryFilter ;
22
35
import com .rabbitmq .tools .Host ;
23
36
import org .junit .After ;
24
37
import org .junit .Before ;
32
45
33
46
import static org .junit .Assert .assertEquals ;
34
47
import static org .junit .Assert .assertTrue ;
48
+ import static org .junit .Assert .fail ;
35
49
36
50
public class RpcTest {
37
51
@@ -40,19 +54,21 @@ public class RpcTest {
40
54
String queue = "rpc.queue" ;
41
55
RpcServer rpcServer ;
42
56
43
- @ Before public void init () throws Exception {
57
+ @ Before
58
+ public void init () throws Exception {
44
59
clientConnection = TestUtils .connectionFactory ().newConnection ();
45
60
clientChannel = clientConnection .createChannel ();
46
61
serverConnection = TestUtils .connectionFactory ().newConnection ();
47
62
serverChannel = serverConnection .createChannel ();
48
63
serverChannel .queueDeclare (queue , false , false , false , null );
49
64
}
50
65
51
- @ After public void tearDown () throws Exception {
52
- if (rpcServer != null ) {
66
+ @ After
67
+ public void tearDown () throws Exception {
68
+ if (rpcServer != null ) {
53
69
rpcServer .terminateMainloop ();
54
70
}
55
- if (serverChannel != null ) {
71
+ if (serverChannel != null ) {
56
72
serverChannel .queueDelete (queue );
57
73
}
58
74
clientConnection .close ();
@@ -63,6 +79,7 @@ public class RpcTest {
63
79
public void rpc () throws Exception {
64
80
rpcServer = new TestRpcServer (serverChannel , queue );
65
81
new Thread (new Runnable () {
82
+
66
83
@ Override
67
84
public void run () {
68
85
try {
@@ -81,10 +98,12 @@ public void run() {
81
98
client .close ();
82
99
}
83
100
84
- @ Test public void brokenAfterBrokerRestart () throws Exception {
101
+ @ Test
102
+ public void givenConsumerNotRecoveredCanCreateNewClientOnSameChannelAfterConnectionFailure () throws Exception {
85
103
// see https://github.com/rabbitmq/rabbitmq-java-client/issues/382
86
104
rpcServer = new TestRpcServer (serverChannel , queue );
87
105
new Thread (new Runnable () {
106
+
88
107
@ Override
89
108
public void run () {
90
109
try {
@@ -96,8 +115,8 @@ public void run() {
96
115
}).start ();
97
116
98
117
ConnectionFactory cf = TestUtils .connectionFactory ();
99
- cf .setTopologyRecoveryEnabled ( false );
100
- cf .setNetworkRecoveryInterval (2000 );
118
+ cf .setTopologyRecoveryFilter ( new NoDirectReplyToConsumerTopologyRecoveryFilter () );
119
+ cf .setNetworkRecoveryInterval (1000 );
101
120
Connection connection = null ;
102
121
try {
103
122
connection = cf .newConnection ();
@@ -107,10 +126,12 @@ public void run() {
107
126
assertEquals ("*** hello ***" , new String (response .getBody ()));
108
127
final CountDownLatch recoveryLatch = new CountDownLatch (1 );
109
128
((AutorecoveringConnection ) connection ).addRecoveryListener (new RecoveryListener () {
129
+
110
130
@ Override
111
131
public void handleRecovery (Recoverable recoverable ) {
112
132
recoveryLatch .countDown ();
113
133
}
134
+
114
135
@ Override
115
136
public void handleRecoveryStarted (Recoverable recoverable ) {
116
137
@@ -126,7 +147,62 @@ public void handleRecoveryStarted(Recoverable recoverable) {
126
147
connection .close ();
127
148
}
128
149
}
150
+ }
151
+
152
+ @ Test
153
+ public void givenConsumerIsRecoveredCanNotCreateNewClientOnSameChannelAfterConnectionFailure () throws Exception {
154
+ // see https://github.com/rabbitmq/rabbitmq-java-client/issues/382
155
+ rpcServer = new TestRpcServer (serverChannel , queue );
156
+ new Thread (new Runnable () {
157
+
158
+ @ Override
159
+ public void run () {
160
+ try {
161
+ rpcServer .mainloop ();
162
+ } catch (Exception e ) {
163
+ // safe to ignore when loops ends/server is canceled
164
+ }
165
+ }
166
+ }).start ();
167
+
168
+ ConnectionFactory cf = TestUtils .connectionFactory ();
169
+ cf .setNetworkRecoveryInterval (1000 );
170
+ Connection connection = null ;
171
+ try {
172
+ connection = cf .newConnection ();
173
+ Channel channel = connection .createChannel ();
174
+ RpcClient client = new RpcClient (channel , "" , queue , 1000 );
175
+ RpcClient .Response response = client .doCall (null , "hello" .getBytes ());
176
+ assertEquals ("*** hello ***" , new String (response .getBody ()));
177
+ final CountDownLatch recoveryLatch = new CountDownLatch (1 );
178
+ ((AutorecoveringConnection ) connection ).addRecoveryListener (new RecoveryListener () {
129
179
180
+ @ Override
181
+ public void handleRecovery (Recoverable recoverable ) {
182
+ recoveryLatch .countDown ();
183
+ }
184
+
185
+ @ Override
186
+ public void handleRecoveryStarted (Recoverable recoverable ) {
187
+
188
+ }
189
+ });
190
+ Host .closeConnection ((NetworkConnection ) connection );
191
+ assertTrue ("Connection should have recovered by now" , recoveryLatch .await (10 , TimeUnit .SECONDS ));
192
+ try {
193
+ new RpcClient (channel , "" , queue , 1000 );
194
+ fail ("Cannot create RPC client on same channel, an exception should have been thrown" );
195
+ } catch (IOException e ) {
196
+ assertTrue (e .getCause () instanceof ShutdownSignalException );
197
+ ShutdownSignalException cause = (ShutdownSignalException ) e .getCause ();
198
+ assertTrue (cause .getReason () instanceof AMQP .Channel .Close );
199
+ assertEquals (406 , ((AMQP .Channel .Close ) cause .getReason ()).getReplyCode ());
200
+ }
201
+ } finally {
202
+ if (connection != null ) {
203
+ connection .close ();
204
+ }
205
+ }
130
206
}
131
207
132
208
private static class TestRpcServer extends RpcServer {
@@ -157,4 +233,27 @@ protected AMQP.BasicProperties postprocessReplyProperties(QueueingConsumer.Deliv
157
233
return builder .build ();
158
234
}
159
235
}
236
+
237
+ private static class NoDirectReplyToConsumerTopologyRecoveryFilter implements TopologyRecoveryFilter {
238
+
239
+ @ Override
240
+ public boolean filterExchange (RecordedExchange recordedExchange ) {
241
+ return true ;
242
+ }
243
+
244
+ @ Override
245
+ public boolean filterQueue (RecordedQueue recordedQueue ) {
246
+ return true ;
247
+ }
248
+
249
+ @ Override
250
+ public boolean filterBinding (RecordedBinding recordedBinding ) {
251
+ return true ;
252
+ }
253
+
254
+ @ Override
255
+ public boolean filterConsumer (RecordedConsumer recordedConsumer ) {
256
+ return !"amq.rabbitmq.reply-to" .equals (recordedConsumer .getQueue ());
257
+ }
258
+ }
160
259
}
0 commit comments