24
24
import static org .mockito .Mockito .when ;
25
25
import static org .testng .Assert .assertEquals ;
26
26
import static org .testng .Assert .assertTrue ;
27
+ import java .io .Closeable ;
27
28
import java .net .InetSocketAddress ;
29
+ import java .time .Duration ;
28
30
import java .util .List ;
29
31
import java .util .UUID ;
30
32
import java .util .concurrent .CompletableFuture ;
36
38
import org .apache .pulsar .client .admin .PulsarAdminException ;
37
39
import org .apache .pulsar .client .api .ClientBuilder ;
38
40
import org .apache .pulsar .client .api .Consumer ;
41
+ import org .apache .pulsar .client .api .MessageId ;
39
42
import org .apache .pulsar .client .api .Producer ;
40
43
import org .apache .pulsar .client .api .ProducerConsumerBase ;
44
+ import org .apache .pulsar .client .api .PulsarClient ;
41
45
import org .apache .pulsar .client .api .PulsarClientException ;
42
46
import org .apache .pulsar .client .impl .LookupService ;
43
47
import org .apache .pulsar .client .impl .LookupTopicResult ;
44
48
import org .apache .pulsar .client .impl .PulsarClientImpl ;
45
49
import org .apache .pulsar .common .naming .NamespaceName ;
50
+ import org .apache .pulsar .common .naming .TopicName ;
46
51
import org .apache .pulsar .common .partition .PartitionedTopicMetadata ;
47
52
import org .apache .pulsar .common .policies .data .AutoTopicCreationOverride ;
48
53
import org .apache .pulsar .common .policies .data .TopicType ;
49
- import org .testng .annotations .AfterMethod ;
50
- import org .testng .annotations .BeforeMethod ;
54
+ import org .testng .annotations .AfterClass ;
55
+ import org .testng .annotations .BeforeClass ;
51
56
import org .testng .annotations .Test ;
52
57
53
58
@ Test (groups = "broker-admin" )
54
59
@ Slf4j
55
60
public class TopicAutoCreationTest extends ProducerConsumerBase {
56
61
57
62
@ Override
58
- @ BeforeMethod
63
+ @ BeforeClass
59
64
protected void setup () throws Exception {
60
65
conf .setAllowAutoTopicCreationType (TopicType .PARTITIONED );
61
66
conf .setAllowAutoTopicCreation (true );
@@ -71,7 +76,7 @@ protected void customizeNewPulsarClientBuilder(ClientBuilder clientBuilder) {
71
76
}
72
77
73
78
@ Override
74
- @ AfterMethod (alwaysRun = true )
79
+ @ AfterClass (alwaysRun = true )
75
80
protected void cleanup () throws Exception {
76
81
super .internalCleanup ();
77
82
}
@@ -87,9 +92,11 @@ public void testPartitionedTopicAutoCreation() throws PulsarAdminException, Puls
87
92
.create ();
88
93
89
94
List <String > partitionedTopics = admin .topics ().getPartitionedTopicList (namespaceName );
95
+ assertTrue (partitionedTopics .contains (topic ));
90
96
List <String > topics = admin .topics ().getList (namespaceName );
91
- assertEquals (partitionedTopics .size (), 1 );
92
- assertEquals (topics .size (), 3 );
97
+ for (int i = 0 ; i < conf .getDefaultNumPartitions (); i ++) {
98
+ assertTrue (topics .contains (topic + TopicName .PARTITIONED_TOPIC_SUFFIX + i ));
99
+ }
93
100
94
101
producer .close ();
95
102
for (String t : topics ) {
@@ -248,4 +255,48 @@ public void testClientWithAutoCreationGotNotFoundException() throws PulsarAdminE
248
255
admin .namespaces ().deleteNamespace (namespace , true );
249
256
}
250
257
258
+ @ Test
259
+ public void testPartitionsNotCreatedAfterDeletion () throws Exception {
260
+ @ Cleanup final var client = PulsarClient .builder ().serviceUrl (pulsar .getBrokerServiceUrl ()).build ();
261
+ final var topicName = TopicName .get ("my-property/my-ns/testPartitionsNotCreatedAfterDeletion" );
262
+ final var topic = topicName .toString ();
263
+ final var interval = Duration .ofSeconds (1 );
264
+ final ThrowableConsumer <ThrowableSupplier <Closeable >> verifier = creator -> {
265
+ admin .topics ().createPartitionedTopic (topic , 1 );
266
+ boolean needCleanup = false ;
267
+ try (final var ignored = creator .get ()) {
268
+ admin .topics ().terminatePartitionedTopic (topic );
269
+ admin .topics ().deletePartitionedTopic (topic , true );
270
+ Thread .sleep (interval .toMillis () + 500 ); // wait until the auto update partitions task has run
271
+
272
+ final var topics = admin .topics ().getList (topicName .getNamespace ()).stream ()
273
+ .filter (__ -> __ .contains (topicName .getLocalName ())).toList ();
274
+ // Without https://github.com/apache/pulsar/pull/24118, the producer or consumer on partition 0 could be
275
+ // automatically created.
276
+ if (!topics .isEmpty ()) {
277
+ assertEquals (topics , List .of (topicName .getPartition (0 ).toString ()));
278
+ needCleanup = true ;
279
+ }
280
+ }
281
+ if (needCleanup ) {
282
+ admin .topics ().delete (topicName .getPartition (0 ).toString ());
283
+ }
284
+ };
285
+ verifier .accept (() -> client .newProducer ().topic (topic )
286
+ .autoUpdatePartitionsInterval (interval .toSecondsPart (), TimeUnit .SECONDS ).create ());
287
+ verifier .accept (() -> client .newConsumer ().topic (topic ).subscriptionName ("sub" )
288
+ .autoUpdatePartitionsInterval (interval .toSecondsPart (), TimeUnit .SECONDS ).subscribe ());
289
+ verifier .accept (() -> client .newReader ().topic (topic ).startMessageId (MessageId .earliest )
290
+ .autoUpdatePartitionsInterval (interval .toSecondsPart (), TimeUnit .SECONDS ).create ());
291
+ }
292
+
293
+ private interface ThrowableConsumer <T > {
294
+
295
+ void accept (T value ) throws Exception ;
296
+ }
297
+
298
+ public interface ThrowableSupplier <T > {
299
+
300
+ T get () throws Exception ;
301
+ }
251
302
}
0 commit comments