HBASE-23253 Rewrite rsgroup related UTs with the new methods introduced in HBASE-22932 (#813)

Signed-off-by: Guanghao Zhang <zghao@apache.org>
This commit is contained in:
Duo Zhang 2019-11-15 18:56:01 +08:00 committed by Duo Zhang
parent 72cbb129a4
commit c8d892cdef
29 changed files with 1909 additions and 2010 deletions

View File

@ -0,0 +1,24 @@
/**
* 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.testclassification;
/**
* Tag the tests related to rs group feature.
*/
public interface RSGroupTests {
}

View File

@ -2338,7 +2338,7 @@ public interface Admin extends Abortable, Closeable {
* @param servers set of servers to remove
* @throws IOException if a remote or network exception occurs
*/
void removeRSGroup(Set<Address> servers) throws IOException;
void removeServersFromRSGroup(Set<Address> servers) throws IOException;
/**
* Move given set of servers to the specified target RegionServer group
@ -2346,7 +2346,7 @@ public interface Admin extends Abortable, Closeable {
* @param targetGroup the group to move servers to
* @throws IOException if a remote or network exception occurs
*/
void moveToRSGroup(Set<Address> servers, String targetGroup) throws IOException;
void moveServersToRSGroup(Set<Address> servers, String targetGroup) throws IOException;
/**
* Set the RegionServer group for tables

View File

@ -980,8 +980,8 @@ class AdminOverAsyncAdmin implements Admin {
}
@Override
public void moveToRSGroup(Set<Address> servers, String groupName) throws IOException {
get(admin.moveToRSGroup(servers, groupName));
public void moveServersToRSGroup(Set<Address> servers, String groupName) throws IOException {
get(admin.moveServersToRSGroup(servers, groupName));
}
@Override
@ -1010,8 +1010,8 @@ class AdminOverAsyncAdmin implements Admin {
}
@Override
public void removeRSGroup(Set<Address> servers) throws IOException {
get(admin.removeRSGroup(servers));
public void removeServersFromRSGroup(Set<Address> servers) throws IOException {
get(admin.removeServersFromRSGroup(servers));
}
@Override

View File

@ -1580,7 +1580,7 @@ public interface AsyncAdmin {
* @param servers set of servers to remove
* @throws IOException if a remote or network exception occurs
*/
CompletableFuture<Void> removeRSGroup(Set<Address> servers);
CompletableFuture<Void> removeServersFromRSGroup(Set<Address> servers);
/**
* Move given set of servers to the specified target RegionServer group
@ -1588,7 +1588,7 @@ public interface AsyncAdmin {
* @param groupName the group to move servers to
* @throws IOException if a remote or network exception occurs
*/
CompletableFuture<Void> moveToRSGroup(Set<Address> servers, String groupName);
CompletableFuture<Void> moveServersToRSGroup(Set<Address> servers, String groupName);
/**
* Set the RegionServer group for tables

View File

@ -858,8 +858,8 @@ class AsyncHBaseAdmin implements AsyncAdmin {
}
@Override
public CompletableFuture<Void> moveToRSGroup(Set<Address> servers, String groupName) {
return wrap(rawAdmin.moveToRSGroup(servers, groupName));
public CompletableFuture<Void> moveServersToRSGroup(Set<Address> servers, String groupName) {
return wrap(rawAdmin.moveServersToRSGroup(servers, groupName));
}
@Override
@ -888,8 +888,8 @@ class AsyncHBaseAdmin implements AsyncAdmin {
}
@Override
public CompletableFuture<Void> removeRSGroup(Set<Address> servers) {
return wrap(rawAdmin.removeRSGroup(servers));
public CompletableFuture<Void> removeServersFromRSGroup(Set<Address> servers) {
return wrap(rawAdmin.removeServersFromRSGroup(servers));
}
@Override

View File

@ -289,6 +289,12 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.AddR
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.AddRSGroupResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.MoveServersRequest;
@ -3885,7 +3891,7 @@ class RawAsyncHBaseAdmin implements AsyncAdmin {
}
@Override
public CompletableFuture<Void> moveToRSGroup(Set<Address> servers, String groupName) {
public CompletableFuture<Void> moveServersToRSGroup(Set<Address> servers, String groupName) {
return this.<Void> newMasterCaller()
.action((controller, stub) -> this.
<MoveServersRequest, MoveServersResponse, Void> call(controller, stub,
@ -3998,25 +4004,21 @@ class RawAsyncHBaseAdmin implements AsyncAdmin {
@Override
public CompletableFuture<RSGroupInfo> getRSGroup(Address hostPort) {
CompletableFuture<RSGroupInfo> future = new CompletableFuture<>();
addListener(listRSGroups(), (groups, err) -> {
if (err != null) {
future.completeExceptionally(err);
return;
}
for (RSGroupInfo rsGroupInfo : groups) {
if (rsGroupInfo.getServers().contains(hostPort)){
future.complete(rsGroupInfo);
return;
}
}
future.complete(null);
});
return future;
return this.<RSGroupInfo> newMasterCaller()
.action(((controller, stub) -> this
.<GetRSGroupInfoOfServerRequest, GetRSGroupInfoOfServerResponse, RSGroupInfo> call(
controller, stub,
GetRSGroupInfoOfServerRequest.newBuilder()
.setServer(HBaseProtos.ServerName.newBuilder().setHostName(hostPort.getHostname())
.setPort(hostPort.getPort()).build())
.build(),
(s, c, req, done) -> s.getRSGroupInfoOfServer(c, req, done),
resp -> resp.hasRSGroupInfo() ? ProtobufUtil.toGroupInfo(resp.getRSGroupInfo()) : null)))
.call();
}
@Override
public CompletableFuture<Void> removeRSGroup(Set<Address> servers) {
public CompletableFuture<Void> removeServersFromRSGroup(Set<Address> servers) {
return this.<Void> newMasterCaller()
.action((controller, stub) -> this.
<RemoveServersRequest, RemoveServersResponse, Void> call(controller, stub,
@ -4069,47 +4071,24 @@ class RawAsyncHBaseAdmin implements AsyncAdmin {
@Override
public CompletableFuture<RSGroupInfo> getRSGroup(TableName table) {
CompletableFuture<RSGroupInfo> future = new CompletableFuture<>();
addListener(getDescriptor(table), (td, err) -> {
if (err != null) {
// return null instead of err to keep compatible with old semantics
// todo: need to change both this and UTs
future.complete(null);
return;
}
addListener(listRSGroups(), (groups, err2) -> {
if (err2 != null) {
future.completeExceptionally(err2);
return;
}
for (RSGroupInfo rsGroupInfo : groups) {
if (rsGroupInfo.getTables().contains(table)) {
future.complete(rsGroupInfo);
return;
}
}
future.complete(null);
});
});
return future;
return this.<RSGroupInfo> newMasterCaller().action(((controller, stub) -> this
.<GetRSGroupInfoOfTableRequest, GetRSGroupInfoOfTableResponse, RSGroupInfo> call(controller,
stub,
GetRSGroupInfoOfTableRequest.newBuilder().setTableName(ProtobufUtil.toProtoTableName(table))
.build(),
(s, c, req, done) -> s.getRSGroupInfoOfTable(c, req, done),
resp -> resp.hasRSGroupInfo() ? ProtobufUtil.toGroupInfo(resp.getRSGroupInfo()) : null)))
.call();
}
@Override
public CompletableFuture<RSGroupInfo> getRSGroup(String groupName) {
CompletableFuture<RSGroupInfo> future = new CompletableFuture<>();
addListener(listRSGroups(), (groups, err) -> {
if (err != null) {
future.completeExceptionally(err);
return;
}
for (RSGroupInfo rsGroupInfo : groups) {
if (rsGroupInfo.getName().equals(groupName)){
future.complete(rsGroupInfo);
return;
}
}
future.complete(null);
});
return future;
return this.<RSGroupInfo> newMasterCaller()
.action(((controller, stub) -> this
.<GetRSGroupInfoRequest, GetRSGroupInfoResponse, RSGroupInfo> call(controller, stub,
GetRSGroupInfoRequest.newBuilder().setRSGroupName(groupName).build(),
(s, c, req, done) -> s.getRSGroupInfo(c, req, done),
resp -> resp.hasRSGroupInfo() ? ProtobufUtil.toGroupInfo(resp.getRSGroupInfo()) : null)))
.call();
}
}

View File

@ -41,7 +41,7 @@ public class IntegrationTestRSGroup extends TestRSGroupsBase {
@Before
public void beforeMethod() throws Exception {
if(!initialized) {
if (!initialized) {
LOG.info("Setting up IntegrationTestRSGroup");
LOG.info("Initializing cluster with " + NUM_SLAVES_BASE + " servers");
TEST_UTIL = new IntegrationTestingUtility();
@ -49,16 +49,15 @@ public class IntegrationTestRSGroup extends TestRSGroupsBase {
RSGroupBasedLoadBalancer.class.getName());
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
RSGroupAdminEndpoint.class.getName());
((IntegrationTestingUtility)TEST_UTIL).initializeCluster(NUM_SLAVES_BASE);
//set shared configs
admin = TEST_UTIL.getAdmin();
cluster = TEST_UTIL.getHBaseClusterInterface();
rsGroupAdmin = new VerifyingRSGroupAdminClient(new RSGroupAdminClient(TEST_UTIL.getConnection()),
TEST_UTIL.getConfiguration());
((IntegrationTestingUtility) TEST_UTIL).initializeCluster(NUM_SLAVES_BASE);
// set shared configs
ADMIN = TEST_UTIL.getAdmin();
CLUSTER = TEST_UTIL.getHBaseClusterInterface();
RS_GROUP_ADMIN_CLIENT = new RSGroupAdminClient(TEST_UTIL.getConnection());
LOG.info("Done initializing cluster");
initialized = true;
//cluster may not be clean
//cleanup when initializing
// cluster may not be clean
// cleanup when initializing
afterMethod();
}
}
@ -70,7 +69,7 @@ public class IntegrationTestRSGroup extends TestRSGroupsBase {
deleteTableIfNecessary();
deleteNamespaceIfNecessary();
deleteGroups();
admin.balancerSwitch(true, true);
ADMIN.balancerSwitch(true, true);
LOG.info("Restoring the cluster");
((IntegrationTestingUtility)TEST_UTIL).restoreCluster();
@ -79,10 +78,10 @@ public class IntegrationTestRSGroup extends TestRSGroupsBase {
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
LOG.info("Waiting for cleanup to finish "+ rsGroupAdmin.listRSGroups());
LOG.info("Waiting for cleanup to finish "+ ADMIN.listRSGroups());
//Might be greater since moving servers back to default
//is after starting a server
return rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size()
return ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size()
>= NUM_SLAVES_BASE;
}
});
@ -90,10 +89,10 @@ public class IntegrationTestRSGroup extends TestRSGroupsBase {
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
LOG.info("Waiting for regionservers to be registered "+ rsGroupAdmin.listRSGroups());
LOG.info("Waiting for regionservers to be registered "+ ADMIN.listRSGroups());
//Might be greater since moving servers back to default
//is after starting a server
return rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size()
return ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size()
== getNumServers();
}
});

View File

@ -1087,6 +1087,15 @@ service MasterService {
rpc ListNamespaces(ListNamespacesRequest)
returns(ListNamespacesResponse);
rpc GetRSGroupInfo(GetRSGroupInfoRequest)
returns (GetRSGroupInfoResponse);
rpc GetRSGroupInfoOfTable(GetRSGroupInfoOfTableRequest)
returns (GetRSGroupInfoOfTableResponse);
rpc GetRSGroupInfoOfServer(GetRSGroupInfoOfServerRequest)
returns (GetRSGroupInfoOfServerResponse);
rpc MoveServers(MoveServersRequest)
returns (MoveServersResponse);

View File

@ -321,6 +321,12 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.AddR
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.AddRSGroupResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosRequest;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.MoveServersRequest;
@ -2918,6 +2924,94 @@ public class MasterRpcServices extends RSRpcServices implements
return response.build();
}
@Override
public GetRSGroupInfoResponse getRSGroupInfo(RpcController controller,
GetRSGroupInfoRequest request) throws ServiceException {
String groupName = request.getRSGroupName();
LOG.info(
master.getClientIdAuditPrefix() + " initiates rsgroup info retrieval, group=" + groupName);
try {
if (master.getMasterCoprocessorHost() != null) {
master.getMasterCoprocessorHost().preGetRSGroupInfo(groupName);
}
RSGroupInfo rsGroupInfo = master.getRSGroupInfoManager().getRSGroup(groupName);
GetRSGroupInfoResponse resp;
if (rsGroupInfo != null) {
resp = GetRSGroupInfoResponse.newBuilder()
.setRSGroupInfo(ProtobufUtil.toProtoGroupInfo(rsGroupInfo)).build();
} else {
resp = GetRSGroupInfoResponse.getDefaultInstance();
}
if (master.getMasterCoprocessorHost() != null) {
master.getMasterCoprocessorHost().postGetRSGroupInfo(groupName);
}
return resp;
} catch (IOException e) {
throw new ServiceException(e);
}
}
@Override
public GetRSGroupInfoOfTableResponse getRSGroupInfoOfTable(RpcController controller,
GetRSGroupInfoOfTableRequest request) throws ServiceException {
TableName tableName = ProtobufUtil.toTableName(request.getTableName());
LOG.info(
master.getClientIdAuditPrefix() + " initiates rsgroup info retrieval, table=" + tableName);
try {
if (master.getMasterCoprocessorHost() != null) {
master.getMasterCoprocessorHost().preGetRSGroupInfoOfTable(tableName);
}
GetRSGroupInfoOfTableResponse resp;
TableDescriptor td = master.getTableDescriptors().get(tableName);
if (td == null) {
resp = GetRSGroupInfoOfTableResponse.getDefaultInstance();
} else {
RSGroupInfo rsGroupInfo = null;
if (td.getRegionServerGroup().isPresent()) {
rsGroupInfo = master.getRSGroupInfoManager().getRSGroup(td.getRegionServerGroup().get());
}
if (rsGroupInfo == null) {
rsGroupInfo = master.getRSGroupInfoManager().getRSGroup(RSGroupInfo.DEFAULT_GROUP);
}
resp = GetRSGroupInfoOfTableResponse.newBuilder()
.setRSGroupInfo(ProtobufUtil.toProtoGroupInfo(rsGroupInfo)).build();
}
if (master.getMasterCoprocessorHost() != null) {
master.getMasterCoprocessorHost().postGetRSGroupInfoOfTable(tableName);
}
return resp;
} catch (IOException e) {
throw new ServiceException(e);
}
}
@Override
public GetRSGroupInfoOfServerResponse getRSGroupInfoOfServer(RpcController controller,
GetRSGroupInfoOfServerRequest request) throws ServiceException {
Address hp =
Address.fromParts(request.getServer().getHostName(), request.getServer().getPort());
LOG.info(master.getClientIdAuditPrefix() + " initiates rsgroup info retrieval, server=" + hp);
try {
if (master.getMasterCoprocessorHost() != null) {
master.getMasterCoprocessorHost().preGetRSGroupInfoOfServer(hp);
}
RSGroupInfo rsGroupInfo = master.getRSGroupInfoManager().getRSGroupOfServer(hp);
GetRSGroupInfoOfServerResponse resp;
if (rsGroupInfo != null) {
resp = GetRSGroupInfoOfServerResponse.newBuilder()
.setRSGroupInfo(ProtobufUtil.toProtoGroupInfo(rsGroupInfo)).build();
} else {
resp = GetRSGroupInfoOfServerResponse.getDefaultInstance();
}
if (master.getMasterCoprocessorHost() != null) {
master.getMasterCoprocessorHost().postGetRSGroupInfoOfServer(hp);
}
return resp;
} catch (IOException e) {
throw new ServiceException(e);
}
}
@Override
public MoveServersResponse moveServers(RpcController controller, MoveServersRequest request)
throws ServiceException {

View File

@ -1,82 +0,0 @@
/**
* 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 java.io.IOException;
import java.util.List;
import java.util.Set;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.net.Address;
import org.apache.yetus.audience.InterfaceAudience;
/**
* Group user API interface used between client and server.
*
* @deprecated Keep it here only for tests, using {@link Admin} instead.
*/
@Deprecated
@InterfaceAudience.Private
public interface RSGroupAdmin {
/**
* Gets {@code RSGroupInfo} for given group name.
*/
RSGroupInfo getRSGroupInfo(String groupName) throws IOException;
/**
* Move given set of servers to the specified target RegionServer group.
*/
void moveServers(Set<Address> servers, String targetGroup) throws IOException;
/**
* Creates a new RegionServer group with the given name.
*/
void addRSGroup(String groupName) throws IOException;
/**
* Removes RegionServer group associated with the given name.
*/
void removeRSGroup(String groupName) throws IOException;
/**
* Balance regions in the given RegionServer group.
*
* @return boolean Whether balance ran or not
*/
boolean balanceRSGroup(String groupName) throws IOException;
/**
* 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
*/
RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException;
/**
* Remove decommissioned servers from rsgroup.
* 1. Sometimes we may find the server aborted due to some hardware failure and we must offline
* the server for repairing. Or we need to move some servers to join other clusters.
* So we need to remove these servers from the rsgroup.
* 2. Dead/recovering/live servers will be disallowed.
* @param servers set of servers to remove
*/
void removeServers(Set<Address> servers) throws IOException;
}

View File

@ -0,0 +1,80 @@
/**
* 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 java.lang.Thread.sleep;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class EnableRSGroupsTestBase {
private static final Logger LOG = LoggerFactory.getLogger(TestEnableRSGroupsCompatibility.class);
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@BeforeClass
public static void setUp() throws Exception {
final Configuration conf = TEST_UTIL.getConfiguration();
conf.setBoolean(CoprocessorHost.COPROCESSORS_ENABLED_CONF_KEY, true);
TEST_UTIL.startMiniCluster(5);
}
@AfterClass
public static void tearDown() throws Exception {
LOG.info("to stop miniCluster");
TEST_UTIL.shutdownMiniCluster();
}
protected abstract void enableRSGroup(Configuration conf);
@Test
public void testEnableRSGroup() throws IOException, InterruptedException {
TEST_UTIL.getMiniHBaseCluster().stopMaster(0);
TEST_UTIL.getMiniHBaseCluster().waitOnMaster(0);
LOG.info("stopped master...");
enableRSGroup(TEST_UTIL.getMiniHBaseCluster().getConfiguration());
TEST_UTIL.getMiniHBaseCluster().startMaster();
TEST_UTIL.getMiniHBaseCluster().waitForActiveAndReadyMaster(60000);
LOG.info("started master...");
// check if master started successfully
assertTrue(TEST_UTIL.getMiniHBaseCluster().getMaster() != null);
// wait RSGroupBasedLoadBalancer online
RSGroupBasedLoadBalancer loadBalancer =
(RSGroupBasedLoadBalancer) TEST_UTIL.getMiniHBaseCluster().getMaster().getLoadBalancer();
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start <= 60000 && !loadBalancer.isOnline()) {
LOG.info("waiting for rsgroup load balancer onLine...");
sleep(200);
}
assertTrue(loadBalancer.isOnline());
}
}

View File

@ -17,80 +17,23 @@
*/
package org.apache.hadoop.hbase.rsgroup;
import static java.lang.Thread.sleep;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Test enable RSGroup
*/
@Category({ MediumTests.class })
public class TestEnableRSGroups {
@Category({ RSGroupTests.class, MediumTests.class })
public class TestEnableRSGroups extends EnableRSGroupsTestBase {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestEnableRSGroups.class);
protected static final Logger LOG = LoggerFactory.getLogger(TestEnableRSGroups.class);
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@BeforeClass
public static void setUp() throws Exception {
final Configuration conf = TEST_UTIL.getConfiguration();
conf.setBoolean(CoprocessorHost.COPROCESSORS_ENABLED_CONF_KEY, true);
TEST_UTIL.startMiniCluster(5);
}
@AfterClass
public static void tearDown() throws Exception {
LOG.info("to stop miniCluster");
TEST_UTIL.shutdownMiniCluster();
}
@Test
public void testEnableRSGroup() throws IOException, InterruptedException {
TEST_UTIL.getMiniHBaseCluster().stopMaster(0);
TEST_UTIL.getMiniHBaseCluster().waitOnMaster(0);
LOG.info("stopped master...");
final Configuration conf = TEST_UTIL.getMiniHBaseCluster().getConfiguration();
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, RSGroupAdminEndpoint.class.getName());
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
RSGroupBasedLoadBalancer.class.getName());
TEST_UTIL.getMiniHBaseCluster().startMaster();
TEST_UTIL.getMiniHBaseCluster().waitForActiveAndReadyMaster(60000);
LOG.info("started master...");
// check if master started successfully
assertTrue(TEST_UTIL.getMiniHBaseCluster().getMaster() != null);
// wait RSGroupBasedLoadBalancer online
RSGroupBasedLoadBalancer loadBalancer =
(RSGroupBasedLoadBalancer) TEST_UTIL.getMiniHBaseCluster().getMaster().getLoadBalancer();
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start <= 60000 && !loadBalancer.isOnline()) {
LOG.info("waiting for rsgroup load balancer onLine...");
sleep(200);
}
assertTrue(loadBalancer.isOnline());
@Override
protected void enableRSGroup(Configuration conf) {
conf.setBoolean(RSGroupInfoManager.RS_GROUP_ENABLED, true);
}
}

