tisonkun commented on issue #18947:
URL: https://github.com/apache/pulsar/issues/18947#issuecomment-1362390472

   I found the root cause - we have two endpoints share the same path but 
differ in params:
   
   ```java
   // org.apache.pulsar.broker.admin.v2.PersistentTopics
   
       @PUT
       @Path("/{tenant}/{namespace}/{topic}/partitions")
       @ApiOperation(value = "Create a partitioned topic.",
               notes = "It needs to be called before creating a producer on a 
partitioned topic.")
       @ApiResponses(value = {
               @ApiResponse(code = 307, message = "Current broker doesn't serve 
the namespace of this topic"),
               @ApiResponse(code = 401, message = "Don't have permission to 
administrate resources on this tenant"),
               @ApiResponse(code = 403, message = "Don't have admin 
permission"),
               @ApiResponse(code = 404, message = "Tenant or namespace doesn't 
exist"),
               @ApiResponse(code = 406, message = "The number of partitions 
should be more than 0 and"
                       + " less than or equal to 
maxNumPartitionsPerPartitionedTopic"),
               @ApiResponse(code = 409, message = "Partitioned topic already 
exist"),
               @ApiResponse(code = 412,
                       message = "Failed Reason : Name is invalid or Namespace 
does not have any clusters configured"),
               @ApiResponse(code = 500, message = "Internal server error"),
               @ApiResponse(code = 503, message = "Failed to validate global 
cluster configuration")
       })
       public void createPartitionedTopic(
               @Suspended final AsyncResponse asyncResponse,
               @ApiParam(value = "Specify the tenant", required = true)
               @PathParam("tenant") String tenant,
               @ApiParam(value = "Specify the namespace", required = true)
               @PathParam("namespace") String namespace,
               @ApiParam(value = "Specify topic name", required = true)
               @PathParam("topic") @Encoded String encodedTopic,
               @ApiParam(value = "The number of partitions for the topic",
                       required = true, type = "int", defaultValue = "0")
                       int numPartitions,
               @QueryParam("createLocalTopicOnly") @DefaultValue("false") 
boolean createLocalTopicOnly) {
           try {
               validateNamespaceName(tenant, namespace);
               validateGlobalNamespaceOwnership();
               validatePartitionedTopicName(tenant, namespace, encodedTopic);
               validateTopicPolicyOperation(topicName, PolicyName.PARTITION, 
PolicyOperation.WRITE);
               validateCreateTopic(topicName);
               internalCreatePartitionedTopic(asyncResponse, numPartitions, 
createLocalTopicOnly);
           } catch (Exception e) {
               log.error("[{}] Failed to create partitioned topic {}", 
clientAppId(), topicName, e);
               resumeAsyncResponseExceptionally(asyncResponse, e);
           }
       }
   
       @PUT
       @Consumes(PartitionedTopicMetadata.MEDIA_TYPE)
       @Path("/{tenant}/{namespace}/{topic}/partitions")
       @ApiOperation(value = "Create a partitioned topic.",
               notes = "It needs to be called before creating a producer on a 
partitioned topic.")
       @ApiResponses(value = {
               @ApiResponse(code = 307, message = "Current broker doesn't serve 
the namespace of this topic"),
               @ApiResponse(code = 401, message = "Don't have permission to 
administrate resources on this tenant"),
               @ApiResponse(code = 403, message = "Don't have admin 
permission"),
               @ApiResponse(code = 404, message = "Tenant or namespace doesn't 
exist"),
               @ApiResponse(code = 406, message = "The number of partitions 
should be more than 0 and"
                       + " less than or equal to 
maxNumPartitionsPerPartitionedTopic"),
               @ApiResponse(code = 409, message = "Partitioned topic already 
exist"),
               @ApiResponse(code = 412,
                       message = "Failed Reason : Name is invalid or Namespace 
does not have any clusters configured"),
               @ApiResponse(code = 500, message = "Internal server error"),
               @ApiResponse(code = 503, message = "Failed to validate global 
cluster configuration")
       })
       public void createPartitionedTopic(
               @Suspended final AsyncResponse asyncResponse,
               @ApiParam(value = "Specify the tenant", required = true)
               @PathParam("tenant") String tenant,
               @ApiParam(value = "Specify the namespace", required = true)
               @PathParam("namespace") String namespace,
               @ApiParam(value = "Specify topic name", required = true)
               @PathParam("topic") @Encoded String encodedTopic,
               @ApiParam(value = "The metadata for the topic",
                       required = true, type = "PartitionedTopicMetadata") 
PartitionedTopicMetadata metadata,
               @QueryParam("createLocalTopicOnly") @DefaultValue("false") 
boolean createLocalTopicOnly) {
           try {
               validateNamespaceName(tenant, namespace);
               validateGlobalNamespaceOwnership();
               validatePartitionedTopicName(tenant, namespace, encodedTopic);
               validateTopicPolicyOperation(topicName, PolicyName.PARTITION, 
PolicyOperation.WRITE);
               validateCreateTopic(topicName);
               internalCreatePartitionedTopic(asyncResponse, 
metadata.partitions, createLocalTopicOnly,
                       metadata.properties);
           } catch (Exception e) {
               log.error("[{}] Failed to create partitioned topic {}", 
clientAppId(), topicName, e);
               resumeAsyncResponseExceptionally(asyncResponse, e);
           }
       }
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to