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 9ea996be1cc..c389dc5d6cf 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 @@ -98,4 +98,11 @@ public interface RSGroupAdmin { * @param servers set of servers to remove */ void removeServers(Set
servers) throws IOException; + + /** + * Rename rsgroup. + * @param oldName old rsgroup name + * @param newName new rsgroup name + */ + void renameRSGroup(String oldName, String newName) throws IOException; } 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 e8a14106438..bcfe3a4865b 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 @@ -46,6 +46,7 @@ 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.RemoveServersRequest; +import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RenameRSGroupRequest; import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos; import org.apache.yetus.audience.InterfaceAudience; @@ -236,4 +237,16 @@ public class RSGroupAdminClient implements RSGroupAdmin { throw ProtobufUtil.handleRemoteException(e); } } + + @Override + public void renameRSGroup(String oldName, String newName) throws IOException { + RenameRSGroupRequest request = RenameRSGroupRequest.newBuilder() + .setOldRsgroupName(oldName) + .setNewRsgroupName(newName).build(); + try { + stub.renameRSGroup(null, request); + } catch (ServiceException e) { + throw ProtobufUtil.handleRemoteException(e); + } + } } 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 b869e81fc64..fbbd671b453 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 @@ -79,6 +79,8 @@ import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGro import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupResponse; import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersRequest; import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServersResponse; +import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RenameRSGroupRequest; +import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RenameRSGroupResponse; import org.apache.hadoop.hbase.protobuf.generated.TableProtos; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.security.UserProvider; @@ -441,6 +443,30 @@ public class RSGroupAdminEndpoint implements MasterCoprocessor, MasterObserver { } done.run(builder.build()); } + + @Override + public void renameRSGroup(RpcController controller, + RenameRSGroupRequest request, + RpcCallback done) { + String oldRSGroup = request.getOldRsgroupName(); + String newRSGroup = request.getNewRsgroupName(); + LOG.info("{} rename rsgroup from {} to {}", + master.getClientIdAuditPrefix(), oldRSGroup, newRSGroup); + + RenameRSGroupResponse.Builder builder = RenameRSGroupResponse.newBuilder(); + try { + if (master.getMasterCoprocessorHost() != null) { + master.getMasterCoprocessorHost().preRenameRSGroup(oldRSGroup, newRSGroup); + } + groupAdminServer.renameRSGroup(oldRSGroup, newRSGroup); + if (master.getMasterCoprocessorHost() != null) { + master.getMasterCoprocessorHost().postRenameRSGroup(oldRSGroup, newRSGroup); + } + } catch (IOException e) { + CoprocessorRpcUtils.setControllerException(controller, e); + } + done.run(builder.build()); + } } boolean rsgroupHasServersOnline(TableDescriptor desc) throws IOException { 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 9f038ffea93..bf9f8488c82 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 @@ -525,6 +525,13 @@ public class RSGroupAdminServer implements RSGroupAdmin { } } + @Override + public void renameRSGroup(String oldName, String newName) throws IOException { + synchronized (rsGroupInfoManager) { + rsGroupInfoManager.renameRSGroup(oldName, newName); + } + } + private Map rsGroupGetRegionsInTransition(String groupName) throws IOException { Map rit = Maps.newTreeMap(); 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 b0cd5ff57f2..d2bf5390bfe 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 @@ -125,4 +125,11 @@ public interface RSGroupInfoManager { * @param servers set of servers to remove */ void removeServers(Set
servers) throws IOException; + + /** + * Rename RSGroup + * @param oldName old rsgroup name + * @param newName new rsgroup name + */ + void renameRSGroup(String oldName, String newName) throws IOException; } diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java index c2c463b497d..2f452b3f41a 100644 --- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java +++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupInfoManagerImpl.java @@ -349,6 +349,23 @@ final class RSGroupInfoManagerImpl implements RSGroupInfoManager { } } + @Override + public void renameRSGroup(String oldName, String newName) throws IOException { + checkGroupName(oldName); + checkGroupName(newName); + if (oldName.equals(RSGroupInfo.DEFAULT_GROUP)) { + throw new ConstraintException("Can't rename default rsgroup"); + } + + RSGroupInfo oldGroup = getRSGroup(oldName); + Map newGroupMap = Maps.newHashMap(rsGroupMap); + newGroupMap.remove(oldName); + RSGroupInfo newGroup = new RSGroupInfo(newName, + (SortedSet
) oldGroup.getServers(), oldGroup.getTables()); + newGroupMap.put(newName, newGroup); + flushConfig(newGroupMap); + } + List retrieveGroupListFromGroupTable() throws IOException { List rsGroupInfoList = Lists.newArrayList(); try (Table table = conn.getTable(RSGROUP_TABLE_NAME); diff --git a/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto b/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto index 316b06f55c9..10f6570a2f8 100644 --- a/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto +++ b/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto @@ -123,6 +123,14 @@ message RemoveServersRequest { message RemoveServersResponse { } +message RenameRSGroupRequest { + required string old_rsgroup_name = 1; + required string new_rsgroup_name = 2; +} + +message RenameRSGroupResponse { +} + service RSGroupAdminService { rpc GetRSGroupInfo(GetRSGroupInfoRequest) returns (GetRSGroupInfoResponse); @@ -156,4 +164,7 @@ service RSGroupAdminService { rpc RemoveServers(RemoveServersRequest) returns (RemoveServersResponse); + + rpc RenameRSGroup(RenameRSGroupRequest) + returns (RenameRSGroupResponse); } diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsAdmin1.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsAdmin1.java index ca53985dc81..60e66bb2da4 100644 --- a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsAdmin1.java +++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsAdmin1.java @@ -497,4 +497,47 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase { TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true); initialize(); } + + @Test + public void testRenameRSGroup() throws Exception { + // Add rsgroup, and assign 2 servers and a table to it. + RSGroupInfo oldgroup = addGroup("oldgroup", 2); + final TableName tb1 = TableName.valueOf("testRename"); + TEST_UTIL.createTable(tb1, "tr"); + rsGroupAdmin.moveTables(Sets.newHashSet(tb1), oldgroup.getName()); + TEST_UTIL.waitFor(1000, + (Waiter.Predicate) () -> + rsGroupAdmin.getRSGroupInfoOfTable(tb1).getServers().size() == 2); + oldgroup = rsGroupAdmin.getRSGroupInfo(oldgroup.getName()); + assertEquals(2, oldgroup.getServers().size()); + assertEquals(oldgroup.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb1).getName()); + assertTrue(oldgroup.getTables().contains(tb1)); + + // Another rsgroup and table for verification + // that they are unchanged during we're renaming oldgroup. + RSGroupInfo normal = addGroup("normal", 1); + final TableName tb2 = TableName.valueOf("unmovedTable"); + TEST_UTIL.createTable(tb2, "ut"); + rsGroupAdmin.moveTables(Sets.newHashSet(tb2), normal.getName()); + TEST_UTIL.waitFor(1000, + (Waiter.Predicate) () -> + rsGroupAdmin.getRSGroupInfoOfTable(tb2).getServers().size() == 1); + normal = rsGroupAdmin.getRSGroupInfo(normal.getName()); + assertEquals(1, normal.getServers().size()); + assertEquals(normal.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb2).getName()); + assertTrue(normal.containsTable(tb2)); + + + // Rename rsgroup + rsGroupAdmin.renameRSGroup(oldgroup.getName(), "newgroup"); + Set
servers = oldgroup.getServers(); + RSGroupInfo newgroup = rsGroupAdmin.getRSGroupInfo("newgroup"); + assertEquals(servers.size(), newgroup.getServers().size()); + for (Address server : servers) { + assertTrue(newgroup.containsServer(server)); + } + assertEquals(newgroup.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb1).getName()); + assertTrue(newgroup.containsTable(tb1)); + assertEquals(normal.getName(), rsGroupAdmin.getRSGroupInfoOfTable(tb2).getName()); + } } diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java index 8d7a67fe106..6cb738d6136 100644 --- a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java +++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsBase.java @@ -304,6 +304,8 @@ public abstract class TestRSGroupsBase { boolean postRemoveServersCalled = false; boolean preMoveServersAndTables = false; boolean postMoveServersAndTables = false; + boolean preReNameRSGroupCalled = false; + boolean postReNameRSGroupCalled = false; public void resetFlags() { preBalanceRSGroupCalled = false; @@ -320,6 +322,8 @@ public abstract class TestRSGroupsBase { postRemoveServersCalled = false; preMoveServersAndTables = false; postMoveServersAndTables = false; + preReNameRSGroupCalled = false; + postReNameRSGroupCalled = false; } @Override @@ -412,6 +416,18 @@ public abstract class TestRSGroupsBase { String groupName, boolean balancerRan) throws IOException { postBalanceRSGroupCalled = true; } + + @Override + public void preRenameRSGroup(ObserverContext ctx, + String oldName, String newName) throws IOException { + preReNameRSGroupCalled = true; + } + + @Override + public void postRenameRSGroup(ObserverContext ctx, + String oldName, String newName) throws IOException { + postReNameRSGroupCalled = true; + } } } diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/VerifyingRSGroupAdminClient.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/VerifyingRSGroupAdminClient.java index 2af2721c2e1..923a77d44f9 100644 --- a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/VerifyingRSGroupAdminClient.java +++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/VerifyingRSGroupAdminClient.java @@ -119,6 +119,12 @@ public class VerifyingRSGroupAdminClient implements RSGroupAdmin { verify(); } + @Override + public void renameRSGroup(String oldName, String newName) throws IOException { + wrapped.renameRSGroup(oldName, newName); + verify(); + } + public void verify() throws IOException { Map groupMap = Maps.newHashMap(); Set zList = Sets.newHashSet(); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java index 69abfc2640e..48c259bac4e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java @@ -1624,4 +1624,26 @@ public interface MasterObserver { default void postHasUserPermissions(ObserverContext ctx, String userName, List permissions) throws IOException { } + + /** + * Called before rename rsgroup. + * @param ctx the environment to interact with the framework and master + * @param oldName old rsgroup name + * @param newName new rsgroup name + * @throws IOException on failure + */ + default void preRenameRSGroup(final ObserverContext ctx, + final String oldName, final String newName) throws IOException { + } + + /** + * Called after rename rsgroup. + * @param ctx the environment to interact with the framework and master + * @param oldName old rsgroup name + * @param newName new rsgroup name + * @throws IOException on failure + */ + default void postRenameRSGroup(final ObserverContext ctx, + final String oldName, final String newName) throws IOException { + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java index 13c67644ea9..236eda0581f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java @@ -1453,6 +1453,26 @@ public class MasterCoprocessorHost }); } + public void preRenameRSGroup(final String oldName, final String newName) + throws IOException { + execOperation(coprocEnvironments.isEmpty() ? null: new MasterObserverOperation() { + @Override + public void call(MasterObserver observer) throws IOException { + observer.preRenameRSGroup(this, oldName, newName); + } + }); + } + + public void postRenameRSGroup(final String oldName, final String newName) + throws IOException { + execOperation(coprocEnvironments.isEmpty() ? null: new MasterObserverOperation() { + @Override + public void call(MasterObserver observer) throws IOException { + observer.postRenameRSGroup(this, oldName, newName); + } + }); + } + public void preRemoveServers(final Set
servers) throws IOException { execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {