HBASE-17600 Implement get/create/modify/delete/list namespace admin operations
This commit is contained in:
parent
9214ad69af
commit
4ff838df13
|
@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
|
|||
import org.apache.hadoop.hbase.HRegionInfo;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.NamespaceDescriptor;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceStability;
|
||||
|
@ -253,6 +254,37 @@ public interface AsyncAdmin {
|
|||
CompletableFuture<Void> modifyColumnFamily(final TableName tableName,
|
||||
final HColumnDescriptor columnFamily);
|
||||
|
||||
/**
|
||||
* Create a new namespace.
|
||||
* @param descriptor descriptor which describes the new namespace
|
||||
*/
|
||||
CompletableFuture<Void> createNamespace(final NamespaceDescriptor descriptor);
|
||||
|
||||
/**
|
||||
* Modify an existing namespace.
|
||||
* @param descriptor descriptor which describes the new namespace
|
||||
*/
|
||||
CompletableFuture<Void> modifyNamespace(final NamespaceDescriptor descriptor);
|
||||
|
||||
/**
|
||||
* Delete an existing namespace. Only empty namespaces (no tables) can be removed.
|
||||
* @param name namespace name
|
||||
*/
|
||||
CompletableFuture<Void> deleteNamespace(final String name);
|
||||
|
||||
/**
|
||||
* Get a namespace descriptor by name
|
||||
* @param name name of namespace descriptor
|
||||
* @return A descriptor wrapped by a {@link CompletableFuture}.
|
||||
*/
|
||||
CompletableFuture<NamespaceDescriptor> getNamespaceDescriptor(final String name);
|
||||
|
||||
/**
|
||||
* List available namespace descriptors
|
||||
* @return List of descriptors wrapped by a {@link CompletableFuture}.
|
||||
*/
|
||||
CompletableFuture<NamespaceDescriptor[]> listNamespaceDescriptors();
|
||||
|
||||
/**
|
||||
* Turn the load balancer on or off.
|
||||
* @param on
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.apache.hadoop.hbase.MetaTableAccessor;
|
|||
import org.apache.hadoop.hbase.NotServingRegionException;
|
||||
import org.apache.hadoop.hbase.RegionLocations;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.NamespaceDescriptor;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.AsyncMetaTableAccessor;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
|
@ -60,12 +61,18 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AddColumnR
|
|||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AddColumnResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.BalanceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.BalanceResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateNamespaceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateNamespaceResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteNamespaceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteNamespaceResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DisableTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DisableTableResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableTableResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteColumnRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteColumnResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetNamespaceDescriptorRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetNamespaceDescriptorResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedureResultRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedureResultResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest;
|
||||
|
@ -80,9 +87,13 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteTabl
|
|||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteTableResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsBalancerEnabledRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsBalancerEnabledResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MasterService;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyColumnRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyColumnResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyNamespaceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyNamespaceResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetBalancerRunningRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetBalancerRunningResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.TruncateTableRequest;
|
||||
|
@ -208,7 +219,7 @@ public class AsyncHBaseAdmin implements AsyncAdmin {
|
|||
|
||||
private <PREQ, PRESP> CompletableFuture<Void> procedureCall(PREQ preq,
|
||||
MasterRpcCall<PRESP, PREQ> rpcCall, Converter<Long, PRESP> respConverter,
|
||||
TableProcedureBiConsumer consumer) {
|
||||
ProcedureBiConsumer consumer) {
|
||||
CompletableFuture<Long> procFuture = this
|
||||
.<Long> newMasterCaller()
|
||||
.action(
|
||||
|
@ -467,6 +478,54 @@ public class AsyncHBaseAdmin implements AsyncAdmin {
|
|||
(resp) -> resp.getProcId(), new ModifyColumnFamilyProcedureBiConsumer(this, tableName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createNamespace(NamespaceDescriptor descriptor) {
|
||||
return this.<CreateNamespaceRequest, CreateNamespaceResponse> procedureCall(
|
||||
RequestConverter.buildCreateNamespaceRequest(descriptor),
|
||||
(s, c, req, done) -> s.createNamespace(c, req, done), (resp) -> resp.getProcId(),
|
||||
new CreateNamespaceProcedureBiConsumer(this, descriptor.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> modifyNamespace(NamespaceDescriptor descriptor) {
|
||||
return this.<ModifyNamespaceRequest, ModifyNamespaceResponse> procedureCall(
|
||||
RequestConverter.buildModifyNamespaceRequest(descriptor),
|
||||
(s, c, req, done) -> s.modifyNamespace(c, req, done), (resp) -> resp.getProcId(),
|
||||
new ModifyNamespaceProcedureBiConsumer(this, descriptor.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteNamespace(String name) {
|
||||
return this.<DeleteNamespaceRequest, DeleteNamespaceResponse> procedureCall(
|
||||
RequestConverter.buildDeleteNamespaceRequest(name),
|
||||
(s, c, req, done) -> s.deleteNamespace(c, req, done), (resp) -> resp.getProcId(),
|
||||
new ModifyNamespaceProcedureBiConsumer(this, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<NamespaceDescriptor> getNamespaceDescriptor(String name) {
|
||||
return this
|
||||
.<NamespaceDescriptor> newMasterCaller()
|
||||
.action(
|
||||
(controller, stub) -> this
|
||||
.<GetNamespaceDescriptorRequest, GetNamespaceDescriptorResponse, NamespaceDescriptor> call(
|
||||
controller, stub, RequestConverter.buildGetNamespaceDescriptorRequest(name), (s, c,
|
||||
req, done) -> s.getNamespaceDescriptor(c, req, done), (resp) -> ProtobufUtil
|
||||
.toNamespaceDescriptor(resp.getNamespaceDescriptor()))).call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<NamespaceDescriptor[]> listNamespaceDescriptors() {
|
||||
return this
|
||||
.<NamespaceDescriptor[]> newMasterCaller()
|
||||
.action(
|
||||
(controller, stub) -> this
|
||||
.<ListNamespaceDescriptorsRequest, ListNamespaceDescriptorsResponse, NamespaceDescriptor[]> call(
|
||||
controller, stub, ListNamespaceDescriptorsRequest.newBuilder().build(), (s, c, req,
|
||||
done) -> s.listNamespaceDescriptors(c, req, done), (resp) -> ProtobufUtil
|
||||
.getNamespaceDescriptorArray(resp))).call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> setBalancerRunning(final boolean on) {
|
||||
return this
|
||||
|
@ -674,6 +733,31 @@ public class AsyncHBaseAdmin implements AsyncAdmin {
|
|||
}
|
||||
}
|
||||
|
||||
private abstract class NamespaceProcedureBiConsumer extends ProcedureBiConsumer {
|
||||
protected final String namespaceName;
|
||||
|
||||
NamespaceProcedureBiConsumer(final AsyncAdmin admin, final String namespaceName) {
|
||||
super(admin);
|
||||
this.namespaceName = namespaceName;
|
||||
}
|
||||
|
||||
abstract String getOperationType();
|
||||
|
||||
String getDescription() {
|
||||
return "Operation: " + getOperationType() + ", Namespace: " + namespaceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
void onFinished() {
|
||||
LOG.info(getDescription() + " completed");
|
||||
}
|
||||
|
||||
@Override
|
||||
void onError(Throwable error) {
|
||||
LOG.info(getDescription() + " failed with " + error.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private class CreateTableProcedureBiConsumer extends TableProcedureBiConsumer {
|
||||
|
||||
CreateTableProcedureBiConsumer(AsyncAdmin admin, TableName tableName) {
|
||||
|
@ -768,6 +852,39 @@ public class AsyncHBaseAdmin implements AsyncAdmin {
|
|||
}
|
||||
}
|
||||
|
||||
private class CreateNamespaceProcedureBiConsumer extends NamespaceProcedureBiConsumer {
|
||||
|
||||
CreateNamespaceProcedureBiConsumer(AsyncAdmin admin, String namespaceName) {
|
||||
super(admin, namespaceName);
|
||||
}
|
||||
|
||||
String getOperationType() {
|
||||
return "CREATE_NAMESPACE";
|
||||
}
|
||||
}
|
||||
|
||||
private class DeleteNamespaceProcedureBiConsumer extends NamespaceProcedureBiConsumer {
|
||||
|
||||
DeleteNamespaceProcedureBiConsumer(AsyncAdmin admin, String namespaceName) {
|
||||
super(admin, namespaceName);
|
||||
}
|
||||
|
||||
String getOperationType() {
|
||||
return "DELETE_NAMESPACE";
|
||||
}
|
||||
}
|
||||
|
||||
private class ModifyNamespaceProcedureBiConsumer extends NamespaceProcedureBiConsumer {
|
||||
|
||||
ModifyNamespaceProcedureBiConsumer(AsyncAdmin admin, String namespaceName) {
|
||||
super(admin, namespaceName);
|
||||
}
|
||||
|
||||
String getOperationType() {
|
||||
return "MODIFY_NAMESPACE";
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> waitProcedureResult(CompletableFuture<Long> procFuture) {
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
procFuture.whenComplete((procId, error) -> {
|
||||
|
|
|
@ -114,6 +114,10 @@ public abstract class AsyncRpcRetryingCaller<T> {
|
|||
protected void onError(Throwable error, Supplier<String> errMsg,
|
||||
Consumer<Throwable> updateCachedLocation) {
|
||||
error = translateException(error);
|
||||
if (error instanceof DoNotRetryIOException) {
|
||||
future.completeExceptionally(error);
|
||||
return;
|
||||
}
|
||||
if (tries > startLogErrorsCnt) {
|
||||
LOG.warn(errMsg.get() + ", tries = " + tries + ", maxAttempts = " + maxAttempts
|
||||
+ ", timeout = " + TimeUnit.NANOSECONDS.toMillis(operationTimeoutNs)
|
||||
|
@ -122,7 +126,7 @@ public abstract class AsyncRpcRetryingCaller<T> {
|
|||
RetriesExhaustedException.ThrowableWithExtraContext qt = new RetriesExhaustedException.ThrowableWithExtraContext(
|
||||
error, EnvironmentEdgeManager.currentTime(), "");
|
||||
exceptions.add(qt);
|
||||
if (error instanceof DoNotRetryIOException || tries >= maxAttempts) {
|
||||
if (tries >= maxAttempts) {
|
||||
completeExceptionally();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MapReduceProtos;
|
|||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsResponse;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerReportRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest;
|
||||
|
@ -393,6 +395,21 @@ public final class ProtobufUtil {
|
|||
return ServerName.valueOf(hostName, port, startCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NamespaceDescriptor[] from ListNamespaceDescriptorsResponse protobuf
|
||||
* @param proto the ListNamespaceDescriptorsResponse
|
||||
* @return NamespaceDescriptor[]
|
||||
*/
|
||||
public static NamespaceDescriptor[] getNamespaceDescriptorArray(
|
||||
ListNamespaceDescriptorsResponse proto) {
|
||||
List<HBaseProtos.NamespaceDescriptor> list = proto.getNamespaceDescriptorList();
|
||||
NamespaceDescriptor[] res = new NamespaceDescriptor[list.size()];
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
res[i] = ProtobufUtil.toNamespaceDescriptor(list.get(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTableDescriptor[] from GetTableDescriptorsResponse protobuf
|
||||
*
|
||||
|
@ -2136,10 +2153,8 @@ public final class ProtobufUtil {
|
|||
return b.build();
|
||||
}
|
||||
|
||||
public static NamespaceDescriptor toNamespaceDescriptor(
|
||||
HBaseProtos.NamespaceDescriptor desc) throws IOException {
|
||||
NamespaceDescriptor.Builder b =
|
||||
NamespaceDescriptor.create(desc.getName().toStringUtf8());
|
||||
public static NamespaceDescriptor toNamespaceDescriptor(HBaseProtos.NamespaceDescriptor desc) {
|
||||
NamespaceDescriptor.Builder b = NamespaceDescriptor.create(desc.getName().toStringUtf8());
|
||||
for (HBaseProtos.NameStringPair prop : desc.getConfigurationList()) {
|
||||
b.addConfiguration(prop.getName(), prop.getValue());
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.hadoop.hbase.HColumnDescriptor;
|
|||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.HRegionInfo;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.NamespaceDescriptor;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.classification.InterfaceAudience;
|
||||
|
@ -80,11 +81,15 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos;
|
|||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AddColumnRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AssignRegionRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.BalanceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateNamespaceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteColumnRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteNamespaceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DeleteTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.DisableTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableCatalogJanitorRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetNamespaceDescriptorRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ModifyNamespaceRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetCleanerChoreRunningRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.EnableTableRequest;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetClusterStatusRequest;
|
||||
|
@ -1644,4 +1649,50 @@ public final class RequestConverter {
|
|||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a protocol buffer CreateNamespaceRequest
|
||||
* @param descriptor
|
||||
* @return a CreateNamespaceRequest
|
||||
*/
|
||||
public static CreateNamespaceRequest buildCreateNamespaceRequest(
|
||||
final NamespaceDescriptor descriptor) {
|
||||
CreateNamespaceRequest.Builder builder = CreateNamespaceRequest.newBuilder();
|
||||
builder.setNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor(descriptor));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a protocol buffer ModifyNamespaceRequest
|
||||
* @param descriptor
|
||||
* @return a ModifyNamespaceRequest
|
||||
*/
|
||||
public static ModifyNamespaceRequest buildModifyNamespaceRequest(
|
||||
final NamespaceDescriptor descriptor) {
|
||||
ModifyNamespaceRequest.Builder builder = ModifyNamespaceRequest.newBuilder();
|
||||
builder.setNamespaceDescriptor(ProtobufUtil.toProtoNamespaceDescriptor(descriptor));
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a protocol buffer DeleteNamespaceRequest
|
||||
* @param name
|
||||
* @return a DeleteNamespaceRequest
|
||||
*/
|
||||
public static DeleteNamespaceRequest buildDeleteNamespaceRequest(final String name) {
|
||||
DeleteNamespaceRequest.Builder builder = DeleteNamespaceRequest.newBuilder();
|
||||
builder.setNamespaceName(name);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a protocol buffer GetNamespaceDescriptorRequest
|
||||
* @param name
|
||||
* @return a GetNamespaceDescriptorRequest
|
||||
*/
|
||||
public static GetNamespaceDescriptorRequest buildGetNamespaceDescriptorRequest(final String name) {
|
||||
GetNamespaceDescriptorRequest.Builder builder = GetNamespaceDescriptorRequest.newBuilder();
|
||||
builder.setNamespaceName(name);
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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.client;
|
||||
|
||||
import static org.apache.hadoop.hbase.client.AsyncProcess.START_LOG_ERRORS_AFTER_COUNT_KEY;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
* Class to test AsyncAdmin.
|
||||
*/
|
||||
public abstract class TestAsyncAdminBase {
|
||||
|
||||
protected static final Log LOG = LogFactory.getLog(TestAdmin1.class);
|
||||
protected final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
|
||||
protected static byte[] FAMILY = Bytes.toBytes("testFamily");
|
||||
protected static final byte[] FAMILY_0 = Bytes.toBytes("cf0");
|
||||
protected static final byte[] FAMILY_1 = Bytes.toBytes("cf1");
|
||||
|
||||
protected static AsyncConnection ASYNC_CONN;
|
||||
protected AsyncAdmin admin;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_PAUSE, 10);
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1000);
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, 3000);
|
||||
TEST_UTIL.getConfiguration().setInt(START_LOG_ERRORS_AFTER_COUNT_KEY, 0);
|
||||
TEST_UTIL.startMiniCluster(1);
|
||||
ASYNC_CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
IOUtils.closeQuietly(ASYNC_CONN);
|
||||
TEST_UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.admin = ASYNC_CONN.getAdmin();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* 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.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.apache.hadoop.hbase.testclassification.ClientTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
@Category({ MediumTests.class, ClientTests.class })
|
||||
public class TestAsyncBalancerAdminApi extends TestAsyncAdminBase {
|
||||
|
||||
@Test
|
||||
public void testBalancer() throws Exception {
|
||||
boolean initialState = admin.isBalancerEnabled().get();
|
||||
|
||||
// Start the balancer, wait for it.
|
||||
boolean prevState = admin.setBalancerRunning(!initialState).get();
|
||||
|
||||
// The previous state should be the original state we observed
|
||||
assertEquals(initialState, prevState);
|
||||
|
||||
// Current state should be opposite of the original
|
||||
assertEquals(!initialState, admin.isBalancerEnabled().get());
|
||||
|
||||
// Reset it back to what it was
|
||||
prevState = admin.setBalancerRunning(initialState).get();
|
||||
|
||||
// The previous state should be the opposite of the initial state
|
||||
assertEquals(!initialState, prevState);
|
||||
// Current state should be the original state again
|
||||
assertEquals(initialState, admin.isBalancerEnabled().get());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
/**
|
||||
* 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.client;
|
||||
|
||||
import static org.apache.hadoop.hbase.client.AsyncProcess.START_LOG_ERRORS_AFTER_COUNT_KEY;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.MiniHBaseCluster;
|
||||
import org.apache.hadoop.hbase.NamespaceDescriptor;
|
||||
import org.apache.hadoop.hbase.NamespaceExistException;
|
||||
import org.apache.hadoop.hbase.NamespaceNotFoundException;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.Waiter;
|
||||
import org.apache.hadoop.hbase.ZKNamespaceManager;
|
||||
import org.apache.hadoop.hbase.master.HMaster;
|
||||
import org.apache.hadoop.hbase.testclassification.ClientTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
/**
|
||||
* Class to test asynchronous namespace admin operations.
|
||||
*/
|
||||
@Category({ MediumTests.class, ClientTests.class })
|
||||
public class TestAsyncNamespaceAdminApi extends TestAsyncAdminBase {
|
||||
|
||||
private String prefix = "TestNamespace";
|
||||
private static HMaster master;
|
||||
private static ZKNamespaceManager zkNamespaceManager;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
TEST_UTIL.getConfiguration().setInt(START_LOG_ERRORS_AFTER_COUNT_KEY, 0);
|
||||
TEST_UTIL.startMiniCluster(1);
|
||||
ASYNC_CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
|
||||
master = ((MiniHBaseCluster) TEST_UTIL.getHBaseCluster()).getMaster();
|
||||
zkNamespaceManager = new ZKNamespaceManager(master.getZooKeeper());
|
||||
zkNamespaceManager.start();
|
||||
LOG.info("Done initializing cluster");
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
public void testCreateAndDelete() throws Exception {
|
||||
String testName = "testCreateAndDelete";
|
||||
String nsName = prefix + "_" + testName;
|
||||
|
||||
// create namespace and verify
|
||||
admin.createNamespace(NamespaceDescriptor.create(nsName).build()).join();
|
||||
assertEquals(3, admin.listNamespaceDescriptors().get().length);
|
||||
TEST_UTIL.waitFor(60000, new Waiter.Predicate<Exception>() {
|
||||
@Override
|
||||
public boolean evaluate() throws Exception {
|
||||
return zkNamespaceManager.list().size() == 3;
|
||||
}
|
||||
});
|
||||
assertNotNull(zkNamespaceManager.get(nsName));
|
||||
// delete namespace and verify
|
||||
admin.deleteNamespace(nsName).join();
|
||||
assertEquals(2, admin.listNamespaceDescriptors().get().length);
|
||||
assertEquals(2, zkNamespaceManager.list().size());
|
||||
assertNull(zkNamespaceManager.get(nsName));
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
public void testDeleteReservedNS() throws Exception {
|
||||
boolean exceptionCaught = false;
|
||||
try {
|
||||
admin.deleteNamespace(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR).join();
|
||||
} catch (Exception exp) {
|
||||
LOG.warn(exp);
|
||||
exceptionCaught = true;
|
||||
} finally {
|
||||
assertTrue(exceptionCaught);
|
||||
}
|
||||
|
||||
try {
|
||||
admin.deleteNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR).join();
|
||||
} catch (Exception exp) {
|
||||
LOG.warn(exp);
|
||||
exceptionCaught = true;
|
||||
} finally {
|
||||
assertTrue(exceptionCaught);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 60000)
|
||||
public void testNamespaceOperations() throws Exception {
|
||||
admin.createNamespace(NamespaceDescriptor.create(prefix + "ns1").build()).join();
|
||||
admin.createNamespace(NamespaceDescriptor.create(prefix + "ns2").build()).join();
|
||||
|
||||
// create namespace that already exists
|
||||
runWithExpectedException(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
admin.createNamespace(NamespaceDescriptor.create(prefix + "ns1").build()).join();
|
||||
return null;
|
||||
}
|
||||
}, NamespaceExistException.class);
|
||||
|
||||
// create a table in non-existing namespace
|
||||
runWithExpectedException(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("non_existing_namespace",
|
||||
"table1"));
|
||||
htd.addFamily(new HColumnDescriptor("family1"));
|
||||
admin.createTable(htd).join();
|
||||
return null;
|
||||
}
|
||||
}, NamespaceNotFoundException.class);
|
||||
|
||||
// get descriptor for existing namespace
|
||||
NamespaceDescriptor ns1 = admin.getNamespaceDescriptor(prefix + "ns1").get();
|
||||
assertEquals(prefix + "ns1", ns1.getName());
|
||||
|
||||
// get descriptor for non-existing namespace
|
||||
runWithExpectedException(new Callable<NamespaceDescriptor>() {
|
||||
@Override
|
||||
public NamespaceDescriptor call() throws Exception {
|
||||
return admin.getNamespaceDescriptor("non_existing_namespace").get();
|
||||
}
|
||||
}, NamespaceNotFoundException.class);
|
||||
|
||||
// delete descriptor for existing namespace
|
||||
admin.deleteNamespace(prefix + "ns2").join();
|
||||
|
||||
// delete descriptor for non-existing namespace
|
||||
runWithExpectedException(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
admin.deleteNamespace("non_existing_namespace").join();
|
||||
return null;
|
||||
}
|
||||
}, NamespaceNotFoundException.class);
|
||||
|
||||
// modify namespace descriptor for existing namespace
|
||||
ns1 = admin.getNamespaceDescriptor(prefix + "ns1").get();
|
||||
ns1.setConfiguration("foo", "bar");
|
||||
admin.modifyNamespace(ns1).join();
|
||||
ns1 = admin.getNamespaceDescriptor(prefix + "ns1").get();
|
||||
assertEquals("bar", ns1.getConfigurationValue("foo"));
|
||||
|
||||
// modify namespace descriptor for non-existing namespace
|
||||
runWithExpectedException(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
admin.modifyNamespace(NamespaceDescriptor.create("non_existing_namespace").build()).join();
|
||||
return null;
|
||||
}
|
||||
}, NamespaceNotFoundException.class);
|
||||
|
||||
admin.deleteNamespace(prefix + "ns1").join();
|
||||
}
|
||||
|
||||
private static <V, E> void runWithExpectedException(Callable<V> callable, Class<E> exceptionClass) {
|
||||
try {
|
||||
callable.call();
|
||||
} catch (Exception ex) {
|
||||
LOG.info("Get exception is " + ex);
|
||||
assertEquals(exceptionClass, ex.getCause().getClass());
|
||||
return;
|
||||
}
|
||||
fail("Should have thrown exception " + exceptionClass);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
* 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.client;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.HRegionInfo;
|
||||
import org.apache.hadoop.hbase.HRegionLocation;
|
||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.regionserver.HRegionServer;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.ClientTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.Pair;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
/**
|
||||
* Class to test asynchronous region admin operations.
|
||||
*/
|
||||
@Category({ MediumTests.class, ClientTests.class })
|
||||
public class TestAsyncRegionAdminApi extends TestAsyncAdminBase {
|
||||
|
||||
private void createTableWithDefaultConf(TableName TABLENAME) throws Exception {
|
||||
HTableDescriptor htd = new HTableDescriptor(TABLENAME);
|
||||
HColumnDescriptor hcd = new HColumnDescriptor("value");
|
||||
htd.addFamily(hcd);
|
||||
|
||||
admin.createTable(htd, null).get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegion() throws Exception {
|
||||
TableName TABLENAME = TableName.valueOf("TestHBACloseRegion");
|
||||
createTableWithDefaultConf(TABLENAME);
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.getTable().isSystemTable()) {
|
||||
info = regionInfo;
|
||||
boolean closed = admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
|
||||
rs.getServerName().getServerName()).get();
|
||||
assertTrue(closed);
|
||||
}
|
||||
}
|
||||
boolean isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
|
||||
long timeout = System.currentTimeMillis() + 10000;
|
||||
while ((System.currentTimeMillis() < timeout) && (isInList)) {
|
||||
Thread.sleep(100);
|
||||
isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
|
||||
}
|
||||
|
||||
assertFalse("The region should not be present in online regions list.", isInList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
|
||||
final String name = "TestHBACloseRegion1";
|
||||
byte[] TABLENAME = Bytes.toBytes(name);
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString().contains(name)) {
|
||||
info = regionInfo;
|
||||
boolean catchNotServingException = false;
|
||||
try {
|
||||
admin.closeRegionWithEncodedRegionName("sample", rs.getServerName().getServerName())
|
||||
.get();
|
||||
} catch (Exception e) {
|
||||
catchNotServingException = true;
|
||||
// expected, ignore it
|
||||
}
|
||||
assertTrue(catchNotServingException);
|
||||
}
|
||||
}
|
||||
}
|
||||
onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
assertTrue("The region should be present in online regions list.",
|
||||
onlineRegions.contains(info));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionWhenServerNameIsNull() throws Exception {
|
||||
byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3");
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
|
||||
try {
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion3")) {
|
||||
admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), null).get();
|
||||
}
|
||||
}
|
||||
}
|
||||
fail("The test should throw exception if the servername passed is null.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionWhenServerNameIsEmpty() throws Exception {
|
||||
byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty");
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
|
||||
try {
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString()
|
||||
.contains("TestHBACloseRegionWhenServerNameIsEmpty")) {
|
||||
admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), " ").get();
|
||||
}
|
||||
}
|
||||
}
|
||||
fail("The test should throw exception if the servername passed is empty.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception {
|
||||
byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4");
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) {
|
||||
info = regionInfo;
|
||||
boolean catchNotServingException = false;
|
||||
try {
|
||||
admin.closeRegionWithEncodedRegionName(regionInfo.getRegionNameAsString(),
|
||||
rs.getServerName().getServerName()).get();
|
||||
} catch (Exception e) {
|
||||
// expected, ignore it.
|
||||
catchNotServingException = true;
|
||||
}
|
||||
assertTrue(catchNotServingException);
|
||||
}
|
||||
}
|
||||
}
|
||||
onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
assertTrue("The region should be present in online regions list.",
|
||||
onlineRegions.contains(info));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRegion() throws Exception {
|
||||
AsyncHBaseAdmin rawAdmin = (AsyncHBaseAdmin) admin;
|
||||
|
||||
final TableName tableName = TableName.valueOf("testGetRegion");
|
||||
LOG.info("Started " + tableName);
|
||||
TEST_UTIL.createMultiRegionTable(tableName, HConstants.CATALOG_FAMILY);
|
||||
|
||||
try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
|
||||
HRegionLocation regionLocation = locator.getRegionLocation(Bytes.toBytes("mmm"));
|
||||
HRegionInfo region = regionLocation.getRegionInfo();
|
||||
byte[] regionName = region.getRegionName();
|
||||
Pair<HRegionInfo, ServerName> pair = rawAdmin.getRegion(regionName).get();
|
||||
assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
|
||||
pair = rawAdmin.getRegion(region.getEncodedNameAsBytes()).get();
|
||||
assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,11 +17,9 @@
|
|||
*/
|
||||
package org.apache.hadoop.hbase.client;
|
||||
|
||||
import static org.apache.hadoop.hbase.client.AsyncProcess.START_LOG_ERRORS_AFTER_COUNT_KEY;
|
||||
import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -36,12 +34,8 @@ import java.util.Set;
|
|||
import java.util.concurrent.CompletionException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.hbase.AsyncMetaTableAccessor;
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HColumnDescriptor;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.HRegionInfo;
|
||||
|
@ -51,63 +45,26 @@ import org.apache.hadoop.hbase.ServerName;
|
|||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.TableNotEnabledException;
|
||||
import org.apache.hadoop.hbase.master.MasterFileSystem;
|
||||
import org.apache.hadoop.hbase.regionserver.HRegionServer;
|
||||
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
|
||||
import org.apache.hadoop.hbase.testclassification.ClientTests;
|
||||
import org.apache.hadoop.hbase.testclassification.LargeTests;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.FSTableDescriptors;
|
||||
import org.apache.hadoop.hbase.util.FSUtils;
|
||||
import org.apache.hadoop.hbase.util.Pair;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.junit.rules.TestName;
|
||||
|
||||
/**
|
||||
* Class to test AsyncAdmin.
|
||||
* Class to test asynchronous table admin operations.
|
||||
*/
|
||||
@Category({LargeTests.class, ClientTests.class})
|
||||
public class TestAsyncAdmin {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(TestAdmin1.class);
|
||||
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
|
||||
private static byte[] FAMILY = Bytes.toBytes("testFamily");
|
||||
private static final byte[] FAMILY_0 = Bytes.toBytes("cf0");
|
||||
private static final byte[] FAMILY_1 = Bytes.toBytes("cf1");
|
||||
|
||||
private static AsyncConnection ASYNC_CONN;
|
||||
private AsyncAdmin admin;
|
||||
public class TestAsyncTableAdminApi extends TestAsyncAdminBase {
|
||||
|
||||
@Rule
|
||||
public TestName name = new TestName();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_PAUSE, 10);
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1000);
|
||||
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, 3000);
|
||||
TEST_UTIL.getConfiguration().setInt(START_LOG_ERRORS_AFTER_COUNT_KEY, 0);
|
||||
TEST_UTIL.startMiniCluster(1);
|
||||
ASYNC_CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
IOUtils.closeQuietly(ASYNC_CONN);
|
||||
TEST_UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.admin = ASYNC_CONN.getAdmin();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableExist() throws Exception {
|
||||
final TableName tableName = TableName.valueOf(name.getMethodName());
|
||||
|
@ -200,7 +157,7 @@ public class TestAsyncAdmin {
|
|||
|
||||
private TableState.State getStateFromMeta(TableName table) throws Exception {
|
||||
Optional<TableState> state = AsyncMetaTableAccessor.getTableState(
|
||||
ASYNC_CONN.getRawTable(META_TABLE_NAME), table).get();
|
||||
ASYNC_CONN.getRawTable(TableName.META_TABLE_NAME), table).get();
|
||||
assertTrue(state.isPresent());
|
||||
return state.get().getState();
|
||||
}
|
||||
|
@ -878,210 +835,4 @@ public class TestAsyncAdmin {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 30000)
|
||||
public void testBalancer() throws Exception {
|
||||
boolean initialState = admin.isBalancerEnabled().get();
|
||||
|
||||
// Start the balancer, wait for it.
|
||||
boolean prevState = admin.setBalancerRunning(!initialState).get();
|
||||
|
||||
// The previous state should be the original state we observed
|
||||
assertEquals(initialState, prevState);
|
||||
|
||||
// Current state should be opposite of the original
|
||||
assertEquals(!initialState, admin.isBalancerEnabled().get());
|
||||
|
||||
// Reset it back to what it was
|
||||
prevState = admin.setBalancerRunning(initialState).get();
|
||||
|
||||
// The previous state should be the opposite of the initial state
|
||||
assertEquals(!initialState, prevState);
|
||||
// Current state should be the original state again
|
||||
assertEquals(initialState, admin.isBalancerEnabled().get());
|
||||
}
|
||||
|
||||
private void createTableWithDefaultConf(TableName TABLENAME) throws Exception {
|
||||
HTableDescriptor htd = new HTableDescriptor(TABLENAME);
|
||||
HColumnDescriptor hcd = new HColumnDescriptor("value");
|
||||
htd.addFamily(hcd);
|
||||
|
||||
admin.createTable(htd, null).get();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegion() throws Exception {
|
||||
TableName TABLENAME = TableName.valueOf("TestHBACloseRegion");
|
||||
createTableWithDefaultConf(TABLENAME);
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.getTable().isSystemTable()) {
|
||||
info = regionInfo;
|
||||
boolean closed = admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
|
||||
rs.getServerName().getServerName()).get();
|
||||
assertTrue(closed);
|
||||
}
|
||||
}
|
||||
boolean isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
|
||||
long timeout = System.currentTimeMillis() + 10000;
|
||||
while ((System.currentTimeMillis() < timeout) && (isInList)) {
|
||||
Thread.sleep(100);
|
||||
isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
|
||||
}
|
||||
|
||||
assertFalse("The region should not be present in online regions list.", isInList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
|
||||
final String name = "TestHBACloseRegion1";
|
||||
byte[] TABLENAME = Bytes.toBytes(name);
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString().contains(name)) {
|
||||
info = regionInfo;
|
||||
boolean catchNotServingException = false;
|
||||
try {
|
||||
admin.closeRegionWithEncodedRegionName("sample", rs.getServerName().getServerName())
|
||||
.get();
|
||||
} catch (Exception e) {
|
||||
catchNotServingException = true;
|
||||
// expected, ignore it
|
||||
}
|
||||
assertTrue(catchNotServingException);
|
||||
}
|
||||
}
|
||||
}
|
||||
onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
assertTrue("The region should be present in online regions list.",
|
||||
onlineRegions.contains(info));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
|
||||
TableName TABLENAME = TableName.valueOf("TestHBACloseRegion2");
|
||||
createTableWithDefaultConf(TABLENAME);
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
|
||||
if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion2")) {
|
||||
info = regionInfo;
|
||||
admin.closeRegion(regionInfo.getRegionNameAsString(), rs.getServerName().getServerName())
|
||||
.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
|
||||
long timeout = System.currentTimeMillis() + 10000;
|
||||
while ((System.currentTimeMillis() < timeout) && (isInList)) {
|
||||
Thread.sleep(100);
|
||||
isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
|
||||
}
|
||||
|
||||
assertFalse("The region should not be present in online regions list.", isInList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionWhenServerNameIsNull() throws Exception {
|
||||
byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3");
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
|
||||
try {
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion3")) {
|
||||
admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), null).get();
|
||||
}
|
||||
}
|
||||
}
|
||||
fail("The test should throw exception if the servername passed is null.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionWhenServerNameIsEmpty() throws Exception {
|
||||
byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty");
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
|
||||
try {
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString()
|
||||
.contains("TestHBACloseRegionWhenServerNameIsEmpty")) {
|
||||
admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), " ").get();
|
||||
}
|
||||
}
|
||||
}
|
||||
fail("The test should throw exception if the servername passed is empty.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception {
|
||||
byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4");
|
||||
createTableWithDefaultConf(TableName.valueOf(TABLENAME));
|
||||
|
||||
HRegionInfo info = null;
|
||||
HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(TABLENAME));
|
||||
|
||||
List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
for (HRegionInfo regionInfo : onlineRegions) {
|
||||
if (!regionInfo.isMetaTable()) {
|
||||
if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) {
|
||||
info = regionInfo;
|
||||
boolean catchNotServingException = false;
|
||||
try {
|
||||
admin.closeRegionWithEncodedRegionName(regionInfo.getRegionNameAsString(),
|
||||
rs.getServerName().getServerName()).get();
|
||||
} catch (Exception e) {
|
||||
// expected, ignore it.
|
||||
catchNotServingException = true;
|
||||
}
|
||||
assertTrue(catchNotServingException);
|
||||
}
|
||||
}
|
||||
}
|
||||
onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
|
||||
assertTrue("The region should be present in online regions list.",
|
||||
onlineRegions.contains(info));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRegion() throws Exception {
|
||||
AsyncHBaseAdmin rawAdmin = (AsyncHBaseAdmin) admin;
|
||||
|
||||
final TableName tableName = TableName.valueOf("testGetRegion");
|
||||
LOG.info("Started " + tableName);
|
||||
TEST_UTIL.createMultiRegionTable(tableName, HConstants.CATALOG_FAMILY);
|
||||
|
||||
try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
|
||||
HRegionLocation regionLocation = locator.getRegionLocation(Bytes.toBytes("mmm"));
|
||||
HRegionInfo region = regionLocation.getRegionInfo();
|
||||
byte[] regionName = region.getRegionName();
|
||||
Pair<HRegionInfo, ServerName> pair = rawAdmin.getRegion(regionName).get();
|
||||
assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
|
||||
pair = rawAdmin.getRegion(region.getEncodedNameAsBytes()).get();
|
||||
assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue