You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zg...@apache.org on 2020/07/08 06:39:51 UTC
[hbase] branch branch-2 updated: HBASE-24431 RSGroupInfo add
configuration map to store something extra (#2031)
This is an automated email from the ASF dual-hosted git repository.
zghao pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new 5fcffae HBASE-24431 RSGroupInfo add configuration map to store something extra (#2031)
5fcffae is described below
commit 5fcffae5db8ba6d3afb2c4292fbac4b9795fc53d
Author: XinSun <dd...@gmail.com>
AuthorDate: Wed Jul 8 14:39:41 2020 +0800
HBASE-24431 RSGroupInfo add configuration map to store something extra (#2031)
Signed-off-by: Guanghao Zhang <zg...@apache.org>
---
.../apache/hadoop/hbase/rsgroup/RSGroupInfo.java | 34 +++++++-
hbase-protocol/src/main/protobuf/RSGroup.proto | 1 +
.../apache/hadoop/hbase/rsgroup/RSGroupAdmin.java | 9 +++
.../hadoop/hbase/rsgroup/RSGroupAdminClient.java | 20 +++++
.../hadoop/hbase/rsgroup/RSGroupAdminEndpoint.java | 28 +++++++
.../hadoop/hbase/rsgroup/RSGroupAdminServer.java | 8 ++
.../hadoop/hbase/rsgroup/RSGroupInfoManager.java | 9 +++
.../hbase/rsgroup/RSGroupInfoManagerImpl.java | 11 +++
.../hadoop/hbase/rsgroup/RSGroupProtobufUtil.java | 19 +++--
hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto | 11 +++
.../hadoop/hbase/rsgroup/TestRSGroupConfig.java | 94 ++++++++++++++++++++++
.../hbase/rsgroup/VerifyingRSGroupAdminClient.java | 7 ++
.../hadoop/hbase/coprocessor/MasterObserver.java | 19 +++++
.../hadoop/hbase/master/MasterCoprocessorHost.java | 21 +++++
hbase-shell/src/main/ruby/hbase/rsgroup_admin.rb | 37 +++++++++
hbase-shell/src/main/ruby/shell.rb | 2 +
.../ruby/shell/commands/alter_rsgroup_config.rb | 38 +++++++++
.../ruby/shell/commands/show_rsgroup_config.rb | 41 ++++++++++
.../src/test/ruby/shell/rsgroup_shell_test.rb | 14 ++++
19 files changed, 416 insertions(+), 7 deletions(-)
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 25e827d..2fe2ba9 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
@@ -19,6 +19,10 @@
package org.apache.hadoop.hbase.rsgroup;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -41,18 +45,22 @@ public class RSGroupInfo {
// Keep tables sorted too.
private final SortedSet<TableName> tables;
+ private final Map<String, String> configuration;
+
public RSGroupInfo(String name) {
- this(name, new TreeSet<Address>(), new TreeSet<TableName>());
+ this(name, new TreeSet<>(), new TreeSet<>());
}
RSGroupInfo(String name, SortedSet<Address> servers, SortedSet<TableName> tables) {
this.name = name;
this.servers = (servers == null) ? new TreeSet<>() : new TreeSet<>(servers);
this.tables = (tables == null) ? new TreeSet<>() : new TreeSet<>(tables);
+ configuration = new HashMap<>();
}
public RSGroupInfo(RSGroupInfo src) {
this(src.name, src.servers, src.tables);
+ src.configuration.forEach(this::setConfiguration);
}
/**
@@ -121,6 +129,30 @@ public class RSGroupInfo {
return tables.remove(table);
}
+ /**
+ * Getter for fetching an unmodifiable {@link #configuration} map.
+ */
+ public Map<String, String> getConfiguration() {
+ // shallow pointer copy
+ return Collections.unmodifiableMap(configuration);
+ }
+
+ /**
+ * Setter for storing a configuration setting in {@link #configuration} map.
+ * @param key Config key.
+ * @param value String value.
+ */
+ public void setConfiguration(String key, String value) {
+ configuration.put(key, Objects.requireNonNull(value));
+ }
+
+ /**
+ * Remove a config setting represented by the key from the {@link #configuration} map
+ */
+ public void removeConfiguration(final String key) {
+ configuration.remove(key);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/hbase-protocol/src/main/protobuf/RSGroup.proto b/hbase-protocol/src/main/protobuf/RSGroup.proto
index ba82175..5ab949c 100644
--- a/hbase-protocol/src/main/protobuf/RSGroup.proto
+++ b/hbase-protocol/src/main/protobuf/RSGroup.proto
@@ -31,5 +31,6 @@ message RSGroupInfo {
required string name = 1;
repeated ServerName servers = 4;
repeated TableName tables = 3;
+ repeated NameStringPair configuration = 5;
}
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 c389dc5..15daf14 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
@@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.rsgroup;
import java.io.IOException;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.hadoop.hbase.TableName;
@@ -105,4 +106,12 @@ public interface RSGroupAdmin {
* @param newName new rsgroup name
*/
void renameRSGroup(String oldName, String newName) throws IOException;
+
+ /**
+ * Update RSGroup configuration
+ * @param groupName the group name
+ * @param configuration new configuration of the group name to be set
+ * @throws IOException if a remote or network exception occurs
+ */
+ void updateRSGroupConfig(String groupName, Map<String, String> configuration) 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 bcfe3a4..b4e5e80 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
@@ -22,6 +22,7 @@ import com.google.protobuf.ServiceException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.hadoop.hbase.TableName;
@@ -31,6 +32,7 @@ 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.HBaseProtos.NameStringPair;
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;
@@ -47,6 +49,7 @@ import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RSGroupAdmi
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.RSGroupAdminProtos.UpdateRSGroupConfigRequest;
import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
import org.apache.yetus.audience.InterfaceAudience;
@@ -249,4 +252,21 @@ public class RSGroupAdminClient implements RSGroupAdmin {
throw ProtobufUtil.handleRemoteException(e);
}
}
+
+ @Override
+ public void updateRSGroupConfig(String groupName, Map<String, String> configuration)
+ throws IOException {
+ UpdateRSGroupConfigRequest.Builder builder = UpdateRSGroupConfigRequest.newBuilder()
+ .setGroupName(groupName);
+ if (configuration != null) {
+ configuration.entrySet().forEach(e ->
+ builder.addConfiguration(NameStringPair.newBuilder().setName(e.getKey())
+ .setValue(e.getValue()).build()));
+ }
+ try {
+ stub.updateRSGroupConfig(null, builder.build());
+ } 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 ad4c1af..0a05c85 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
@@ -26,6 +26,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -81,6 +82,8 @@ import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.RemoveServe
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.RSGroupAdminProtos.UpdateRSGroupConfigRequest;
+import org.apache.hadoop.hbase.protobuf.generated.RSGroupAdminProtos.UpdateRSGroupConfigResponse;
import org.apache.hadoop.hbase.protobuf.generated.TableProtos;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.security.UserProvider;
@@ -90,6 +93,8 @@ import org.apache.hadoop.util.Shell.ShellCommandExecutor;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
+import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
// TODO: Encapsulate MasterObserver functions into separate subclass.
@@ -425,6 +430,29 @@ public class RSGroupAdminEndpoint implements MasterCoprocessor, MasterObserver {
}
done.run(builder.build());
}
+
+ @Override
+ public void updateRSGroupConfig(RpcController controller, UpdateRSGroupConfigRequest request,
+ RpcCallback<UpdateRSGroupConfigResponse> done) {
+ UpdateRSGroupConfigResponse.Builder builder = UpdateRSGroupConfigResponse.newBuilder();
+ String groupName = request.getGroupName();
+ Map<String, String> configuration = Maps.newHashMap();
+ request.getConfigurationList().forEach(p -> configuration.put(p.getName(), p.getValue()));
+ LOG.info("{} update rsgroup {} configuration {}", master.getClientIdAuditPrefix(), groupName,
+ configuration);
+ try {
+ if (master.getMasterCoprocessorHost() != null) {
+ master.getMasterCoprocessorHost().preUpdateRSGroupConfig(groupName, configuration);
+ }
+ groupAdminServer.updateRSGroupConfig(groupName, configuration);
+ if (master.getMasterCoprocessorHost() != null) {
+ master.getMasterCoprocessorHost().postUpdateRSGroupConfig(groupName, configuration);
+ }
+ } 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 bf9f8488..a1f988d 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
@@ -532,6 +532,14 @@ public class RSGroupAdminServer implements RSGroupAdmin {
}
}
+ @Override
+ public void updateRSGroupConfig(String groupName, Map<String, String> configuration)
+ throws IOException {
+ synchronized (rsGroupInfoManager) {
+ rsGroupInfoManager.updateRSGroupConfig(groupName, configuration);
+ }
+ }
+
private Map<String, RegionState> rsGroupGetRegionsInTransition(String groupName)
throws IOException {
Map<String, RegionState> 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 594f0f0..e64e2d2 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
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.rsgroup;
import java.io.IOException;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.hadoop.hbase.NamespaceDescriptor;
@@ -139,4 +140,12 @@ public interface RSGroupInfoManager {
* @return {@link RSGroupInfo} which table should belong to
*/
RSGroupInfo determineRSGroupInfoForTable(TableName tableName) throws IOException;
+
+ /**
+ * Update RSGroup configuration
+ * @param groupName the group name
+ * @param configuration new configuration of the group name to be set
+ * @throws IOException if a remote or network exception occurs
+ */
+ void updateRSGroupConfig(String groupName, Map<String, String> configuration) 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 8c2c313..c6a53e9 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
@@ -32,6 +32,7 @@ import java.util.OptionalLong;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.DoNotRetryIOException;
@@ -452,6 +453,16 @@ final class RSGroupInfoManagerImpl implements RSGroupInfoManager {
return getRSGroup(RSGroupInfo.DEFAULT_GROUP);
}
+ @Override
+ public void updateRSGroupConfig(String groupName, Map<String, String> configuration)
+ throws IOException {
+ RSGroupInfo rsGroupInfo = getRSGroupInfo(groupName);
+ new HashSet<>(rsGroupInfo.getConfiguration().keySet())
+ .forEach(rsGroupInfo::removeConfiguration);
+ configuration.forEach(rsGroupInfo::setConfiguration);
+ flushConfig();
+ }
+
List<RSGroupInfo> retrieveGroupListFromGroupTable() throws IOException {
List<RSGroupInfo> rsGroupInfoList = Lists.newArrayList();
try (Table table = conn.getTable(RSGROUP_TABLE_NAME);
diff --git a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupProtobufUtil.java b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupProtobufUtil.java
index 9b6ba1c..9f092c5 100644
--- a/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupProtobufUtil.java
+++ b/hbase-rsgroup/src/main/java/org/apache/hadoop/hbase/rsgroup/RSGroupProtobufUtil.java
@@ -20,11 +20,13 @@ package org.apache.hadoop.hbase.rsgroup;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
import org.apache.hadoop.hbase.TableName;
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.HBaseProtos.NameStringPair;
import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
import org.apache.hadoop.hbase.protobuf.generated.TableProtos;
import org.apache.yetus.audience.InterfaceAudience;
@@ -35,14 +37,16 @@ final class RSGroupProtobufUtil {
}
static RSGroupInfo toGroupInfo(RSGroupProtos.RSGroupInfo proto) {
- RSGroupInfo RSGroupInfo = new RSGroupInfo(proto.getName());
+ RSGroupInfo rsGroupInfo = new RSGroupInfo(proto.getName());
for(HBaseProtos.ServerName el: proto.getServersList()) {
- RSGroupInfo.addServer(Address.fromParts(el.getHostName(), el.getPort()));
+ rsGroupInfo.addServer(Address.fromParts(el.getHostName(), el.getPort()));
}
for(TableProtos.TableName pTableName: proto.getTablesList()) {
- RSGroupInfo.addTable(ProtobufUtil.toTableName(pTableName));
+ rsGroupInfo.addTable(ProtobufUtil.toTableName(pTableName));
}
- return RSGroupInfo;
+ proto.getConfigurationList().forEach(pair ->
+ rsGroupInfo.setConfiguration(pair.getName(), pair.getValue()));
+ return rsGroupInfo;
}
static RSGroupProtos.RSGroupInfo toProtoGroupInfo(RSGroupInfo pojo) {
@@ -57,8 +61,11 @@ final class RSGroupProtobufUtil {
.setPort(el.getPort())
.build());
}
+ List<NameStringPair> configuration = pojo.getConfiguration().entrySet()
+ .stream().map(entry -> NameStringPair.newBuilder()
+ .setName(entry.getKey()).setValue(entry.getValue()).build())
+ .collect(Collectors.toList());
return RSGroupProtos.RSGroupInfo.newBuilder().setName(pojo.getName())
- .addAllServers(hostports)
- .addAllTables(tables).build();
+ .addAllServers(hostports).addAllTables(tables).addAllConfiguration(configuration).build();
}
}
diff --git a/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto b/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto
index 10f6570..54add90 100644
--- a/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto
+++ b/hbase-rsgroup/src/main/protobuf/RSGroupAdmin.proto
@@ -131,6 +131,14 @@ message RenameRSGroupRequest {
message RenameRSGroupResponse {
}
+message UpdateRSGroupConfigRequest {
+ required string group_name = 1;
+ repeated NameStringPair configuration = 2;
+}
+
+message UpdateRSGroupConfigResponse {
+}
+
service RSGroupAdminService {
rpc GetRSGroupInfo(GetRSGroupInfoRequest)
returns (GetRSGroupInfoResponse);
@@ -167,4 +175,7 @@ service RSGroupAdminService {
rpc RenameRSGroup(RenameRSGroupRequest)
returns (RenameRSGroupResponse);
+
+ rpc UpdateRSGroupConfig(UpdateRSGroupConfigRequest)
+ returns (UpdateRSGroupConfigResponse);
}
diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupConfig.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupConfig.java
new file mode 100644
index 0000000..79d0a1e
--- /dev/null
+++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupConfig.java
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.rsgroup;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.TestName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
+
+@Category(MediumTests.class)
+public class TestRSGroupConfig extends TestRSGroupsBase {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestRSGroupConfig.class);
+
+ @Rule
+ public TestName name = new TestName();
+
+ protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupConfig.class);
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ TestRSGroupsBase.setUpTestBeforeClass();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TestRSGroupsBase.tearDownAfterClass();
+ }
+
+ @Test
+ public void testSetDefaultGroupConfiguration() throws IOException {
+ testSetConfiguration(RSGroupInfo.DEFAULT_GROUP);
+ }
+
+ @Test
+ public void testSetNonDefaultGroupConfiguration() throws IOException {
+ String group = getGroupName(name.getMethodName());
+ rsGroupAdmin.addRSGroup(group);
+ testSetConfiguration(RSGroupInfo.DEFAULT_GROUP);
+ rsGroupAdmin.removeRSGroup(group);
+ }
+
+ private void testSetConfiguration(String group) throws IOException {
+ Map<String, String> configuration = new HashMap<>();
+ configuration.put("aaa", "111");
+ configuration.put("bbb", "222");
+ rsGroupAdmin.updateRSGroupConfig(group, configuration);
+ RSGroupInfo rsGroup = rsGroupAdmin.getRSGroupInfo(group);
+ Map<String, String> configFromGroup = Maps.newHashMap(rsGroup.getConfiguration());
+ assertNotNull(configFromGroup);
+ assertEquals(2, configFromGroup.size());
+ assertEquals("111", configFromGroup.get("aaa"));
+ // unset configuration
+ rsGroupAdmin.updateRSGroupConfig(group, null);
+ rsGroup = rsGroupAdmin.getRSGroupInfo(group);
+ configFromGroup = rsGroup.getConfiguration();
+ assertNotNull(configFromGroup);
+ assertEquals(0, configFromGroup.size());
+ }
+
+}
\ No newline at end of file
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 923a77d..faa0bc0 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
@@ -125,6 +125,13 @@ public class VerifyingRSGroupAdminClient implements RSGroupAdmin {
verify();
}
+ @Override
+ public void updateRSGroupConfig(String groupName, Map<String, String> configuration)
+ throws IOException {
+ wrapped.updateRSGroupConfig(groupName, configuration);
+ verify();
+ }
+
public void verify() throws IOException {
Map<String, RSGroupInfo> groupMap = Maps.newHashMap();
Set<RSGroupInfo> 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 48c259b..4ea80de 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
@@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.coprocessor;
import java.io.IOException;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
@@ -1646,4 +1647,22 @@ public interface MasterObserver {
default void postRenameRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
final String oldName, final String newName) throws IOException {
}
+
+ /**
+ * Called before update rsgroup config.
+ * @param ctx the environment to interact with the framework and master
+ * @param groupName the group name
+ * @param configuration new configuration of the group name to be set
+ */
+ default void preUpdateRSGroupConfig(final ObserverContext<MasterCoprocessorEnvironment> ctx,
+ final String groupName, final Map<String, String> configuration) throws IOException {}
+
+ /**
+ * Called after update rsgroup config.
+ * @param ctx the environment to interact with the framework and master
+ * @param groupName the group name
+ * @param configuration new configuration of the group name to be set
+ */
+ default void postUpdateRSGroupConfig(final ObserverContext<MasterCoprocessorEnvironment> ctx,
+ final String groupName, final Map<String, String> configuration) 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 236eda0..2a29c72 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
@@ -22,6 +22,7 @@ import com.google.protobuf.Service;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.ClusterMetrics;
@@ -1493,6 +1494,26 @@ public class MasterCoprocessorHost
});
}
+ public void preUpdateRSGroupConfig(final String groupName,
+ final Map<String, String> configuration) throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ protected void call(MasterObserver observer) throws IOException {
+ observer.preUpdateRSGroupConfig(this, groupName, configuration);
+ }
+ });
+ }
+
+ public void postUpdateRSGroupConfig(final String groupName,
+ final Map<String, String> configuration) throws IOException {
+ execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
+ @Override
+ protected void call(MasterObserver observer) throws IOException {
+ observer.postUpdateRSGroupConfig(this, groupName, configuration);
+ }
+ });
+ }
+
public void preAddReplicationPeer(final String peerId, final ReplicationPeerConfig peerConfig)
throws IOException {
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
diff --git a/hbase-shell/src/main/ruby/hbase/rsgroup_admin.rb b/hbase-shell/src/main/ruby/hbase/rsgroup_admin.rb
index 76a480b..e163875 100644
--- a/hbase-shell/src/main/ruby/hbase/rsgroup_admin.rb
+++ b/hbase-shell/src/main/ruby/hbase/rsgroup_admin.rb
@@ -185,5 +185,42 @@ module Hbase
def rename_rsgroup(oldname, newname)
@admin.renameRSGroup(oldname, newname)
end
+
+ #----------------------------------------------------------------------------------------------
+ # modify a rsgroup configuration
+ def alter_rsgroup_config(rsgroup_name, *args)
+ # Fail if table name is not a string
+ raise(ArgumentError, 'RSGroup name must be of type String') unless rsgroup_name.is_a?(String)
+
+ group = @admin.getRSGroupInfo(rsgroup_name)
+
+ raise(ArgumentError, 'RSGroup does not exist') unless group
+
+ configuration = java.util.HashMap.new
+ configuration.putAll(group.getConfiguration)
+
+ # Flatten params array
+ args = args.flatten.compact
+
+ # Start defining the table
+ args.each do |arg|
+ unless arg.is_a?(Hash)
+ raise(ArgumentError, "#{arg.class} of #{arg.inspect} is not of Hash type")
+ end
+ method = arg[METHOD]
+ if method == 'unset'
+ configuration.remove(arg[NAME])
+ elsif method == 'set'
+ arg.delete(METHOD)
+ for k, v in arg
+ v = v.to_s unless v.nil?
+ configuration.put(k, v)
+ end
+ else
+ raise(ArgumentError, "Unknown method #{method}")
+ end
+ end
+ @admin.updateRSGroupConfig(rsgroup_name, configuration)
+ end
end
end
diff --git a/hbase-shell/src/main/ruby/shell.rb b/hbase-shell/src/main/ruby/shell.rb
index 6303d6b..b638bbe 100644
--- a/hbase-shell/src/main/ruby/shell.rb
+++ b/hbase-shell/src/main/ruby/shell.rb
@@ -508,5 +508,7 @@ Shell.load_command_group(
get_table_rsgroup
remove_servers_rsgroup
rename_rsgroup
+ alter_rsgroup_config
+ show_rsgroup_config
]
)
diff --git a/hbase-shell/src/main/ruby/shell/commands/alter_rsgroup_config.rb b/hbase-shell/src/main/ruby/shell/commands/alter_rsgroup_config.rb
new file mode 100644
index 0000000..a8489b8
--- /dev/null
+++ b/hbase-shell/src/main/ruby/shell/commands/alter_rsgroup_config.rb
@@ -0,0 +1,38 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module Shell
+ module Commands
+ class AlterRsgroupConfig < Command
+ def help
+ <<-EOF
+Alter RSGroup configuration.
+Example:
+ hbase> alter_rsgroup_config 'grp1', {METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}
+To delete a property:
+ hbase> alter_rsgroup_config 'grp1', {METHOD => 'unset', NAME=>'PROPERTY_NAME'}
+EOF
+ end
+
+ def command(group, args)
+ rsgroup_admin.alter_rsgroup_config(group, args)
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/hbase-shell/src/main/ruby/shell/commands/show_rsgroup_config.rb b/hbase-shell/src/main/ruby/shell/commands/show_rsgroup_config.rb
new file mode 100644
index 0000000..54344a1
--- /dev/null
+++ b/hbase-shell/src/main/ruby/shell/commands/show_rsgroup_config.rb
@@ -0,0 +1,41 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module Shell
+ module Commands
+ class ShowRsgroupConfig < Command
+ def help
+ <<-EOF
+Show the configuration of a special RSGroup.
+Example:
+ hbase> show_rsgroup_config 'group'
+EOF
+ end
+
+ def command(group)
+ formatter.header(%w['KEY' 'VALUE'])
+ config = rsgroup_admin.get_rsgroup(group).getConfiguration
+ config.each { |key, val|
+ formatter.row([key, val])
+ }
+ formatter.footer(config.size)
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/hbase-shell/src/test/ruby/shell/rsgroup_shell_test.rb b/hbase-shell/src/test/ruby/shell/rsgroup_shell_test.rb
index 5e7f37d..8b1fba4 100644
--- a/hbase-shell/src/test/ruby/shell/rsgroup_shell_test.rb
+++ b/hbase-shell/src/test/ruby/shell/rsgroup_shell_test.rb
@@ -142,5 +142,19 @@ module Hbase
assert_equal(1, @rsgroup_admin.getRSGroupInfo(new_rs_group_name).getTables.count)
assert_equal(table_name, @rsgroup_admin.getRSGroupInfo(new_rs_group_name).getTables.iterator.next.toString)
end
+
+ define_test 'Test alter rsgroup configuration' do
+ group_name = 'grp1'
+ @shell.command('add_rsgroup', group_name)
+ assert_not_nil(@rsgroup_admin.getRSGroupInfo(group_name))
+
+ @hbase.rsgroup_admin.alter_rsgroup_config(group_name, {'METHOD' => 'set', 'a' => 'a'})
+ assert_equal(1, @rsgroup_admin.getRSGroupInfo(group_name).getConfiguration.size)
+ @hbase.rsgroup_admin.alter_rsgroup_config(group_name, {'METHOD' => 'unset', 'NAME' => 'a'})
+ assert_equal(0, @rsgroup_admin.getRSGroupInfo(group_name).getConfiguration.size)
+
+ @shell.command('remove_rsgroup', group_name)
+ assert_nil(@rsgroup_admin.getRSGroupInfo(group_name))
+ end
end
end