You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2017/02/26 06:12:11 UTC

[2/2] hbase git commit: HBASE-17654 RSGroup refactoring.

HBASE-17654 RSGroup refactoring.

Changes contain:
- Making rsGroupInfoManager non-static in RSGroupAdminEndpoint
- Encapsulate RSGroupAdminService into an internal class in RSGroupAdminEndpoint (on need of inheritence).
- Change two internal classes in RSGroupAdminServer to non-static (so outer classes' variables can be shared).
- Rename RSGroupSerDe to RSGroupProtobufUtil('ProtobufUtil' is what we use in other places). Moved 2 functions to RSGroupManagerImpl because they are only used there.
- Javadoc comments
- Improving variable names
- Maybe other misc refactoring

Change-Id: I09f0f5aa413150390c91795b8a8fd5e6cdd6c416


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/ce64e7eb
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/ce64e7eb
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/ce64e7eb

Branch: refs/heads/master
Commit: ce64e7eb6e9a6c3954b8ab6b5441ca6e4f952b26
Parents: f4bf375
Author: Apekshit Sharma <ap...@apache.org>
Authored: Thu Feb 16 02:00:37 2017 -0800
Committer: Apekshit Sharma <ap...@apache.org>
Committed: Sat Feb 25 22:12:03 2017 -0800

----------------------------------------------------------------------
 .../hadoop/hbase/rsgroup/RSGroupInfo.java       |  30 +-
 .../hbase/rsgroup/IntegrationTestRSGroup.java   |   6 +-
 .../hadoop/hbase/rsgroup/RSGroupAdmin.java      |  52 +--
 .../hbase/rsgroup/RSGroupAdminClient.java       |  77 ++--
 .../hbase/rsgroup/RSGroupAdminEndpoint.java     | 344 +++++++++---------
 .../hbase/rsgroup/RSGroupAdminServer.java       | 154 +++-----
 .../hbase/rsgroup/RSGroupBasedLoadBalancer.java |  34 +-
 .../hbase/rsgroup/RSGroupInfoManager.java       |  53 +--
 .../hbase/rsgroup/RSGroupInfoManagerImpl.java   | 361 +++++++++----------
 .../hbase/rsgroup/RSGroupProtobufUtil.java      |  60 +++
 .../hadoop/hbase/rsgroup/RSGroupSerDe.java      | 121 -------
 .../hbase/rsgroup/RSGroupableBalancer.java      |   5 +-
 .../balancer/TestRSGroupBasedLoadBalancer.java  |   5 +-
 .../hadoop/hbase/rsgroup/TestRSGroups.java      |  14 +-
 .../hadoop/hbase/rsgroup/TestRSGroupsBase.java  | 102 +++---
 .../hbase/rsgroup/TestRSGroupsOfflineMode.java  |  94 ++---
 .../rsgroup/VerifyingRSGroupAdminClient.java    |   8 +-
 17 files changed, 656 insertions(+), 864 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-common/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfo.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfo.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfo.java
index ed0aec1..35563c5 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfo.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfo.java
@@ -34,15 +34,14 @@ import org.apache.hadoop.hbase.net.Address;
 @InterfaceAudience.Public
 @InterfaceStability.Evolving
 public class RSGroupInfo {
-
   public static final String DEFAULT_GROUP = "default";
-  public static final String NAMESPACEDESC_PROP_GROUP = "hbase.rsgroup.name";
+  public static final String NAMESPACE_DESC_PROP_GROUP = "hbase.rsgroup.name";
 
-  private String name;
+  private final String name;
   // Keep servers in a sorted set so has an expected ordering when displayed.
-  private SortedSet<Address> servers;
+  private final SortedSet<Address> servers;
   // Keep tables sorted too.
-  private SortedSet<TableName> tables;
+  private final SortedSet<TableName> tables;
 
   public RSGroupInfo(String name) {
     this(name, new TreeSet<Address>(), new TreeSet<TableName>());
@@ -50,7 +49,7 @@ public class RSGroupInfo {
 
   RSGroupInfo(String name, SortedSet<Address> servers, SortedSet<TableName> tables) {
     this.name = name;
-    this.servers = servers == null? new TreeSet<Address>(): servers;
+    this.servers = servers == null? new TreeSet<>(): servers;
     this.servers.addAll(servers);
     this.tables = new TreeSet<>(tables);
   }
@@ -61,26 +60,20 @@ public class RSGroupInfo {
 
   /**
    * Get group name.
-   *
-   * @return group name
    */
   public String getName() {
     return name;
   }
 
   /**
-   * Adds the server to the group.
-   *
-   * @param hostPort the server
+   * Adds the given server to the group.
    */
   public void addServer(Address hostPort){
     servers.add(hostPort);
   }
 
   /**
-   * Adds a group of servers.
-   *
-   * @param hostPort the servers
+   * Adds the given servers to the group.
    */
   public void addAllServers(Collection<Address> hostPort){
     servers.addAll(hostPort);
@@ -96,25 +89,20 @@ public class RSGroupInfo {
 
   /**
    * Get list of servers.
-   *
-   * @return set of servers
    */
   public Set<Address> getServers() {
     return servers;
   }
 
   /**
-   * Remove a server from this group.
-   *
-   * @param hostPort HostPort of the server to remove
+   * Remove given server from the group.
    */
   public boolean removeServer(Address hostPort) {
     return servers.remove(hostPort);
   }
 
   /**
-   * Set of tables that are members of this group
-   * @return set of tables
+   * Get set of tables that are members of the group.
    */
   public SortedSet<TableName> getTables() {
     return tables;

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-it/src/test/java/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.java
----------------------------------------------------------------------
diff --git a/hbase-it/src/test/java/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.java b/hbase-it/src/test/java/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.java
index da94bd7..6b1f1a7 100644
--- a/hbase-it/src/test/java/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.java
+++ b/hbase-it/src/test/java/org/apache/hadoop/hbase/rsgroup/IntegrationTestRSGroup.java
@@ -29,20 +29,18 @@ import org.junit.BeforeClass;
 import org.junit.experimental.categories.Category;
 
 /**
- * Runs all of the units tests defined in TestGroupBase
- * as an integration test.
+ * Runs all of the units tests defined in TestGroupBase as an integration test.
  * Requires TestRSGroupBase.NUM_SLAVE_BASE servers to run.
  */
 @Category(IntegrationTests.class)
 public class IntegrationTestRSGroup extends TestRSGroupsBase {
-  //Integration specific
   private final static Log LOG = LogFactory.getLog(IntegrationTestRSGroup.class);
   private static boolean initialized = false;
 
   @BeforeClass
   public void beforeMethod() throws Exception {
     if(!initialized) {
-      LOG.info("Setting up IntegrationTestGroup");
+      LOG.info("Setting up IntegrationTestRSGroup");
       LOG.info("Initializing cluster with " + NUM_SLAVES_BASE + " servers");
       TEST_UTIL = new IntegrationTestingUtility();
       ((IntegrationTestingUtility)TEST_UTIL).initializeCluster(NUM_SLAVES_BASE);

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdmin.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdmin.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdmin.java
index 72b5f6e..20fdaa2 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdmin.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdmin.java
@@ -17,7 +17,6 @@
  */
 package org.apache.hadoop.hbase.rsgroup;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.util.List;
 import java.util.Set;
@@ -32,76 +31,51 @@ import org.apache.hadoop.hbase.net.Address;
 @InterfaceAudience.Private
 public interface RSGroupAdmin {
   /**
-   * Gets the regionserver group information.
-   *
-   * @param groupName the group name
-   * @return An instance of RSGroupInfo
+   * Gets {@code RSGroupInfo} for given group name.
    */
   RSGroupInfo getRSGroupInfo(String groupName) throws IOException;
 
   /**
-   * Gets the regionserver group info of table.
-   *
-   * @param tableName the table name
-   * @return An instance of RSGroupInfo.
+   * Gets {@code RSGroupInfo} for the given table's group.
    */
   RSGroupInfo getRSGroupInfoOfTable(TableName tableName) throws IOException;
 
   /**
-   * Move a set of serves to another group
-   *
-   *
-   * @param servers set of servers, must be in the form HOST:PORT
-   * @param targetGroup the target group
-   * @throws java.io.IOException Signals that an I/O exception has occurred.
+   * Move given set of servers to the specified target RegionServer group.
    */
-  void moveServers(Set<Address> servers, String targetGroup)
-  throws IOException;
+  void moveServers(Set<Address> servers, String targetGroup) throws IOException;
 
   /**
-   * Move tables to a new group.
+   * Move given set of tables to the specified target RegionServer group.
    * This will unassign all of a table's region so it can be reassigned to the correct group.
-   * @param tables list of tables to move
-   * @param targetGroup target group
-   * @throws java.io.IOException on failure to move tables
    */
   void moveTables(Set<TableName> tables, String targetGroup) throws IOException;
 
   /**
-   * Add a new group
-   * @param name name of the group
-   * @throws java.io.IOException on failure to add group
+   * Creates a new RegionServer group with the given name.
    */
-  void addRSGroup(String name) throws IOException;
+  void addRSGroup(String groupName) throws IOException;
 
   /**
-   * Remove a regionserver group
-   * @param name name of the group
-   * @throws java.io.IOException on failure to remove group
+   * Removes RegionServer group associated with the given name.
    */
-  void removeRSGroup(String name) throws IOException;
+  void removeRSGroup(String groupName) throws IOException;
 
   /**
-   * Balance the regions in a group
+   * Balance regions in the given RegionServer group.
    *
-   * @param name the name of the group to balance
-   * @return boolean whether balance ran or not
-   * @throws java.io.IOException on unexpected failure to balance group
+   * @return boolean Whether balance ran or not
    */
-  boolean balanceRSGroup(String name) throws IOException;
+  boolean balanceRSGroup(String groupName) throws IOException;
 
   /**
-   * Lists the existing groups.
-   *
-   * @return Collection of RSGroupInfo.
+   * Lists current set of RegionServer groups.
    */
   List<RSGroupInfo> listRSGroups() throws IOException;
 
   /**
    * Retrieve the RSGroupInfo a server is affiliated to
    * @param hostPort HostPort to get RSGroupInfo for
-   * @return RSGroupInfo associated with the server
-   * @throws java.io.IOException on unexpected failure to retrieve GroupInfo
    */
   RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminClient.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminClient.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminClient.java
index 381fc60..74e91fe 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminClient.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminClient.java
@@ -28,36 +28,42 @@ import org.apache.hadoop.hbase.client.Connection;
 import org.apache.hadoop.hbase.net.Address;
 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
-import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.AddRSGroupRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerRequest;
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerResponse;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableRequest;
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableResponse;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoResponse;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveServersRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveTablesRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RSGroupAdminService;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupRequest;
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
 
 import com.google.common.collect.Sets;
 import com.google.protobuf.ServiceException;
 
-
 /**
  * Client used for managing region server group information.
  */
 @InterfaceAudience.Private
 class RSGroupAdminClient implements RSGroupAdmin {
-  private RSGroupAdminProtos.RSGroupAdminService.BlockingInterface stub;
+  private RSGroupAdminService.BlockingInterface stub;
 
   public RSGroupAdminClient(Connection conn) throws IOException {
-    stub = RSGroupAdminProtos.RSGroupAdminService.newBlockingStub(
-        conn.getAdmin().coprocessorService());
+    stub = RSGroupAdminService.newBlockingStub(conn.getAdmin().coprocessorService());
   }
 
   @Override
   public RSGroupInfo getRSGroupInfo(String groupName) throws IOException {
     try {
-      RSGroupAdminProtos.GetRSGroupInfoResponse resp =
-        stub.getRSGroupInfo(null,
-            RSGroupAdminProtos.GetRSGroupInfoRequest.newBuilder()
-                .setRSGroupName(groupName).build());
+      GetRSGroupInfoResponse resp = stub.getRSGroupInfo(null,
+          GetRSGroupInfoRequest.newBuilder().setRSGroupName(groupName).build());
       if(resp.hasRSGroupInfo()) {
-        return RSGroupSerDe.toGroupInfo(resp.getRSGroupInfo());
+        return RSGroupProtobufUtil.toGroupInfo(resp.getRSGroupInfo());
       }
       return null;
     } catch (ServiceException e) {
@@ -67,14 +73,12 @@ class RSGroupAdminClient implements RSGroupAdmin {
 
   @Override
   public RSGroupInfo getRSGroupInfoOfTable(TableName tableName) throws IOException {
-    RSGroupAdminProtos.GetRSGroupInfoOfTableRequest request =
-        RSGroupAdminProtos.GetRSGroupInfoOfTableRequest.newBuilder()
-            .setTableName(ProtobufUtil.toProtoTableName(tableName)).build();
-
+    GetRSGroupInfoOfTableRequest request = GetRSGroupInfoOfTableRequest.newBuilder().setTableName(
+        ProtobufUtil.toProtoTableName(tableName)).build();
     try {
       GetRSGroupInfoOfTableResponse resp = stub.getRSGroupInfoOfTable(null, request);
       if (resp.hasRSGroupInfo()) {
-        return RSGroupSerDe.toGroupInfo(resp.getRSGroupInfo());
+        return RSGroupProtobufUtil.toGroupInfo(resp.getRSGroupInfo());
       }
       return null;
     } catch (ServiceException e) {
@@ -91,11 +95,10 @@ class RSGroupAdminClient implements RSGroupAdmin {
         .setPort(el.getPort())
         .build());
     }
-    RSGroupAdminProtos.MoveServersRequest request =
-        RSGroupAdminProtos.MoveServersRequest.newBuilder()
+    MoveServersRequest request = MoveServersRequest.newBuilder()
             .setTargetGroup(targetGroup)
-            .addAllServers(hostPorts).build();
-
+            .addAllServers(hostPorts)
+            .build();
     try {
       stub.moveServers(null, request);
     } catch (ServiceException e) {
@@ -105,9 +108,7 @@ class RSGroupAdminClient implements RSGroupAdmin {
 
   @Override
   public void moveTables(Set<TableName> tables, String targetGroup) throws IOException {
-    RSGroupAdminProtos.MoveTablesRequest.Builder builder =
-        RSGroupAdminProtos.MoveTablesRequest.newBuilder()
-            .setTargetGroup(targetGroup);
+    MoveTablesRequest.Builder builder = MoveTablesRequest.newBuilder().setTargetGroup(targetGroup);
     for(TableName tableName: tables) {
       builder.addTableName(ProtobufUtil.toProtoTableName(tableName));
     }
@@ -120,9 +121,7 @@ class RSGroupAdminClient implements RSGroupAdmin {
 
   @Override
   public void addRSGroup(String groupName) throws IOException {
-    RSGroupAdminProtos.AddRSGroupRequest request =
-        RSGroupAdminProtos.AddRSGroupRequest.newBuilder()
-            .setRSGroupName(groupName).build();
+    AddRSGroupRequest request = AddRSGroupRequest.newBuilder().setRSGroupName(groupName).build();
     try {
       stub.addRSGroup(null, request);
     } catch (ServiceException e) {
@@ -132,9 +131,7 @@ class RSGroupAdminClient implements RSGroupAdmin {
 
   @Override
   public void removeRSGroup(String name) throws IOException {
-    RSGroupAdminProtos.RemoveRSGroupRequest request =
-        RSGroupAdminProtos.RemoveRSGroupRequest.newBuilder()
-            .setRSGroupName(name).build();
+    RemoveRSGroupRequest request = RemoveRSGroupRequest.newBuilder().setRSGroupName(name).build();
     try {
       stub.removeRSGroup(null, request);
     } catch (ServiceException e) {
@@ -143,11 +140,9 @@ class RSGroupAdminClient implements RSGroupAdmin {
   }
 
   @Override
-  public boolean balanceRSGroup(String name) throws IOException {
-    RSGroupAdminProtos.BalanceRSGroupRequest request =
-        RSGroupAdminProtos.BalanceRSGroupRequest.newBuilder()
-            .setRSGroupName(name).build();
-
+  public boolean balanceRSGroup(String groupName) throws IOException {
+    BalanceRSGroupRequest request = BalanceRSGroupRequest.newBuilder()
+        .setRSGroupName(groupName).build();
     try {
       return stub.balanceRSGroup(null, request).getBalanceRan();
     } catch (ServiceException e) {
@@ -158,12 +153,11 @@ class RSGroupAdminClient implements RSGroupAdmin {
   @Override
   public List<RSGroupInfo> listRSGroups() throws IOException {
     try {
-      List<RSGroupProtos.RSGroupInfo> resp =
-          stub.listRSGroupInfos(null,
-              RSGroupAdminProtos.ListRSGroupInfosRequest.newBuilder().build()).getRSGroupInfoList();
-      List<RSGroupInfo> result = new ArrayList<RSGroupInfo>(resp.size());
-      for(RSGroupProtos.RSGroupInfo entry: resp) {
-        result.add(RSGroupSerDe.toGroupInfo(entry));
+      List<RSGroupProtos.RSGroupInfo> resp = stub.listRSGroupInfos(null,
+          ListRSGroupInfosRequest.getDefaultInstance()).getRSGroupInfoList();
+      List<RSGroupInfo> result = new ArrayList<>(resp.size());
+      for(RSGroupProtos.RSGroupInfo entry : resp) {
+        result.add(RSGroupProtobufUtil.toGroupInfo(entry));
       }
       return result;
     } catch (ServiceException e) {
@@ -173,8 +167,7 @@ class RSGroupAdminClient implements RSGroupAdmin {
 
   @Override
   public RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException {
-    RSGroupAdminProtos.GetRSGroupInfoOfServerRequest request =
-        RSGroupAdminProtos.GetRSGroupInfoOfServerRequest.newBuilder()
+    GetRSGroupInfoOfServerRequest request = GetRSGroupInfoOfServerRequest.newBuilder()
             .setServer(HBaseProtos.ServerName.newBuilder()
                 .setHostName(hostPort.getHostname())
                 .setPort(hostPort.getPort())
@@ -183,7 +176,7 @@ class RSGroupAdminClient implements RSGroupAdmin {
     try {
       GetRSGroupInfoOfServerResponse resp = stub.getRSGroupInfoOfServer(null, request);
       if (resp.hasRSGroupInfo()) {
-        return RSGroupSerDe.toGroupInfo(resp.getRSGroupInfo());
+        return RSGroupProtobufUtil.toGroupInfo(resp.getRSGroupInfo());
       }
       return null;
     } catch (ServiceException e) {

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
index 3dc8817..b917716 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java
@@ -20,22 +20,21 @@ package org.apache.hadoop.hbase.rsgroup;
 
 import java.io.IOException;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
-import org.apache.hadoop.hbase.Coprocessor;
+import com.google.common.collect.Sets;
+import com.google.protobuf.RpcCallback;
+import com.google.protobuf.RpcController;
+import com.google.protobuf.Service;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.CoprocessorEnvironment;
-import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
-import org.apache.hadoop.hbase.ProcedureInfo;
-import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
-import org.apache.hadoop.hbase.client.MasterSwitchType;
-import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.constraint.ConstraintException;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorService;
 import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
@@ -43,12 +42,7 @@ import org.apache.hadoop.hbase.coprocessor.MasterObserver;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils;
 import org.apache.hadoop.hbase.master.MasterServices;
-import org.apache.hadoop.hbase.master.RegionPlan;
-import org.apache.hadoop.hbase.master.locking.LockProcedure;
-import org.apache.hadoop.hbase.master.locking.LockProcedure.LockType;
-import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
 import org.apache.hadoop.hbase.net.Address;
-import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos;
@@ -71,228 +65,231 @@ import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.MoveTablesR
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RSGroupAdminService;
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupRequest;
 import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupResponse;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.SnapshotDescription;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas;
-
-import com.google.common.collect.Sets;
-import com.google.protobuf.RpcCallback;
-import com.google.protobuf.RpcController;
-import com.google.protobuf.Service;
-
 
 @InterfaceAudience.Private
-public class RSGroupAdminEndpoint extends RSGroupAdminService implements CoprocessorService, 
-    Coprocessor, MasterObserver {
-  private MasterServices master = null;
+public class RSGroupAdminEndpoint implements MasterObserver, CoprocessorService {
+  private static final Log LOG = LogFactory.getLog(RSGroupAdminEndpoint.class);
 
-  // TODO: Static? Fix.
-  private static RSGroupInfoManager groupInfoManager;
+  private MasterServices master = null;
+  // Only instance of RSGroupInfoManager. RSGroup aware load balancers ask for this instance on
+  // their setup.
+  private RSGroupInfoManager groupInfoManager;
   private RSGroupAdminServer groupAdminServer;
+  private final RSGroupAdminService groupAdminService = new RSGroupAdminServiceImpl();
 
   @Override
   public void start(CoprocessorEnvironment env) throws IOException {
-    MasterCoprocessorEnvironment menv = (MasterCoprocessorEnvironment)env;
-    master = menv.getMasterServices();
-    setGroupInfoManager(new RSGroupInfoManagerImpl(master));
+    master = ((MasterCoprocessorEnvironment)env).getMasterServices();
+    groupInfoManager = RSGroupInfoManagerImpl.getInstance(master);
     groupAdminServer = new RSGroupAdminServer(master, groupInfoManager);
     Class<?> clazz =
         master.getConfiguration().getClass(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, null);
     if (!RSGroupableBalancer.class.isAssignableFrom(clazz)) {
-      throw new IOException("Configured balancer is not a GroupableBalancer");
+      throw new IOException("Configured balancer does not support RegionServer groups.");
     }
   }
 
   @Override
-  public void stop(CoprocessorEnvironment env) throws IOException {
-  }
-
-  @Override
   public Service getService() {
-    return this;
-  }
-
-  private static void setStaticGroupInfoManager(RSGroupInfoManagerImpl groupInfoManager) {
-    RSGroupAdminEndpoint.groupInfoManager = groupInfoManager;
-  }
-
-  private void setGroupInfoManager(RSGroupInfoManagerImpl groupInfoManager) throws IOException {
-    if (groupInfoManager == null) {
-      groupInfoManager = new RSGroupInfoManagerImpl(master);
-      groupInfoManager.init();
-    } else if (!groupInfoManager.isInit()) {
-      groupInfoManager.init();
-    }
-    setStaticGroupInfoManager(groupInfoManager);
+    return groupAdminService;
   }
 
   RSGroupInfoManager getGroupInfoManager() {
     return groupInfoManager;
   }
 
-  @Override
-  public void getRSGroupInfo(RpcController controller,
-                           GetRSGroupInfoRequest request,
-                           RpcCallback<GetRSGroupInfoResponse> done) {
-    GetRSGroupInfoResponse.Builder builder =
-          GetRSGroupInfoResponse.newBuilder();
-    String groupName = request.getRSGroupName();
-    try {
-      RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName);
-      if (rsGroupInfo != null) {
-        builder.setRSGroupInfo(RSGroupSerDe.toProtoGroupInfo(rsGroupInfo));
+  /**
+   * Implementation of RSGroupAdminService defined in RSGroupAdmin.proto.
+   * This class calls {@link RSGroupAdminServer} for actual work, converts result to protocol
+   * buffer response, handles exceptions if any occurred and then calls the {@code RpcCallback} with
+   * the response.
+   * Since our CoprocessorHost asks the Coprocessor for a Service
+   * ({@link CoprocessorService#getService()}) instead of doing "coproc instanceOf Service"
+   * and requiring Coprocessor itself to be Service (something we do with our observers),
+   * we can use composition instead of inheritance here. That makes it easy to manage
+   * functionalities in concise classes (sometimes inner classes) instead of single class doing
+   * many different things.
+   */
+  private class RSGroupAdminServiceImpl extends RSGroupAdminProtos.RSGroupAdminService {
+    @Override
+    public void getRSGroupInfo(RpcController controller,
+        GetRSGroupInfoRequest request, RpcCallback<GetRSGroupInfoResponse> done) {
+      GetRSGroupInfoResponse.Builder builder = GetRSGroupInfoResponse.newBuilder();
+      String groupName = request.getRSGroupName();
+      try {
+        RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName);
+        if (rsGroupInfo != null) {
+          builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(rsGroupInfo));
+        }
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
       }
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void getRSGroupInfoOfTable(RpcController controller,
-                                  GetRSGroupInfoOfTableRequest request,
-                                  RpcCallback<GetRSGroupInfoOfTableResponse> done) {
-    GetRSGroupInfoOfTableResponse.Builder builder =
-          GetRSGroupInfoOfTableResponse.newBuilder();
-    try {
-      TableName tableName = ProtobufUtil.toTableName(request.getTableName());
-      RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupInfoOfTable(tableName);
-      if (RSGroupInfo != null) {
-        builder.setRSGroupInfo(RSGroupSerDe.toProtoGroupInfo(RSGroupInfo));
+    @Override
+    public void getRSGroupInfoOfTable(RpcController controller,
+        GetRSGroupInfoOfTableRequest request, RpcCallback<GetRSGroupInfoOfTableResponse> done) {
+      GetRSGroupInfoOfTableResponse.Builder builder = GetRSGroupInfoOfTableResponse.newBuilder();
+      try {
+        TableName tableName = ProtobufUtil.toTableName(request.getTableName());
+        RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupInfoOfTable(tableName);
+        if (RSGroupInfo != null) {
+          builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo));
+        }
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
       }
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void moveServers(RpcController controller,
-                          MoveServersRequest request,
-                          RpcCallback<MoveServersResponse> done) {
-    RSGroupAdminProtos.MoveServersResponse.Builder builder =
-          RSGroupAdminProtos.MoveServersResponse.newBuilder();
-    try {
-      Set<Address> hostPorts = Sets.newHashSet();
-      for(HBaseProtos.ServerName el: request.getServersList()) {
-        hostPorts.add(Address.fromParts(el.getHostName(), el.getPort()));
+    @Override
+    public void moveServers(RpcController controller, MoveServersRequest request,
+        RpcCallback<MoveServersResponse> done) {
+      MoveServersResponse.Builder builder = MoveServersResponse.newBuilder();
+      try {
+        Set<Address> hostPorts = Sets.newHashSet();
+        for (HBaseProtos.ServerName el : request.getServersList()) {
+          hostPorts.add(Address.fromParts(el.getHostName(), el.getPort()));
+        }
+        groupAdminServer.moveServers(hostPorts, request.getTargetGroup());
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
       }
-      groupAdminServer.moveServers(hostPorts, request.getTargetGroup());
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void moveTables(RpcController controller,
-                         MoveTablesRequest request,
-                         RpcCallback<MoveTablesResponse> done) {
-    MoveTablesResponse.Builder builder =
-          MoveTablesResponse.newBuilder();
-    try {
-      Set<TableName> tables = new HashSet<TableName>(request.getTableNameList().size());
-      for(HBaseProtos.TableName tableName: request.getTableNameList()) {
-        tables.add(ProtobufUtil.toTableName(tableName));
+    @Override
+    public void moveTables(RpcController controller, MoveTablesRequest request,
+        RpcCallback<MoveTablesResponse> done) {
+      MoveTablesResponse.Builder builder = MoveTablesResponse.newBuilder();
+      try {
+        Set<TableName> tables = new HashSet<>(request.getTableNameList().size());
+        for (HBaseProtos.TableName tableName : request.getTableNameList()) {
+          tables.add(ProtobufUtil.toTableName(tableName));
+        }
+        groupAdminServer.moveTables(tables, request.getTargetGroup());
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
       }
-      groupAdminServer.moveTables(tables, request.getTargetGroup());
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void addRSGroup(RpcController controller,
-                       AddRSGroupRequest request,
-                       RpcCallback<AddRSGroupResponse> done) {
-    AddRSGroupResponse.Builder builder =
-          AddRSGroupResponse.newBuilder();
-    try {
-      groupAdminServer.addRSGroup(request.getRSGroupName());
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+    @Override
+    public void addRSGroup(RpcController controller, AddRSGroupRequest request,
+        RpcCallback<AddRSGroupResponse> done) {
+      AddRSGroupResponse.Builder builder = AddRSGroupResponse.newBuilder();
+      try {
+        groupAdminServer.addRSGroup(request.getRSGroupName());
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
+      }
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void removeRSGroup(RpcController controller,
-                          RemoveRSGroupRequest request,
-                          RpcCallback<RemoveRSGroupResponse> done) {
-    RemoveRSGroupResponse.Builder builder =
+    @Override
+    public void removeRSGroup(RpcController controller,
+        RemoveRSGroupRequest request, RpcCallback<RemoveRSGroupResponse> done) {
+      RemoveRSGroupResponse.Builder builder =
           RemoveRSGroupResponse.newBuilder();
-    try {
-      groupAdminServer.removeRSGroup(request.getRSGroupName());
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      try {
+        groupAdminServer.removeRSGroup(request.getRSGroupName());
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
+      }
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void balanceRSGroup(RpcController controller,
-                           BalanceRSGroupRequest request,
-                           RpcCallback<BalanceRSGroupResponse> done) {
-    BalanceRSGroupResponse.Builder builder = BalanceRSGroupResponse.newBuilder();
-    try {
-      builder.setBalanceRan(groupAdminServer.balanceRSGroup(request.getRSGroupName()));
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
-      builder.setBalanceRan(false);
+    @Override
+    public void balanceRSGroup(RpcController controller,
+        BalanceRSGroupRequest request, RpcCallback<BalanceRSGroupResponse> done) {
+      BalanceRSGroupResponse.Builder builder = BalanceRSGroupResponse.newBuilder();
+      try {
+        builder.setBalanceRan(groupAdminServer.balanceRSGroup(request.getRSGroupName()));
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
+        builder.setBalanceRan(false);
+      }
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void listRSGroupInfos(RpcController controller,
-                             ListRSGroupInfosRequest request,
-                             RpcCallback<ListRSGroupInfosResponse> done) {
-    ListRSGroupInfosResponse.Builder builder =
-          ListRSGroupInfosResponse.newBuilder();
-    try {
-      for(RSGroupInfo RSGroupInfo : groupAdminServer.listRSGroups()) {
-        builder.addRSGroupInfo(RSGroupSerDe.toProtoGroupInfo(RSGroupInfo));
+    @Override
+    public void listRSGroupInfos(RpcController controller,
+        ListRSGroupInfosRequest request, RpcCallback<ListRSGroupInfosResponse> done) {
+      ListRSGroupInfosResponse.Builder builder = ListRSGroupInfosResponse.newBuilder();
+      try {
+        for (RSGroupInfo RSGroupInfo : groupAdminServer.listRSGroups()) {
+          builder.addRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo));
+        }
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
       }
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      done.run(builder.build());
     }
-    done.run(builder.build());
-  }
 
-  @Override
-  public void getRSGroupInfoOfServer(RpcController controller,
-                                   GetRSGroupInfoOfServerRequest request,
-                                   RpcCallback<GetRSGroupInfoOfServerResponse> done) {
-    GetRSGroupInfoOfServerResponse.Builder builder = GetRSGroupInfoOfServerResponse.newBuilder();
-    try {
-      Address hp =
-          Address.fromParts(request.getServer().getHostName(), request.getServer().getPort());
-      RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupOfServer(hp);
-      if (RSGroupInfo != null) {
-        builder.setRSGroupInfo(RSGroupSerDe.toProtoGroupInfo(RSGroupInfo));
+    @Override
+    public void getRSGroupInfoOfServer(RpcController controller,
+        GetRSGroupInfoOfServerRequest request, RpcCallback<GetRSGroupInfoOfServerResponse> done) {
+      GetRSGroupInfoOfServerResponse.Builder builder = GetRSGroupInfoOfServerResponse.newBuilder();
+      try {
+        Address hp = Address.fromParts(request.getServer().getHostName(),
+            request.getServer().getPort());
+        RSGroupInfo RSGroupInfo = groupAdminServer.getRSGroupOfServer(hp);
+        if (RSGroupInfo != null) {
+          builder.setRSGroupInfo(RSGroupProtobufUtil.toProtoGroupInfo(RSGroupInfo));
+        }
+      } catch (IOException e) {
+        CoprocessorRpcUtils.setControllerException(controller, e);
       }
-    } catch (IOException e) {
-      CoprocessorRpcUtils.setControllerException(controller, e);
+      done.run(builder.build());
     }
-    done.run(builder.build());
   }
 
+  /////////////////////////////////////////////////////////////////////////////
+  // MasterObserver overrides
+  /////////////////////////////////////////////////////////////////////////////
+
+  // Assign table to default RSGroup.
   @Override
   public void preCreateTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
       HTableDescriptor desc, HRegionInfo[] regions) throws IOException {
-    groupAdminServer.prepareRSGroupForTable(desc);
+    String groupName =
+        master.getClusterSchema().getNamespace(desc.getTableName().getNamespaceAsString())
+                .getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP);
+    if (groupName == null) {
+      groupName = RSGroupInfo.DEFAULT_GROUP;
+    }
+    RSGroupInfo rsGroupInfo = groupAdminServer.getRSGroupInfo(groupName);
+    if (rsGroupInfo == null) {
+      throw new ConstraintException("Default RSGroup (" + groupName + ") for this table's "
+          + "namespace does not exist.");
+    }
+    if (!rsGroupInfo.containsTable(desc.getTableName())) {
+      LOG.debug("Pre-moving table " + desc.getTableName() + " to RSGroup " + groupName);
+      groupAdminServer.moveTables(Sets.newHashSet(desc.getTableName()), groupName);
+    }
   }
 
+  // Remove table from its RSGroup.
   @Override
   public void postDeleteTable(ObserverContext<MasterCoprocessorEnvironment> ctx,
                               TableName tableName) throws IOException {
-    groupAdminServer.cleanupRSGroupForTable(tableName);
+    try {
+      RSGroupInfo group = groupAdminServer.getRSGroupInfoOfTable(tableName);
+      if (group != null) {
+        LOG.debug(String.format("Removing deleted table '%s' from rsgroup '%s'", tableName,
+            group.getName()));
+        groupAdminServer.moveTables(Sets.newHashSet(tableName), null);
+      }
+    } catch (IOException ex) {
+      LOG.debug("Failed to perform RSGroup information cleanup for table: " + tableName, ex);
+    }
   }
 
   @Override
   public void preCreateNamespace(ObserverContext<MasterCoprocessorEnvironment> ctx,
                                  NamespaceDescriptor ns) throws IOException {
-    String group = ns.getConfigurationValue(RSGroupInfo.NAMESPACEDESC_PROP_GROUP);
+    String group = ns.getConfigurationValue(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP);
     if(group != null && groupAdminServer.getRSGroupInfo(group) == null) {
       throw new ConstraintException("Region server group "+group+" does not exit");
     }
@@ -303,4 +300,5 @@ public class RSGroupAdminEndpoint extends RSGroupAdminService implements Coproce
                                  NamespaceDescriptor ns) throws IOException {
     preCreateNamespace(ctx, ns);
   }
+  /////////////////////////////////////////////////////////////////////////////
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminServer.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminServer.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminServer.java
index 5a00ddb..1f0be5a 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminServer.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupAdminServer.java
@@ -32,7 +32,6 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.HRegionInfo;
-import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
@@ -50,7 +49,6 @@ import org.apache.hadoop.hbase.net.Address;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 
 /**
  * Service to support Region Server Grouping (HBase-6721).
@@ -62,23 +60,23 @@ public class RSGroupAdminServer implements RSGroupAdmin {
   private MasterServices master;
   private final RSGroupInfoManager rsGroupInfoManager;
 
-  public RSGroupAdminServer(MasterServices master,
-                            RSGroupInfoManager RSGroupInfoManager) throws IOException {
+  public RSGroupAdminServer(MasterServices master, RSGroupInfoManager rsGroupInfoManager)
+      throws IOException {
     this.master = master;
-    this.rsGroupInfoManager = RSGroupInfoManager;
+    this.rsGroupInfoManager = rsGroupInfoManager;
   }
 
   @Override
   public RSGroupInfo getRSGroupInfo(String groupName) throws IOException {
-    return getRSGroupInfoManager().getRSGroup(groupName);
+    return rsGroupInfoManager.getRSGroup(groupName);
   }
 
   @Override
   public RSGroupInfo getRSGroupInfoOfTable(TableName tableName) throws IOException {
     // We are reading across two Maps in the below with out synchronizing across
     // them; should be safe most of the time.
-    String groupName = getRSGroupInfoManager().getRSGroupOfTable(tableName);
-    return groupName == null? null: getRSGroupInfoManager().getRSGroup(groupName);
+    String groupName = rsGroupInfoManager.getRSGroupOfTable(tableName);
+    return groupName == null? null: rsGroupInfoManager.getRSGroup(groupName);
   }
 
   private void checkOnlineServersOnly(Set<Address> servers) throws ConstraintException {
@@ -99,18 +97,17 @@ public class RSGroupAdminServer implements RSGroupAdmin {
   /**
    * Check passed name. Fail if nulls or if corresponding RSGroupInfo not found.
    * @return The RSGroupInfo named <code>name</code>
-   * @throws IOException
    */
   private RSGroupInfo getAndCheckRSGroupInfo(String name)
   throws IOException {
     if (StringUtils.isEmpty(name)) {
       throw new ConstraintException("RSGroup cannot be null.");
     }
-    RSGroupInfo rsgi = getRSGroupInfo(name);
-    if (rsgi == null) {
+    RSGroupInfo rsGroupInfo = getRSGroupInfo(name);
+    if (rsGroupInfo == null) {
       throw new ConstraintException("RSGroup does not exist: " + name);
     }
-    return rsgi;
+    return rsGroupInfo;
   }
 
   /**
@@ -141,7 +138,8 @@ public class RSGroupAdminServer implements RSGroupAdmin {
     else regions.addFirst(hri);
   }
 
-  @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE",
+  @edu.umd.cs.findbugs.annotations.SuppressWarnings(
+      value="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE",
       justification="Ignoring complaint because don't know what it is complaining about")
   @Override
   public void moveServers(Set<Address> servers, String targetGroupName)
@@ -155,19 +153,20 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       return;
     }
     RSGroupInfo targetGrp = getAndCheckRSGroupInfo(targetGroupName);
-    RSGroupInfoManager manager = getRSGroupInfoManager();
+
     // Hold a lock on the manager instance while moving servers to prevent
     // another writer changing our state while we are working.
-    synchronized (manager) {
+    synchronized (rsGroupInfoManager) {
       if (master.getMasterCoprocessorHost() != null) {
         master.getMasterCoprocessorHost().preMoveServers(servers, targetGroupName);
       }
       // Presume first server's source group. Later ensure all servers are from this group.
       Address firstServer = servers.iterator().next();
-      RSGroupInfo srcGrp = manager.getRSGroupOfServer(firstServer);
+      RSGroupInfo srcGrp = rsGroupInfoManager.getRSGroupOfServer(firstServer);
       if (srcGrp == null) {
         // Be careful. This exception message is tested for in TestRSGroupsBase...
-        throw new ConstraintException("Source RSGroup for server " + firstServer + " does not exist.");
+        throw new ConstraintException("Source RSGroup for server " + firstServer
+            + " does not exist.");
       }
       if (srcGrp.getName().equals(targetGroupName)) {
         throw new ConstraintException( "Target RSGroup " + targetGroupName +
@@ -180,7 +179,7 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       }
       // Ensure all servers are of same rsgroup.
       for (Address server: servers) {
-        String tmpGroup = manager.getRSGroupOfServer(server).getName();
+        String tmpGroup = rsGroupInfoManager.getRSGroupOfServer(server).getName();
         if (!tmpGroup.equals(srcGrp.getName())) {
           throw new ConstraintException("Move server request should only come from one source " +
               "RSGroup. Expecting only " + srcGrp.getName() + " but contains " + tmpGroup);
@@ -192,7 +191,8 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       }
 
       // MovedServers may be < passed in 'servers'.
-      Set<Address> movedServers = manager.moveServers(servers, srcGrp.getName(), targetGroupName);
+      Set<Address> movedServers = rsGroupInfoManager.moveServers(servers, srcGrp.getName(),
+          targetGroupName);
       List<Address> editableMovedServers = Lists.newArrayList(movedServers);
       boolean foundRegionsToUnassign;
       do {
@@ -231,7 +231,7 @@ public class RSGroupAdminServer implements RSGroupAdmin {
           }
         }
         try {
-          manager.wait(1000);
+          rsGroupInfoManager.wait(1000);
         } catch (InterruptedException e) {
           LOG.warn("Sleep interrupted", e);
           Thread.currentThread().interrupt();
@@ -247,22 +247,21 @@ public class RSGroupAdminServer implements RSGroupAdmin {
   @Override
   public void moveTables(Set<TableName> tables, String targetGroup) throws IOException {
     if (tables == null) {
-      throw new ConstraintException(
-          "The list of servers cannot be null.");
+      throw new ConstraintException("The list of servers cannot be null.");
     }
     if (tables.size() < 1) {
       LOG.debug("moveTables() passed an empty set. Ignoring.");
       return;
     }
-    RSGroupInfoManager manager = getRSGroupInfoManager();
+
     // Hold a lock on the manager instance while moving servers to prevent
     // another writer changing our state while we are working.
-    synchronized (manager) {
+    synchronized (rsGroupInfoManager) {
       if (master.getMasterCoprocessorHost() != null) {
         master.getMasterCoprocessorHost().preMoveTables(tables, targetGroup);
       }
       if(targetGroup != null) {
-        RSGroupInfo destGroup = manager.getRSGroup(targetGroup);
+        RSGroupInfo destGroup = rsGroupInfoManager.getRSGroup(targetGroup);
         if(destGroup == null) {
           throw new ConstraintException("Target " + targetGroup + " RSGroup does not exist.");
         }
@@ -272,14 +271,14 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       }
 
       for (TableName table : tables) {
-        String srcGroup = manager.getRSGroupOfTable(table);
+        String srcGroup = rsGroupInfoManager.getRSGroupOfTable(table);
         if(srcGroup != null && srcGroup.equals(targetGroup)) {
           throw new ConstraintException(
               "Source RSGroup " + srcGroup + " is same as target " + targetGroup +
               " RSGroup for table " + table);
         }
       }
-      manager.moveTables(tables, targetGroup);
+      rsGroupInfoManager.moveTables(tables, targetGroup);
       if (master.getMasterCoprocessorHost() != null) {
         master.getMasterCoprocessorHost().postMoveTables(tables, targetGroup);
       }
@@ -308,7 +307,7 @@ public class RSGroupAdminServer implements RSGroupAdmin {
     if (master.getMasterCoprocessorHost() != null) {
       master.getMasterCoprocessorHost().preAddRSGroup(name);
     }
-    getRSGroupInfoManager().addRSGroup(new RSGroupInfo(name));
+    rsGroupInfoManager.addRSGroup(new RSGroupInfo(name));
     if (master.getMasterCoprocessorHost() != null) {
       master.getMasterCoprocessorHost().postAddRSGroup(name);
     }
@@ -316,37 +315,36 @@ public class RSGroupAdminServer implements RSGroupAdmin {
 
   @Override
   public void removeRSGroup(String name) throws IOException {
-    RSGroupInfoManager manager = getRSGroupInfoManager();
     // Hold a lock on the manager instance while moving servers to prevent
     // another writer changing our state while we are working.
-    synchronized (manager) {
+    synchronized (rsGroupInfoManager) {
       if (master.getMasterCoprocessorHost() != null) {
         master.getMasterCoprocessorHost().preRemoveRSGroup(name);
       }
-      RSGroupInfo rsgi = manager.getRSGroup(name);
-      if (rsgi == null) {
+      RSGroupInfo rsGroupInfo = rsGroupInfoManager.getRSGroup(name);
+      if (rsGroupInfo == null) {
         throw new ConstraintException("RSGroup " + name + " does not exist");
       }
-      int tableCount = rsgi.getTables().size();
+      int tableCount = rsGroupInfo.getTables().size();
       if (tableCount > 0) {
         throw new ConstraintException("RSGroup " + name + " has " + tableCount +
             " tables; you must remove these tables from the rsgroup before " +
             "the rsgroup can be removed.");
       }
-      int serverCount = rsgi.getServers().size();
+      int serverCount = rsGroupInfo.getServers().size();
       if (serverCount > 0) {
         throw new ConstraintException("RSGroup " + name + " has " + serverCount +
             " servers; you must remove these servers from the RSGroup before" +
             "the RSGroup can be removed.");
       }
       for (NamespaceDescriptor ns: master.getClusterSchema().getNamespaces()) {
-        String nsGroup = ns.getConfigurationValue(RSGroupInfo.NAMESPACEDESC_PROP_GROUP);
+        String nsGroup = ns.getConfigurationValue(rsGroupInfo.NAMESPACE_DESC_PROP_GROUP);
         if (nsGroup != null &&  nsGroup.equals(name)) {
           throw new ConstraintException("RSGroup " + name + " is referenced by namespace: " +
               ns.getName());
         }
       }
-      manager.removeRSGroup(name);
+      rsGroupInfoManager.removeRSGroup(name);
       if (master.getMasterCoprocessorHost() != null) {
         master.getMasterCoprocessorHost().postRemoveRSGroup(name);
       }
@@ -370,9 +368,7 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       // Only allow one balance run at at time.
       Map<String, RegionState> groupRIT = rsGroupGetRegionsInTransition(groupName);
       if (groupRIT.size() > 0) {
-        LOG.debug("Not running balancer because " +
-          groupRIT.size() +
-          " region(s) in transition: " +
+        LOG.debug("Not running balancer because " + groupRIT.size() + " region(s) in transition: " +
           StringUtils.abbreviate(
               master.getAssignmentManager().getRegionStates().getRegionsInTransition().toString(),
               256));
@@ -388,9 +384,10 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       List<RegionPlan> plans = new ArrayList<RegionPlan>();
       for(Map.Entry<TableName, Map<ServerName, List<HRegionInfo>>> tableMap:
           getRSGroupAssignmentsByTable(groupName).entrySet()) {
-        LOG.info("Creating partial plan for table "+tableMap.getKey()+": "+tableMap.getValue());
+        LOG.info("Creating partial plan for table " + tableMap.getKey() + ": "
+            + tableMap.getValue());
         List<RegionPlan> partialPlans = balancer.balanceCluster(tableMap.getValue());
-        LOG.info("Partial plan for table "+tableMap.getKey()+": "+partialPlans);
+        LOG.info("Partial plan for table " + tableMap.getKey() + ": " + partialPlans);
         if (partialPlans != null) {
           plans.addAll(partialPlans);
         }
@@ -398,13 +395,13 @@ public class RSGroupAdminServer implements RSGroupAdmin {
       long startTime = System.currentTimeMillis();
       balancerRan = plans != null;
       if (plans != null && !plans.isEmpty()) {
-        LOG.info("RSGroup balance "+groupName+" starting with plan count: "+plans.size());
+        LOG.info("RSGroup balance " + groupName + " starting with plan count: " + plans.size());
         for (RegionPlan plan: plans) {
           LOG.info("balance " + plan);
           assignmentManager.balance(plan);
         }
-        LOG.info("RSGroup balance "+groupName+" completed after "+
-            (System.currentTimeMillis()-startTime)+" seconds");
+        LOG.info("RSGroup balance " + groupName + " completed after " +
+            (System.currentTimeMillis()-startTime) + " seconds");
       }
       if (master.getMasterCoprocessorHost() != null) {
         master.getMasterCoprocessorHost().postBalanceRSGroup(groupName, balancerRan);
@@ -415,27 +412,21 @@ public class RSGroupAdminServer implements RSGroupAdmin {
 
   @Override
   public List<RSGroupInfo> listRSGroups() throws IOException {
-    return getRSGroupInfoManager().listRSGroups();
+    return rsGroupInfoManager.listRSGroups();
   }
 
   @Override
   public RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException {
-    return getRSGroupInfoManager().getRSGroupOfServer(hostPort);
-  }
-
-  private RSGroupInfoManager getRSGroupInfoManager() throws IOException {
-    return rsGroupInfoManager;
+    return rsGroupInfoManager.getRSGroupOfServer(hostPort);
   }
 
   private Map<String, RegionState> rsGroupGetRegionsInTransition(String groupName)
       throws IOException {
     Map<String, RegionState> rit = Maps.newTreeMap();
     AssignmentManager am = master.getAssignmentManager();
-    RSGroupInfo RSGroupInfo = getRSGroupInfo(groupName);
-    for(TableName tableName : RSGroupInfo.getTables()) {
+    for(TableName tableName : getRSGroupInfo(groupName).getTables()) {
       for(HRegionInfo regionInfo: am.getRegionStates().getRegionsOfTable(tableName)) {
-        RegionState state =
-            master.getAssignmentManager().getRegionStates().getRegionTransitionState(regionInfo);
+        RegionState state = am.getRegionStates().getRegionTransitionState(regionInfo);
         if(state != null) {
           rit.put(regionInfo.getEncodedName(), state);
         }
@@ -447,72 +438,37 @@ public class RSGroupAdminServer implements RSGroupAdmin {
   private Map<TableName, Map<ServerName, List<HRegionInfo>>>
       getRSGroupAssignmentsByTable(String groupName) throws IOException {
     Map<TableName, Map<ServerName, List<HRegionInfo>>> result = Maps.newHashMap();
-    RSGroupInfo RSGroupInfo = getRSGroupInfo(groupName);
+    RSGroupInfo rsGroupInfo = getRSGroupInfo(groupName);
     Map<TableName, Map<ServerName, List<HRegionInfo>>> assignments = Maps.newHashMap();
     for(Map.Entry<HRegionInfo, ServerName> entry:
         master.getAssignmentManager().getRegionStates().getRegionAssignments().entrySet()) {
       TableName currTable = entry.getKey().getTable();
       ServerName currServer = entry.getValue();
       HRegionInfo currRegion = entry.getKey();
-      if(RSGroupInfo.getTables().contains(currTable)) {
-        if(!assignments.containsKey(entry.getKey().getTable())) {
-          assignments.put(currTable, new HashMap<ServerName, List<HRegionInfo>>());
-        }
-        if(!assignments.get(currTable).containsKey(currServer)) {
-          assignments.get(currTable).put(currServer, new ArrayList<HRegionInfo>());
-        }
+      if (rsGroupInfo.getTables().contains(currTable)) {
+        assignments.putIfAbsent(currTable, new HashMap<>());
+        assignments.get(currTable).putIfAbsent(currServer, new ArrayList<>());
         assignments.get(currTable).get(currServer).add(currRegion);
       }
     }
 
     Map<ServerName, List<HRegionInfo>> serverMap = Maps.newHashMap();
     for(ServerName serverName: master.getServerManager().getOnlineServers().keySet()) {
-      if(RSGroupInfo.getServers().contains(serverName.getAddress())) {
+      if(rsGroupInfo.getServers().contains(serverName.getAddress())) {
         serverMap.put(serverName, Collections.emptyList());
       }
     }
 
-    //add all tables that are members of the group
-    for(TableName tableName : RSGroupInfo.getTables()) {
+    // add all tables that are members of the group
+    for(TableName tableName : rsGroupInfo.getTables()) {
       if(assignments.containsKey(tableName)) {
-        result.put(tableName, new HashMap<ServerName, List<HRegionInfo>>());
+        result.put(tableName, new HashMap<>());
         result.get(tableName).putAll(serverMap);
         result.get(tableName).putAll(assignments.get(tableName));
-        LOG.debug("Adding assignments for "+tableName+": "+assignments.get(tableName));
+        LOG.debug("Adding assignments for " + tableName + ": " + assignments.get(tableName));
       }
     }
 
     return result;
   }
-
-  public void prepareRSGroupForTable(HTableDescriptor desc) throws IOException {
-    String groupName =
-        master.getClusterSchema().getNamespace(desc.getTableName().getNamespaceAsString())
-                .getConfigurationValue(RSGroupInfo.NAMESPACEDESC_PROP_GROUP);
-    if (groupName == null) {
-      groupName = RSGroupInfo.DEFAULT_GROUP;
-    }
-    RSGroupInfo RSGroupInfo = getRSGroupInfo(groupName);
-    if (RSGroupInfo == null) {
-      throw new ConstraintException("RSGroup " + groupName + " does not exist.");
-    }
-    if (!RSGroupInfo.containsTable(desc.getTableName())) {
-      LOG.debug("Pre-moving table " + desc.getTableName() + " to RSGroup " + groupName);
-      moveTables(Sets.newHashSet(desc.getTableName()), groupName);
-    }
-  }
-
-  public void cleanupRSGroupForTable(TableName tableName) throws IOException {
-    try {
-      RSGroupInfo group = getRSGroupInfoOfTable(tableName);
-      if (group != null) {
-        LOG.debug("Removing deleted table from table rsgroup " + group.getName());
-        moveTables(Sets.newHashSet(tableName), null);
-      }
-    } catch (ConstraintException ex) {
-      LOG.debug("Failed to perform RSGroup information cleanup for table: " + tableName, ex);
-    } catch (IOException ex) {
-      LOG.debug("Failed to perform RSGroup information cleanup for table: " + tableName, ex);
-    }
-  }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java
index b70c236..b36fd21 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupBasedLoadBalancer.java
@@ -18,6 +18,7 @@
 
 package org.apache.hadoop.hbase.rsgroup;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.LinkedListMultimap;
 import com.google.common.collect.ListMultimap;
@@ -38,7 +39,6 @@ import java.util.TreeMap;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.ClusterStatus;
 import org.apache.hadoop.hbase.HBaseIOException;
@@ -70,10 +70,7 @@ import org.apache.hadoop.util.ReflectionUtils;
  *
  */
 @InterfaceAudience.Private
-public class RSGroupBasedLoadBalancer implements RSGroupableBalancer, LoadBalancer {
-  /** Config for pluggable load balancers */
-  public static final String HBASE_GROUP_LOADBALANCER_CLASS = "hbase.group.grouploadbalancer.class";
-
+public class RSGroupBasedLoadBalancer implements RSGroupableBalancer {
   private static final Log LOG = LogFactory.getLog(RSGroupBasedLoadBalancer.class);
 
   private Configuration config;
@@ -82,16 +79,12 @@ public class RSGroupBasedLoadBalancer implements RSGroupableBalancer, LoadBalanc
   private volatile RSGroupInfoManager rsGroupInfoManager;
   private LoadBalancer internalBalancer;
 
-  //used during reflection by LoadBalancerFactory
+  /**
+   * Used by reflection in {@link org.apache.hadoop.hbase.master.balancer.LoadBalancerFactory}.
+   */
   @InterfaceAudience.Private
   public RSGroupBasedLoadBalancer() {}
 
-  //This constructor should only be used for unit testing
-  @InterfaceAudience.Private
-  public RSGroupBasedLoadBalancer(RSGroupInfoManager rsGroupInfoManager) {
-    this.rsGroupInfoManager = rsGroupInfoManager;
-  }
-
   @Override
   public Configuration getConf() {
     return config;
@@ -113,11 +106,6 @@ public class RSGroupBasedLoadBalancer implements RSGroupableBalancer, LoadBalanc
   }
 
   @Override
-  public void setClusterLoad(Map<TableName, Map<ServerName, List<HRegionInfo>>> clusterLoad){
-
-  }
-
-  @Override
   public List<RegionPlan> balanceCluster(TableName tableName, Map<ServerName, List<HRegionInfo>>
       clusterState) throws HBaseIOException {
     return balanceCluster(clusterState);
@@ -384,8 +372,7 @@ public class RSGroupBasedLoadBalancer implements RSGroupableBalancer, LoadBalanc
     }
 
     // Create the balancer
-    Class<? extends LoadBalancer> balancerKlass = config.getClass(
-        HBASE_GROUP_LOADBALANCER_CLASS,
+    Class<? extends LoadBalancer> balancerKlass = config.getClass(HBASE_RSGROUP_LOADBALANCER_CLASS,
         StochasticLoadBalancer.class, LoadBalancer.class);
     internalBalancer = ReflectionUtils.newInstance(balancerKlass, config);
     internalBalancer.setMasterServices(masterServices);
@@ -400,6 +387,10 @@ public class RSGroupBasedLoadBalancer implements RSGroupableBalancer, LoadBalanc
   }
 
   @Override
+  public void setClusterLoad(Map<TableName, Map<ServerName, List<HRegionInfo>>> clusterLoad) {
+  }
+
+  @Override
   public void regionOnline(HRegionInfo regionInfo, ServerName sn) {
   }
 
@@ -420,4 +411,9 @@ public class RSGroupBasedLoadBalancer implements RSGroupableBalancer, LoadBalanc
   public boolean isStopped() {
     return false;
   }
+
+  @VisibleForTesting
+  public void setRsGroupInfoManager(RSGroupInfoManager rsGroupInfoManager) {
+    this.rsGroupInfoManager = rsGroupInfoManager;
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/ce64e7eb/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManager.java
----------------------------------------------------------------------
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManager.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManager.java
index 6d8c2c8..88ea04b 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManager.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManager.java
@@ -37,28 +37,21 @@ import org.apache.hadoop.hbase.net.Address;
 @InterfaceAudience.Private
 public interface RSGroupInfoManager {
   //Assigned before user tables
-  public static final TableName RSGROUP_TABLE_NAME =
+  TableName RSGROUP_TABLE_NAME =
       TableName.valueOf(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR, "rsgroup");
-  public static final byte[] RSGROUP_TABLE_NAME_BYTES = RSGROUP_TABLE_NAME.toBytes();
-  public static final String rsGroupZNode = "rsgroup";
-  public static final byte[] META_FAMILY_BYTES = Bytes.toBytes("m");
-  public static final byte[] META_QUALIFIER_BYTES = Bytes.toBytes("i");
-  public static final byte[] ROW_KEY = {0};
-
+  byte[] RSGROUP_TABLE_NAME_BYTES = RSGROUP_TABLE_NAME.toBytes();
+  String rsGroupZNode = "rsgroup";
+  byte[] META_FAMILY_BYTES = Bytes.toBytes("m");
+  byte[] META_QUALIFIER_BYTES = Bytes.toBytes("i");
+  byte[] ROW_KEY = {0};
 
   /**
-   * Adds the group.
-   *
-   * @param rsGroupInfo the group name
-   * @throws java.io.IOException Signals that an I/O exception has occurred.
+   * Add given RSGroupInfo to existing list of group infos.
    */
   void addRSGroup(RSGroupInfo rsGroupInfo) throws IOException;
 
   /**
    * Remove a region server group.
-   *
-   * @param groupName the group name
-   * @throws java.io.IOException Signals that an I/O exception has occurred.
    */
   void removeRSGroup(String groupName) throws IOException;
 
@@ -68,32 +61,22 @@ public interface RSGroupInfoManager {
    * @param srcGroup groupName being moved from
    * @param dstGroup groupName being moved to
    * @return Set of servers moved (May be a subset of {@code servers}).
-   * @throws java.io.IOException on move failure
    */
-  Set<Address> moveServers(Set<Address> servers,
-                      String srcGroup, String dstGroup) throws IOException;
+  Set<Address> moveServers(Set<Address> servers, String srcGroup, String dstGroup)
+      throws IOException;
 
   /**
    * Gets the group info of server.
-   *
-   * @param hostPort the server
-   * @return An instance of RSGroupInfo
    */
-  RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException;
+  RSGroupInfo getRSGroupOfServer(Address serverHostPort) throws IOException;
 
   /**
-   * Gets the group information.
-   *
-   * @param groupName the group name
-   * @return An instance of RSGroupInfo
+   * Gets {@code RSGroupInfo} for the given group name.
    */
   RSGroupInfo getRSGroup(String groupName) throws IOException;
 
   /**
    * Get the group membership of a table
-   * @param tableName name of table to get group membership
-   * @return Group name of table
-   * @throws java.io.IOException on failure to retrive information
    */
   String getRSGroupOfTable(TableName tableName) throws IOException;
 
@@ -102,29 +85,21 @@ public interface RSGroupInfoManager {
    *
    * @param tableNames set of tables to move
    * @param groupName name of group of tables to move to
-   * @throws java.io.IOException on failure to move
    */
   void moveTables(Set<TableName> tableNames, String groupName) throws IOException;
 
   /**
-   * List the groups
-   *
-   * @return list of RSGroupInfo
-   * @throws java.io.IOException on failure
+   * List the existing {@code RSGroupInfo}s.
    */
   List<RSGroupInfo> listRSGroups() throws IOException;
 
   /**
-   * Refresh/reload the group information from
-   * the persistent store
-   *
-   * @throws java.io.IOException on failure to refresh
+   * Refresh/reload the group information from the persistent store
    */
   void refresh() throws IOException;
 
   /**
-   * Whether the manager is able to fully
-   * return group metadata
+   * Whether the manager is able to fully return group metadata
    *
    * @return whether the manager is in online mode
    */