diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ClustersBase.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ClustersBase.java index 69d84878f5fc15..e9a1a467947a50 100644 --- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ClustersBase.java +++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/ClustersBase.java @@ -36,6 +36,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -83,13 +84,14 @@ public class ClustersBase extends AdminResource { @ApiResponse(code = 200, message = "Return a list of clusters."), @ApiResponse(code = 500, message = "Internal server error.") }) - public void getClusters(@Suspended AsyncResponse asyncResponse) { + public void getClusters(@QueryParam("verbose") @DefaultValue("false") boolean verbose, + @Suspended AsyncResponse asyncResponse) { clusterResources().listAsync() .thenApply(clusters -> clusters.stream() // Remove "global" cluster from returned list .filter(cluster -> !Constants.GLOBAL_CLUSTER.equals(cluster)) .map(cluster -> pulsar().getConfig().getClusterName().equalsIgnoreCase(cluster) - ? cluster + "(local)" : cluster + ? (verbose ? (cluster + "(local)") : cluster) : cluster ).collect(Collectors.toSet())) .thenAccept(asyncResponse::resume) .exceptionally(ex -> { diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java index 046f2b4cf14c6e..7165f16a5cea66 100644 --- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java +++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java @@ -254,14 +254,15 @@ public void internalConfigurationRetroCompatibility() throws Exception { @Test @SuppressWarnings("unchecked") public void clusters() throws Exception { - assertEquals(asyncRequests(ctx -> clusters.getClusters(ctx)), new HashSet<>()); + assertEquals(asyncRequests(ctx -> clusters.getClusters(false, ctx)), new HashSet<>()); verify(clusters, never()).validateSuperUserAccessAsync(); asyncRequests(ctx -> clusters.createCluster(ctx, "use", ClusterDataImpl.builder().serviceUrl("http://broker.messaging.use.example.com:8080").build())); // ensure to read from ZooKeeper directly //clusters.clustersListCache().clear(); - assertEquals(asyncRequests(ctx -> clusters.getClusters(ctx)), Set.of("use")); + assertEquals(asyncRequests(ctx -> clusters.getClusters(false, ctx)), Set.of("use")); + assertEquals(asyncRequests(ctx -> clusters.getClusters(true, ctx)), Set.of("use(local)")); // Check creating existing cluster try { @@ -324,7 +325,7 @@ public void clusters() throws Exception { clusters.getNamespaceIsolationPolicies(ctx, "use"))).isEmpty()); asyncRequests(ctx -> clusters.deleteCluster(ctx, "use")); - assertEquals(asyncRequests(ctx -> clusters.getClusters(ctx)), new HashSet<>()); + assertEquals(asyncRequests(ctx -> clusters.getClusters(false, ctx)), new HashSet<>()); try { asyncRequests(ctx -> clusters.getCluster(ctx, "use")); @@ -361,7 +362,7 @@ public void clusters() throws Exception { clusterCache.invalidateAll(); store.invalidateAll(); try { - asyncRequests(ctx -> clusters.getClusters(ctx)); + asyncRequests(ctx -> clusters.getClusters(false, ctx)); fail("should have failed"); } catch (RestException e) { assertEquals(e.getResponse().getStatus(), Status.INTERNAL_SERVER_ERROR.getStatusCode()); diff --git a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/client/admin/Clusters.java b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/client/admin/Clusters.java index 4178bc7483df52..7781976753814f 100644 --- a/pulsar-client-admin-api/src/main/java/org/apache/pulsar/client/admin/Clusters.java +++ b/pulsar-client-admin-api/src/main/java/org/apache/pulsar/client/admin/Clusters.java @@ -53,7 +53,9 @@ public interface Clusters { * @throws PulsarAdminException * Unexpected error */ - List getClusters() throws PulsarAdminException; + default List getClusters() throws PulsarAdminException{ + return getClusters(false); + } /** * Get the list of clusters asynchronously. @@ -67,7 +69,42 @@ public interface Clusters { * * */ - CompletableFuture> getClustersAsync(); + default CompletableFuture> getClustersAsync() { + return getClustersAsync(false); + } + + /** + * Get the list of clusters. + *

+ * Get the list of all the Pulsar clusters. + *

+ * Response Example: + * + *

+     * ["c1", "c2", "c3"]
+     * 
+ * @param verbose Verbose information output of the clusters + * + * @throws NotAuthorizedException + * Don't have admin permission + * @throws PulsarAdminException + * Unexpected error + */ + List getClusters(boolean verbose) throws PulsarAdminException; + + /** + * Get the list of clusters asynchronously. + *

+ * Get the list of all the Pulsar clusters. + *

+ * Response Example: + * + *

+     * ["c1", "c2", "c3"]
+     * 
+ * + */ + CompletableFuture> getClustersAsync(boolean verbose); /** * Get the configuration data for the specified cluster. diff --git a/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/ClustersImpl.java b/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/ClustersImpl.java index 02e44aca626046..45278b96f14144 100644 --- a/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/ClustersImpl.java +++ b/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/ClustersImpl.java @@ -61,6 +61,17 @@ public CompletableFuture> getClustersAsync() { return asyncGetRequest(path, new FutureCallback>(){}); } + @Override + public List getClusters(boolean verbose) throws PulsarAdminException { + return sync(() -> getClustersAsync(verbose)); + } + + @Override + public CompletableFuture> getClustersAsync(boolean verbose) { + WebTarget path = adminClusters.queryParam("verbose", verbose); + return asyncGetRequest(path, new FutureCallback>(){}); + } + @Override public ClusterData getCluster(String cluster) throws PulsarAdminException { return sync(() -> getClusterAsync(cluster)); diff --git a/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdClusters.java b/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdClusters.java index 6d6b4e72268cbb..bbaa7eb472edfc 100644 --- a/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdClusters.java +++ b/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdClusters.java @@ -41,8 +41,12 @@ public class CmdClusters extends CmdBase { @Parameters(commandDescription = "List the existing clusters") private class List extends CliCommand { + + @Parameter(names = { "-v", "--verbose" }, + description = "Verbose information output of the clusters", required = false) + private boolean verbose = false; void run() throws PulsarAdminException { - print(getAdmin().clusters().getClusters()); + print(getAdmin().clusters().getClusters(verbose)); } }