87
87
import org .apache .pulsar .broker .loadbalance .impl .ModularLoadManagerImpl ;
88
88
import org .apache .pulsar .broker .lookup .LookupResult ;
89
89
import org .apache .pulsar .broker .namespace .LookupOptions ;
90
+ import org .apache .pulsar .broker .namespace .NamespaceBundleOwnershipListener ;
91
+ import org .apache .pulsar .broker .namespace .NamespaceBundleSplitListener ;
90
92
import org .apache .pulsar .broker .testcontext .PulsarTestContext ;
91
93
import org .apache .pulsar .client .admin .PulsarAdminException ;
92
94
import org .apache .pulsar .client .impl .TableViewImpl ;
@@ -126,6 +128,8 @@ public class ExtensibleLoadManagerImplTest extends MockedPulsarServiceBaseTest {
126
128
private ServiceUnitStateChannelImpl channel1 ;
127
129
private ServiceUnitStateChannelImpl channel2 ;
128
130
131
+ private final String defaultTestNamespace = "public/test" ;
132
+
129
133
@ BeforeClass
130
134
@ Override
131
135
public void setup () throws Exception {
@@ -136,6 +140,7 @@ public void setup() throws Exception {
136
140
conf .setLoadBalancerLoadSheddingStrategy (TransferShedder .class .getName ());
137
141
conf .setLoadBalancerSheddingEnabled (false );
138
142
conf .setLoadBalancerDebugModeEnabled (true );
143
+ conf .setTopicLevelPoliciesEnabled (false );
139
144
super .internalSetup (conf );
140
145
pulsar1 = pulsar ;
141
146
ServiceConfiguration defaultConf = getDefaultConf ();
@@ -144,6 +149,7 @@ public void setup() throws Exception {
144
149
defaultConf .setLoadManagerClassName (ExtensibleLoadManagerImpl .class .getName ());
145
150
defaultConf .setLoadBalancerLoadSheddingStrategy (TransferShedder .class .getName ());
146
151
defaultConf .setLoadBalancerSheddingEnabled (false );
152
+ defaultConf .setTopicLevelPoliciesEnabled (false );
147
153
additionalPulsarTestContext = createAdditionalPulsarTestContext (defaultConf );
148
154
pulsar2 = additionalPulsarTestContext .getPulsarService ();
149
155
@@ -159,6 +165,10 @@ public void setup() throws Exception {
159
165
admin .namespaces ().createNamespace ("public/default" );
160
166
admin .namespaces ().setNamespaceReplicationClusters ("public/default" ,
161
167
Sets .newHashSet (this .conf .getClusterName ()));
168
+
169
+ admin .namespaces ().createNamespace (defaultTestNamespace );
170
+ admin .namespaces ().setNamespaceReplicationClusters (defaultTestNamespace ,
171
+ Sets .newHashSet (this .conf .getClusterName ()));
162
172
}
163
173
164
174
@ Override
@@ -172,7 +182,7 @@ protected void cleanup() throws Exception {
172
182
173
183
@ BeforeMethod (alwaysRun = true )
174
184
protected void initializeState () throws PulsarAdminException {
175
- admin .namespaces ().unload ("public/default" );
185
+ admin .namespaces ().unload (defaultTestNamespace );
176
186
reset (primaryLoadManager , secondaryLoadManager );
177
187
}
178
188
@@ -196,7 +206,7 @@ public void testAssignInternalTopic() throws Exception {
196
206
197
207
@ Test
198
208
public void testAssign () throws Exception {
199
- TopicName topicName = TopicName .get (" test-assign" );
209
+ TopicName topicName = TopicName .get (defaultTestNamespace + "/ test-assign" );
200
210
NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
201
211
Optional <BrokerLookupData > brokerLookupData = primaryLoadManager .assign (Optional .empty (), bundle ).get ();
202
212
assertTrue (brokerLookupData .isPresent ());
@@ -221,7 +231,8 @@ public void testAssign() throws Exception {
221
231
222
232
@ Test
223
233
public void testCheckOwnershipAsync () throws Exception {
224
- NamespaceBundle bundle = getBundleAsync (pulsar1 , TopicName .get ("test-check-ownership" )).get ();
234
+ TopicName topicName = TopicName .get (defaultTestNamespace + "/test-check-ownership" );
235
+ NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
225
236
// 1. The bundle is never assigned.
226
237
assertFalse (primaryLoadManager .checkOwnershipAsync (Optional .empty (), bundle ).get ());
227
238
assertFalse (secondaryLoadManager .checkOwnershipAsync (Optional .empty (), bundle ).get ());
@@ -241,7 +252,7 @@ public void testCheckOwnershipAsync() throws Exception {
241
252
242
253
@ Test
243
254
public void testFilter () throws Exception {
244
- TopicName topicName = TopicName .get (" test-filter" );
255
+ TopicName topicName = TopicName .get (defaultTestNamespace + "/ test-filter" );
245
256
NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
246
257
247
258
doReturn (List .of (new BrokerFilter () {
@@ -267,7 +278,7 @@ public Map<String, BrokerLookupData> filter(Map<String, BrokerLookupData> broker
267
278
268
279
@ Test
269
280
public void testFilterHasException () throws Exception {
270
- TopicName topicName = TopicName .get (" test-filter-has-exception" );
281
+ TopicName topicName = TopicName .get (defaultTestNamespace + "/ test-filter-has-exception" );
271
282
NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
272
283
273
284
doReturn (List .of (new MockBrokerFilter () {
@@ -286,20 +297,58 @@ public Map<String, BrokerLookupData> filter(Map<String, BrokerLookupData> broker
286
297
287
298
@ Test (timeOut = 30 * 1000 )
288
299
public void testUnloadAdminAPI () throws Exception {
289
- TopicName topicName = TopicName .get (" test-unload" );
300
+ TopicName topicName = TopicName .get (defaultTestNamespace + "/ test-unload" );
290
301
NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
291
302
303
+ AtomicInteger onloadCount = new AtomicInteger (0 );
304
+ AtomicInteger unloadCount = new AtomicInteger (0 );
305
+
306
+ NamespaceBundleOwnershipListener listener = new NamespaceBundleOwnershipListener () {
307
+ @ Override
308
+ public void onLoad (NamespaceBundle bundle ) {
309
+ onloadCount .incrementAndGet ();
310
+ }
311
+
312
+ @ Override
313
+ public void unLoad (NamespaceBundle bundle ) {
314
+ unloadCount .incrementAndGet ();
315
+ }
316
+
317
+ @ Override
318
+ public boolean test (NamespaceBundle namespaceBundle ) {
319
+ return namespaceBundle .equals (bundle );
320
+ }
321
+ };
322
+ pulsar1 .getNamespaceService ().addNamespaceBundleOwnershipListener (listener );
323
+ pulsar2 .getNamespaceService ().addNamespaceBundleOwnershipListener (listener );
292
324
String broker = admin .lookups ().lookupTopic (topicName .toString ());
293
325
log .info ("Assign the bundle {} to {}" , bundle , broker );
294
326
295
327
checkOwnershipState (broker , bundle );
328
+ Awaitility .await ().untilAsserted (() -> {
329
+ assertEquals (onloadCount .get (), 1 );
330
+ assertEquals (unloadCount .get (), 0 );
331
+ });
332
+
296
333
admin .namespaces ().unloadNamespaceBundle (topicName .getNamespace (), bundle .getBundleRange ());
297
334
assertFalse (primaryLoadManager .checkOwnershipAsync (Optional .empty (), bundle ).get ());
298
335
assertFalse (secondaryLoadManager .checkOwnershipAsync (Optional .empty (), bundle ).get ());
336
+ Awaitility .await ().untilAsserted (() -> {
337
+ assertEquals (onloadCount .get (), 1 );
338
+ assertEquals (unloadCount .get (), 1 );
339
+ });
299
340
300
341
broker = admin .lookups ().lookupTopic (topicName .toString ());
301
342
log .info ("Assign the bundle {} to {}" , bundle , broker );
302
343
344
+ String finalBroker = broker ;
345
+ Awaitility .await ().untilAsserted (() -> {
346
+ checkOwnershipState (finalBroker , bundle );
347
+ assertEquals (onloadCount .get (), 2 );
348
+ assertEquals (unloadCount .get (), 1 );
349
+ });
350
+
351
+
303
352
String dstBrokerUrl = pulsar1 .getLookupServiceAddress ();
304
353
String dstBrokerServiceUrl ;
305
354
if (broker .equals (pulsar1 .getBrokerServiceUrl ())) {
@@ -311,6 +360,10 @@ public void testUnloadAdminAPI() throws Exception {
311
360
checkOwnershipState (broker , bundle );
312
361
313
362
admin .namespaces ().unloadNamespaceBundle (topicName .getNamespace (), bundle .getBundleRange (), dstBrokerUrl );
363
+ Awaitility .await ().untilAsserted (() -> {
364
+ assertEquals (onloadCount .get (), 3 );
365
+ assertEquals (unloadCount .get (), 2 );
366
+ });
314
367
315
368
assertEquals (admin .lookups ().lookupTopic (topicName .toString ()), dstBrokerServiceUrl );
316
369
@@ -338,7 +391,7 @@ private void checkOwnershipState(String broker, NamespaceBundle bundle)
338
391
339
392
@ Test (timeOut = 30 * 1000 )
340
393
public void testSplitBundleAdminAPI () throws Exception {
341
- String namespace = "public/default" ;
394
+ String namespace = defaultTestNamespace ;
342
395
String topic = "persistent://" + namespace + "/test-split" ;
343
396
admin .topics ().createPartitionedTopic (topic , 10 );
344
397
BundlesData bundles = admin .namespaces ().getBundles (namespace );
@@ -347,6 +400,23 @@ public void testSplitBundleAdminAPI() throws Exception {
347
400
348
401
String firstBundle = bundleRanges .get (0 ) + "_" + bundleRanges .get (1 );
349
402
403
+ AtomicInteger splitCount = new AtomicInteger (0 );
404
+ NamespaceBundleSplitListener namespaceBundleSplitListener = new NamespaceBundleSplitListener () {
405
+ @ Override
406
+ public void onSplit (NamespaceBundle bundle ) {
407
+ splitCount .incrementAndGet ();
408
+ }
409
+
410
+ @ Override
411
+ public boolean test (NamespaceBundle namespaceBundle ) {
412
+ return namespaceBundle
413
+ .toString ()
414
+ .equals (String .format (namespace + "/0x%08x_0x%08x" , bundleRanges .get (0 ), bundleRanges .get (1 )));
415
+ }
416
+ };
417
+ pulsar1 .getNamespaceService ().addNamespaceBundleSplitListener (namespaceBundleSplitListener );
418
+ pulsar2 .getNamespaceService ().addNamespaceBundleSplitListener (namespaceBundleSplitListener );
419
+
350
420
long mid = bundleRanges .get (0 ) + (bundleRanges .get (1 ) - bundleRanges .get (0 )) / 2 ;
351
421
352
422
admin .namespaces ().splitNamespaceBundle (namespace , firstBundle , true , null );
@@ -359,6 +429,7 @@ public void testSplitBundleAdminAPI() throws Exception {
359
429
assertTrue (bundlesData .getBoundaries ().contains (lowBundle ));
360
430
assertTrue (bundlesData .getBoundaries ().contains (midBundle ));
361
431
assertTrue (bundlesData .getBoundaries ().contains (highBundle ));
432
+ assertEquals (splitCount .get (), 1 );
362
433
363
434
// Test split bundle with invalid bundle range.
364
435
try {
@@ -371,7 +442,7 @@ public void testSplitBundleAdminAPI() throws Exception {
371
442
372
443
@ Test (timeOut = 30 * 1000 )
373
444
public void testSplitBundleWithSpecificPositionAdminAPI () throws Exception {
374
- String namespace = "public/default" ;
445
+ String namespace = defaultTestNamespace ;
375
446
String topic = "persistent://" + namespace + "/test-split-with-specific-position" ;
376
447
admin .topics ().createPartitionedTopic (topic , 10 );
377
448
BundlesData bundles = admin .namespaces ().getBundles (namespace );
@@ -398,7 +469,9 @@ public void testSplitBundleWithSpecificPositionAdminAPI() throws Exception {
398
469
}
399
470
@ Test (timeOut = 30 * 1000 )
400
471
public void testDeleteNamespaceBundle () throws Exception {
401
- TopicName topicName = TopicName .get ("test-delete-namespace-bundle" );
472
+ final String namespace = "public/testDeleteNamespaceBundle" ;
473
+ admin .namespaces ().createNamespace (namespace , 3 );
474
+ TopicName topicName = TopicName .get (namespace + "/test-delete-namespace-bundle" );
402
475
NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
403
476
404
477
String broker = admin .lookups ().lookupTopic (topicName .toString ());
@@ -447,7 +520,7 @@ public void testCheckOwnershipPresentWithSystemNamespace() throws Exception {
447
520
448
521
@ Test
449
522
public void testMoreThenOneFilter () throws Exception {
450
- TopicName topicName = TopicName .get (" test-filter-has-exception" );
523
+ TopicName topicName = TopicName .get (defaultTestNamespace + "/ test-filter-has-exception" );
451
524
NamespaceBundle bundle = getBundleAsync (pulsar1 , topicName ).get ();
452
525
453
526
String lookupServiceAddress1 = pulsar1 .getLookupServiceAddress ();
@@ -485,7 +558,7 @@ public void testDeployAndRollbackLoadManager() throws Exception {
485
558
try (var additionalPulsarTestContext = createAdditionalPulsarTestContext (defaultConf )) {
486
559
// start pulsar3 with old load manager
487
560
var pulsar3 = additionalPulsarTestContext .getPulsarService ();
488
- String topic = "persistent://public/default /test" ;
561
+ String topic = "persistent://" + defaultTestNamespace + " /test" ;
489
562
490
563
String lookupResult1 = pulsar3 .getAdminClient ().lookups ().lookupTopic (topic );
491
564
assertEquals (lookupResult1 , pulsar3 .getBrokerServiceUrl ());
@@ -594,7 +667,7 @@ public void testTopBundlesLoadDataStoreTableViewFromChannelOwner() throws Except
594
667
restartBroker ();
595
668
pulsar1 = pulsar ;
596
669
setPrimaryLoadManager ();
597
- admin .namespaces ().setNamespaceReplicationClusters ("public/default" ,
670
+ admin .namespaces ().setNamespaceReplicationClusters (defaultTestNamespace ,
598
671
Sets .newHashSet (this .conf .getClusterName ()));
599
672
600
673
var serviceUnitStateChannelPrimaryNew =
@@ -614,10 +687,7 @@ public void testTopBundlesLoadDataStoreTableViewFromChannelOwner() throws Except
614
687
}
615
688
616
689
@ Test
617
- public void testRoleChange ()
618
- throws Exception {
619
-
620
-
690
+ public void testRoleChange () throws Exception {
621
691
var topBundlesLoadDataStorePrimary = (LoadDataStore <TopBundlesLoadData >)
622
692
FieldUtils .readDeclaredField (primaryLoadManager , "topBundlesLoadDataStore" , true );
623
693
var topBundlesLoadDataStorePrimarySpy = spy (topBundlesLoadDataStorePrimary );
@@ -962,6 +1032,7 @@ public void testListTopic() throws Exception {
962
1032
963
1033
List <String > list = admin .topics ().getList (namespace );
964
1034
assertEquals (list .size (), 6 );
1035
+ admin .namespaces ().deleteNamespace (namespace , true );
965
1036
}
966
1037
967
1038
private static abstract class MockBrokerFilter implements BrokerFilter {
0 commit comments