From 70709b224a2c6595e8efb2ac96644b6cbc5c4475 Mon Sep 17 00:00:00 2001
From: Shalin Shekhar Mangar <shalin@apache.org>
Date: Fri, 27 Jun 2014 11:29:14 +0000
Subject: [PATCH] SOLR-6069: The 'clusterstatus' API should return 'roles'
 information

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1606034 13f79535-47bb-0310-9956-ffa450edef68
---
 solr/CHANGES.txt                              |  2 +
 .../cloud/OverseerCollectionProcessor.java    | 12 +++++-
 .../apache/solr/cloud/TestCollectionAPI.java  | 37 ++++++++++++++++++-
 3 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 3ae15a2c9b9..dfbd4a7ed42 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -94,6 +94,8 @@ New Features
 * SOLR-6196: The overseerstatus collection API instruments amILeader and ZK state update calls.
   (shalin)
 
+* SOLR-6069: The 'clusterstatus' API should return 'roles' information. (shalin)
+
 Bug Fixes
 ----------------------
 
diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
index 69f02240b87..4ce1601eb27 100644
--- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
+++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
@@ -668,7 +668,7 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread {
 
   }
 
-  private void getClusterStatus(ClusterState clusterState, ZkNodeProps message, NamedList results) {
+  private void getClusterStatus(ClusterState clusterState, ZkNodeProps message, NamedList results) throws KeeperException, InterruptedException {
     String collection = message.getStr(ZkStateReader.COLLECTION_PROP);
 
     // read aliases
@@ -692,6 +692,11 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread {
       }
     }
 
+    Map roles = null;
+    if(zkStateReader.getZkClient().exists(ZkStateReader.ROLES, true)){
+      roles = (Map) ZkStateReader.fromJSON(zkStateReader.getZkClient().getData(ZkStateReader.ROLES, null, null, true));
+    }
+
     // convert cluster state into a map of writable types
     byte[] bytes = ZkStateReader.toJSON(clusterState);
     Map<String, Object> stateMap = (Map<String, Object>) ZkStateReader.fromJSON(bytes);
@@ -753,6 +758,11 @@ public class OverseerCollectionProcessor implements Runnable, ClosableThread {
       clusterStatus.add("aliases", aliasVsCollections);
     }
 
+    // add the roles map
+    if (roles != null)  {
+      clusterStatus.add("roles", roles);
+    }
+
     results.add("cluster", clusterStatus);
   }
 
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java b/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java
index 31eda5265a8..ce14c2ed419 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestCollectionAPI.java
@@ -24,6 +24,7 @@ import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrServer;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.params.CollectionParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.ShardParams;
@@ -74,6 +75,7 @@ public class TestCollectionAPI extends AbstractFullDistribZkTestBase {
     clusterStatusWithCollectionAndShard();
     clusterStatusWithRouteKey();
     clusterStatusAliasTest();
+    clusterStatusRolesTest();
   }
 
   private void clusterStatusWithCollectionAndShard() throws IOException, SolrServerException {
@@ -239,7 +241,40 @@ public class TestCollectionAPI extends AbstractFullDistribZkTestBase {
       List<String> collAlias = (List<String>) collection.get("aliases");
       assertEquals("Aliases not found", Lists.newArrayList("myalias"), collAlias);
     } finally {
-      //remove collections
+      client.shutdown();
+    }
+  }
+
+  private void clusterStatusRolesTest() throws Exception  {
+    CloudSolrServer client = createCloudClient(null);
+    try {
+      client.connect();
+      Replica replica = client.getZkStateReader().getLeaderRetry(DEFAULT_COLLECTION, SHARD1);
+
+      ModifiableSolrParams params = new ModifiableSolrParams();
+      params.set("action", CollectionParams.CollectionAction.ADDROLE.toString());
+      params.set("node", replica.getNodeName());
+      params.set("role", "overseer");
+      SolrRequest request = new QueryRequest(params);
+      request.setPath("/admin/collections");
+      client.request(request);
+
+      params = new ModifiableSolrParams();
+      params.set("action", CollectionParams.CollectionAction.CLUSTERSTATUS.toString());
+      params.set("collection", DEFAULT_COLLECTION);
+      request = new QueryRequest(params);
+      request.setPath("/admin/collections");
+
+      NamedList<Object> rsp = client.request(request);
+      NamedList<Object> cluster = (NamedList<Object>) rsp.get("cluster");
+      assertNotNull("Cluster state should not be null", cluster);
+      Map<String, Object> roles = (Map<String, Object>) cluster.get("roles");
+      assertNotNull("Role information should not be null", roles);
+      List<String> overseer = (List<String>) roles.get("overseer");
+      assertNotNull(overseer);
+      assertEquals(1, overseer.size());
+      assertTrue(overseer.contains(replica.getNodeName()));
+    } finally {
       client.shutdown();
     }
   }