diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java index b3c8a6aee6bd..e16c21eb2c33 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java @@ -141,6 +141,13 @@ public interface Admin extends Abortable, Closeable { */ List listTableDescriptors() throws IOException; + /** + * List all enabled or disabled tables + * @param isEnabled is true means return enabled tables, false means return disabled tables + * @return a list of enabled or disabled tables + */ + List listTableDescriptorsByState(boolean isEnabled) throws IOException; + /** * List all the userspace tables that match the given pattern. * @param pattern The compiled regular expression to match against @@ -264,6 +271,14 @@ default TableName[] listTableNames(Pattern pattern) throws IOException { @Deprecated TableName[] listTableNames(String regex, boolean includeSysTables) throws IOException; + /** + * List all enabled or disabled table names + * @param isEnabled is true means return enabled table names, false means return disabled table + * names + * @return a list of enabled or disabled table names + */ + List listTableNamesByState(boolean isEnabled) throws IOException; + /** * Get a table descriptor. * @param tableName as a {@link TableName} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java index be8a961ee2ea..361e967b8bcb 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncAdmin.java @@ -106,6 +106,14 @@ CompletableFuture> listTableDescriptors(Pattern pattern, */ CompletableFuture> listTableDescriptorsByNamespace(String name); + /** + * List all enabled or disabled table descriptors + * @param isEnabled is true means return enabled table descriptors, false means return disabled + * table descriptors + * @return a list of table names wrapped by a {@link CompletableFuture}. + */ + CompletableFuture> listTableDescriptorsByState(boolean isEnabled); + /** * List all of the names of userspace tables. * @return a list of table names wrapped by a {@link CompletableFuture}. @@ -137,6 +145,14 @@ default CompletableFuture> listTableNames() { */ CompletableFuture> listTableNamesByNamespace(String name); + /** + * List all enabled or disabled table names + * @param isEnabled is true means return enabled table names, false means return disabled table + * names + * @return a list of table names wrapped by a {@link CompletableFuture}. + */ + CompletableFuture> listTableNamesByState(boolean isEnabled); + /** * Method for getting the tableDescriptor * @param tableName as a {@link TableName} diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java index 925891ff58c2..bf5e2905c3b0 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncHBaseAdmin.java @@ -99,6 +99,11 @@ public CompletableFuture> listTableDescriptorsByNamespace( return wrap(rawAdmin.listTableDescriptorsByNamespace(name)); } + @Override + public CompletableFuture> listTableDescriptorsByState(boolean isEnabled) { + return wrap(rawAdmin.listTableDescriptorsByState(isEnabled)); + } + @Override public CompletableFuture> listTableNames(boolean includeSysTables) { return wrap(rawAdmin.listTableNames(includeSysTables)); @@ -115,6 +120,11 @@ public CompletableFuture> listTableNamesByNamespace(String name) return wrap(rawAdmin.listTableNamesByNamespace(name)); } + @Override + public CompletableFuture> listTableNamesByState(boolean isEnabled) { + return wrap(rawAdmin.listTableNamesByState(isEnabled)); + } + @Override public CompletableFuture getDescriptor(TableName tableName) { return wrap(rawAdmin.getDescriptor(tableName)); diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java index a834da72d28e..a45a4a89dc75 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java @@ -1734,12 +1734,26 @@ public MasterProtos.GetTableDescriptorsResponse getTableDescriptors(RpcControlle return stub.getTableDescriptors(controller, request); } + @Override + public MasterProtos.ListTableDescriptorsByStateResponse listTableDescriptorsByState( + RpcController controller, MasterProtos.ListTableDescriptorsByStateRequest request) + throws ServiceException { + return stub.listTableDescriptorsByState(controller, request); + } + @Override public MasterProtos.GetTableNamesResponse getTableNames(RpcController controller, MasterProtos.GetTableNamesRequest request) throws ServiceException { return stub.getTableNames(controller, request); } + @Override + public MasterProtos.ListTableNamesByStateResponse listTableNamesByState( + RpcController controller, MasterProtos.ListTableNamesByStateRequest request) + throws ServiceException { + return stub.listTableNamesByState(controller, request); + } + @Override public MasterProtos.GetClusterStatusResponse getClusterStatus(RpcController controller, MasterProtos.GetClusterStatusRequest request) throws ServiceException { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index bc6288197b9a..36c8304ecb94 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -190,7 +190,11 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespacesRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampForRegionRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTableRegionsRequest; @@ -343,6 +347,20 @@ public List listTableDescriptors() throws IOException { return listTableDescriptors((Pattern) null, false); } + @Override + public List listTableDescriptorsByState(boolean isEnabled) throws IOException { + return executeCallable( + new MasterCallable>(getConnection(), getRpcControllerFactory()) { + @Override + protected List rpcCall() throws Exception { + ListTableDescriptorsByStateResponse response = + master.listTableDescriptorsByState(getRpcController(), + ListTableDescriptorsByStateRequest.newBuilder().setIsEnabled(isEnabled).build()); + return ProtobufUtil.toTableDescriptorList(response); + } + }); + } + @Override public List listTableDescriptors(Pattern pattern, boolean includeSysTables) throws IOException { @@ -566,6 +584,19 @@ public TableName[] listTableNames(final String regex, final boolean includeSysTa return listTableNames(Pattern.compile(regex), includeSysTables); } + @Override + public List listTableNamesByState(boolean isEnabled) throws IOException { + return executeCallable( + new MasterCallable>(getConnection(), getRpcControllerFactory()) { + @Override + protected List rpcCall() throws Exception { + ListTableNamesByStateResponse response = master.listTableNamesByState(getRpcController(), + ListTableNamesByStateRequest.newBuilder().setIsEnabled(isEnabled).build()); + return ProtobufUtil.toTableNameList(response.getTableNamesList()); + } + }); + } + @Override public HTableDescriptor getTableDescriptor(final TableName tableName) throws IOException { return getHTableDescriptor(tableName, getConnection(), rpcCallerFactory, rpcControllerFactory, diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java index 7970f8f3e111..e2187f8b4e8a 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/RawAsyncHBaseAdmin.java @@ -219,8 +219,12 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespacesResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampForRegionRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampResponse; @@ -550,6 +554,17 @@ ListTableDescriptorsByNamespaceResponse, List> call(controller, .call(); } + @Override + public CompletableFuture> listTableDescriptorsByState(boolean isEnabled) { + return this.> newMasterCaller() + .action((controller, stub) -> this.> call(controller, stub, + ListTableDescriptorsByStateRequest.newBuilder().setIsEnabled(isEnabled).build(), + (s, c, req, done) -> s.listTableDescriptorsByState(c, req, done), + (resp) -> ProtobufUtil.toTableDescriptorList(resp))) + .call(); + } + @Override public CompletableFuture> listTableNamesByNamespace(String name) { return this.> newMasterCaller() @@ -561,6 +576,17 @@ ListTableNamesByNamespaceResponse, List> call(controller, stub, .call(); } + @Override + public CompletableFuture> listTableNamesByState(boolean isEnabled) { + return this.> newMasterCaller() + .action((controller, stub) -> this.> call(controller, stub, + ListTableNamesByStateRequest.newBuilder().setIsEnabled(isEnabled).build(), + (s, c, req, done) -> s.listTableNamesByState(c, req, done), + (resp) -> ProtobufUtil.toTableNameList(resp.getTableNamesList()))) + .call(); + } + @Override public CompletableFuture getDescriptor(TableName tableName) { CompletableFuture future = new CompletableFuture<>(); diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java index 6827700d9f7c..62b9cf16e9d4 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java @@ -117,8 +117,12 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespacesResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampForRegionRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampResponse; @@ -443,12 +447,24 @@ public GetTableNamesResponse getTableNames(RpcController controller, GetTableNam return stub.getTableNames(controller, request); } + @Override + public ListTableNamesByStateResponse listTableNamesByState(RpcController controller, + ListTableNamesByStateRequest request) throws ServiceException { + return stub.listTableNamesByState(controller, request); + } + @Override public GetTableDescriptorsResponse getTableDescriptors(RpcController controller, GetTableDescriptorsRequest request) throws ServiceException { return stub.getTableDescriptors(controller, request); } + @Override + public ListTableDescriptorsByStateResponse listTableDescriptorsByState(RpcController controller, + ListTableDescriptorsByStateRequest request) throws ServiceException { + return stub.listTableDescriptorsByState(controller, request); + } + @Override public SecurityCapabilitiesResponse getSecurityCapabilities(RpcController controller, SecurityCapabilitiesRequest request) throws ServiceException { diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java index 1c1125f6aea5..49e3f85cdc08 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java @@ -195,6 +195,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; @@ -457,6 +458,20 @@ public static List toTableDescriptorList(GetTableDescriptorsRes .collect(Collectors.toList()); } + /** + * Get a list of TableDescriptor from ListTableDescriptorsByNamespaceResponse protobuf + * @param proto the ListTableDescriptorsByNamespaceResponse + * @return a list of TableDescriptor + */ + public static List + toTableDescriptorList(ListTableDescriptorsByStateResponse proto) { + if (proto == null) { + return new ArrayList<>(); + } + return proto.getTableSchemaList().stream().map(ProtobufUtil::toTableDescriptor) + .collect(Collectors.toList()); + } + /** * get the split keys in form "byte [][]" from a CreateTableRequest proto * @param proto the CreateTableRequest diff --git a/hbase-protocol-shaded/src/main/protobuf/Master.proto b/hbase-protocol-shaded/src/main/protobuf/Master.proto index 29fc22d618c8..5e5a44621734 100644 --- a/hbase-protocol-shaded/src/main/protobuf/Master.proto +++ b/hbase-protocol-shaded/src/main/protobuf/Master.proto @@ -511,6 +511,14 @@ message GetTableDescriptorsResponse { repeated TableSchema table_schema = 1; } +message ListTableDescriptorsByStateRequest { + required bool is_enabled = 1; +} + +message ListTableDescriptorsByStateResponse { + repeated TableSchema table_schema = 1; +} + message GetTableNamesRequest { optional string regex = 1; optional bool include_sys_tables = 2 [default=false]; @@ -521,6 +529,14 @@ message GetTableNamesResponse { repeated TableName table_names = 1; } +message ListTableNamesByStateRequest { + required bool is_enabled = 1; +} + +message ListTableNamesByStateResponse { + repeated TableName table_names = 1; +} + message GetTableStateRequest { required TableName table_name = 1; } @@ -769,10 +785,18 @@ service MasterService { rpc GetTableDescriptors(GetTableDescriptorsRequest) returns(GetTableDescriptorsResponse); + /** List all enabled or disabled table descriptors. */ + rpc ListTableDescriptorsByState(ListTableDescriptorsByStateRequest) + returns(ListTableDescriptorsByStateResponse); + /** Get the list of table names. */ rpc GetTableNames(GetTableNamesRequest) returns(GetTableNamesResponse); + /** List all enabled or disabled table names. */ + rpc ListTableNamesByState(ListTableNamesByStateRequest) + returns(ListTableNamesByStateResponse); + /** Return cluster status. */ rpc GetClusterStatus(GetClusterStatusRequest) returns(GetClusterStatusResponse); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java index 437d9d8a07ba..e6244aae026e 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java @@ -253,8 +253,12 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespacesResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByNamespaceResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableNamesByStateResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampForRegionRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MajorCompactionTimestampResponse; @@ -1101,6 +1105,31 @@ public GetTableDescriptorsResponse getTableDescriptors(RpcController c, } } + @Override + public ListTableDescriptorsByStateResponse listTableDescriptorsByState(RpcController controller, + ListTableDescriptorsByStateRequest request) throws ServiceException { + try { + master.checkInitialized(); + List descriptors = master.listTableDescriptors(null, null, null, false); + + ListTableDescriptorsByStateResponse.Builder builder = + ListTableDescriptorsByStateResponse.newBuilder(); + if (descriptors != null && descriptors.size() > 0) { + // Add the table descriptors to the response + TableState.State state = + request.getIsEnabled() ? TableState.State.ENABLED : TableState.State.DISABLED; + for (TableDescriptor htd : descriptors) { + if (master.getTableStateManager().isTableState(htd.getTableName(), state)) { + builder.addTableSchema(ProtobufUtil.toTableSchema(htd)); + } + } + } + return builder.build(); + } catch (IOException ioe) { + throw new ServiceException(ioe); + } + } + /** * Get list of userspace table names * @param controller Unused (set to null). @@ -1130,6 +1159,29 @@ public GetTableNamesResponse getTableNames(RpcController controller, GetTableNam } } + @Override + public ListTableNamesByStateResponse listTableNamesByState(RpcController controller, + ListTableNamesByStateRequest request) throws ServiceException { + try { + master.checkServiceStarted(); + List tableNames = master.listTableNames(null, null, false); + ListTableNamesByStateResponse.Builder builder = ListTableNamesByStateResponse.newBuilder(); + if (tableNames != null && tableNames.size() > 0) { + // Add the disabled table names to the response + TableState.State state = + request.getIsEnabled() ? TableState.State.ENABLED : TableState.State.DISABLED; + for (TableName table : tableNames) { + if (master.getTableStateManager().isTableState(table, state)) { + builder.addTableNames(ProtobufUtil.toProtoTableName(table)); + } + } + } + return builder.build(); + } catch (IOException e) { + throw new ServiceException(e); + } + } + @Override public GetTableStateResponse getTableState(RpcController controller, GetTableStateRequest request) throws ServiceException { diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestListTablesByState.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestListTablesByState.java new file mode 100644 index 000000000000..f545eb9ae94a --- /dev/null +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestListTablesByState.java @@ -0,0 +1,83 @@ +/* + * 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.master; + +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.TableDescriptor; +import org.apache.hadoop.hbase.client.TableDescriptorBuilder; +import org.apache.hadoop.hbase.testclassification.MasterTests; +import org.apache.hadoop.hbase.testclassification.MediumTests; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +@Category({ MasterTests.class, MediumTests.class }) +public class TestListTablesByState { + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestListTablesByState.class); + + private static HBaseTestingUtility UTIL; + private static Admin ADMIN; + private final static int SLAVES = 1; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + UTIL = new HBaseTestingUtility(); + UTIL.startMiniCluster(SLAVES); + ADMIN = UTIL.getAdmin(); + } + + @Test + public void testListTableNamesByState() throws Exception { + TableName testTableName = TableName.valueOf("test"); + TableDescriptor testTableDesc = TableDescriptorBuilder.newBuilder(testTableName).build(); + ADMIN.createTable(testTableDesc); + ADMIN.disableTable(testTableName); + Assert.assertEquals(ADMIN.listTableNamesByState(false).get(0), testTableName); + ADMIN.enableTable(testTableName); + Assert.assertEquals(ADMIN.listTableNamesByState(true).get(0), testTableName); + } + + @Test + public void testListTableDescriptorByState() throws Exception { + TableName testTableName = TableName.valueOf("test"); + TableDescriptor testTableDesc = TableDescriptorBuilder.newBuilder(testTableName).build(); + ADMIN.createTable(testTableDesc); + ADMIN.disableTable(testTableName); + Assert.assertEquals(ADMIN.listTableDescriptorsByState(false).get(0), testTableDesc); + ADMIN.enableTable(testTableName); + Assert.assertEquals(ADMIN.listTableDescriptorsByState(true).get(0), testTableDesc); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + if (ADMIN != null) { + ADMIN.close(); + } + if (UTIL != null) { + UTIL.shutdownMiniCluster(); + } + } +} diff --git a/hbase-shell/src/main/ruby/hbase/admin.rb b/hbase-shell/src/main/ruby/hbase/admin.rb index 42f25111c1a6..a6dcb541c71e 100644 --- a/hbase-shell/src/main/ruby/hbase/admin.rb +++ b/hbase-shell/src/main/ruby/hbase/admin.rb @@ -1812,6 +1812,12 @@ def modify_table_family_sft(tableName, family_bytes, sft) def flush_master_store() @admin.flushMasterStore() end + + #---------------------------------------------------------------------------------------------- + # Returns a list of enable or disabled tables in hbase + def list_tables_by_state(is_enabled) + @admin.listTableNamesByState(is_enabled).map(&:getNameAsString) + end end # rubocop:enable Metrics/ClassLength end diff --git a/hbase-shell/src/main/ruby/shell.rb b/hbase-shell/src/main/ruby/shell.rb index f6b3efd945f1..adb253725404 100644 --- a/hbase-shell/src/main/ruby/shell.rb +++ b/hbase-shell/src/main/ruby/shell.rb @@ -390,6 +390,8 @@ def self.exception_handler(hide_traceback) locate_region list_regions clone_table_schema + list_enabled_tables + list_disabled_tables ], aliases: { 'describe' => ['desc'] diff --git a/hbase-shell/src/main/ruby/shell/commands/list_disabled_tables.rb b/hbase-shell/src/main/ruby/shell/commands/list_disabled_tables.rb new file mode 100644 index 000000000000..2108098b150d --- /dev/null +++ b/hbase-shell/src/main/ruby/shell/commands/list_disabled_tables.rb @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module Shell + module Commands + # list all disabled tables + class ListDisabledTables < Command + def help + <<~EOF + List all disabled tables + Examples: + hbase> list_disabled_tables + EOF + end + + def command + formatter.header(['TABLE']) + + list = admin.list_tables_by_state(false) + list.each do |table| + formatter.row([table]) + end + + formatter.footer(list.size) + list + end + end + end +end diff --git a/hbase-shell/src/main/ruby/shell/commands/list_enabled_tables.rb b/hbase-shell/src/main/ruby/shell/commands/list_enabled_tables.rb new file mode 100644 index 000000000000..d386473a5806 --- /dev/null +++ b/hbase-shell/src/main/ruby/shell/commands/list_enabled_tables.rb @@ -0,0 +1,43 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +module Shell + module Commands + # list all enabled tables + class ListEnabledTables < Command + def help + <<~EOF + List all enabled tables + Examples: + hbase> list_enabled_tables + EOF + end + + def command + formatter.header(['TABLE']) + + list = admin.list_tables_by_state(true) + list.each do |table| + formatter.row([table]) + end + + formatter.footer(list.size) + list + end + end + end +end diff --git a/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestListTablesShell.java b/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestListTablesShell.java new file mode 100644 index 000000000000..b823b6fc3aa7 --- /dev/null +++ b/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestListTablesShell.java @@ -0,0 +1,46 @@ +/* + * 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 org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.testclassification.ClientTests; +import org.apache.hadoop.hbase.testclassification.LargeTests; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.experimental.categories.Category; + +@Category({ ClientTests.class, LargeTests.class }) +public class TestListTablesShell extends AbstractTestShell { + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestListTablesShell.class); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + setUpConfig(); + + TEST_UTIL.startMiniCluster(3); + + setUpJRubyRuntime(); + } + + @Override + protected String getIncludeList() { + return "list_tables_test.rb"; + } +} diff --git a/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java b/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java index b97f7b516b57..47918f68019f 100644 --- a/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java +++ b/hbase-shell/src/test/java/org/apache/hadoop/hbase/client/TestShell.java @@ -32,6 +32,6 @@ public class TestShell extends AbstractTestShell { @Override protected String getExcludeList() { return "replication_admin_test.rb,rsgroup_shell_test.rb,admin_test.rb,table_test.rb," - + "quotas_test.rb,admin2_test.rb"; + + "quotas_test.rb,admin2_test.rb,list_tables_test.rb"; } } diff --git a/hbase-shell/src/test/ruby/shell/list_tables_test.rb b/hbase-shell/src/test/ruby/shell/list_tables_test.rb new file mode 100644 index 000000000000..961e662fa625 --- /dev/null +++ b/hbase-shell/src/test/ruby/shell/list_tables_test.rb @@ -0,0 +1,44 @@ +# 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. +# + +require 'hbase_constants' +require 'hbase_shell' + +# test for list_enabled_tables and list_disabled_tables +class ListTablesTest < Test::Unit::TestCase + def setup + @shell = Shell::Shell.new(::Hbase::Hbase.new($TEST_CLUSTER.getConfiguration)) + end + + define_test 'List enabled tables' do + table = 'test_table1' + family = 'f1' + @shell.command('create', table, family) + assert_equal [table], @shell.command('list_enabled_tables') + @shell.command(:disable, table) + @shell.command(:drop, table) + end + + define_test 'List disabled tables' do + table = 'test_table2' + family = 'f2' + @shell.command('create', table, family) + @shell.command(:disable, table) + assert_equal [table], @shell.command('list_disabled_tables') + @shell.command(:drop, table) + end +end diff --git a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java index 2084467a313f..60cee0945dd8 100644 --- a/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java +++ b/hbase-thrift/src/main/java/org/apache/hadoop/hbase/thrift2/client/ThriftAdmin.java @@ -155,6 +155,11 @@ public List listTableDescriptors() throws IOException { return listTableDescriptors((Pattern) null); } + @Override + public List listTableDescriptorsByState(boolean isEnabled) throws IOException { + throw new NotImplementedException("listTableDescriptorsByState not supported in ThriftAdmin"); + } + @Override public HTableDescriptor[] listTables(Pattern pattern) throws IOException { String regex = (pattern == null ? null : pattern.toString()); @@ -236,6 +241,11 @@ public TableName[] listTableNames(String regex, boolean includeSysTables) throws } } + @Override + public List listTableNamesByState(boolean isEnabled) throws IOException { + throw new NotImplementedException("listTableNamesByState not supported in ThriftAdmin"); + } + @Override public HTableDescriptor getTableDescriptor(TableName tableName) throws TableNotFoundException, IOException {