View File

@ -0,0 +1,45 @@
/**
* 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 org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.junit.ClassRule;
import org.junit.experimental.categories.Category;
/**
* Test enable RSGroup using the old coprocessor way, to make sure that we keep compatible with old
* config way.
*/
@Category({ RSGroupTests.class, MediumTests.class })
public class TestEnableRSGroupsCompatibility extends EnableRSGroupsTestBase {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestEnableRSGroupsCompatibility.class);
@Override
protected void enableRSGroup(Configuration conf) {
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, RSGroupAdminEndpoint.class.getName());
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, RSGroupBasedLoadBalancer.class.getName());
}
}

View File

@ -39,6 +39,7 @@ import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.zookeeper.KeeperException;
import org.junit.After;
@ -46,14 +47,11 @@ import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
/**
* Testcase for HBASE-22819
*/
@RunWith(Parameterized.class)
@Category({ MediumTests.class })
@Category({ RSGroupTests.class, MediumTests.class })
public class TestMigrateRSGroupInfo extends TestRSGroupsBase {
@ClassRule
@ -109,10 +107,9 @@ public class TestMigrateRSGroupInfo extends TestRSGroupsBase {
@Test
public void testMigrate() throws IOException, InterruptedException {
setAdmin();
String groupName = getNameWithoutIndex(name.getMethodName());
addGroup(groupName, TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads().size() - 1);
RSGroupInfo rsGroupInfo = rsGroupAdmin.getRSGroup(groupName);
RSGroupInfo rsGroupInfo = ADMIN.getRSGroup(groupName);
assertTrue(rsGroupInfo.getTables().isEmpty());
for (int i = 0; i < NUM_TABLES; i++) {
rsGroupInfo.addTable(TableName.valueOf(TABLE_NAME_PREFIX + i));
@ -131,7 +128,7 @@ public class TestMigrateRSGroupInfo extends TestRSGroupsBase {
// wait until we can get the rs group info for a table
TEST_UTIL.waitFor(30000, () -> {
try {
rsGroupAdmin.getRSGroup(TableName.valueOf(TABLE_NAME_PREFIX + 0));
RS_GROUP_ADMIN_CLIENT.getRSGroupInfoOfTable(TableName.valueOf(TABLE_NAME_PREFIX + 0));
return true;
} catch (IOException e) {
return false;
@ -140,7 +137,7 @@ public class TestMigrateRSGroupInfo extends TestRSGroupsBase {
// confirm that before migrating, we could still get the correct rs group for a table.
for (int i = 0; i < NUM_TABLES; i++) {
RSGroupInfo info =
rsGroupAdmin.getRSGroup(TableName.valueOf(TABLE_NAME_PREFIX + i));
RS_GROUP_ADMIN_CLIENT.getRSGroupInfoOfTable(TableName.valueOf(TABLE_NAME_PREFIX + i));
assertEquals(rsGroupInfo.getName(), info.getName());
assertEquals(NUM_TABLES, info.getTables().size());
}
@ -176,7 +173,7 @@ public class TestMigrateRSGroupInfo extends TestRSGroupsBase {
// make sure we could still get the correct rs group info after migration
for (int i = 0; i < NUM_TABLES; i++) {
RSGroupInfo info =
rsGroupAdmin.getRSGroup(TableName.valueOf(TABLE_NAME_PREFIX + i));
RS_GROUP_ADMIN_CLIENT.getRSGroupInfoOfTable(TableName.valueOf(TABLE_NAME_PREFIX + i));
assertEquals(rsGroupInfo.getName(), info.getName());
assertEquals(NUM_TABLES, info.getTables().size());
}

View File

@ -6,38 +6,41 @@
* 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.assertTrue;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.MiniHBaseCluster;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.Waiter;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.ServerManager;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.compaction.TestMajorCompactorTTL;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupMajorCompactionTTL extends TestMajorCompactorTTL {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
@ -50,8 +53,7 @@ public class TestRSGroupMajorCompactionTTL extends TestMajorCompactorTTL {
public void setUp() throws Exception {
utility = new HBaseTestingUtility();
Configuration conf = utility.getConfiguration();
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, RSGroupBasedLoadBalancer.class.getName());
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, RSGroupAdminEndpoint.class.getName());
conf.setBoolean(RSGroupInfoManager.RS_GROUP_ENABLED, true);
conf.setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, NUM_SLAVES_BASE);
conf.setInt("hbase.hfile.compaction.discharger.interval", 10);
utility.startMiniCluster(NUM_SLAVES_BASE);

View File

@ -24,13 +24,11 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.MiniHBaseCluster;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableExistsException;
@ -45,31 +43,28 @@ import org.apache.hadoop.hbase.constraint.ConstraintException;
import org.apache.hadoop.hbase.master.TableNamespaceManager;
import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
@RunWith(Parameterized.class)
@Category({ MediumTests.class })
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestRSGroupsAdmin1.class);
protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsAdmin1.class);
private static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsAdmin1.class);
@BeforeClass
public static void setUp() throws Exception {
@ -98,7 +93,7 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
for (String entry : badNames) {
try {
rsGroupAdmin.addRSGroup(entry);
ADMIN.addRSGroup(entry);
fail("Expected a constraint exception for: " + entry);
} catch (ConstraintException ex) {
// expected
@ -106,42 +101,41 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
}
for (String entry : goodNames) {
rsGroupAdmin.addRSGroup(entry);
ADMIN.addRSGroup(entry);
}
}
@Test
public void testBogusArgs() throws Exception {
assertNull(rsGroupAdmin.getRSGroup(TableName.valueOf("nonexistent")));
assertNull(rsGroupAdmin.getRSGroup(Address.fromParts("bogus", 123)));
assertNull(rsGroupAdmin.getRSGroup("bogus"));
assertNull(ADMIN.getRSGroup(TableName.valueOf("nonexistent")));
assertNull(ADMIN.getRSGroup(Address.fromParts("bogus", 123)));
assertNull(ADMIN.getRSGroup("bogus"));
try {
rsGroupAdmin.removeRSGroup("bogus");
ADMIN.removeRSGroup("bogus");
fail("Expected removing bogus group to fail");
} catch (ConstraintException ex) {
// expected
}
try {
rsGroupAdmin.setRSGroup(Sets.newHashSet(TableName.valueOf("bogustable")), "bogus");
ADMIN.setRSGroup(Sets.newHashSet(TableName.valueOf("bogustable")), "bogus");
fail("Expected set table to bogus group fail");
} catch (ConstraintException | TableNotFoundException ex) {
// expected
}
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(Address.fromParts("bogus", 123)),
"bogus");
ADMIN.moveServersToRSGroup(Sets.newHashSet(Address.fromParts("bogus", 123)), "bogus");
fail("Expected move with bogus group to fail");
} catch (ConstraintException ex) {
// expected
}
try {
admin.balancerSwitch(true, true);
rsGroupAdmin.balanceRSGroup("bogus");
admin.balancerSwitch(false, true);
ADMIN.balancerSwitch(true, true);
ADMIN.balanceRSGroup("bogus");
ADMIN.balancerSwitch(false, true);
fail("Expected move with bogus group to fail");
} catch (ConstraintException ex) {
// expected
@ -150,127 +144,81 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
@Test
public void testNamespaceConstraint() throws Exception {
String nsName = tablePrefix + "_foo";
String groupName = tablePrefix + "_foo";
String nsName = TABLE_PREFIX + "_foo";
String groupName = TABLE_PREFIX + "_foo";
LOG.info("testNamespaceConstraint");
addGroup(groupName, 1);
assertTrue(observer.preAddRSGroupCalled);
assertTrue(observer.postAddRSGroupCalled);
assertTrue(OBSERVER.preAddRSGroupCalled);
assertTrue(OBSERVER.postAddRSGroupCalled);
admin.createNamespace(NamespaceDescriptor.create(nsName)
ADMIN.createNamespace(NamespaceDescriptor.create(nsName)
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, groupName).build());
RSGroupInfo rsGroupInfo = rsGroupAdmin.getRSGroup(groupName);
rsGroupAdmin.moveToRSGroup(rsGroupInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
RSGroupInfo rsGroupInfo = ADMIN.getRSGroup(groupName);
ADMIN.moveServersToRSGroup(rsGroupInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
// test removing a referenced group
try {
rsGroupAdmin.removeRSGroup(groupName);
ADMIN.removeRSGroup(groupName);
fail("Expected a constraint exception");
} catch (IOException ex) {
}
// test modify group
// changing with the same name is fine
admin.modifyNamespace(NamespaceDescriptor.create(nsName)
ADMIN.modifyNamespace(NamespaceDescriptor.create(nsName)
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, groupName).build());
String anotherGroup = tablePrefix + "_anotherGroup";
rsGroupAdmin.addRSGroup(anotherGroup);
String anotherGroup = TABLE_PREFIX + "_anotherGroup";
ADMIN.addRSGroup(anotherGroup);
// test add non-existent group
admin.deleteNamespace(nsName);
rsGroupAdmin.removeRSGroup(groupName);
assertTrue(observer.preRemoveRSGroupCalled);
assertTrue(observer.postRemoveRSGroupCalled);
ADMIN.deleteNamespace(nsName);
ADMIN.removeRSGroup(groupName);
assertTrue(OBSERVER.preRemoveRSGroupCalled);
assertTrue(OBSERVER.postRemoveRSGroupCalled);
try {
admin.createNamespace(NamespaceDescriptor.create(nsName)
ADMIN.createNamespace(NamespaceDescriptor.create(nsName)
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "foo").build());
fail("Expected a constraint exception");
} catch (IOException ex) {
}
}
@Test
public void testGroupInfoMultiAccessing() throws Exception {
RSGroupInfoManager manager = rsGroupAdminEndpoint.getGroupInfoManager();
RSGroupInfo defaultGroup = manager.getRSGroup("default");
// getRSGroup updates default group's server list
// this process must not affect other threads iterating the list
Iterator<Address> it = defaultGroup.getServers().iterator();
manager.getRSGroup("default");
it.next();
}
@Test
public void testGetRSGroupInfoCPHookCalled() throws Exception {
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
if (rsGroupAdmin instanceof RSGroupAdminClient) {
assertTrue(observer.preGetRSGroupInfoCalled);
assertTrue(observer.postGetRSGroupInfoCalled);
}
}
@Test
public void testGetRSGroupInfoOfTableCPHookCalled() throws Exception {
rsGroupAdmin.getRSGroup(TableName.META_TABLE_NAME);
if (rsGroupAdmin instanceof RSGroupAdminClient) {
assertTrue(observer.preGetRSGroupInfoOfTableCalled);
assertTrue(observer.postGetRSGroupInfoOfTableCalled);
}
}
@Test
public void testListRSGroupsCPHookCalled() throws Exception {
rsGroupAdmin.listRSGroups();
assertTrue(observer.preListRSGroupsCalled);
assertTrue(observer.postListRSGroupsCalled);
}
@Test
public void testGetRSGroupInfoOfServerCPHookCalled() throws Exception {
ServerName masterServerName = ((MiniHBaseCluster) cluster).getMaster().getServerName();
rsGroupAdmin.getRSGroup(masterServerName.getAddress());
if (rsGroupAdmin instanceof RSGroupAdminClient) {
assertTrue(observer.preGetRSGroupInfoOfServerCalled);
assertTrue(observer.postGetRSGroupInfoOfServerCalled);
}
}
@Test
public void testFailRemoveGroup() throws IOException, InterruptedException {
int initNumGroups = rsGroupAdmin.listRSGroups().size();
int initNumGroups = ADMIN.listRSGroups().size();
addGroup("bar", 3);
TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), "bar");
RSGroupInfo barGroup = rsGroupAdmin.getRSGroup("bar");
ADMIN.setRSGroup(Sets.newHashSet(tableName), "bar");
RSGroupInfo barGroup = RS_GROUP_ADMIN_CLIENT.getRSGroupInfo("bar");
// group is not empty therefore it should fail
try {
rsGroupAdmin.removeRSGroup(barGroup.getName());
ADMIN.removeRSGroup(barGroup.getName());
fail("Expected remove group to fail");
} catch (IOException e) {
}
// group cannot lose all it's servers therefore it should fail
try {
rsGroupAdmin.moveToRSGroup(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.moveServersToRSGroup(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
fail("Expected move servers to fail");
} catch (IOException e) {
}
rsGroupAdmin.setRSGroup(barGroup.getTables(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.setRSGroup(barGroup.getTables(), RSGroupInfo.DEFAULT_GROUP);
try {
rsGroupAdmin.removeRSGroup(barGroup.getName());
ADMIN.removeRSGroup(barGroup.getName());
fail("Expected move servers to fail");
} catch (IOException e) {
}
rsGroupAdmin.moveToRSGroup(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.removeRSGroup(barGroup.getName());
ADMIN.moveServersToRSGroup(barGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.removeRSGroup(barGroup.getName());
Assert.assertEquals(initNumGroups, rsGroupAdmin.listRSGroups().size());
assertEquals(initNumGroups, ADMIN.listRSGroups().size());
}
@Test
public void testMultiTableMove() throws Exception {
final TableName tableNameA = TableName.valueOf(tablePrefix +
getNameWithoutIndex(name.getMethodName()) + "A");
final TableName tableNameB = TableName.valueOf(tablePrefix +
getNameWithoutIndex(name.getMethodName()) + "B");
final TableName tableNameA =
TableName.valueOf(TABLE_PREFIX + getNameWithoutIndex(name.getMethodName()) + "A");
final TableName tableNameB =
TableName.valueOf(TABLE_PREFIX + getNameWithoutIndex(name.getMethodName()) + "B");
final byte[] familyNameBytes = Bytes.toBytes("f");
String newGroupName = getGroupName(getNameWithoutIndex(name.getMethodName()));
final RSGroupInfo newGroup = addGroup(newGroupName, 1);
@ -293,30 +241,28 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
}
});
RSGroupInfo tableGrpA = rsGroupAdmin.getRSGroup(tableNameA);
RSGroupInfo tableGrpA = ADMIN.getRSGroup(tableNameA);
assertTrue(tableGrpA.getName().equals(RSGroupInfo.DEFAULT_GROUP));
RSGroupInfo tableGrpB = rsGroupAdmin.getRSGroup(tableNameB);
RSGroupInfo tableGrpB = ADMIN.getRSGroup(tableNameB);
assertTrue(tableGrpB.getName().equals(RSGroupInfo.DEFAULT_GROUP));
// change table's group
LOG.info("Moving table [" + tableNameA + "," + tableNameB + "] to " + newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableNameA, tableNameB), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(tableNameA, tableNameB), newGroup.getName());
// verify group change
Assert.assertEquals(newGroup.getName(),
rsGroupAdmin.getRSGroup(tableNameA).getName());
assertEquals(newGroup.getName(), ADMIN.getRSGroup(tableNameA).getName());
Assert.assertEquals(newGroup.getName(),
rsGroupAdmin.getRSGroup(tableNameB).getName());
assertEquals(newGroup.getName(), ADMIN.getRSGroup(tableNameB).getName());
// verify tables' not exist in old group
Set<TableName> DefaultTables =
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getTables();
assertFalse(DefaultTables.contains(tableNameA));
assertFalse(DefaultTables.contains(tableNameB));
Set<TableName> defaultTables =
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables();
assertFalse(defaultTables.contains(tableNameA));
assertFalse(defaultTables.contains(tableNameB));
// verify tables' exist in new group
Set<TableName> newGroupTables = rsGroupAdmin.getRSGroup(newGroupName).getTables();
Set<TableName> newGroupTables = RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(newGroupName).getTables();
assertTrue(newGroupTables.contains(tableNameA));
assertTrue(newGroupTables.contains(tableNameB));
}
@ -340,17 +286,16 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
}
});
RSGroupInfo tableGrp = rsGroupAdmin.getRSGroup(tableName);
RSGroupInfo tableGrp = ADMIN.getRSGroup(tableName);
LOG.info("got table group info is {}", tableGrp);
assertTrue(tableGrp.getName().equals(RSGroupInfo.DEFAULT_GROUP));
// change table's group
LOG.info("Moving table " + tableName + " to " + newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
// verify group change
Assert.assertEquals(newGroup.getName(),
rsGroupAdmin.getRSGroup(tableName).getName());
assertEquals(newGroup.getName(), ADMIN.getRSGroup(tableName).getName());
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
@ -369,16 +314,15 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
});
// test truncate
admin.disableTable(tableName);
admin.truncateTable(tableName, true);
Assert.assertEquals(1, rsGroupAdmin.getRSGroup(newGroup.getName()).getTables().size());
Assert.assertEquals(tableName,
rsGroupAdmin.getRSGroup(newGroup.getName()).getTables().first());
ADMIN.disableTable(tableName);
ADMIN.truncateTable(tableName, true);
assertEquals(1, RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(newGroup.getName()).getTables().size());
assertEquals(tableName,
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(newGroup.getName()).getTables().first());
// verify removed table is removed from group
TEST_UTIL.deleteTable(tableName);
Assert.assertEquals(0, rsGroupAdmin.getRSGroup(newGroup.getName()).getTables().size());
assertEquals(0, RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(newGroup.getName()).getTables().size());
}
@Test
@ -399,50 +343,49 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
}
});
RSGroupInfo tableGrp = rsGroupAdmin.getRSGroup(tableName);
RSGroupInfo tableGrp = ADMIN.getRSGroup(tableName);
assertTrue(tableGrp.getName().equals(RSGroupInfo.DEFAULT_GROUP));
// test disable table
admin.disableTable(tableName);
ADMIN.disableTable(tableName);
// change table's group
LOG.info("Moving table " + tableName + " to " + newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
// verify group change
Assert.assertEquals(newGroup.getName(),
rsGroupAdmin.getRSGroup(tableName).getName());
assertEquals(newGroup.getName(), ADMIN.getRSGroup(tableName).getName());
}
@Test
public void testNonExistentTableMove() throws Exception {
TableName tableName = TableName.valueOf(tablePrefix +
getNameWithoutIndex(name.getMethodName()));
RSGroupInfo tableGrp = rsGroupAdmin.getRSGroup(tableName);
TableName tableName =
TableName.valueOf(TABLE_PREFIX + getNameWithoutIndex(name.getMethodName()));
RSGroupInfo tableGrp = ADMIN.getRSGroup(tableName);
assertNull(tableGrp);
// test if table exists already.
boolean exist = admin.tableExists(tableName);
boolean exist = ADMIN.tableExists(tableName);
assertFalse(exist);
LOG.info("Moving table " + tableName + " to " + RSGroupInfo.DEFAULT_GROUP);
try {
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
ADMIN.setRSGroup(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
fail("Table " + tableName + " shouldn't have been successfully moved.");
} catch (IOException ex) {
assertTrue(ex instanceof TableNotFoundException);
}
try {
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(Address.fromParts("bogus", 123)),
ADMIN.setRSGroup(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
ADMIN.moveServersToRSGroup(Sets.newHashSet(Address.fromParts("bogus", 123)),
RSGroupInfo.DEFAULT_GROUP);
fail("Table " + tableName + " shouldn't have been successfully moved.");
} catch (IOException ex) {
assertTrue(ex instanceof TableNotFoundException);
}
// verify group change
assertNull(rsGroupAdmin.getRSGroup(tableName));
assertNull(ADMIN.getRSGroup(tableName));
}
@Test
@ -452,13 +395,13 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
NamespaceDescriptor nspDesc =
NamespaceDescriptor.create(nsp).addConfiguration(TableNamespaceManager.KEY_MAX_REGIONS, "5")
.addConfiguration(TableNamespaceManager.KEY_MAX_TABLES, "2").build();
admin.createNamespace(nspDesc);
assertEquals(3, admin.listNamespaceDescriptors().length);
ADMIN.createNamespace(nspDesc);
assertEquals(3, ADMIN.listNamespaceDescriptors().length);
ColumnFamilyDescriptor fam1 = ColumnFamilyDescriptorBuilder.of("fam1");
TableDescriptor tableDescOne = TableDescriptorBuilder
.newBuilder(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table1"))
.setColumnFamily(fam1).build();
admin.createTable(tableDescOne);
ADMIN.createTable(tableDescOne);
TableDescriptor tableDescTwo = TableDescriptorBuilder
.newBuilder(TableName.valueOf(nsp + TableName.NAMESPACE_DELIM + "table2"))
@ -466,8 +409,8 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
boolean constraintViolated = false;
try {
admin.createTable(tableDescTwo, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 6);
Assert.fail("Creation table should fail because of quota violation.");
ADMIN.createTable(tableDescTwo, Bytes.toBytes("AAA"), Bytes.toBytes("ZZZ"), 6);
fail("Creation table should fail because of quota violation.");
} catch (Exception exp) {
assertTrue(exp instanceof IOException);
constraintViolated = true;
@ -475,7 +418,7 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
assertTrue("Constraint not violated for table " + tableDescTwo.getTableName(),
constraintViolated);
}
List<RSGroupInfo> rsGroupInfoList = rsGroupAdmin.listRSGroups();
List<RSGroupInfo> rsGroupInfoList = RS_GROUP_ADMIN_CLIENT.listRSGroups();
boolean foundTable2 = false;
boolean foundTable1 = false;
for (int i = 0; i < rsGroupInfoList.size(); i++) {
@ -490,14 +433,13 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
assertTrue("Did not find table1 in rsgroup list", foundTable1);
TEST_UTIL.deleteTable(tableDescOne.getTableName());
admin.deleteNamespace(nspDesc.getName());
ADMIN.deleteNamespace(nspDesc.getName());
toggleQuotaCheckAndRestartMiniCluster(false);
}
@Test
public void testNotMoveTableToNullRSGroupWhenCreatingExistingTable()
throws Exception {
public void testNotMoveTableToNullRSGroupWhenCreatingExistingTable() throws Exception {
// Trigger
TableName tn1 = TableName.valueOf("t1");
TEST_UTIL.createTable(tn1, "cf1");
@ -516,12 +458,11 @@ public class TestRSGroupsAdmin1 extends TestRSGroupsBase {
TEST_UTIL.waitFor(5000, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return
(master.getMasterProcedureExecutor().getActiveExecutorCount() == 0);
return (MASTER.getMasterProcedureExecutor().getActiveExecutorCount() == 0);
}
});
SortedSet<TableName> tables
= rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getTables();
SortedSet<TableName> tables =
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables();
assertTrue("Table 't1' must be in 'default' rsgroup", tables.contains(tn1));
// Cleanup

View File

@ -44,33 +44,30 @@ import org.apache.hadoop.hbase.master.RegionState;
import org.apache.hadoop.hbase.master.assignment.RegionStateNode;
import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.testclassification.LargeTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
@RunWith(Parameterized.class)
@Category({ LargeTests.class })
@Category({ RSGroupTests.class, LargeTests.class })
public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestRSGroupsAdmin2.class);
protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsAdmin2.class);
private static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsAdmin2.class);
@BeforeClass
public static void setUp() throws Exception {
@ -121,7 +118,7 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
}
// get server which is not a member of new group
ServerName tmpTargetServer = null;
for (ServerName server : admin.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
for (ServerName server : ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
.getLiveServerMetrics().keySet()) {
if (!newGroup.containsServer(server.getAddress())) {
tmpTargetServer = server;
@ -130,11 +127,11 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
}
final ServerName targetServer = tmpTargetServer;
// move target server to group
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(targetServer.getAddress()), newGroup.getName());
ADMIN.moveServersToRSGroup(Sets.newHashSet(targetServer.getAddress()), newGroup.getName());
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return admin.getRegions(targetServer).size() <= 0;
return ADMIN.getRegions(targetServer).size() <= 0;
}
});
@ -146,13 +143,13 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
public boolean evaluate() throws Exception {
return getTableRegionMap().get(tableName) != null &&
getTableRegionMap().get(tableName).size() == 6 &&
admin.getClusterMetrics(EnumSet.of(Option.REGIONS_IN_TRANSITION))
ADMIN.getClusterMetrics(EnumSet.of(Option.REGIONS_IN_TRANSITION))
.getRegionStatesInTransition().size() < 1;
}
});
// verify that targetServer didn't open it
for (RegionInfo region : admin.getRegions(targetServer)) {
for (RegionInfo region : ADMIN.getRegions(targetServer)) {
if (targetRegion.equals(region.getRegionNameAsString())) {
fail("Target server opened region");
}
@ -161,35 +158,35 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
@Test
public void testRegionServerMove() throws IOException, InterruptedException {
int initNumGroups = rsGroupAdmin.listRSGroups().size();
int initNumGroups = ADMIN.listRSGroups().size();
RSGroupInfo appInfo = addGroup(getGroupName(name.getMethodName()), 1);
RSGroupInfo adminInfo = addGroup(getGroupName(name.getMethodName()), 1);
RSGroupInfo dInfo = rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
Assert.assertEquals(initNumGroups + 2, rsGroupAdmin.listRSGroups().size());
RSGroupInfo dInfo = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
assertEquals(initNumGroups + 2, ADMIN.listRSGroups().size());
assertEquals(1, adminInfo.getServers().size());
assertEquals(1, appInfo.getServers().size());
assertEquals(getNumServers() - 2, dInfo.getServers().size());
rsGroupAdmin.moveToRSGroup(appInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.removeRSGroup(appInfo.getName());
rsGroupAdmin.moveToRSGroup(adminInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.removeRSGroup(adminInfo.getName());
Assert.assertEquals(rsGroupAdmin.listRSGroups().size(), initNumGroups);
ADMIN.moveServersToRSGroup(appInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.removeRSGroup(appInfo.getName());
ADMIN.moveServersToRSGroup(adminInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.removeRSGroup(adminInfo.getName());
assertEquals(ADMIN.listRSGroups().size(), initNumGroups);
}
@Test
public void testMoveServers() throws Exception {
// create groups and assign servers
addGroup("bar", 3);
rsGroupAdmin.addRSGroup("foo");
ADMIN.addRSGroup("foo");
RSGroupInfo barGroup = rsGroupAdmin.getRSGroup("bar");
RSGroupInfo fooGroup = rsGroupAdmin.getRSGroup("foo");
RSGroupInfo barGroup = ADMIN.getRSGroup("bar");
RSGroupInfo fooGroup = ADMIN.getRSGroup("foo");
assertEquals(3, barGroup.getServers().size());
assertEquals(0, fooGroup.getServers().size());
// test fail bogus server move
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(Address.fromString("foo:9999")), "foo");
ADMIN.moveServersToRSGroup(Sets.newHashSet(Address.fromString("foo:9999")), "foo");
fail("Bogus servers shouldn't have been successfully moved.");
} catch (IOException ex) {
String exp = "Source RSGroup for server foo:9999 does not exist.";
@ -199,34 +196,33 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
// test success case
LOG.info("moving servers " + barGroup.getServers() + " to group foo");
rsGroupAdmin.moveToRSGroup(barGroup.getServers(), fooGroup.getName());
ADMIN.moveServersToRSGroup(barGroup.getServers(), fooGroup.getName());
barGroup = rsGroupAdmin.getRSGroup("bar");
fooGroup = rsGroupAdmin.getRSGroup("foo");
barGroup = ADMIN.getRSGroup("bar");
fooGroup = ADMIN.getRSGroup("foo");
assertEquals(0, barGroup.getServers().size());
assertEquals(3, fooGroup.getServers().size());
LOG.info("moving servers " + fooGroup.getServers() + " to group default");
rsGroupAdmin.moveToRSGroup(fooGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.moveServersToRSGroup(fooGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return getNumServers() == rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP)
.getServers().size();
return getNumServers() == ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size();
}
});
fooGroup = rsGroupAdmin.getRSGroup("foo");
fooGroup = ADMIN.getRSGroup("foo");
assertEquals(0, fooGroup.getServers().size());
// test group removal
LOG.info("Remove group " + barGroup.getName());
rsGroupAdmin.removeRSGroup(barGroup.getName());
Assert.assertEquals(null, rsGroupAdmin.getRSGroup(barGroup.getName()));
ADMIN.removeRSGroup(barGroup.getName());
assertEquals(null, ADMIN.getRSGroup(barGroup.getName()));
LOG.info("Remove group " + fooGroup.getName());
rsGroupAdmin.removeRSGroup(fooGroup.getName());
Assert.assertEquals(null, rsGroupAdmin.getRSGroup(fooGroup.getName()));
ADMIN.removeRSGroup(fooGroup.getName());
assertEquals(null, ADMIN.getRSGroup(fooGroup.getName()));
}
@Test
@ -238,7 +234,7 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
// remove online servers
try {
rsGroupAdmin.removeRSGroup(Sets.newHashSet(targetServer.getAddress()));
ADMIN.removeServersFromRSGroup(Sets.newHashSet(targetServer.getAddress()));
fail("Online servers shouldn't have been successfully removed.");
} catch (IOException ex) {
String exp =
@ -249,12 +245,12 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
assertTrue(newGroup.getServers().contains(targetServer.getAddress()));
// remove dead servers
NUM_DEAD_SERVERS = cluster.getClusterMetrics().getDeadServerNames().size();
NUM_DEAD_SERVERS = CLUSTER.getClusterMetrics().getDeadServerNames().size();
try {
// stopping may cause an exception
// due to the connection loss
LOG.info("stopping server " + targetServer.getServerName());
admin.stopRegionServer(targetServer.getAddress().toString());
ADMIN.stopRegionServer(targetServer.getAddress().toString());
NUM_DEAD_SERVERS++;
} catch (Exception e) {
}
@ -263,13 +259,13 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return !master.getServerManager().areDeadServersInProgress() &&
cluster.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS;
return !MASTER.getServerManager().areDeadServersInProgress() &&
CLUSTER.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS;
}
});
try {
rsGroupAdmin.removeRSGroup(Sets.newHashSet(targetServer.getAddress()));
ADMIN.removeServersFromRSGroup(Sets.newHashSet(targetServer.getAddress()));
fail("Dead servers shouldn't have been successfully removed.");
} catch (IOException ex) {
String exp = "Server " + targetServer.getAddress() + " is on the dead servers list," +
@ -282,20 +278,20 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
// remove decommissioned servers
List<ServerName> serversToDecommission = new ArrayList<>();
targetServer = getServerName(iterator.next());
assertTrue(master.getServerManager().getOnlineServers().containsKey(targetServer));
assertTrue(MASTER.getServerManager().getOnlineServers().containsKey(targetServer));
serversToDecommission.add(targetServer);
admin.decommissionRegionServers(serversToDecommission, true);
assertEquals(1, admin.listDecommissionedRegionServers().size());
ADMIN.decommissionRegionServers(serversToDecommission, true);
assertEquals(1, ADMIN.listDecommissionedRegionServers().size());
assertTrue(newGroup.getServers().contains(targetServer.getAddress()));
rsGroupAdmin.removeRSGroup(Sets.newHashSet(targetServer.getAddress()));
Set<Address> newGroupServers = rsGroupAdmin.getRSGroup(newGroup.getName()).getServers();
ADMIN.removeServersFromRSGroup(Sets.newHashSet(targetServer.getAddress()));
Set<Address> newGroupServers = ADMIN.getRSGroup(newGroup.getName()).getServers();
assertFalse(newGroupServers.contains(targetServer.getAddress()));
assertEquals(2, newGroupServers.size());
assertTrue(observer.preRemoveServersCalled);
assertTrue(observer.postRemoveServersCalled);
assertTrue(OBSERVER.preRemoveServersCalled);
assertTrue(OBSERVER.postRemoveServersCalled);
}
@Test
@ -319,26 +315,25 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
// get server which is not a member of new group
ServerName targetServer = null;
for (ServerName server : admin.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
for (ServerName server : ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
.getLiveServerMetrics().keySet()) {
if (!newGroup.containsServer(server.getAddress()) &&
!rsGroupAdmin.getRSGroup("master").containsServer(server.getAddress())) {
!ADMIN.getRSGroup("master").containsServer(server.getAddress())) {
targetServer = server;
break;
}
}
LOG.debug("Print group info : " + rsGroupAdmin.listRSGroups());
int oldDefaultGroupServerSize =
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size();
LOG.debug("Print group info : " + ADMIN.listRSGroups());
int oldDefaultGroupServerSize = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size();
int oldDefaultGroupTableSize =
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getTables().size();
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables().size();
// test fail bogus server move
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(Address.fromString("foo:9999")),
ADMIN.moveServersToRSGroup(Sets.newHashSet(Address.fromString("foo:9999")),
newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
fail("Bogus servers shouldn't have been successfully moved.");
} catch (IOException ex) {
String exp = "Source RSGroup for server foo:9999 does not exist.";
@ -347,19 +342,19 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
}
// test move when src = dst
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(targetServer.getAddress()),
ADMIN.moveServersToRSGroup(Sets.newHashSet(targetServer.getAddress()),
RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
ADMIN.setRSGroup(Sets.newHashSet(tableName), RSGroupInfo.DEFAULT_GROUP);
// verify default group info
Assert.assertEquals(oldDefaultGroupServerSize,
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size());
Assert.assertEquals(oldDefaultGroupTableSize,
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getTables().size());
assertEquals(oldDefaultGroupServerSize,
ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size());
assertEquals(oldDefaultGroupTableSize,
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables().size());
// verify new group info
Assert.assertEquals(1, rsGroupAdmin.getRSGroup(newGroup.getName()).getServers().size());
Assert.assertEquals(0, rsGroupAdmin.getRSGroup(newGroup.getName()).getTables().size());
assertEquals(1, ADMIN.getRSGroup(newGroup.getName()).getServers().size());
assertEquals(0, RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(newGroup.getName()).getTables().size());
// get all region to move targetServer
List<String> regionList = getTableRegionMap().get(tableName);
@ -375,63 +370,61 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
return getTableRegionMap().get(tableName) != null &&
getTableRegionMap().get(tableName).size() == 5 &&
getTableServerRegionMap().get(tableName).size() == 1 &&
admin.getClusterMetrics(EnumSet.of(Option.REGIONS_IN_TRANSITION))
ADMIN.getClusterMetrics(EnumSet.of(Option.REGIONS_IN_TRANSITION))
.getRegionStatesInTransition().size() < 1;
}
});
// verify that all region move to targetServer
Assert.assertEquals(5, getTableServerRegionMap().get(tableName).get(targetServer).size());
assertEquals(5, getTableServerRegionMap().get(tableName).get(targetServer).size());
// move targetServer and table to newGroup
LOG.info("moving server and table to newGroup");
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(targetServer.getAddress()),
newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
ADMIN.moveServersToRSGroup(Sets.newHashSet(targetServer.getAddress()), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(tableName), newGroup.getName());
// verify group change
Assert.assertEquals(newGroup.getName(),
rsGroupAdmin.getRSGroup(tableName).getName());
assertEquals(newGroup.getName(), ADMIN.getRSGroup(tableName).getName());
// verify servers' not exist in old group
Set<Address> defaultServers =
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers();
Set<Address> defaultServers = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers();
assertFalse(defaultServers.contains(targetServer.getAddress()));
// verify servers' exist in new group
Set<Address> newGroupServers = rsGroupAdmin.getRSGroup(newGroup.getName()).getServers();
Set<Address> newGroupServers = ADMIN.getRSGroup(newGroup.getName()).getServers();
assertTrue(newGroupServers.contains(targetServer.getAddress()));
// verify tables' not exist in old group
Set<TableName> defaultTables =
rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getTables();
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(RSGroupInfo.DEFAULT_GROUP).getTables();
assertFalse(defaultTables.contains(tableName));
// verify tables' exist in new group
Set<TableName> newGroupTables = rsGroupAdmin.getRSGroup(newGroup.getName()).getTables();
Set<TableName> newGroupTables =
RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(newGroup.getName()).getTables();
assertTrue(newGroupTables.contains(tableName));
// verify that all region still assgin on targetServer
// verify that all region still assign on targetServer
// TODO: uncomment after we reimplement moveServersAndTables, now the implementation is
// moveToRSGroup first and then moveTables, so the region will be moved to other region servers.
// Assert.assertEquals(5, getTableServerRegionMap().get(tableName).get(targetServer).size());
// assertEquals(5, getTableServerRegionMap().get(tableName).get(targetServer).size());
assertTrue(observer.preMoveServersCalled);
assertTrue(observer.postMoveServersCalled);
assertTrue(OBSERVER.preMoveServersCalled);
assertTrue(OBSERVER.postMoveServersCalled);
}
@Test
public void testMoveServersFromDefaultGroup() throws Exception {
// create groups and assign servers
rsGroupAdmin.addRSGroup("foo");
ADMIN.addRSGroup("foo");
RSGroupInfo fooGroup = rsGroupAdmin.getRSGroup("foo");
RSGroupInfo fooGroup = ADMIN.getRSGroup("foo");
assertEquals(0, fooGroup.getServers().size());
RSGroupInfo defaultGroup = rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
RSGroupInfo defaultGroup = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
// test remove all servers from default
try {
rsGroupAdmin.moveToRSGroup(defaultGroup.getServers(), fooGroup.getName());
ADMIN.moveServersToRSGroup(defaultGroup.getServers(), fooGroup.getName());
fail(RSGroupInfoManagerImpl.KEEP_ONE_SERVER_IN_DEFAULT_ERROR_MESSAGE);
} catch (ConstraintException ex) {
assertTrue(
@ -443,51 +436,49 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
Address serverInDefaultGroup = defaultGroup.getServers().iterator().next();
LOG.info("moving server " + serverInDefaultGroup + " from group default to group " +
fooGroup.getName());
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(serverInDefaultGroup), fooGroup.getName());
ADMIN.moveServersToRSGroup(Sets.newHashSet(serverInDefaultGroup), fooGroup.getName());
}
fooGroup = rsGroupAdmin.getRSGroup("foo");
fooGroup = ADMIN.getRSGroup("foo");
LOG.info("moving servers " + fooGroup.getServers() + " to group default");
rsGroupAdmin.moveToRSGroup(fooGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.moveServersToRSGroup(fooGroup.getServers(), RSGroupInfo.DEFAULT_GROUP);
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return getNumServers() == rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP)
.getServers().size();
return getNumServers() == ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size();
}
});
fooGroup = rsGroupAdmin.getRSGroup("foo");
fooGroup = ADMIN.getRSGroup("foo");
assertEquals(0, fooGroup.getServers().size());
// test group removal
LOG.info("Remove group " + fooGroup.getName());
rsGroupAdmin.removeRSGroup(fooGroup.getName());
Assert.assertEquals(null, rsGroupAdmin.getRSGroup(fooGroup.getName()));
ADMIN.removeRSGroup(fooGroup.getName());
assertEquals(null, ADMIN.getRSGroup(fooGroup.getName()));
}
@Test
public void testFailedMoveBeforeRetryExhaustedWhenMoveServer() throws Exception {
String groupName = getGroupName(name.getMethodName());
rsGroupAdmin.addRSGroup(groupName);
final RSGroupInfo newGroup = rsGroupAdmin.getRSGroup(groupName);
Pair<ServerName, RegionStateNode> gotPair = createTableWithRegionSplitting(newGroup,
10);
ADMIN.addRSGroup(groupName);
final RSGroupInfo newGroup = ADMIN.getRSGroup(groupName);
Pair<ServerName, RegionStateNode> gotPair = createTableWithRegionSplitting(newGroup, 10);
// start thread to recover region state
final ServerName movedServer = gotPair.getFirst();
final RegionStateNode rsn = gotPair.getSecond();
AtomicBoolean changed = new AtomicBoolean(false);
Thread t1 = recoverRegionStateThread(movedServer,
server -> master.getAssignmentManager().getRegionsOnServer(movedServer), rsn, changed);
server -> MASTER.getAssignmentManager().getRegionsOnServer(movedServer), rsn, changed);
t1.start();
// move target server to group
Thread t2 = new Thread(() -> {
LOG.info("thread2 start running, to move regions");
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(movedServer.getAddress()), newGroup.getName());
ADMIN.moveServersToRSGroup(Sets.newHashSet(movedServer.getAddress()), newGroup.getName());
} catch (IOException e) {
LOG.error("move server error", e);
}
@ -501,8 +492,8 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
@Override
public boolean evaluate() {
if (changed.get()) {
return master.getAssignmentManager().getRegionsOnServer(movedServer).size() == 0 && !rsn
.getRegionLocation().equals(movedServer);
return MASTER.getAssignmentManager().getRegionsOnServer(movedServer).size() == 0 &&
!rsn.getRegionLocation().equals(movedServer);
}
return false;
}
@ -510,15 +501,15 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
}
private <T> Thread recoverRegionStateThread(T owner, Function<T, List<RegionInfo>> getRegions,
RegionStateNode rsn, AtomicBoolean changed){
RegionStateNode rsn, AtomicBoolean changed) {
return new Thread(() -> {
LOG.info("thread1 start running, will recover region state");
long current = System.currentTimeMillis();
// wait until there is only left the region we changed state and recover its state.
// wait time is set according to the number of max retries, all except failed regions will be
// moved in one retry, and will sleep 1s until next retry.
while (System.currentTimeMillis() - current <=
RSGroupInfoManagerImpl.DEFAULT_MAX_RETRY_VALUE * 1000) {
while (System.currentTimeMillis() -
current <= RSGroupInfoManagerImpl.DEFAULT_MAX_RETRY_VALUE * 1000) {
List<RegionInfo> regions = getRegions.apply(owner);
LOG.debug("server table region size is:{}", regions.size());
assert regions.size() >= 1;
@ -538,7 +529,7 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
}
private Pair<ServerName, RegionStateNode> createTableWithRegionSplitting(RSGroupInfo rsGroupInfo,
int tableRegionCount) throws Exception{
int tableRegionCount) throws Exception {
final byte[] familyNameBytes = Bytes.toBytes("f");
// All the regions created below will be assigned to the default group.
TEST_UTIL.createMultiRegionTable(tableName, familyNameBytes, tableRegionCount);
@ -562,11 +553,11 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
* @return source server of region, and region state
* @throws IOException if methods called throw
*/
private Pair<ServerName, RegionStateNode> randomlySetOneRegionStateToSplitting(
RSGroupInfo newGroup) throws IOException{
private Pair<ServerName, RegionStateNode>
randomlySetOneRegionStateToSplitting(RSGroupInfo newGroup) throws IOException {
// get target server to move, which should has more than one regions
// randomly set a region state to SPLITTING to make move fail
return randomlySetRegionState(newGroup, RegionState.State.SPLITTING,tableName);
return randomlySetRegionState(newGroup, RegionState.State.SPLITTING, tableName);
}
private Pair<ServerName, RegionStateNode> randomlySetRegionState(RSGroupInfo groupInfo,
@ -605,7 +596,7 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
}
@Test
public void testFailedMoveServersAndRepair() throws Exception{
public void testFailedMoveServersAndRepair() throws Exception {
// This UT calls moveToRSGroup() twice to test the idempotency of it.
// The first time, movement fails because a region is made in SPLITTING state
// which will not be moved.
@ -615,35 +606,36 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
// create table
// randomly set a region state to SPLITTING to make move abort
Pair<ServerName, RegionStateNode> gotPair = createTableWithRegionSplitting(newGroup,
new Random().nextInt(8) + 4);
Pair<ServerName, RegionStateNode> gotPair =
createTableWithRegionSplitting(newGroup, new Random().nextInt(8) + 4);
RegionStateNode rsn = gotPair.getSecond();
ServerName srcServer = rsn.getRegionLocation();
// move server to newGroup and check regions
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
fail("should get IOException when retry exhausted but there still exists failed moved "
+ "regions");
}catch (Exception e){
assertTrue(e.getMessage().contains(
gotPair.getSecond().getRegionInfo().getRegionNameAsString()));
ADMIN.moveServersToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
fail("should get IOException when retry exhausted but there still exists failed moved " +
"regions");
} catch (Exception e) {
assertTrue(
e.getMessage().contains(gotPair.getSecond().getRegionInfo().getRegionNameAsString()));
}
for(RegionInfo regionInfo : master.getAssignmentManager().getAssignedRegions()){
for (RegionInfo regionInfo : MASTER.getAssignmentManager().getAssignedRegions()) {
if (regionInfo.getTable().equals(tableName) && regionInfo.equals(rsn.getRegionInfo())) {
assertEquals(master.getAssignmentManager().getRegionStates()
.getRegionServerOfRegion(regionInfo), srcServer);
assertEquals(
MASTER.getAssignmentManager().getRegionStates().getRegionServerOfRegion(regionInfo),
srcServer);
}
}
// retry move server to newGroup and check if all regions on srcServer was moved
rsn.setState(RegionState.State.OPEN);
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
assertEquals(master.getAssignmentManager().getRegionsOnServer(srcServer).size(), 0);
ADMIN.moveServersToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
assertEquals(MASTER.getAssignmentManager().getRegionsOnServer(srcServer).size(), 0);
}
@Test
public void testFailedMoveServersTablesAndRepair() throws Exception{
public void testFailedMoveServersTablesAndRepair() throws Exception {
// This UT calls moveTablesAndServers() twice to test the idempotency of it.
// The first time, movement fails because a region is made in SPLITTING state
// which will not be moved.
@ -654,10 +646,8 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
final byte[] familyNameBytes = Bytes.toBytes("f");
TableName table1 = TableName.valueOf(tableName.getNameAsString() + "_1");
TableName table2 = TableName.valueOf(tableName.getNameAsString() + "_2");
TEST_UTIL.createMultiRegionTable(table1, familyNameBytes,
new Random().nextInt(12) + 4);
TEST_UTIL.createMultiRegionTable(table2, familyNameBytes,
new Random().nextInt(12) + 4);
TEST_UTIL.createMultiRegionTable(table1, familyNameBytes, new Random().nextInt(12) + 4);
TEST_UTIL.createMultiRegionTable(table2, familyNameBytes, new Random().nextInt(12) + 4);
// randomly set a region state to SPLITTING to make move abort
Pair<ServerName, RegionStateNode> gotPair =
@ -667,27 +657,28 @@ public class TestRSGroupsAdmin2 extends TestRSGroupsBase {
// move server and table to newGroup and check regions
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(table2), newGroup.getName());
fail("should get IOException when retry exhausted but there still exists failed moved "
+ "regions");
}catch (Exception e){
assertTrue(e.getMessage().contains(
gotPair.getSecond().getRegionInfo().getRegionNameAsString()));
ADMIN.moveServersToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(table2), newGroup.getName());
fail("should get IOException when retry exhausted but there still exists failed moved " +
"regions");
} catch (Exception e) {
assertTrue(
e.getMessage().contains(gotPair.getSecond().getRegionInfo().getRegionNameAsString()));
}
for(RegionInfo regionInfo : master.getAssignmentManager().getAssignedRegions()){
for (RegionInfo regionInfo : MASTER.getAssignmentManager().getAssignedRegions()) {
if (regionInfo.getTable().equals(table1) && regionInfo.equals(rsn.getRegionInfo())) {
assertEquals(master.getAssignmentManager().getRegionStates()
.getRegionServerOfRegion(regionInfo), srcServer);
assertEquals(
MASTER.getAssignmentManager().getRegionStates().getRegionServerOfRegion(regionInfo),
srcServer);
}
}
// retry moveServersAndTables to newGroup and check if all regions on srcServer belongs to
// table2
rsn.setState(RegionState.State.OPEN);
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
rsGroupAdmin.setRSGroup(Sets.newHashSet(table2), newGroup.getName());
for(RegionInfo regionsInfo : master.getAssignmentManager().getRegionsOnServer(srcServer)){
ADMIN.moveServersToRSGroup(Sets.newHashSet(srcServer.getAddress()), newGroup.getName());
ADMIN.setRSGroup(Sets.newHashSet(table2), newGroup.getName());
for (RegionInfo regionsInfo : MASTER.getAssignmentManager().getRegionsOnServer(srcServer)) {
assertEquals(regionsInfo.getTable(), table2);
}
}

View File

@ -34,6 +34,7 @@ import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.AfterClass;
@ -42,13 +43,10 @@ import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@RunWith(Parameterized.class)
@Category({ MediumTests.class })
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupsBalance extends TestRSGroupsBase {
@ClassRule
@ -83,15 +81,15 @@ public class TestRSGroupsBalance extends TestRSGroupsBase {
String newGroupName = getGroupName(name.getMethodName());
addGroup(newGroupName, 3);
final TableName tableName = TableName.valueOf(tablePrefix + "_ns",
getNameWithoutIndex(name.getMethodName()));
admin.createNamespace(NamespaceDescriptor.create(tableName.getNamespaceAsString())
final TableName tableName =
TableName.valueOf(TABLE_PREFIX + "_ns", getNameWithoutIndex(name.getMethodName()));
ADMIN.createNamespace(NamespaceDescriptor.create(tableName.getNamespaceAsString())
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, newGroupName).build());
final TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build();
byte[] startKey = Bytes.toBytes("aaaaa");
byte[] endKey = Bytes.toBytes("zzzzz");
admin.createTable(desc, startKey, endKey, 6);
ADMIN.createTable(desc, startKey, endKey, 6);
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
@ -106,9 +104,9 @@ public class TestRSGroupsBalance extends TestRSGroupsBase {
// make assignment uneven, move all regions to one server
Map<ServerName, List<String>> assignMap = getTableServerRegionMap().get(tableName);
final ServerName first = assignMap.entrySet().iterator().next().getKey();
for (RegionInfo region : admin.getRegions(tableName)) {
for (RegionInfo region : ADMIN.getRegions(tableName)) {
if (!assignMap.get(first).contains(region.getRegionNameAsString())) {
admin.move(region.getEncodedNameAsBytes(), first);
ADMIN.move(region.getEncodedNameAsBytes(), first);
}
}
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@ -127,18 +125,18 @@ public class TestRSGroupsBalance extends TestRSGroupsBase {
});
// balance the other group and make sure it doesn't affect the new group
admin.balancerSwitch(true, true);
rsGroupAdmin.balanceRSGroup(RSGroupInfo.DEFAULT_GROUP);
ADMIN.balancerSwitch(true, true);
ADMIN.balanceRSGroup(RSGroupInfo.DEFAULT_GROUP);
assertEquals(6, getTableServerRegionMap().get(tableName).get(first).size());
// disable balance, balancer will not be run and return false
admin.balancerSwitch(false, true);
assertFalse(rsGroupAdmin.balanceRSGroup(newGroupName));
ADMIN.balancerSwitch(false, true);
assertFalse(ADMIN.balanceRSGroup(newGroupName));
assertEquals(6, getTableServerRegionMap().get(tableName).get(first).size());
// enable balance
admin.balancerSwitch(true, true);
rsGroupAdmin.balanceRSGroup(newGroupName);
ADMIN.balancerSwitch(true, true);
ADMIN.balanceRSGroup(newGroupName);
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
@ -150,15 +148,15 @@ public class TestRSGroupsBalance extends TestRSGroupsBase {
return true;
}
});
admin.balancerSwitch(false, true);
ADMIN.balancerSwitch(false, true);
}
@Test
public void testMisplacedRegions() throws Exception {
String namespace = tablePrefix + "_" + getNameWithoutIndex(name.getMethodName());
String namespace = TABLE_PREFIX + "_" + getNameWithoutIndex(name.getMethodName());
TEST_UTIL.getAdmin().createNamespace(NamespaceDescriptor.create(namespace).build());
final TableName tableName = TableName.valueOf(namespace, tablePrefix + "_" +
getNameWithoutIndex(name.getMethodName()));
final TableName tableName =
TableName.valueOf(namespace, TABLE_PREFIX + "_" + getNameWithoutIndex(name.getMethodName()));
final RSGroupInfo rsGroupInfo = addGroup(getGroupName(name.getMethodName()), 1);
@ -167,18 +165,18 @@ public class TestRSGroupsBalance extends TestRSGroupsBase {
TEST_UTIL.getAdmin().modifyNamespace(NamespaceDescriptor.create(namespace)
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, rsGroupInfo.getName()).build());
admin.balancerSwitch(true, true);
assertTrue(rsGroupAdmin.balanceRSGroup(rsGroupInfo.getName()));
admin.balancerSwitch(false, true);
assertTrue(observer.preBalanceRSGroupCalled);
assertTrue(observer.postBalanceRSGroupCalled);
ADMIN.balancerSwitch(true, true);
assertTrue(ADMIN.balanceRSGroup(rsGroupInfo.getName()));
ADMIN.balancerSwitch(false, true);
assertTrue(OBSERVER.preBalanceRSGroupCalled);
assertTrue(OBSERVER.postBalanceRSGroupCalled);
TEST_UTIL.waitFor(60000, new Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
ServerName serverName =
ServerName.valueOf(rsGroupInfo.getServers().iterator().next().toString(), 1);
return admin.getConnection().getAdmin().getRegions(serverName).size() == 15;
return ADMIN.getConnection().getAdmin().getRegions(serverName).size() == 15;
}
});
}

View File

@ -21,23 +21,20 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Supplier;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Pattern;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.ClusterMetrics.Option;
import org.apache.hadoop.hbase.HBaseCluster;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.MiniHBaseCluster;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
@ -59,7 +56,6 @@ import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.quotas.QuotaUtil;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -69,22 +65,21 @@ import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
public abstract class TestRSGroupsBase {
protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsBase.class);
//shared
protected final static String groupPrefix = "Group";
protected final static String tablePrefix = "Group";
protected final static Random rand = new Random();
// shared
protected static final String GROUP_PREFIX = "Group";
protected static final String TABLE_PREFIX = "Group";
//shared, cluster type specific
// shared, cluster type specific
protected static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
protected static Admin admin;
protected static HBaseCluster cluster;
protected static HMaster master;
protected static Admin ADMIN;
protected static HBaseCluster CLUSTER;
protected static HMaster MASTER;
protected boolean INIT = false;
protected static RSGroupAdminEndpoint rsGroupAdminEndpoint;
protected static CPMasterObserver observer;
protected static CPMasterObserver OBSERVER;
protected static RSGroupAdminClient RS_GROUP_ADMIN_CLIENT;
public final static long WAIT_TIMEOUT = 60000;
public final static int NUM_SLAVES_BASE = 4; //number of slaves for the smallest cluster
public final static int NUM_SLAVES_BASE = 4; // number of slaves for the smallest cluster
public static int NUM_DEAD_SERVERS = 0;
// Per test variables
@ -92,58 +87,16 @@ public abstract class TestRSGroupsBase {
public TestName name = new TestName();
protected TableName tableName;
protected Admin rsGroupAdmin;
@Parameterized.Parameter
public Supplier<Object> getAdmin;
private static RSGroupAdminClient getRSGroupAdmin(){
try {
return new VerifyingRSGroupAdminClient(
new RSGroupAdminClient(TEST_UTIL.getConnection()), TEST_UTIL.getConfiguration());
} catch (IOException e) {
LOG.error("Get group admin failed", e);
return null;
}
}
private static Admin getAdmin(){
try {
return TEST_UTIL.getAdmin();
} catch (IOException e) {
LOG.error("Get hbase admin failed", e);
return null;
}
}
public static Object resetAdminConnection(Object admin) {
if(admin instanceof RSGroupAdminClient) {
return getRSGroupAdmin();
}else {
return getAdmin();
}
}
public static String getNameWithoutIndex(String name) {
return name.split("\\[")[0];
}
@Parameterized.Parameters
public static List<Object[]> params() {
return Arrays.asList(new Supplier<?>[] { TestRSGroupsBase::getRSGroupAdmin },
new Supplier<?>[] { TestRSGroupsBase::getAdmin });
}
public static void setUpTestBeforeClass() throws Exception {
TEST_UTIL.getConfiguration().setFloat(
"hbase.master.balancer.stochastic.tableSkewCost", 6000);
TEST_UTIL.getConfiguration().set(
HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
RSGroupBasedLoadBalancer.class.getName());
TEST_UTIL.getConfiguration().setFloat("hbase.master.balancer.stochastic.tableSkewCost", 6000);
TEST_UTIL.getConfiguration().setBoolean(RSGroupInfoManager.RS_GROUP_ENABLED, true);
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
RSGroupAdminEndpoint.class.getName() + "," + CPMasterObserver.class.getName());
TEST_UTIL.getConfiguration().setInt(
ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART,
TEST_UTIL.getConfiguration().setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART,
NUM_SLAVES_BASE - 1);
TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
TEST_UTIL.getConfiguration().setInt("hbase.rpc.timeout", 100000);
@ -152,28 +105,23 @@ public abstract class TestRSGroupsBase {
initialize();
}
public void setAdmin(){
rsGroupAdmin = (Admin) getAdmin.get();
}
protected static void initialize() throws Exception {
admin = TEST_UTIL.getAdmin();
cluster = TEST_UTIL.getHBaseCluster();
master = TEST_UTIL.getMiniHBaseCluster().getMaster();
ADMIN = new VerifyingRSGroupAdmin(TEST_UTIL.getConfiguration());
CLUSTER = TEST_UTIL.getHBaseCluster();
MASTER = TEST_UTIL.getMiniHBaseCluster().getMaster();
//wait for balancer to come online
// wait for balancer to come online
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return master.isInitialized() &&
((RSGroupBasedLoadBalancer) master.getLoadBalancer()).isOnline();
return MASTER.isInitialized() &&
((RSGroupBasedLoadBalancer) MASTER.getLoadBalancer()).isOnline();
}
});
admin.balancerSwitch(false, true);
MasterCoprocessorHost host = master.getMasterCoprocessorHost();
observer = (CPMasterObserver) host.findCoprocessor(CPMasterObserver.class.getName());
rsGroupAdminEndpoint = (RSGroupAdminEndpoint)
host.findCoprocessor(RSGroupAdminEndpoint.class.getName());
ADMIN.balancerSwitch(false, true);
MasterCoprocessorHost host = MASTER.getMasterCoprocessorHost();
OBSERVER = (CPMasterObserver) host.findCoprocessor(CPMasterObserver.class.getName());
RS_GROUP_ADMIN_CLIENT = new RSGroupAdminClient(TEST_UTIL.getConnection());
}
public static void tearDownAfterClass() throws Exception {
@ -181,14 +129,13 @@ public abstract class TestRSGroupsBase {
}
public void setUpBeforeMethod() throws Exception {
setAdmin();
LOG.info(name.getMethodName());
tableName = TableName.valueOf(tablePrefix + "_" + name.getMethodName().split("\\[")[0]);
tableName = TableName.valueOf(TABLE_PREFIX + "_" + name.getMethodName().split("\\[")[0]);
if (!INIT) {
INIT = true;
tearDownAfterMethod();
}
observer.resetFlags();
OBSERVER.resetFlags();
}
public void tearDownAfterMethod() throws Exception {
@ -196,45 +143,40 @@ public abstract class TestRSGroupsBase {
deleteNamespaceIfNecessary();
deleteGroups();
for(ServerName sn : admin.listDecommissionedRegionServers()){
admin.recommissionRegionServer(sn, null);
for (ServerName sn : ADMIN.listDecommissionedRegionServers()) {
ADMIN.recommissionRegionServer(sn, null);
}
assertTrue(admin.listDecommissionedRegionServers().isEmpty());
assertTrue(ADMIN.listDecommissionedRegionServers().isEmpty());
int missing = NUM_SLAVES_BASE - getNumServers();
LOG.info("Restoring servers: "+missing);
for(int i=0; i<missing; i++) {
((MiniHBaseCluster)cluster).startRegionServer();
LOG.info("Restoring servers: " + missing);
for (int i = 0; i < missing; i++) {
((MiniHBaseCluster) CLUSTER).startRegionServer();
}
rsGroupAdmin.addRSGroup("master");
ServerName masterServerName =
((MiniHBaseCluster)cluster).getMaster().getServerName();
ADMIN.addRSGroup("master");
ServerName masterServerName = ((MiniHBaseCluster) CLUSTER).getMaster().getServerName();
try {
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(masterServerName.getAddress()),
"master");
ADMIN.moveServersToRSGroup(Sets.newHashSet(masterServerName.getAddress()), "master");
} catch (Exception ex) {
LOG.warn("Got this on setup, FYI", ex);
}
assertTrue(observer.preMoveServersCalled);
assertTrue(OBSERVER.preMoveServersCalled);
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
LOG.info("Waiting for cleanup to finish " + rsGroupAdmin.listRSGroups());
//Might be greater since moving servers back to default
//is after starting a server
LOG.info("Waiting for cleanup to finish " + ADMIN.listRSGroups());
// Might be greater since moving servers back to default
// is after starting a server
return rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size()
== NUM_SLAVES_BASE;
return ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().size() == NUM_SLAVES_BASE;
}
});
}
protected RSGroupInfo addGroup(String groupName, int serverCount)
protected final RSGroupInfo addGroup(String groupName, int serverCount)
throws IOException, InterruptedException {
RSGroupInfo defaultInfo = rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.addRSGroup(groupName);
RSGroupInfo defaultInfo = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
ADMIN.addRSGroup(groupName);
Set<Address> set = new HashSet<>();
for (Address server : defaultInfo.getServers()) {
if (set.size() == serverCount) {
@ -242,53 +184,56 @@ public abstract class TestRSGroupsBase {
}
set.add(server);
}
rsGroupAdmin.moveToRSGroup(set, groupName);
RSGroupInfo result = rsGroupAdmin.getRSGroup(groupName);
ADMIN.moveServersToRSGroup(set, groupName);
RSGroupInfo result = ADMIN.getRSGroup(groupName);
return result;
}
public void removeGroup(String groupName) throws IOException {
RSGroupInfo groupInfo = rsGroupAdmin.getRSGroup(groupName);
rsGroupAdmin.setRSGroup(groupInfo.getTables(), RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.moveToRSGroup(groupInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
rsGroupAdmin.removeRSGroup(groupName);
protected final void removeGroup(String groupName) throws IOException {
Set<TableName> tables = new HashSet<>();
for (TableDescriptor td : ADMIN.listTableDescriptors(true)) {
RSGroupInfo groupInfo = ADMIN.getRSGroup(td.getTableName());
if (groupInfo != null && groupInfo.getName().equals(groupName)) {
tables.add(td.getTableName());
}
}
ADMIN.setRSGroup(tables, RSGroupInfo.DEFAULT_GROUP);
RSGroupInfo groupInfo = ADMIN.getRSGroup(groupName);
ADMIN.moveServersToRSGroup(groupInfo.getServers(), RSGroupInfo.DEFAULT_GROUP);
ADMIN.removeRSGroup(groupName);
}
protected void deleteTableIfNecessary() throws IOException {
protected final void deleteTableIfNecessary() throws IOException {
for (TableDescriptor desc : TEST_UTIL.getAdmin()
.listTableDescriptors(Pattern.compile(tablePrefix + ".*"))) {
.listTableDescriptors(Pattern.compile(TABLE_PREFIX + ".*"))) {
TEST_UTIL.deleteTable(desc.getTableName());
}
}
protected void deleteNamespaceIfNecessary() throws IOException {
protected final void deleteNamespaceIfNecessary() throws IOException {
for (NamespaceDescriptor desc : TEST_UTIL.getAdmin().listNamespaceDescriptors()) {
if(desc.getName().startsWith(tablePrefix)) {
admin.deleteNamespace(desc.getName());
if (desc.getName().startsWith(TABLE_PREFIX)) {
ADMIN.deleteNamespace(desc.getName());
}
}
}
protected void deleteGroups() throws IOException {
RSGroupAdminClient groupAdmin = new RSGroupAdminClient(TEST_UTIL.getConnection());
for(RSGroupInfo group: groupAdmin.listRSGroups()) {
if(!group.getName().equals(RSGroupInfo.DEFAULT_GROUP)) {
groupAdmin.setRSGroup(group.getTables(), RSGroupInfo.DEFAULT_GROUP);
groupAdmin.moveServers(group.getServers(), RSGroupInfo.DEFAULT_GROUP);
groupAdmin.removeRSGroup(group.getName());
protected final void deleteGroups() throws IOException {
for (RSGroupInfo groupInfo : ADMIN.listRSGroups()) {
if (!groupInfo.getName().equals(RSGroupInfo.DEFAULT_GROUP)) {
removeGroup(groupInfo.getName());
}
}
}
protected Map<TableName, List<String>> getTableRegionMap() throws IOException {
Map<TableName, List<String>> map = Maps.newTreeMap();
Map<TableName, Map<ServerName, List<String>>> tableServerRegionMap
= getTableServerRegionMap();
for(TableName tableName : tableServerRegionMap.keySet()) {
if(!map.containsKey(tableName)) {
Map<TableName, Map<ServerName, List<String>>> tableServerRegionMap = getTableServerRegionMap();
for (TableName tableName : tableServerRegionMap.keySet()) {
if (!map.containsKey(tableName)) {
map.put(tableName, new LinkedList<>());
}
for(List<String> subset: tableServerRegionMap.get(tableName).values()) {
for (List<String> subset : tableServerRegionMap.get(tableName).values()) {
map.get(tableName).addAll(subset);
}
}
@ -313,8 +258,7 @@ public abstract class TestRSGroupsBase {
// return the real number of region servers, excluding the master embedded region server in 2.0+
protected int getNumServers() throws IOException {
ClusterMetrics status =
admin.getClusterMetrics(EnumSet.of(Option.MASTER, Option.LIVE_SERVERS));
ClusterMetrics status = ADMIN.getClusterMetrics(EnumSet.of(Option.MASTER, Option.LIVE_SERVERS));
ServerName masterName = status.getMasterName();
int count = 0;
for (ServerName sn : status.getLiveServerMetrics().keySet()) {
@ -325,22 +269,22 @@ public abstract class TestRSGroupsBase {
return count;
}
public String getGroupName(String baseName) {
return groupPrefix + "_" + getNameWithoutIndex(baseName) + "_" +
rand.nextInt(Integer.MAX_VALUE);
protected final String getGroupName(String baseName) {
return GROUP_PREFIX + "_" + getNameWithoutIndex(baseName) + "_" +
ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
}
/**
* The server name in group does not contain the start code, this method will find out the start
* code and construct the ServerName object.
*/
protected ServerName getServerName(Address addr) {
protected final ServerName getServerName(Address addr) {
return TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads().stream()
.map(t -> t.getRegionServer().getServerName()).filter(sn -> sn.getAddress().equals(addr))
.findFirst().get();
}
protected void toggleQuotaCheckAndRestartMiniCluster(boolean enable) throws Exception {
protected final void toggleQuotaCheckAndRestartMiniCluster(boolean enable) throws Exception {
TEST_UTIL.shutdownMiniCluster();
TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, enable);
TEST_UTIL.startMiniCluster(NUM_SLAVES_BASE - 1);
@ -348,7 +292,6 @@ public abstract class TestRSGroupsBase {
NUM_SLAVES_BASE - 1);
TEST_UTIL.getConfiguration().setBoolean(SnapshotManager.HBASE_SNAPSHOT_ENABLED, true);
initialize();
rsGroupAdmin = (Admin) resetAdminConnection(rsGroupAdmin);
}
public static class CPMasterObserver implements MasterCoprocessor, MasterObserver {
@ -422,15 +365,13 @@ public abstract class TestRSGroupsBase {
}
@Override
public void preRemoveServers(
final ObserverContext<MasterCoprocessorEnvironment> ctx,
public void preRemoveServers(final ObserverContext<MasterCoprocessorEnvironment> ctx,
Set<Address> servers) throws IOException {
preRemoveServersCalled = true;
}
@Override
public void postRemoveServers(
final ObserverContext<MasterCoprocessorEnvironment> ctx,
public void postRemoveServers(final ObserverContext<MasterCoprocessorEnvironment> ctx,
Set<Address> servers) throws IOException {
postRemoveServersCalled = true;
}
@ -448,14 +389,14 @@ public abstract class TestRSGroupsBase {
}
@Override
public void preAddRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
String name) throws IOException {
public void preAddRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
throws IOException {
preAddRSGroupCalled = true;
}
@Override
public void postAddRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx,
String name) throws IOException {
public void postAddRSGroup(final ObserverContext<MasterCoprocessorEnvironment> ctx, String name)
throws IOException {
postAddRSGroupCalled = true;
}

View File

@ -35,6 +35,7 @@ import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.quotas.QuotaTableUtil;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.AfterClass;
@ -44,15 +45,12 @@ import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
@RunWith(Parameterized.class)
@Category({ MediumTests.class })
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupsBasics extends TestRSGroupsBase {
@ClassRule
@ -83,12 +81,12 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
@Test
public void testBasicStartUp() throws IOException {
RSGroupInfo defaultInfo = rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
RSGroupInfo defaultInfo = ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
assertEquals(NUM_SLAVES_BASE, defaultInfo.getServers().size());
// Assignment of meta and rsgroup regions.
int count = master.getAssignmentManager().getRegionStates().getRegionAssignments().size();
int count = MASTER.getAssignmentManager().getRegionStates().getRegionAssignments().size();
LOG.info("regions assignments are" +
master.getAssignmentManager().getRegionStates().getRegionAssignments().toString());
MASTER.getAssignmentManager().getRegionStates().getRegionAssignments().toString());
// 2 (meta and rsgroup)
assertEquals(2, count);
}
@ -117,14 +115,14 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
@Test
public void testNamespaceCreateAndAssign() throws Exception {
LOG.info("testNamespaceCreateAndAssign");
String nsName = tablePrefix + "_foo";
final TableName tableName = TableName.valueOf(nsName, tablePrefix + "_testCreateAndAssign");
String nsName = TABLE_PREFIX + "_foo";
final TableName tableName = TableName.valueOf(nsName, TABLE_PREFIX + "_testCreateAndAssign");
RSGroupInfo appInfo = addGroup("appInfo", 1);
admin.createNamespace(NamespaceDescriptor.create(nsName)
ADMIN.createNamespace(NamespaceDescriptor.create(nsName)
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "appInfo").build());
final TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build();
admin.createTable(desc);
ADMIN.createTable(desc);
// wait for created table to be assigned
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
@ -134,18 +132,18 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
});
ServerName targetServer = getServerName(appInfo.getServers().iterator().next());
// verify it was assigned to the right group
Assert.assertEquals(1, admin.getRegions(targetServer).size());
Assert.assertEquals(1, ADMIN.getRegions(targetServer).size());
}
@Test
public void testDefaultNamespaceCreateAndAssign() throws Exception {
LOG.info("testDefaultNamespaceCreateAndAssign");
String tableName = tablePrefix + "_testCreateAndAssign";
admin.modifyNamespace(NamespaceDescriptor.create("default")
String tableName = TABLE_PREFIX + "_testCreateAndAssign";
ADMIN.modifyNamespace(NamespaceDescriptor.create("default")
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, "default").build());
final TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName))
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build();
admin.createTable(desc);
ADMIN.createTable(desc);
// wait for created table to be assigned
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
@ -165,11 +163,11 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
TEST_UTIL.createTable(tableName, FAMILY);
// create snapshot
admin.snapshot(snapshotName, tableName);
ADMIN.snapshot(snapshotName, tableName);
// clone
admin.cloneSnapshot(snapshotName, clonedTableName);
admin.deleteSnapshot(snapshotName);
ADMIN.cloneSnapshot(snapshotName, clonedTableName);
ADMIN.deleteSnapshot(snapshotName);
}
@Test
@ -182,14 +180,14 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
addGroup(getGroupName(name.getMethodName()), serverCountToMoveToNewGroup);
// get the existing dead servers
NUM_DEAD_SERVERS = cluster.getClusterMetrics().getDeadServerNames().size();
NUM_DEAD_SERVERS = CLUSTER.getClusterMetrics().getDeadServerNames().size();
// stop 1 region server in new group
ServerName serverToStop = getServerName(newGroup.getServers().iterator().next());
try {
// stopping may cause an exception
// due to the connection loss
admin.stopRegionServer(serverToStop.getAddress().toString());
ADMIN.stopRegionServer(serverToStop.getAddress().toString());
NUM_DEAD_SERVERS++;
} catch (Exception e) {
}
@ -198,20 +196,20 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return cluster.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS &&
!master.getServerManager().areDeadServersInProgress();
return CLUSTER.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS &&
!MASTER.getServerManager().areDeadServersInProgress();
}
});
assertFalse(cluster.getClusterMetrics().getLiveServerMetrics().containsKey(serverToStop));
assertTrue(cluster.getClusterMetrics().getDeadServerNames().contains(serverToStop));
assertFalse(CLUSTER.getClusterMetrics().getLiveServerMetrics().containsKey(serverToStop));
assertTrue(CLUSTER.getClusterMetrics().getDeadServerNames().contains(serverToStop));
assertTrue(newGroup.getServers().contains(serverToStop.getAddress()));
// clear dead servers list
List<ServerName> notClearedServers = admin.clearDeadServers(Lists.newArrayList(serverToStop));
List<ServerName> notClearedServers = ADMIN.clearDeadServers(Lists.newArrayList(serverToStop));
assertEquals(0, notClearedServers.size());
// the stopped region server gets cleared and removed from the group
Set<Address> newGroupServers = rsGroupAdmin.getRSGroup(newGroup.getName()).getServers();
Set<Address> newGroupServers = ADMIN.getRSGroup(newGroup.getName()).getServers();
assertFalse(newGroupServers.contains(serverToStop.getAddress()));
assertEquals(serverCountToMoveToNewGroup - 1 /* 1 stopped */, newGroupServers.size());
}
@ -221,31 +219,30 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
LOG.info("testClearNotProcessedDeadServer");
// get the existing dead servers
NUM_DEAD_SERVERS = cluster.getClusterMetrics().getDeadServerNames().size();
NUM_DEAD_SERVERS = CLUSTER.getClusterMetrics().getDeadServerNames().size();
// move region servers from default group to "dead server" group
final int serverCountToMoveToDeadServerGroup = 1;
RSGroupInfo deadServerGroup =
addGroup("deadServerGroup", serverCountToMoveToDeadServerGroup);
RSGroupInfo deadServerGroup = addGroup("deadServerGroup", serverCountToMoveToDeadServerGroup);
// stop 1 region servers in "dead server" group
ServerName serverToStop = getServerName(deadServerGroup.getServers().iterator().next());
try {
// stopping may cause an exception
// due to the connection loss
admin.stopRegionServer(serverToStop.getAddress().toString());
ADMIN.stopRegionServer(serverToStop.getAddress().toString());
NUM_DEAD_SERVERS++;
} catch (Exception e) {
}
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return cluster.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS;
return CLUSTER.getClusterMetrics().getDeadServerNames().size() == NUM_DEAD_SERVERS;
}
});
Set<Address> ServersInDeadServerGroup =
rsGroupAdmin.getRSGroup(deadServerGroup.getName()).getServers();
ADMIN.getRSGroup(deadServerGroup.getName()).getServers();
assertEquals(serverCountToMoveToDeadServerGroup, ServersInDeadServerGroup.size());
assertTrue(ServersInDeadServerGroup.contains(serverToStop.getAddress()));
}
@ -256,7 +253,7 @@ public class TestRSGroupsBasics extends TestRSGroupsBase {
TEST_UTIL.waitFor(90000, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return admin.isTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
return ADMIN.isTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
}
});
toggleQuotaCheckAndRestartMiniCluster(false);

View File

@ -0,0 +1,91 @@
/**
* 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.assertTrue;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.MiniHBaseCluster;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupsCPHookCalled extends TestRSGroupsBase {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestRSGroupsCPHookCalled.class);
@BeforeClass
public static void setUp() throws Exception {
setUpTestBeforeClass();
}
@AfterClass
public static void tearDown() throws Exception {
tearDownAfterClass();
}
@Before
public void beforeMethod() throws Exception {
setUpBeforeMethod();
}
@After
public void afterMethod() throws Exception {
tearDownAfterMethod();
}
@Test
public void testGetRSGroupInfoCPHookCalled() throws Exception {
ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP);
assertTrue(OBSERVER.preGetRSGroupInfoCalled);
assertTrue(OBSERVER.postGetRSGroupInfoCalled);
}
@Test
public void testGetRSGroupInfoOfTableCPHookCalled() throws Exception {
ADMIN.getRSGroup(TableName.META_TABLE_NAME);
assertTrue(OBSERVER.preGetRSGroupInfoOfTableCalled);
assertTrue(OBSERVER.postGetRSGroupInfoOfTableCalled);
}
@Test
public void testListRSGroupsCPHookCalled() throws Exception {
ADMIN.listRSGroups();
assertTrue(OBSERVER.preListRSGroupsCalled);
assertTrue(OBSERVER.postListRSGroupsCalled);
}
@Test
public void testGetRSGroupInfoOfServerCPHookCalled() throws Exception {
ServerName masterServerName = ((MiniHBaseCluster) CLUSTER).getMaster().getServerName();
ADMIN.getRSGroup(masterServerName.getAddress());
assertTrue(OBSERVER.preGetRSGroupInfoOfServerCalled);
assertTrue(OBSERVER.postGetRSGroupInfoOfServerCalled);
}
}

View File

@ -42,6 +42,7 @@ import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.JVMClusterUtil;
import org.apache.hadoop.hbase.util.VersionInfo;
@ -50,24 +51,22 @@ import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
@RunWith(Parameterized.class)
@Category({ MediumTests.class })
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupsKillRS extends TestRSGroupsBase {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestRSGroupsKillRS.class);
protected static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsKillRS.class);
private static final Logger LOG = LoggerFactory.getLogger(TestRSGroupsKillRS.class);
@BeforeClass
public static void setUp() throws Exception {
@ -92,13 +91,13 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
@Test
public void testKillRS() throws Exception {
RSGroupInfo appInfo = addGroup("appInfo", 1);
final TableName tableName = TableName.valueOf(tablePrefix + "_ns",
getNameWithoutIndex(name.getMethodName()));
admin.createNamespace(NamespaceDescriptor.create(tableName.getNamespaceAsString())
final TableName tableName =
TableName.valueOf(TABLE_PREFIX + "_ns", getNameWithoutIndex(name.getMethodName()));
ADMIN.createNamespace(NamespaceDescriptor.create(tableName.getNamespaceAsString())
.addConfiguration(RSGroupInfo.NAMESPACE_DESC_PROP_GROUP, appInfo.getName()).build());
final TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build();
admin.createTable(desc);
ADMIN.createTable(desc);
// wait for created table to be assigned
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
@ -108,19 +107,19 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
});
ServerName targetServer = getServerName(appInfo.getServers().iterator().next());
assertEquals(1, admin.getRegions(targetServer).size());
assertEquals(1, ADMIN.getRegions(targetServer).size());
try {
// stopping may cause an exception
// due to the connection loss
admin.stopRegionServer(targetServer.getAddress().toString());
ADMIN.stopRegionServer(targetServer.getAddress().toString());
} catch (Exception e) {
}
// wait until the server is actually down
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return !cluster.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer);
return !CLUSTER.getClusterMetrics().getLiveServerMetrics().containsKey(targetServer);
}
});
// there is only one rs in the group and we killed it, so the region can not be online, until
@ -128,30 +127,29 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return !cluster.getClusterMetrics().getRegionStatesInTransition().isEmpty();
return !CLUSTER.getClusterMetrics().getRegionStatesInTransition().isEmpty();
}
});
Set<Address> newServers = Sets.newHashSet();
newServers
.add(rsGroupAdmin.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().iterator().next());
rsGroupAdmin.moveToRSGroup(newServers, appInfo.getName());
newServers.add(ADMIN.getRSGroup(RSGroupInfo.DEFAULT_GROUP).getServers().iterator().next());
ADMIN.moveServersToRSGroup(newServers, appInfo.getName());
// Make sure all the table's regions get reassigned
// disabling the table guarantees no conflicting assign/unassign (ie SSH) happens
admin.disableTable(tableName);
admin.enableTable(tableName);
ADMIN.disableTable(tableName);
ADMIN.enableTable(tableName);
// wait for region to be assigned
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
return cluster.getClusterMetrics().getRegionStatesInTransition().isEmpty();
return CLUSTER.getClusterMetrics().getRegionStatesInTransition().isEmpty();
}
});
ServerName targetServer1 = getServerName(newServers.iterator().next());
assertEquals(1, admin.getRegions(targetServer1).size());
assertEquals(tableName, admin.getRegions(targetServer1).get(0).getTable());
assertEquals(1, ADMIN.getRegions(targetServer1).size());
assertEquals(tableName, ADMIN.getRegions(targetServer1).get(0).getTable());
}
@Test
@ -166,32 +164,31 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
TEST_UTIL.loadTable(t, Bytes.toBytes("f"));
Set<TableName> toAddTables = new HashSet<>();
toAddTables.add(tableName);
rsGroupAdmin.setRSGroup(toAddTables, groupName);
assertTrue(rsGroupAdmin.getRSGroup(groupName).getTables().contains(tableName));
ADMIN.setRSGroup(toAddTables, groupName);
assertTrue(RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(groupName).getTables().contains(tableName));
TEST_UTIL.waitTableAvailable(tableName, 30000);
// check my_group servers and table regions
Set<Address> servers = rsGroupAdmin.getRSGroup(groupName).getServers();
Set<Address> servers = ADMIN.getRSGroup(groupName).getServers();
assertEquals(2, servers.size());
LOG.debug("group servers {}", servers);
for (RegionInfo tr :
master.getAssignmentManager().getRegionStates().getRegionsOfTable(tableName)) {
assertTrue(servers.contains(
master.getAssignmentManager().getRegionStates().getRegionAssignments()
.get(tr).getAddress()));
for (RegionInfo tr : MASTER.getAssignmentManager().getRegionStates()
.getRegionsOfTable(tableName)) {
assertTrue(servers.contains(MASTER.getAssignmentManager().getRegionStates()
.getRegionAssignments().get(tr).getAddress()));
}
// Move a region, to ensure there exists a region whose 'lastHost' is in my_group
// ('lastHost' of other regions are in 'default' group)
// and check if all table regions are online
List<ServerName> gsn = new ArrayList<>();
for(Address addr : servers){
for (Address addr : servers) {
gsn.add(getServerName(addr));
}
assertEquals(2, gsn.size());
for(Map.Entry<RegionInfo, ServerName> entry :
master.getAssignmentManager().getRegionStates().getRegionAssignments().entrySet()){
if(entry.getKey().getTable().equals(tableName)){
for (Map.Entry<RegionInfo, ServerName> entry : MASTER.getAssignmentManager().getRegionStates()
.getRegionAssignments().entrySet()) {
if (entry.getKey().getTable().equals(tableName)) {
LOG.debug("move region {} from {} to {}", entry.getKey().getRegionNameAsString(),
entry.getValue(), gsn.get(1 - gsn.indexOf(entry.getValue())));
TEST_UTIL.moveRegionAndWait(entry.getKey(), gsn.get(1 - gsn.indexOf(entry.getValue())));
@ -202,7 +199,7 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
// case 1: stop all the regionservers in my_group, and restart a regionserver in my_group,
// and then check if all table regions are online
for(Address addr : rsGroupAdmin.getRSGroup(groupName).getServers()) {
for (Address addr : ADMIN.getRSGroup(groupName).getServers()) {
TEST_UTIL.getMiniHBaseCluster().stopRegionServer(getServerName(addr));
}
// better wait for a while for region reassign
@ -218,9 +215,9 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
// case 2: stop all the regionservers in my_group, and move another
// regionserver(from the 'default' group) to my_group,
// and then check if all table regions are online
for(JVMClusterUtil.RegionServerThread rst :
TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads()){
if(rst.getRegionServer().getServerName().getAddress().equals(gsn.get(0).getAddress())){
for (JVMClusterUtil.RegionServerThread rst : TEST_UTIL.getMiniHBaseCluster()
.getLiveRegionServerThreads()) {
if (rst.getRegionServer().getServerName().getAddress().equals(gsn.get(0).getAddress())) {
TEST_UTIL.getMiniHBaseCluster().stopRegionServer(rst.getRegionServer().getServerName());
break;
}
@ -228,14 +225,17 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
sleep(10000);
assertEquals(NUM_SLAVES_BASE - gsn.size(),
TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size());
ServerName newServer = master.getServerManager().getOnlineServersList().get(0);
rsGroupAdmin.moveToRSGroup(Sets.newHashSet(newServer.getAddress()), groupName);
ServerName newServer = MASTER.getServerManager().getOnlineServersList().get(0);
ADMIN.moveServersToRSGroup(Sets.newHashSet(newServer.getAddress()), groupName);
// wait and check if table regions are online
TEST_UTIL.waitTableAvailable(tableName, 30000);
}
// TODO: can not change meta group for now as we can not change the table descriptor of meta
// table, this has to be done before we merge back to master.
@Ignore
@Test
public void testLowerMetaGroupVersion() throws Exception{
public void testLowerMetaGroupVersion() throws Exception {
// create a rsgroup and move one regionserver to it
String groupName = "meta_group";
int groupRSCount = 1;
@ -244,17 +244,18 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
// move hbase:meta to meta_group
Set<TableName> toAddTables = new HashSet<>();
toAddTables.add(TableName.META_TABLE_NAME);
rsGroupAdmin.setRSGroup(toAddTables, groupName);
assertTrue(rsGroupAdmin.getRSGroup(groupName).getTables().contains(TableName.META_TABLE_NAME));
ADMIN.setRSGroup(toAddTables, groupName);
assertTrue(RS_GROUP_ADMIN_CLIENT.getRSGroupInfo(groupName).getTables()
.contains(TableName.META_TABLE_NAME));
TEST_UTIL.waitTableAvailable(tableName, 30000);
// restart the regionserver in meta_group, and lower its version
String originVersion = "";
Set<Address> servers = new HashSet<>();
for(Address addr : rsGroupAdmin.getRSGroup(groupName).getServers()) {
for (Address addr : ADMIN.getRSGroup(groupName).getServers()) {
servers.add(addr);
TEST_UTIL.getMiniHBaseCluster().stopRegionServer(getServerName(addr));
originVersion = master.getRegionServerVersion(getServerName(addr));
originVersion = MASTER.getRegionServerVersion(getServerName(addr));
}
// better wait for a while for region reassign
sleep(10000);
@ -265,12 +266,11 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase {
assertTrue(majorVersion >= 1);
String lowerVersion = String.valueOf(majorVersion - 1) + originVersion.split("\\.")[1];
setFinalStatic(Version.class.getField("version"), lowerVersion);
TEST_UTIL.getMiniHBaseCluster().startRegionServer(address.getHostname(),
address.getPort());
TEST_UTIL.getMiniHBaseCluster().startRegionServer(address.getHostname(), address.getPort());
assertEquals(NUM_SLAVES_BASE,
TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size());
assertTrue(VersionInfo.compareVersion(originVersion,
master.getRegionServerVersion(getServerName(servers.iterator().next()))) > 0);
MASTER.getRegionServerVersion(getServerName(servers.iterator().next()))) > 0);
LOG.debug("wait for META assigned...");
// SCP finished, which means all regions assigned too.
TEST_UTIL.waitFor(60000, () -> !TEST_UTIL.getHBaseCluster().getMaster().getProcedures().stream()

View File

@ -17,26 +17,25 @@
*/
package org.apache.hadoop.hbase.rsgroup;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseCluster;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.MiniHBaseCluster;
import org.apache.hadoop.hbase.StartMiniClusterOption;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.Waiter;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.ServerManager;
import org.apache.hadoop.hbase.regionserver.HRegionServer;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
@ -48,14 +47,17 @@ import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
// This tests that GroupBasedBalancer will use data in zk to do balancing during master startup.
// This does not test retain assignment.
// The tests brings up 3 RS, creates a new RS group 'my_group', moves 1 RS to 'my_group', assigns
// 'hbase:rsgroup' to 'my_group', and kill the only server in that group so that 'hbase:rsgroup'
// table isn't available. It then kills the active master and waits for backup master to come
// online. In new master, RSGroupInfoManagerImpl gets the data from zk and waits for the expected
// assignment with a timeout.
@Category(MediumTests.class)
/**
* This tests that GroupBasedBalancer will use data in zk to do balancing during master startup.
* This does not test retain assignment.
* <p/>
* The tests brings up 3 RS, creates a new RS group 'my_group', moves 1 RS to 'my_group', assigns
* 'hbase:rsgroup' to 'my_group', and kill the only server in that group so that 'hbase:rsgroup'
* table isn't available. It then kills the active master and waits for backup master to come
* online. In new master, RSGroupInfoManagerImpl gets the data from zk and waits for the expected
* assignment with a timeout.
*/
@Category({ RSGroupTests.class, MediumTests.class })
public class TestRSGroupsOfflineMode extends TestRSGroupsBase {
@ClassRule
@ -75,10 +77,7 @@ public class TestRSGroupsOfflineMode extends TestRSGroupsBase {
@BeforeClass
public static void setUp() throws Exception {
TEST_UTIL = new HBaseTestingUtility();
TEST_UTIL.getConfiguration().set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS,
RSGroupBasedLoadBalancer.class.getName());
TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
RSGroupAdminEndpoint.class.getName());
TEST_UTIL.getConfiguration().setBoolean(RSGroupInfoManager.RS_GROUP_ENABLED, true);
TEST_UTIL.getConfiguration().set(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, "1");
StartMiniClusterOption option =
StartMiniClusterOption.builder().numMasters(2).numRegionServers(3).numDataNodes(3).build();
@ -112,8 +111,8 @@ public class TestRSGroupsOfflineMode extends TestRSGroupsBase {
final HRegionServer groupRS = ((MiniHBaseCluster) cluster).getRegionServer(1);
final HRegionServer failoverRS = ((MiniHBaseCluster) cluster).getRegionServer(2);
String newGroup = "my_group";
RSGroupAdminClient groupAdmin = new RSGroupAdminClient(TEST_UTIL.getConnection());
groupAdmin.addRSGroup(newGroup);
Admin admin = TEST_UTIL.getAdmin();
admin.addRSGroup(newGroup);
if (master.getAssignmentManager().getRegionStates().getRegionAssignments()
.containsValue(failoverRS.getServerName())) {
for (RegionInfo regionInfo : hbaseAdmin.getRegions(failoverRS.getServerName())) {
@ -130,7 +129,7 @@ public class TestRSGroupsOfflineMode extends TestRSGroupsBase {
}
// Move server to group and make sure all tables are assigned.
groupAdmin.moveServers(Sets.newHashSet(groupRS.getServerName().getAddress()), newGroup);
admin.moveServersToRSGroup(Sets.newHashSet(groupRS.getServerName().getAddress()), newGroup);
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
public boolean evaluate() throws Exception {
@ -139,7 +138,7 @@ public class TestRSGroupsOfflineMode extends TestRSGroupsBase {
}
});
// Move table to group and wait.
groupAdmin.setRSGroup(Sets.newHashSet(RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME), newGroup);
admin.setRSGroup(Sets.newHashSet(RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME), newGroup);
LOG.info("Waiting for move table...");
TEST_UTIL.waitFor(WAIT_TIMEOUT, new Waiter.Predicate<Exception>() {
@Override
@ -177,7 +176,7 @@ public class TestRSGroupsOfflineMode extends TestRSGroupsBase {
return failoverRS.getRegions(failoverTable).size() >= 1;
}
});
Assert.assertEquals(0, failoverRS.getRegions(RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME).size());
assertEquals(0, failoverRS.getRegions(RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME).size());
// Need this for minicluster to shutdown cleanly.
master.stopMaster();

View File

@ -26,13 +26,11 @@ import java.util.Optional;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNotFoundException;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.security.User;
@ -96,8 +94,6 @@ public class TestRSGroupsWithACL extends SecureTestUtil {
private static User USER_GROUP_WRITE;
private static byte[] TEST_FAMILY = Bytes.toBytes("f1");
private static RSGroupAdminEndpoint rsGroupAdminEndpoint;
private static HMaster master;
private static AccessChecker accessChecker;
private static UserProvider userProvider;
@ -106,17 +102,14 @@ public class TestRSGroupsWithACL extends SecureTestUtil {
public static void setupBeforeClass() throws Exception {
// setup configuration
conf = TEST_UTIL.getConfiguration();
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, RSGroupBasedLoadBalancer.class.getName());
// Enable security
enableSecurity(conf);
// Verify enableSecurity sets up what we require
verifyConfiguration(conf);
// Enable rsgroup
configureRSGroupAdminEndpoint(conf);
conf.setBoolean(RSGroupInfoManager.RS_GROUP_ENABLED, true);
TEST_UTIL.startMiniCluster();
rsGroupAdminEndpoint = (RSGroupAdminEndpoint) TEST_UTIL.getMiniHBaseCluster().getMaster()
.getMasterCoprocessorHost().findCoprocessor(RSGroupAdminEndpoint.class.getName());
// Wait for the ACL table to become available
TEST_UTIL.waitUntilAllRegionsAssigned(PermissionStorage.ACL_TABLE_NAME);
@ -216,16 +209,6 @@ public class TestRSGroupsWithACL extends SecureTestUtil {
TEST_UTIL.shutdownMiniCluster();
}
private static void configureRSGroupAdminEndpoint(Configuration conf) {
String currentCoprocessors = conf.get(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY);
String coprocessors = RSGroupAdminEndpoint.class.getName();
if (currentCoprocessors != null) {
coprocessors += "," + currentCoprocessors;
}
conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, coprocessors);
conf.set(HConstants.HBASE_MASTER_LOADBALANCER_CLASS, RSGroupBasedLoadBalancer.class.getName());
}
@Test
public void testGetRSGroupInfo() throws Exception {
AccessTestAction action = () -> {

View File

@ -0,0 +1,885 @@
/**
* 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.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.CacheEvictionStats;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.ClusterMetrics.Option;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.NamespaceNotFoundException;
import org.apache.hadoop.hbase.RegionMetrics;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableExistsException;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.TableNotFoundException;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
import org.apache.hadoop.hbase.client.CompactType;
import org.apache.hadoop.hbase.client.CompactionState;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.SlowLogQueryFilter;
import org.apache.hadoop.hbase.client.SlowLogRecord;
import org.apache.hadoop.hbase.client.SnapshotDescription;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.client.replication.TableCFs;
import org.apache.hadoop.hbase.client.security.SecurityCapability;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
import org.apache.hadoop.hbase.quotas.QuotaFilter;
import org.apache.hadoop.hbase.quotas.QuotaSettings;
import org.apache.hadoop.hbase.quotas.SpaceQuotaSnapshotView;
import org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException;
import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
import org.apache.hadoop.hbase.replication.ReplicationPeerDescription;
import org.apache.hadoop.hbase.replication.SyncReplicationState;
import org.apache.hadoop.hbase.security.access.GetUserPermissionsRequest;
import org.apache.hadoop.hbase.security.access.Permission;
import org.apache.hadoop.hbase.security.access.UserPermission;
import org.apache.hadoop.hbase.snapshot.HBaseSnapshotException;
import org.apache.hadoop.hbase.snapshot.RestoreSnapshotException;
import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
import org.apache.hadoop.hbase.snapshot.UnknownSnapshotException;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
import org.apache.hadoop.hbase.zookeeper.ZNodePaths;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.zookeeper.KeeperException;
import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
@InterfaceAudience.Private
public class VerifyingRSGroupAdmin implements Admin, Closeable {
private final Connection conn;
private final Admin admin;
private final ZKWatcher zkw;
public VerifyingRSGroupAdmin(Configuration conf) throws IOException {
conn = ConnectionFactory.createConnection(conf);
admin = conn.getAdmin();
zkw = new ZKWatcher(conf, this.getClass().getSimpleName(), null);
}
public int getOperationTimeout() {
return admin.getOperationTimeout();
}
public int getSyncWaitTimeout() {
return admin.getSyncWaitTimeout();
}
public void abort(String why, Throwable e) {
admin.abort(why, e);
}
public boolean isAborted() {
return admin.isAborted();
}
public Connection getConnection() {
return admin.getConnection();
}
public boolean tableExists(TableName tableName) throws IOException {
return admin.tableExists(tableName);
}
public List<TableDescriptor> listTableDescriptors() throws IOException {
return admin.listTableDescriptors();
}
public List<TableDescriptor> listTableDescriptors(boolean includeSysTables) throws IOException {
return admin.listTableDescriptors(includeSysTables);
}
public List<TableDescriptor> listTableDescriptors(Pattern pattern, boolean includeSysTables)
throws IOException {
return admin.listTableDescriptors(pattern, includeSysTables);
}
public TableName[] listTableNames() throws IOException {
return admin.listTableNames();
}
public TableName[] listTableNames(Pattern pattern, boolean includeSysTables) throws IOException {
return admin.listTableNames(pattern, includeSysTables);
}
public TableDescriptor getDescriptor(TableName tableName)
throws TableNotFoundException, IOException {
return admin.getDescriptor(tableName);
}
public void createTable(TableDescriptor desc, byte[] startKey, byte[] endKey, int numRegions)
throws IOException {
admin.createTable(desc, startKey, endKey, numRegions);
}
public Future<Void> createTableAsync(TableDescriptor desc) throws IOException {
return admin.createTableAsync(desc);
}
public Future<Void> createTableAsync(TableDescriptor desc, byte[][] splitKeys)
throws IOException {
return admin.createTableAsync(desc, splitKeys);
}
public Future<Void> deleteTableAsync(TableName tableName) throws IOException {
return admin.deleteTableAsync(tableName);
}
public Future<Void> truncateTableAsync(TableName tableName, boolean preserveSplits)
throws IOException {
return admin.truncateTableAsync(tableName, preserveSplits);
}
public Future<Void> enableTableAsync(TableName tableName) throws IOException {
return admin.enableTableAsync(tableName);
}
public Future<Void> disableTableAsync(TableName tableName) throws IOException {
return admin.disableTableAsync(tableName);
}
public boolean isTableEnabled(TableName tableName) throws IOException {
return admin.isTableEnabled(tableName);
}
public boolean isTableDisabled(TableName tableName) throws IOException {
return admin.isTableDisabled(tableName);
}
public boolean isTableAvailable(TableName tableName) throws IOException {
return admin.isTableAvailable(tableName);
}
public Future<Void> addColumnFamilyAsync(TableName tableName, ColumnFamilyDescriptor columnFamily)
throws IOException {
return admin.addColumnFamilyAsync(tableName, columnFamily);
}
public Future<Void> deleteColumnFamilyAsync(TableName tableName, byte[] columnFamily)
throws IOException {
return admin.deleteColumnFamilyAsync(tableName, columnFamily);
}
public Future<Void> modifyColumnFamilyAsync(TableName tableName,
ColumnFamilyDescriptor columnFamily) throws IOException {
return admin.modifyColumnFamilyAsync(tableName, columnFamily);
}
public List<RegionInfo> getRegions(ServerName serverName) throws IOException {
return admin.getRegions(serverName);
}
public void flush(TableName tableName) throws IOException {
admin.flush(tableName);
}
public void flushRegion(byte[] regionName) throws IOException {
admin.flushRegion(regionName);
}
public void flushRegionServer(ServerName serverName) throws IOException {
admin.flushRegionServer(serverName);
}
public void compact(TableName tableName) throws IOException {
admin.compact(tableName);
}
public void compactRegion(byte[] regionName) throws IOException {
admin.compactRegion(regionName);
}
public void compact(TableName tableName, byte[] columnFamily) throws IOException {
admin.compact(tableName, columnFamily);
}
public void compactRegion(byte[] regionName, byte[] columnFamily) throws IOException {
admin.compactRegion(regionName, columnFamily);
}
public void compact(TableName tableName, CompactType compactType)
throws IOException, InterruptedException {
admin.compact(tableName, compactType);
}
public void compact(TableName tableName, byte[] columnFamily, CompactType compactType)
throws IOException, InterruptedException {
admin.compact(tableName, columnFamily, compactType);
}
public void majorCompact(TableName tableName) throws IOException {
admin.majorCompact(tableName);
}
public void majorCompactRegion(byte[] regionName) throws IOException {
admin.majorCompactRegion(regionName);
}
public void majorCompact(TableName tableName, byte[] columnFamily) throws IOException {
admin.majorCompact(tableName, columnFamily);
}
public void majorCompactRegion(byte[] regionName, byte[] columnFamily) throws IOException {
admin.majorCompactRegion(regionName, columnFamily);
}
public void majorCompact(TableName tableName, CompactType compactType)
throws IOException, InterruptedException {
admin.majorCompact(tableName, compactType);
}
public void majorCompact(TableName tableName, byte[] columnFamily, CompactType compactType)
throws IOException, InterruptedException {
admin.majorCompact(tableName, columnFamily, compactType);
}
public Map<ServerName, Boolean> compactionSwitch(boolean switchState,
List<String> serverNamesList) throws IOException {
return admin.compactionSwitch(switchState, serverNamesList);
}
public void compactRegionServer(ServerName serverName) throws IOException {
admin.compactRegionServer(serverName);
}
public void majorCompactRegionServer(ServerName serverName) throws IOException {
admin.majorCompactRegionServer(serverName);
}
public void move(byte[] encodedRegionName) throws IOException {
admin.move(encodedRegionName);
}
public void move(byte[] encodedRegionName, ServerName destServerName) throws IOException {
admin.move(encodedRegionName, destServerName);
}
public void assign(byte[] regionName) throws IOException {
admin.assign(regionName);
}
public void unassign(byte[] regionName, boolean force) throws IOException {
admin.unassign(regionName, force);
}
public void offline(byte[] regionName) throws IOException {
admin.offline(regionName);
}
public boolean balancerSwitch(boolean onOrOff, boolean synchronous) throws IOException {
return admin.balancerSwitch(onOrOff, synchronous);
}
public boolean balance() throws IOException {
return admin.balance();
}
public boolean balance(boolean force) throws IOException {
return admin.balance(force);
}
public boolean isBalancerEnabled() throws IOException {
return admin.isBalancerEnabled();
}
public CacheEvictionStats clearBlockCache(TableName tableName) throws IOException {
return admin.clearBlockCache(tableName);
}
public boolean normalize() throws IOException {
return admin.normalize();
}
public boolean isNormalizerEnabled() throws IOException {
return admin.isNormalizerEnabled();
}
public boolean normalizerSwitch(boolean on) throws IOException {
return admin.normalizerSwitch(on);
}
public boolean catalogJanitorSwitch(boolean onOrOff) throws IOException {
return admin.catalogJanitorSwitch(onOrOff);
}
public int runCatalogJanitor() throws IOException {
return admin.runCatalogJanitor();
}
public boolean isCatalogJanitorEnabled() throws IOException {
return admin.isCatalogJanitorEnabled();
}
public boolean cleanerChoreSwitch(boolean onOrOff) throws IOException {
return admin.cleanerChoreSwitch(onOrOff);
}
public boolean runCleanerChore() throws IOException {
return admin.runCleanerChore();
}
public boolean isCleanerChoreEnabled() throws IOException {
return admin.isCleanerChoreEnabled();
}
public Future<Void> mergeRegionsAsync(byte[][] nameofRegionsToMerge, boolean forcible)
throws IOException {
return admin.mergeRegionsAsync(nameofRegionsToMerge, forcible);
}
public void split(TableName tableName) throws IOException {
admin.split(tableName);
}
public void split(TableName tableName, byte[] splitPoint) throws IOException {
admin.split(tableName, splitPoint);
}
public Future<Void> splitRegionAsync(byte[] regionName) throws IOException {
return admin.splitRegionAsync(regionName);
}
public Future<Void> splitRegionAsync(byte[] regionName, byte[] splitPoint) throws IOException {
return admin.splitRegionAsync(regionName, splitPoint);
}
public Future<Void> modifyTableAsync(TableDescriptor td) throws IOException {
return admin.modifyTableAsync(td);
}
public void shutdown() throws IOException {
admin.shutdown();
}
public void stopMaster() throws IOException {
admin.stopMaster();
}
public boolean isMasterInMaintenanceMode() throws IOException {
return admin.isMasterInMaintenanceMode();
}
public void stopRegionServer(String hostnamePort) throws IOException {
admin.stopRegionServer(hostnamePort);
}
public ClusterMetrics getClusterMetrics(EnumSet<Option> options) throws IOException {
return admin.getClusterMetrics(options);
}
public List<RegionMetrics> getRegionMetrics(ServerName serverName) throws IOException {
return admin.getRegionMetrics(serverName);
}
public List<RegionMetrics> getRegionMetrics(ServerName serverName, TableName tableName)
throws IOException {
return admin.getRegionMetrics(serverName, tableName);
}
public Configuration getConfiguration() {
return admin.getConfiguration();
}
public Future<Void> createNamespaceAsync(NamespaceDescriptor descriptor) throws IOException {
return admin.createNamespaceAsync(descriptor);
}
public Future<Void> modifyNamespaceAsync(NamespaceDescriptor descriptor) throws IOException {
return admin.modifyNamespaceAsync(descriptor);
}
public Future<Void> deleteNamespaceAsync(String name) throws IOException {
return admin.deleteNamespaceAsync(name);
}
public NamespaceDescriptor getNamespaceDescriptor(String name)
throws NamespaceNotFoundException, IOException {
return admin.getNamespaceDescriptor(name);
}
public String[] listNamespaces() throws IOException {
return admin.listNamespaces();
}
public NamespaceDescriptor[] listNamespaceDescriptors() throws IOException {
return admin.listNamespaceDescriptors();
}
public List<TableDescriptor> listTableDescriptorsByNamespace(byte[] name) throws IOException {
return admin.listTableDescriptorsByNamespace(name);
}
public TableName[] listTableNamesByNamespace(String name) throws IOException {
return admin.listTableNamesByNamespace(name);
}
public List<RegionInfo> getRegions(TableName tableName) throws IOException {
return admin.getRegions(tableName);
}
public void close() {
admin.close();
}
public List<TableDescriptor> listTableDescriptors(List<TableName> tableNames) throws IOException {
return admin.listTableDescriptors(tableNames);
}
public Future<Boolean> abortProcedureAsync(long procId, boolean mayInterruptIfRunning)
throws IOException {
return admin.abortProcedureAsync(procId, mayInterruptIfRunning);
}
public String getProcedures() throws IOException {
return admin.getProcedures();
}
public String getLocks() throws IOException {
return admin.getLocks();
}
public void rollWALWriter(ServerName serverName) throws IOException, FailedLogCloseException {
admin.rollWALWriter(serverName);
}
public CompactionState getCompactionState(TableName tableName) throws IOException {
return admin.getCompactionState(tableName);
}
public CompactionState getCompactionState(TableName tableName, CompactType compactType)
throws IOException {
return admin.getCompactionState(tableName, compactType);
}
public CompactionState getCompactionStateForRegion(byte[] regionName) throws IOException {
return admin.getCompactionStateForRegion(regionName);
}
public long getLastMajorCompactionTimestamp(TableName tableName) throws IOException {
return admin.getLastMajorCompactionTimestamp(tableName);
}
public long getLastMajorCompactionTimestampForRegion(byte[] regionName) throws IOException {
return admin.getLastMajorCompactionTimestampForRegion(regionName);
}
public void snapshot(SnapshotDescription snapshot)
throws IOException, SnapshotCreationException, IllegalArgumentException {
admin.snapshot(snapshot);
}
public Future<Void> snapshotAsync(SnapshotDescription snapshot)
throws IOException, SnapshotCreationException {
return admin.snapshotAsync(snapshot);
}
public boolean isSnapshotFinished(SnapshotDescription snapshot)
throws IOException, HBaseSnapshotException, UnknownSnapshotException {
return admin.isSnapshotFinished(snapshot);
}
public void restoreSnapshot(String snapshotName) throws IOException, RestoreSnapshotException {
admin.restoreSnapshot(snapshotName);
}
public void restoreSnapshot(String snapshotName, boolean takeFailSafeSnapshot, boolean restoreAcl)
throws IOException, RestoreSnapshotException {
admin.restoreSnapshot(snapshotName, takeFailSafeSnapshot, restoreAcl);
}
public Future<Void> cloneSnapshotAsync(String snapshotName, TableName tableName,
boolean restoreAcl) throws IOException, TableExistsException, RestoreSnapshotException {
return admin.cloneSnapshotAsync(snapshotName, tableName, restoreAcl);
}
public void execProcedure(String signature, String instance, Map<String, String> props)
throws IOException {
admin.execProcedure(signature, instance, props);
}
public byte[] execProcedureWithReturn(String signature, String instance,
Map<String, String> props) throws IOException {
return admin.execProcedureWithReturn(signature, instance, props);
}
public boolean isProcedureFinished(String signature, String instance, Map<String, String> props)
throws IOException {
return admin.isProcedureFinished(signature, instance, props);
}
public List<SnapshotDescription> listSnapshots() throws IOException {
return admin.listSnapshots();
}
public List<SnapshotDescription> listSnapshots(Pattern pattern) throws IOException {
return admin.listSnapshots(pattern);
}
public List<SnapshotDescription> listTableSnapshots(Pattern tableNamePattern,
Pattern snapshotNamePattern) throws IOException {
return admin.listTableSnapshots(tableNamePattern, snapshotNamePattern);
}
public void deleteSnapshot(String snapshotName) throws IOException {
admin.deleteSnapshot(snapshotName);
}
public void deleteSnapshots(Pattern pattern) throws IOException {
admin.deleteSnapshots(pattern);
}
public void deleteTableSnapshots(Pattern tableNamePattern, Pattern snapshotNamePattern)
throws IOException {
admin.deleteTableSnapshots(tableNamePattern, snapshotNamePattern);
}
public void setQuota(QuotaSettings quota) throws IOException {
admin.setQuota(quota);
}
public List<QuotaSettings> getQuota(QuotaFilter filter) throws IOException {
return admin.getQuota(filter);
}
public CoprocessorRpcChannel coprocessorService() {
return admin.coprocessorService();
}
public CoprocessorRpcChannel coprocessorService(ServerName serverName) {
return admin.coprocessorService(serverName);
}
public void updateConfiguration(ServerName server) throws IOException {
admin.updateConfiguration(server);
}
public void updateConfiguration() throws IOException {
admin.updateConfiguration();
}
public List<SecurityCapability> getSecurityCapabilities() throws IOException {
return admin.getSecurityCapabilities();
}
public boolean splitSwitch(boolean enabled, boolean synchronous) throws IOException {
return admin.splitSwitch(enabled, synchronous);
}
public boolean mergeSwitch(boolean enabled, boolean synchronous) throws IOException {
return admin.mergeSwitch(enabled, synchronous);
}
public boolean isSplitEnabled() throws IOException {
return admin.isSplitEnabled();
}
public boolean isMergeEnabled() throws IOException {
return admin.isMergeEnabled();
}
public Future<Void> addReplicationPeerAsync(String peerId, ReplicationPeerConfig peerConfig,
boolean enabled) throws IOException {
return admin.addReplicationPeerAsync(peerId, peerConfig, enabled);
}
public Future<Void> removeReplicationPeerAsync(String peerId) throws IOException {
return admin.removeReplicationPeerAsync(peerId);
}
public Future<Void> enableReplicationPeerAsync(String peerId) throws IOException {
return admin.enableReplicationPeerAsync(peerId);
}
public Future<Void> disableReplicationPeerAsync(String peerId) throws IOException {
return admin.disableReplicationPeerAsync(peerId);
}
public ReplicationPeerConfig getReplicationPeerConfig(String peerId) throws IOException {
return admin.getReplicationPeerConfig(peerId);
}
public Future<Void> updateReplicationPeerConfigAsync(String peerId,
ReplicationPeerConfig peerConfig) throws IOException {
return admin.updateReplicationPeerConfigAsync(peerId, peerConfig);
}
public List<ReplicationPeerDescription> listReplicationPeers() throws IOException {
return admin.listReplicationPeers();
}
public List<ReplicationPeerDescription> listReplicationPeers(Pattern pattern) throws IOException {
return admin.listReplicationPeers(pattern);
}
public Future<Void> transitReplicationPeerSyncReplicationStateAsync(String peerId,
SyncReplicationState state) throws IOException {
return admin.transitReplicationPeerSyncReplicationStateAsync(peerId, state);
}
public void decommissionRegionServers(List<ServerName> servers, boolean offload)
throws IOException {
admin.decommissionRegionServers(servers, offload);
}
public List<ServerName> listDecommissionedRegionServers() throws IOException {
return admin.listDecommissionedRegionServers();
}
public void recommissionRegionServer(ServerName server, List<byte[]> encodedRegionNames)
throws IOException {
admin.recommissionRegionServer(server, encodedRegionNames);
}
public List<TableCFs> listReplicatedTableCFs() throws IOException {
return admin.listReplicatedTableCFs();
}
public void enableTableReplication(TableName tableName) throws IOException {
admin.enableTableReplication(tableName);
}
public void disableTableReplication(TableName tableName) throws IOException {
admin.disableTableReplication(tableName);
}
public void clearCompactionQueues(ServerName serverName, Set<String> queues)
throws IOException, InterruptedException {
admin.clearCompactionQueues(serverName, queues);
}
public List<ServerName> clearDeadServers(List<ServerName> servers) throws IOException {
return admin.clearDeadServers(servers);
}
public void cloneTableSchema(TableName tableName, TableName newTableName, boolean preserveSplits)
throws IOException {
admin.cloneTableSchema(tableName, newTableName, preserveSplits);
}
public boolean switchRpcThrottle(boolean enable) throws IOException {
return admin.switchRpcThrottle(enable);
}
public boolean isRpcThrottleEnabled() throws IOException {
return admin.isRpcThrottleEnabled();
}
public boolean exceedThrottleQuotaSwitch(boolean enable) throws IOException {
return admin.exceedThrottleQuotaSwitch(enable);
}
public Map<TableName, Long> getSpaceQuotaTableSizes() throws IOException {
return admin.getSpaceQuotaTableSizes();
}
public Map<TableName, ? extends SpaceQuotaSnapshotView>
getRegionServerSpaceQuotaSnapshots(ServerName serverName) throws IOException {
return admin.getRegionServerSpaceQuotaSnapshots(serverName);
}
public SpaceQuotaSnapshotView getCurrentSpaceQuotaSnapshot(String namespace) throws IOException {
return admin.getCurrentSpaceQuotaSnapshot(namespace);
}
public SpaceQuotaSnapshotView getCurrentSpaceQuotaSnapshot(TableName tableName)
throws IOException {
return admin.getCurrentSpaceQuotaSnapshot(tableName);
}
public void grant(UserPermission userPermission, boolean mergeExistingPermissions)
throws IOException {
admin.grant(userPermission, mergeExistingPermissions);
}
public void revoke(UserPermission userPermission) throws IOException {
admin.revoke(userPermission);
}
public List<UserPermission>
getUserPermissions(GetUserPermissionsRequest getUserPermissionsRequest) throws IOException {
return admin.getUserPermissions(getUserPermissionsRequest);
}
public List<Boolean> hasUserPermissions(String userName, List<Permission> permissions)
throws IOException {
return admin.hasUserPermissions(userName, permissions);
}
public boolean snapshotCleanupSwitch(boolean on, boolean synchronous) throws IOException {
return admin.snapshotCleanupSwitch(on, synchronous);
}
public boolean isSnapshotCleanupEnabled() throws IOException {
return admin.isSnapshotCleanupEnabled();
}
public void addRSGroup(String groupName) throws IOException {
admin.addRSGroup(groupName);
verify();
}
public RSGroupInfo getRSGroup(String groupName) throws IOException {
return admin.getRSGroup(groupName);
}
public RSGroupInfo getRSGroup(Address hostPort) throws IOException {
return admin.getRSGroup(hostPort);
}
public RSGroupInfo getRSGroup(TableName tableName) throws IOException {
return admin.getRSGroup(tableName);
}
public List<RSGroupInfo> listRSGroups() throws IOException {
return admin.listRSGroups();
}
public void removeRSGroup(String groupName) throws IOException {
admin.removeRSGroup(groupName);
verify();
}
public void removeServersFromRSGroup(Set<Address> servers) throws IOException {
admin.removeServersFromRSGroup(servers);
verify();
}
public void moveServersToRSGroup(Set<Address> servers, String targetGroup) throws IOException {
admin.moveServersToRSGroup(servers, targetGroup);
verify();
}
public void setRSGroup(Set<TableName> tables, String groupName) throws IOException {
admin.setRSGroup(tables, groupName);
verify();
}
public boolean balanceRSGroup(String groupName) throws IOException {
return admin.balanceRSGroup(groupName);
}
private void verify() throws IOException {
Map<String, RSGroupInfo> groupMap = Maps.newHashMap();
Set<RSGroupInfo> zList = Sets.newHashSet();
List<TableDescriptor> tds = new ArrayList<>();
try (Admin admin = conn.getAdmin()) {
tds.addAll(admin.listTableDescriptors());
tds.addAll(admin.listTableDescriptorsByNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME));
}
SortedSet<Address> lives = Sets.newTreeSet();
for (ServerName sn : conn.getAdmin().getClusterMetrics().getLiveServerMetrics().keySet()) {
lives.add(sn.getAddress());
}
for (ServerName sn : conn.getAdmin().listDecommissionedRegionServers()) {
lives.remove(sn.getAddress());
}
try (Table table = conn.getTable(RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME);
ResultScanner scanner = table.getScanner(new Scan())) {
for (;;) {
Result result = scanner.next();
if (result == null) {
break;
}
RSGroupProtos.RSGroupInfo proto = RSGroupProtos.RSGroupInfo.parseFrom(result.getValue(
RSGroupInfoManagerImpl.META_FAMILY_BYTES, RSGroupInfoManagerImpl.META_QUALIFIER_BYTES));
RSGroupInfo rsGroupInfo = ProtobufUtil.toGroupInfo(proto);
groupMap.put(proto.getName(), RSGroupUtil.fillTables(rsGroupInfo, tds));
for (Address address : rsGroupInfo.getServers()) {
lives.remove(address);
}
}
}
SortedSet<TableName> tables = Sets.newTreeSet();
for (TableDescriptor td : conn.getAdmin().listTableDescriptors(Pattern.compile(".*"), true)) {
String groupName = td.getRegionServerGroup().orElse(RSGroupInfo.DEFAULT_GROUP);
if (groupName.equals(RSGroupInfo.DEFAULT_GROUP)) {
tables.add(td.getTableName());
}
}
groupMap.put(RSGroupInfo.DEFAULT_GROUP,
new RSGroupInfo(RSGroupInfo.DEFAULT_GROUP, lives, tables));
assertEquals(Sets.newHashSet(groupMap.values()), Sets.newHashSet(admin.listRSGroups()));
try {
String groupBasePath = ZNodePaths.joinZNode(zkw.getZNodePaths().baseZNode, "rsgroup");
for (String znode : ZKUtil.listChildrenNoWatch(zkw, groupBasePath)) {
byte[] data = ZKUtil.getData(zkw, ZNodePaths.joinZNode(groupBasePath, znode));
if (data.length > 0) {
ProtobufUtil.expectPBMagicPrefix(data);
ByteArrayInputStream bis =
new ByteArrayInputStream(data, ProtobufUtil.lengthOfPBMagic(), data.length);
RSGroupInfo rsGroupInfo =
ProtobufUtil.toGroupInfo(RSGroupProtos.RSGroupInfo.parseFrom(bis));
zList.add(RSGroupUtil.fillTables(rsGroupInfo, tds));
}
}
groupMap.remove(RSGroupInfo.DEFAULT_GROUP);
assertEquals(zList.size(), groupMap.size());
for (RSGroupInfo rsGroupInfo : zList) {
assertTrue(groupMap.get(rsGroupInfo.getName()).equals(rsGroupInfo));
}
} catch (KeeperException e) {
throw new IOException("ZK verification failed", e);
} catch (DeserializationException e) {
throw new IOException("ZK verification failed", e);
} catch (InterruptedException e) {
throw new IOException("ZK verification failed", e);
}
}
@Override
public List<SlowLogRecord> getSlowLogResponses(Set<ServerName> serverNames,
SlowLogQueryFilter slowLogQueryFilter) throws IOException {
return null;
}
@Override
public List<Boolean> clearSlowLogResponses(Set<ServerName> serverNames) throws IOException {
return null;
}
}

View File

@ -1,193 +0,0 @@
/**
* 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.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.regex.Pattern;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.net.Address;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
import org.apache.hadoop.hbase.zookeeper.ZKUtil;
import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
import org.apache.hadoop.hbase.zookeeper.ZNodePaths;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.zookeeper.KeeperException;
import org.apache.hbase.thirdparty.com.google.common.collect.Maps;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
@InterfaceAudience.Private
public class VerifyingRSGroupAdminClient extends RSGroupAdminClient {
private Connection conn;
private ZKWatcher zkw;
private RSGroupAdminClient wrapped;
public VerifyingRSGroupAdminClient(RSGroupAdminClient RSGroupAdmin, Configuration conf)
throws IOException {
wrapped = RSGroupAdmin;
conn = ConnectionFactory.createConnection(conf);
zkw = new ZKWatcher(conf, this.getClass().getSimpleName(), null);
}
@Override
public void addRSGroup(String groupName) throws IOException {
wrapped.addRSGroup(groupName);
verify();
}
@Override
public RSGroupInfo getRSGroup(String groupName) throws IOException {
return wrapped.getRSGroupInfo(groupName);
}
@Override
public RSGroupInfo getRSGroup(TableName tableName) throws IOException {
return wrapped.getRSGroup(tableName);
}
@Override
public void moveToRSGroup(Set<Address> servers, String targetGroup) throws IOException {
wrapped.moveToRSGroup(servers, targetGroup);
verify();
}
@Override
public void removeRSGroup(String name) throws IOException {
wrapped.removeRSGroup(name);
verify();
}
@Override
public boolean balanceRSGroup(String groupName) throws IOException {
return wrapped.balanceRSGroup(groupName);
}
@Override
public List<RSGroupInfo> listRSGroups() throws IOException {
return wrapped.listRSGroups();
}
@Override
public RSGroupInfo getRSGroup(Address hostPort) throws IOException {
return wrapped.getRSGroup(hostPort);
}
@Override
public void removeRSGroup(Set<Address> servers) throws IOException {
wrapped.removeRSGroup(servers);
verify();
}
@Override
public void setRSGroup(Set<TableName> tables, String groupName) throws IOException{
wrapped.setRSGroup(tables, groupName);
verify();
}
public void verify() throws IOException {
Map<String, RSGroupInfo> groupMap = Maps.newHashMap();
Set<RSGroupInfo> zList = Sets.newHashSet();
List<TableDescriptor> tds = new ArrayList<>();
try (Admin admin = conn.getAdmin()) {
tds.addAll(admin.listTableDescriptors());
tds.addAll(admin.listTableDescriptorsByNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME));
}
SortedSet<Address> lives = Sets.newTreeSet();
for (ServerName sn : conn.getAdmin().getClusterMetrics().getLiveServerMetrics().keySet()) {
lives.add(sn.getAddress());
}
for (ServerName sn : conn.getAdmin().listDecommissionedRegionServers()) {
lives.remove(sn.getAddress());
}
try (Table table = conn.getTable(RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME);
ResultScanner scanner = table.getScanner(new Scan())) {
for (;;) {
Result result = scanner.next();
if (result == null) {
break;
}
RSGroupProtos.RSGroupInfo proto = RSGroupProtos.RSGroupInfo.parseFrom(result.getValue(
RSGroupInfoManagerImpl.META_FAMILY_BYTES, RSGroupInfoManagerImpl.META_QUALIFIER_BYTES));
RSGroupInfo rsGroupInfo = ProtobufUtil.toGroupInfo(proto);
groupMap.put(proto.getName(), RSGroupUtil.fillTables(rsGroupInfo, tds));
for(Address address : rsGroupInfo.getServers()){
lives.remove(address);
}
}
}
SortedSet<TableName> tables = Sets.newTreeSet();
for (TableDescriptor td : conn.getAdmin().listTableDescriptors(Pattern.compile(".*"),
true)){
String groupName = td.getRegionServerGroup().orElse(RSGroupInfo.DEFAULT_GROUP);
if (groupName.equals(RSGroupInfo.DEFAULT_GROUP)) {
tables.add(td.getTableName());
}
}
groupMap.put(RSGroupInfo.DEFAULT_GROUP,
new RSGroupInfo(RSGroupInfo.DEFAULT_GROUP, lives, tables));
assertEquals(Sets.newHashSet(groupMap.values()), Sets.newHashSet(wrapped.listRSGroups()));
try {
String groupBasePath = ZNodePaths.joinZNode(zkw.getZNodePaths().baseZNode, "rsgroup");
for (String znode : ZKUtil.listChildrenNoWatch(zkw, groupBasePath)) {
byte[] data = ZKUtil.getData(zkw, ZNodePaths.joinZNode(groupBasePath, znode));
if (data.length > 0) {
ProtobufUtil.expectPBMagicPrefix(data);
ByteArrayInputStream bis =
new ByteArrayInputStream(data, ProtobufUtil.lengthOfPBMagic(), data.length);
RSGroupInfo rsGroupInfo =
ProtobufUtil.toGroupInfo(RSGroupProtos.RSGroupInfo.parseFrom(bis));
zList.add(RSGroupUtil.fillTables(rsGroupInfo, tds));
}
}
groupMap.remove(RSGroupInfo.DEFAULT_GROUP);
assertEquals(zList.size(), groupMap.size());
for (RSGroupInfo rsGroupInfo : zList) {
assertTrue(groupMap.get(rsGroupInfo.getName()).equals(rsGroupInfo));
}
} catch (KeeperException e) {
throw new IOException("ZK verification failed", e);
} catch (DeserializationException e) {
throw new IOException("ZK verification failed", e);
} catch (InterruptedException e) {
throw new IOException("ZK verification failed", e);
}
}
}

View File

@ -1178,7 +1178,7 @@ public class ThriftAdmin implements Admin {
}
@Override
public void moveToRSGroup(Set<Address> servers, String targetGroup) {
public void moveServersToRSGroup(Set<Address> servers, String targetGroup) {
throw new NotImplementedException("moveToRSGroup not supported in ThriftAdmin");
}
@ -1208,7 +1208,7 @@ public class ThriftAdmin implements Admin {
}
@Override
public void removeRSGroup(Set<Address> servers) {
public void removeServersFromRSGroup(Set<Address> servers) {
throw new NotImplementedException("removeRSGroup not supported in ThriftAdmin");
}

15
pom.xml
View File

@ -3635,6 +3635,21 @@
<surefire.secondPartGroups></surefire.secondPartGroups>
</properties>
</profile>
<profile>
<id>runRSGroupTests</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<surefire.firstPartForkCount>1</surefire.firstPartForkCount>
<surefire.secondPartForkCount>1</surefire.secondPartForkCount>
<surefire.skipFirstPart>false</surefire.skipFirstPart>
<surefire.skipSecondPart>true</surefire.skipSecondPart>
<surefire.firstPartGroups>org.apache.hadoop.hbase.testclassification.RSGroupTests
</surefire.firstPartGroups>
<surefire.secondPartGroups></surefire.secondPartGroups>
</properties>
</profile>
<profile>
<!-- Use it to launch tests locally-->