HBASE-9182. Allow non-admin users to list all table names

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1513703 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew Kyle Purtell 2013-08-14 00:34:30 +00:00
parent cd72d29eae
commit 6d7fdfd108
16 changed files with 2625 additions and 304 deletions

View File

@ -321,6 +321,52 @@ public class HBaseAdmin implements Abortable, Closeable {
return listTables(Pattern.compile(regex));
}
/**
* List all of the names of userspace tables.
* @return String[] table names
* @throws IOException if a remote or network exception occurs
*/
@Deprecated
public String[] getTableNames() throws IOException {
return this.connection.getTableNames();
}
/**
* List all of the names of userspace tables matching the given regular expression.
* @param pattern The regular expression to match against
* @return String[] table names
* @throws IOException if a remote or network exception occurs
*/
@Deprecated
public String[] getTableNames(Pattern pattern) throws IOException {
List<String> matched = new ArrayList<String>();
for (String name: this.connection.getTableNames()) {
if (pattern.matcher(name).matches()) {
matched.add(name);
}
}
return matched.toArray(new String[matched.size()]);
}
/**
* List all of the names of userspace tables matching the given regular expression.
* @param regex The regular expression to match against
* @return String[] table names
* @throws IOException if a remote or network exception occurs
*/
@Deprecated
public String[] getTableNames(String regex) throws IOException {
return getTableNames(Pattern.compile(regex));
}
/**
* List all of the names of userspace tables.
* @return TableName[] table names
* @throws IOException if a remote or network exception occurs
*/
public TableName[] listTableNames() throws IOException {
return this.connection.listTableNames();
}
/**
* Method for getting the tableDescriptor
@ -2155,14 +2201,14 @@ public class HBaseAdmin implements Abortable, Closeable {
* @return A descriptor
* @throws IOException
*/
public HTableDescriptor[] getTableDescriptorsByNamespace(final String name) throws IOException {
public HTableDescriptor[] listTableDescriptorsByNamespace(final String name) throws IOException {
return
executeCallable(new MasterAdminCallable<HTableDescriptor[]>(getConnection()) {
@Override
public HTableDescriptor[] call() throws Exception {
List<TableSchema> list =
masterAdmin.getTableDescriptorsByNamespace(null,
MasterAdminProtos.GetTableDescriptorsByNamespaceRequest.newBuilder()
masterAdmin.listTableDescriptorsByNamespace(null,
MasterAdminProtos.ListTableDescriptorsByNamespaceRequest.newBuilder()
.setNamespaceName(name).build())
.getTableSchemaList();
HTableDescriptor[] res = new HTableDescriptor[list.size()];
@ -2175,6 +2221,31 @@ public class HBaseAdmin implements Abortable, Closeable {
});
}
/**
* Get list of table names by namespace
* @param name namespace name
* @return The list of table names in the namespace
* @throws IOException
*/
public TableName[] listTableNamesByNamespace(final String name) throws IOException {
return
executeCallable(new MasterAdminCallable<TableName[]>(getConnection()) {
@Override
public TableName[] call() throws Exception {
List<HBaseProtos.TableName> tableNames =
masterAdmin.listTableNamesByNamespace(null,
MasterAdminProtos.ListTableNamesByNamespaceRequest.newBuilder()
.setNamespaceName(name).build())
.getTableNameList();
TableName[] result = new TableName[tableNames.size()];
for (int i = 0; i < tableNames.size(); i++) {
result[i] = ProtobufUtil.toTableName(tableNames.get(i));
}
return result;
}
});
}
/**
* Check to see if HBase is running. Throw an exception if not.
* We consider that HBase is running if ZooKeeper and Master are running.
@ -2283,7 +2354,6 @@ public class HBaseAdmin implements Abortable, Closeable {
return getTableDescriptorsByTableName(tableNames);
}
/**
* Roll the log writer. That is, start writing log messages to a new file.
*

View File

@ -220,6 +220,15 @@ public interface HConnection extends Abortable, Closeable {
*/
HTableDescriptor[] listTables() throws IOException;
// This is a bit ugly - We call this getTableNames in 0.94 and the
// successor function, returning TableName, listTableNames in later versions
// because Java polymorphism doesn't consider return value types
@Deprecated
String[] getTableNames() throws IOException;
TableName[] listTableNames() throws IOException;
/**
* @param tableName table name
* @return table metadata

View File

@ -86,9 +86,13 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos
.ListNamespaceDescriptorsRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos
.GetTableDescriptorsByNamespaceResponse;
.ListTableDescriptorsByNamespaceResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos
.GetTableDescriptorsByNamespaceRequest;
.ListTableDescriptorsByNamespaceRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos
.ListTableNamesByNamespaceResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos
.ListTableNamesByNamespaceRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos.AddColumnRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos.AddColumnResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterAdminProtos.AssignRegionRequest;
@ -148,6 +152,8 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetSchemaA
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetSchemaAlterStatusResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableDescriptorsRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableDescriptorsResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableNamesRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableNamesResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.MasterMonitorService;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
@ -2114,8 +2120,14 @@ public class HConnectionManager {
}
@Override
public GetTableDescriptorsByNamespaceResponse getTableDescriptorsByNamespace(RpcController controller, GetTableDescriptorsByNamespaceRequest request) throws ServiceException {
return stub.getTableDescriptorsByNamespace(controller, request);
public ListTableDescriptorsByNamespaceResponse listTableDescriptorsByNamespace(RpcController controller, ListTableDescriptorsByNamespaceRequest request) throws ServiceException {
return stub.listTableDescriptorsByNamespace(controller, request);
}
@Override
public ListTableNamesByNamespaceResponse listTableNamesByNamespace(RpcController controller,
ListTableNamesByNamespaceRequest request) throws ServiceException {
return stub.listTableNamesByNamespace(controller, request);
}
@Override
@ -2159,6 +2171,13 @@ public class HConnectionManager {
return stub.getTableDescriptors(controller, request);
}
@Override
public GetTableNamesResponse getTableNames(
RpcController controller, GetTableNamesRequest request)
throws ServiceException {
return stub.getTableNames(controller, request);
}
@Override
public GetClusterStatusResponse getClusterStatus(
RpcController controller, GetClusterStatusRequest request)
@ -2619,6 +2638,30 @@ public class HConnectionManager {
}
}
@Override
public String[] getTableNames() throws IOException {
TableName[] tableNames = listTableNames();
String result[] = new String[tableNames.length];
for (int i = 0; i < tableNames.length; i++) {
result[i] = tableNames[i].getNameAsString();
}
return result;
}
@Override
public TableName[] listTableNames() throws IOException {
MasterMonitorKeepAliveConnection master = getKeepAliveMasterMonitorService();
try {
return ProtobufUtil.getTableNameArray(master.getTableNames(null,
GetTableNamesRequest.newBuilder().build())
.getTableNamesList());
} catch (ServiceException se) {
throw ProtobufUtil.getRemoteException(se);
} finally {
master.close();
}
}
@Override
public HTableDescriptor[] getHTableDescriptorsByTableName(
List<TableName> tableNames) throws IOException {

View File

@ -163,6 +163,16 @@ public class HConnectionWrapper implements HConnection {
return hconnection.listTables();
}
@Override
public String[] getTableNames() throws IOException {
return hconnection.getTableNames();
}
@Override
public TableName[] listTableNames() throws IOException {
return hconnection.listTableNames();
}
@Override
public HTableDescriptor getHTableDescriptor(TableName tableName) throws IOException {
return hconnection.getHTableDescriptor(tableName);

View File

@ -2251,4 +2251,16 @@ public final class ProtobufUtil {
.setNamespace(ByteString.copyFrom(tableName.getNamespace()))
.setQualifier(ByteString.copyFrom(tableName.getQualifier())).build();
}
public static TableName[] getTableNameArray(List<HBaseProtos.TableName> tableNamesList) {
if (tableNamesList == null) {
return new TableName[0];
}
TableName[] tableNames = new TableName[tableNamesList.size()];
for (int i = 0; i < tableNamesList.size(); i++) {
tableNames[i] = toTableName(tableNamesList.get(i));
}
return tableNames;
}
}

View File

@ -176,14 +176,21 @@ message ListNamespaceDescriptorsResponse {
repeated NamespaceDescriptor namespaceDescriptor = 1;
}
message GetTableDescriptorsByNamespaceRequest {
message ListTableDescriptorsByNamespaceRequest {
required string namespaceName = 1;
}
message GetTableDescriptorsByNamespaceResponse {
message ListTableDescriptorsByNamespaceResponse {
repeated TableSchema tableSchema = 1;
}
message ListTableNamesByNamespaceRequest {
required string namespaceName = 1;
}
message ListTableNamesByNamespaceResponse {
repeated TableName tableName = 1;
}
/* Cluster-level protobufs */
@ -454,6 +461,10 @@ service MasterAdminService {
returns(ListNamespaceDescriptorsResponse);
/** returns a list of tables for a given namespace*/
rpc GetTableDescriptorsByNamespace(GetTableDescriptorsByNamespaceRequest)
returns(GetTableDescriptorsByNamespaceResponse);
rpc ListTableDescriptorsByNamespace(ListTableDescriptorsByNamespaceRequest)
returns(ListTableDescriptorsByNamespaceResponse);
/** returns a list of tables for a given namespace*/
rpc ListTableNamesByNamespace(ListTableNamesByNamespaceRequest)
returns(ListTableNamesByNamespaceResponse);
}

View File

@ -45,6 +45,13 @@ message GetTableDescriptorsResponse {
repeated TableSchema table_schema = 1;
}
message GetTableNamesRequest {
}
message GetTableNamesResponse {
repeated TableName table_names = 1;
}
message GetClusterStatusRequest {
}
@ -61,6 +68,10 @@ service MasterMonitorService {
rpc GetTableDescriptors(GetTableDescriptorsRequest)
returns(GetTableDescriptorsResponse);
/** Get the list of table names. */
rpc GetTableNames(GetTableNamesRequest)
returns(GetTableNamesResponse);
/** Return cluster status. */
rpc GetClusterStatus(GetClusterStatusRequest)
returns(GetClusterStatusResponse);

View File

@ -298,7 +298,7 @@ AssignmentManager assignmentManager = master.getAssignmentManager();
<%def catalogTables>
<%java>
HTableDescriptor[] sysTables = admin.getTableDescriptorsByNamespace(NamespaceDescriptor
HTableDescriptor[] sysTables = admin.listTableDescriptorsByNamespace(NamespaceDescriptor
.SYSTEM_NAMESPACE_NAME_STR);
</%java>

View File

@ -25,6 +25,7 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@ -175,6 +176,8 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetSchemaA
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetSchemaAlterStatusResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableDescriptorsRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableDescriptorsResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableNamesRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterMonitorProtos.GetTableNamesResponse;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest;
import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningResponse;
import org.apache.hadoop.hbase.protobuf.generated.RegionServerStatusProtos;
@ -2629,6 +2632,27 @@ MasterServices, Server {
return builder.build();
}
/**
* Get list of table names
* @param controller Unused (set to null).
* @param req GetTableNamesRequest
* @return GetTableNamesResponse
* @throws ServiceException
*/
public GetTableNamesResponse getTableNames(
RpcController controller, GetTableNamesRequest req) throws ServiceException {
try {
Collection<HTableDescriptor> descriptors = this.tableDescriptors.getAll().values();
GetTableNamesResponse.Builder builder = GetTableNamesResponse.newBuilder();
for (HTableDescriptor descriptor: descriptors) {
builder.addTableNames(ProtobufUtil.toProtoTableName(descriptor.getTableName()));
}
return builder.build();
} catch (IOException e) {
throw new ServiceException(e);
}
}
/**
* Compute the average load across all region servers.
* Currently, this uses a very naive computation - just uses the number of
@ -3014,13 +3038,13 @@ MasterServices, Server {
}
@Override
public MasterAdminProtos.GetTableDescriptorsByNamespaceResponse getTableDescriptorsByNamespace(
RpcController controller, MasterAdminProtos.GetTableDescriptorsByNamespaceRequest request)
public MasterAdminProtos.ListTableDescriptorsByNamespaceResponse listTableDescriptorsByNamespace(
RpcController controller, MasterAdminProtos.ListTableDescriptorsByNamespaceRequest request)
throws ServiceException {
try {
MasterAdminProtos.GetTableDescriptorsByNamespaceResponse.Builder b =
MasterAdminProtos.GetTableDescriptorsByNamespaceResponse.newBuilder();
for(HTableDescriptor htd: getTableDescriptorsByNamespace(request.getNamespaceName())) {
MasterAdminProtos.ListTableDescriptorsByNamespaceResponse.Builder b =
MasterAdminProtos.ListTableDescriptorsByNamespaceResponse.newBuilder();
for(HTableDescriptor htd: listTableDescriptorsByNamespace(request.getNamespaceName())) {
b.addTableSchema(htd.convert());
}
return b.build();
@ -3029,6 +3053,22 @@ MasterServices, Server {
}
}
@Override
public MasterAdminProtos.ListTableNamesByNamespaceResponse listTableNamesByNamespace(
RpcController controller, MasterAdminProtos.ListTableNamesByNamespaceRequest request)
throws ServiceException {
try {
MasterAdminProtos.ListTableNamesByNamespaceResponse.Builder b =
MasterAdminProtos.ListTableNamesByNamespaceResponse.newBuilder();
for (TableName tableName: listTableNamesByNamespace(request.getNamespaceName())) {
b.addTableName(ProtobufUtil.toProtoTableName(tableName));
}
return b.build();
} catch (IOException e) {
throw new ServiceException(e);
}
}
private boolean isHealthCheckerConfigured() {
String healthScriptLocation = this.conf.get(HConstants.HEALTH_SCRIPT_LOC);
return org.apache.commons.lang.StringUtils.isNotBlank(healthScriptLocation);
@ -3080,7 +3120,16 @@ MasterServices, Server {
return Lists.newArrayList(tableNamespaceManager.list());
}
public List<HTableDescriptor> getTableDescriptorsByNamespace(String name) throws IOException {
public List<HTableDescriptor> listTableDescriptorsByNamespace(String name) throws IOException {
return Lists.newArrayList(tableDescriptors.getByNamespace(name).values());
}
public List<TableName> listTableNamesByNamespace(String name) throws IOException {
List<TableName> tableNames = Lists.newArrayList();
for (HTableDescriptor descriptor: tableDescriptors.getByNamespace(name).values()) {
tableNames.add(TableName.valueOf(name, descriptor.getNameAsString()));
}
return tableNames;
}
}

View File

@ -230,8 +230,16 @@ public interface MasterServices extends Server {
/**
* Get list of table descriptors by namespace
* @param name namespace name
* @return A descriptor
* @return descriptors
* @throws IOException
*/
public List<HTableDescriptor> getTableDescriptorsByNamespace(String name) throws IOException;
public List<HTableDescriptor> listTableDescriptorsByNamespace(String name) throws IOException;
/**
* Get list of table names by namespace
* @param name namespace name
* @return table names
* @throws IOException
*/
public List<TableName> listTableNamesByNamespace(String name) throws IOException;
}

View File

@ -155,7 +155,7 @@ public class TableNamespaceManager {
if (NamespaceDescriptor.RESERVED_NAMESPACES.contains(name)) {
throw new ConstraintException("Reserved namespace "+name+" cannot be removed.");
}
int tableCount = masterServices.getTableDescriptorsByNamespace(name).size();
int tableCount = masterServices.listTableDescriptorsByNamespace(name).size();
if (tableCount > 0) {
throw new ConstraintException("Only empty namespaces can be removed. " +
"Namespace "+name+" has "+tableCount+" tables");

View File

@ -42,7 +42,7 @@ module Hbase
#----------------------------------------------------------------------------------------------
# Returns a list of tables in hbase
def list(regex = ".*")
@admin.listTables(regex).map { |t| t.getTableName().getNameAsString }
@admin.getTableNames(regex)
end
#----------------------------------------------------------------------------------------------
@ -745,7 +745,7 @@ module Hbase
# Returns a list of tables in namespace
def list_namespace_tables(namespace_name)
unless namespace_name.nil?
return @admin.getTableDescriptorsByNamespace(namespace_name).map { |t| t.getTableName().getNameAsString }
return @admin.listTableNamesByNamespace(namespace_name).map { |t| t.getQualifierAsString() }
end
raise(ArgumentError, "Failed to find namespace named #{namespace_name}")

View File

@ -109,7 +109,7 @@ public class TestNamespace {
TableName.META_TABLE_NAME,
TableName.NAMESPACE_TABLE_NAME);
HTableDescriptor[] descs =
admin.getTableDescriptorsByNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE.getName());
admin.listTableDescriptorsByNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE.getName());
assertEquals(systemTables.size(), descs.length);
for (HTableDescriptor desc : descs) {
assertTrue(systemTables.contains(desc.getTableName()));

View File

@ -330,10 +330,15 @@ public class TestCatalogJanitor {
}
@Override
public List<HTableDescriptor> getTableDescriptorsByNamespace(String name) throws IOException {
public List<HTableDescriptor> listTableDescriptorsByNamespace(String name) throws IOException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public List<TableName> listTableNamesByNamespace(String name) throws IOException {
return null;
}
@Override
public void deleteTable(TableName tableName) throws IOException { }