16
16
import redis .clients .jedis .JedisClientConfig ;
17
17
import redis .clients .jedis .MultiClusterClientConfig ;
18
18
import redis .clients .jedis .providers .MultiClusterPooledConnectionProvider ;
19
- import java . lang . reflect . Method ;
19
+ import redis . clients . jedis . providers . MultiClusterPooledConnectionProviderHelper ;
20
20
21
21
@ ExtendWith (MockitoExtension .class )
22
22
class FailbackMechanismIntegrationTest {
@@ -43,23 +43,6 @@ private MockedConstruction<ConnectionPool> mockPool() {
43
43
});
44
44
}
45
45
46
- /**
47
- * Helper method to trigger health status changes using reflection
48
- */
49
- private void triggerHealthStatusChange (MultiClusterPooledConnectionProvider provider , HostAndPort endpoint ,
50
- HealthStatus oldStatus , HealthStatus newStatus ) {
51
- try {
52
- Method handleHealthStatusChange = MultiClusterPooledConnectionProvider .class
53
- .getDeclaredMethod ("handleHealthStatusChange" , HealthStatusChangeEvent .class );
54
- handleHealthStatusChange .setAccessible (true );
55
-
56
- HealthStatusChangeEvent event = new HealthStatusChangeEvent (endpoint , oldStatus , newStatus );
57
- handleHealthStatusChange .invoke (provider , event );
58
- } catch (Exception e ) {
59
- throw new RuntimeException ("Failed to trigger health status change" , e );
60
- }
61
- }
62
-
63
46
@ Test
64
47
void testFailbackDisabledDoesNotPerformFailback () throws InterruptedException {
65
48
try (MockedConstruction <ConnectionPool > mockedPool = mockPool ()) {
@@ -81,13 +64,13 @@ void testFailbackDisabledDoesNotPerformFailback() throws InterruptedException {
81
64
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
82
65
83
66
// Make cluster2 unhealthy to force failover to cluster1
84
- triggerHealthStatusChange (provider , endpoint2 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
67
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint2 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
85
68
86
69
// Should now be on cluster1 (only healthy option)
87
70
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
88
71
89
72
// Make cluster2 healthy again (higher weight - would normally trigger failback)
90
- triggerHealthStatusChange (provider , endpoint2 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
73
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint2 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
91
74
92
75
// Wait longer than failback interval
93
76
Thread .sleep (200 );
@@ -121,13 +104,13 @@ void testFailbackToHigherWeightCluster() throws InterruptedException {
121
104
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
122
105
123
106
// Make cluster1 unhealthy to force failover to cluster2
124
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
107
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
125
108
126
109
// Should now be on cluster2 (lower weight, but only healthy option)
127
110
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
128
111
129
112
// Make cluster1 healthy again
130
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
113
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
131
114
132
115
// Wait for failback check interval + some buffer
133
116
Thread .sleep (250 );
@@ -163,14 +146,14 @@ void testNoFailbackToLowerWeightCluster() throws InterruptedException {
163
146
assertEquals (provider .getCluster (endpoint3 ), provider .getCluster ());
164
147
165
148
// Make cluster3 unhealthy to force failover to cluster2 (medium weight)
166
- triggerHealthStatusChange (provider , endpoint3 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
149
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint3 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
167
150
168
151
// Should now be on cluster2 (highest weight among healthy clusters)
169
152
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
170
153
171
154
// Make cluster1 (lowest weight) healthy - this should NOT trigger failback
172
155
// since we don't failback to lower weight clusters
173
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
156
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
174
157
175
158
// Wait for failback check interval
176
159
Thread .sleep (250 );
@@ -199,13 +182,13 @@ void testFailbackToHigherWeightClusterImmediately() throws InterruptedException
199
182
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
200
183
201
184
// Make cluster1 unhealthy to force failover to cluster2
202
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
185
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
203
186
204
187
// Should now be on cluster2 (only healthy option)
205
188
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
206
189
207
190
// Make cluster1 healthy again
208
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
191
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
209
192
210
193
// Wait for failback check
211
194
Thread .sleep (150 );
@@ -234,19 +217,19 @@ void testUnhealthyClusterCancelsFailback() throws InterruptedException {
234
217
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
235
218
236
219
// Make cluster1 unhealthy to force failover to cluster2
237
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
220
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
238
221
239
222
// Should now be on cluster2 (only healthy option)
240
223
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
241
224
242
225
// Make cluster1 healthy again (should trigger failback attempt)
243
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
226
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
244
227
245
228
// Wait a bit
246
229
Thread .sleep (100 );
247
230
248
231
// Make cluster1 unhealthy again before failback completes
249
- triggerHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
232
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint1 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
250
233
251
234
// Wait past the original failback interval
252
235
Thread .sleep (150 );
@@ -279,13 +262,13 @@ void testMultipleClusterFailbackPriority() throws InterruptedException {
279
262
assertEquals (provider .getCluster (endpoint3 ), provider .getCluster ());
280
263
281
264
// Make cluster3 unhealthy to force failover to cluster2 (next highest weight)
282
- triggerHealthStatusChange (provider , endpoint3 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
265
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint3 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
283
266
284
267
// Should now be on cluster2 (highest weight among healthy clusters)
285
268
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
286
269
287
270
// Make cluster3 healthy again
288
- triggerHealthStatusChange (provider , endpoint3 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
271
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint3 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
289
272
290
273
// Wait for failback
291
274
Thread .sleep (200 );
@@ -315,7 +298,7 @@ void testGracePeriodDisablesClusterOnUnhealthy() throws InterruptedException {
315
298
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
316
299
317
300
// Now make cluster2 unhealthy - it should be disabled for grace period
318
- triggerHealthStatusChange (provider , endpoint2 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
301
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint2 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
319
302
320
303
// Should failover to cluster1
321
304
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
@@ -346,7 +329,7 @@ void testGracePeriodReEnablesClusterAfterPeriod() throws InterruptedException {
346
329
assertEquals (provider .getCluster (endpoint2 ), provider .getCluster ());
347
330
348
331
// Make cluster2 unhealthy to start grace period and force failover
349
- triggerHealthStatusChange (provider , endpoint2 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
332
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint2 , HealthStatus .HEALTHY , HealthStatus .UNHEALTHY );
350
333
351
334
// Should failover to cluster1
352
335
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
@@ -355,7 +338,7 @@ void testGracePeriodReEnablesClusterAfterPeriod() throws InterruptedException {
355
338
assertTrue (provider .getCluster (endpoint2 ).isInGracePeriod ());
356
339
357
340
// Make cluster2 healthy again while it's still in grace period
358
- triggerHealthStatusChange (provider , endpoint2 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
341
+ MultiClusterPooledConnectionProviderHelper . onHealthStatusChange (provider , endpoint2 , HealthStatus .UNHEALTHY , HealthStatus .HEALTHY );
359
342
360
343
// Should still be on cluster1 because cluster2 is in grace period
361
344
assertEquals (provider .getCluster (endpoint1 ), provider .getCluster ());
0 commit comments