diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java index e677746bfeb9f..085404e755a25 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/PersistentTopicsBase.java @@ -442,7 +442,8 @@ protected void internalUpdatePartitionedTopic(int numPartitions, } try { tryCreatePartitionsAsync(numPartitions).get(DEFAULT_OPERATION_TIMEOUT_SEC, TimeUnit.SECONDS); - createSubscriptions(topicName, numPartitions).get(DEFAULT_OPERATION_TIMEOUT_SEC, TimeUnit.SECONDS); + createSubscriptions(topicName, numPartitions, force).get(DEFAULT_OPERATION_TIMEOUT_SEC, + TimeUnit.SECONDS); } catch (Exception e) { if (e.getCause() instanceof RestException) { throw (RestException) e.getCause(); @@ -4127,7 +4128,7 @@ private PersistentReplicator getReplicatorReference(String replName, PersistentT private CompletableFuture updatePartitionedTopic(TopicName topicName, int numPartitions, boolean force) { CompletableFuture result = new CompletableFuture<>(); - createSubscriptions(topicName, numPartitions).thenCompose(__ -> { + createSubscriptions(topicName, numPartitions, force).thenCompose(__ -> { CompletableFuture future = namespaceResources().getPartitionedTopicResources() .updatePartitionedTopicAsync(topicName, p -> new PartitionedTopicMetadata(numPartitions)); future.exceptionally(ex -> { @@ -4164,8 +4165,10 @@ private CompletableFuture updatePartitionedTopic(TopicName topicName, int * * @param topicName : topic-name: persistent://prop/cluster/ns/topic * @param numPartitions : number partitions for the topics + * @param ignoreConflictException : If true, ignore ConflictException: subscription already exists for topic */ - private CompletableFuture createSubscriptions(TopicName topicName, int numPartitions) { + private CompletableFuture createSubscriptions(TopicName topicName, int numPartitions, + boolean ignoreConflictException) { CompletableFuture result = new CompletableFuture<>(); pulsar().getBrokerService().fetchPartitionedTopicMetadataAsync(topicName).thenAccept(partitionMetadata -> { if (partitionMetadata.partitions < 1) { @@ -4200,9 +4203,20 @@ private CompletableFuture createSubscriptions(TopicName topicName, int num for (int i = partitionMetadata.partitions; i < numPartitions; i++) { final String topicNamePartition = topicName.getPartition(i).toString(); - - subscriptionFutures.add(admin.topics().createSubscriptionAsync(topicNamePartition, - subscription, MessageId.latest)); + CompletableFuture future = new CompletableFuture<>(); + admin.topics().createSubscriptionAsync(topicNamePartition, + subscription, MessageId.latest).whenComplete((__, ex) -> { + if (ex == null) { + future.complete(null); + } else { + if (ignoreConflictException && ex instanceof PulsarAdminException.ConflictException) { + future.complete(null); + } else { + future.completeExceptionally(ex); + } + } + }); + subscriptionFutures.add(future); } }); diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApi2Test.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApi2Test.java index 62aed23ea4cca..3cb67eada5e16 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApi2Test.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApi2Test.java @@ -2464,9 +2464,17 @@ public void testFailedUpdatePartitionedTopic() throws Exception { } catch (PulsarAdminException.PreconditionFailedException e) { // Ok } + assertEquals(admin.topics().getPartitionedTopicMetadata(partitionedTopicName).partitions, startPartitions); admin.topics().updatePartitionedTopic(partitionedTopicName, newPartitions, false, true); // validate subscription is created for new partition. assertNotNull(admin.topics().getStats(partitionedTopicName + "-partition-" + 6).getSubscriptions().get(subName1)); + for (int i = startPartitions; i < newPartitions; i++) { + assertNotNull( + admin.topics().getStats(partitionedTopicName + "-partition-" + i).getSubscriptions().get(subName1)); + } + + // validate update partition is success + assertEquals(admin.topics().getPartitionedTopicMetadata(partitionedTopicName).partitions, newPartitions); } @Test(dataProvider = "topicType")