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 b9c6432c34b..c5d95562a44 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 @@ -114,6 +114,30 @@ public interface Admin extends Abortable, Closeable { */ HTableDescriptor[] listTables(String regex) throws IOException; + /** + * List all the tables matching the given pattern. + * + * @param pattern The compiled regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return - returns an array of HTableDescriptors + * @throws IOException if a remote or network exception occurs + * @see #listTables() + */ + HTableDescriptor[] listTables(Pattern pattern, boolean includeSysTables) + throws IOException; + + /** + * List all the tables matching the given pattern. + * + * @param regex The regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return - returns an array of HTableDescriptors + * @throws IOException if a remote or network exception occurs + * @see #listTables(java.util.regex.Pattern, boolean) + */ + HTableDescriptor[] listTables(String regex, boolean includeSysTables) + throws IOException; + /** * List all of the names of userspace tables. * @@ -122,6 +146,42 @@ public interface Admin extends Abortable, Closeable { */ TableName[] listTableNames() throws IOException; + /** + * List all of the names of userspace tables. + * @param pattern The regular expression to match against + * @return TableName[] table names + * @throws IOException if a remote or network exception occurs + */ + TableName[] listTableNames(Pattern pattern) throws IOException; + + /** + * List all of the names of userspace tables. + * @param regex The regular expression to match against + * @return TableName[] table names + * @throws IOException if a remote or network exception occurs + */ + TableName[] listTableNames(String regex) throws IOException; + + /** + * List all of the names of userspace tables. + * @param pattern The regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return TableName[] table names + * @throws IOException if a remote or network exception occurs + */ + TableName[] listTableNames(final Pattern pattern, final boolean includeSysTables) + throws IOException; + + /** + * List all of the names of userspace tables. + * @param regex The regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return TableName[] table names + * @throws IOException if a remote or network exception occurs + */ + TableName[] listTableNames(final String regex, final boolean includeSysTables) + throws IOException; + /** * Method for getting the tableDescriptor * diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java index d8856ad3ad4..a30ce9d98ab 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionAdapter.java @@ -38,7 +38,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.MasterService; /** * An internal class that delegates to an {@link HConnection} instance. * A convenience to override when customizing method implementations. - * + * * * @see ConnectionUtils#createShortCircuitHConnection(HConnection, ServerName, * AdminService.BlockingInterface, ClientService.BlockingInterface) for case where we make @@ -176,11 +176,6 @@ abstract class ConnectionAdapter implements ClusterConnection { return wrappedConnection.listTables(); } - @Override - public HTableDescriptor[] listTables(String regex) throws IOException { - return wrappedConnection.listTables(regex); - } - @Override public String[] getTableNames() throws IOException { return wrappedConnection.getTableNames(); diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java index 7f599da693a..ce8651c24f7 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionManager.java @@ -2383,20 +2383,6 @@ class ConnectionManager { * @deprecated Use {@link Admin#listTableNames()} instead */ @Deprecated - @Override - public HTableDescriptor[] listTables(String regex) throws IOException { - MasterKeepAliveConnection master = getKeepAliveMasterService(); - try { - GetTableDescriptorsRequest req = - RequestConverter.buildGetTableDescriptorsRequest(regex); - return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(null, req)); - } catch (ServiceException se) { - throw ProtobufUtil.getRemoteException(se); - } finally { - master.close(); - } - } - @Override public String[] getTableNames() throws IOException { TableName[] tableNames = listTableNames(); 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 2289ad8a0b9..0677606ee6e 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 @@ -296,52 +296,38 @@ public class HBaseAdmin implements Admin { return tableExists(TableName.valueOf(tableName)); } - /** - * List all the userspace tables. In other words, scan the hbase:meta table. - * - * If we wanted this to be really fast, we could implement a special - * catalog table that just contains table names and their descriptors. - * Right now, it only exists as part of the hbase:meta table's region info. - * - * @return - returns an array of HTableDescriptors - * @throws IOException if a remote or network exception occurs - */ @Override public HTableDescriptor[] listTables() throws IOException { - return executeCallable(new MasterCallable(getConnection()) { + return listTables((Pattern)null, false); + } + + @Override + public HTableDescriptor[] listTables(Pattern pattern) throws IOException { + return listTables(pattern, false); + } + + @Override + public HTableDescriptor[] listTables(String regex) throws IOException { + return listTables(Pattern.compile(regex), false); + } + + @Override + public HTableDescriptor[] listTables(final Pattern pattern, final boolean includeSysTables) + throws IOException { + return executeCallable(new MasterCallable(getConnection()) { @Override public HTableDescriptor[] call(int callTimeout) throws ServiceException { GetTableDescriptorsRequest req = - RequestConverter.buildGetTableDescriptorsRequest((List)null); + RequestConverter.buildGetTableDescriptorsRequest(pattern, includeSysTables); return ProtobufUtil.getHTableDescriptorArray(master.getTableDescriptors(null, req)); } }); } - /** - * List all the userspace tables matching the given pattern. - * - * @param pattern The compiled regular expression to match against - * @return - returns an array of HTableDescriptors - * @throws IOException if a remote or network exception occurs - * @see #listTables() - */ @Override - public HTableDescriptor[] listTables(Pattern pattern) throws IOException { - return this.connection.listTables(pattern.toString()); - } - - /** - * List all the userspace tables matching the given regular expression. - * - * @param regex The regular expression to match against - * @return - returns an array of HTableDescriptors - * @throws IOException if a remote or network exception occurs - * @see #listTables(java.util.regex.Pattern) - */ - @Override - public HTableDescriptor[] listTables(String regex) throws IOException { - return listTables(Pattern.compile(regex)); + public HTableDescriptor[] listTables(String regex, boolean includeSysTables) + throws IOException { + return listTables(Pattern.compile(regex), includeSysTables); } /** @@ -365,17 +351,16 @@ public class HBaseAdmin implements Admin { * @param pattern The regular expression to match against * @return String[] table names * @throws IOException if a remote or network exception occurs - * @deprecated Use {@link Admin#listTables(Pattern)} instead. + * @deprecated Use {@link Admin#listTableNames(Pattern)} instead. */ @Deprecated public String[] getTableNames(Pattern pattern) throws IOException { - List matched = new ArrayList(); - for (String name: getTableNames()) { - if (pattern.matcher(name).matches()) { - matched.add(name); - } + TableName[] tableNames = listTableNames(pattern); + String result[] = new String[tableNames.length]; + for (int i = 0; i < tableNames.length; i++) { + result[i] = tableNames[i].getNameAsString(); } - return matched.toArray(new String[matched.size()]); + return result; } /** @@ -383,30 +368,48 @@ public class HBaseAdmin implements Admin { * @param regex The regular expression to match against * @return String[] table names * @throws IOException if a remote or network exception occurs - * @deprecated Use {@link Admin#listTables(Pattern)} instead. + * @deprecated Use {@link Admin#listTableNames(Pattern)} instead. */ @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 - */ @Override public TableName[] listTableNames() throws IOException { + return listTableNames((Pattern)null, false); + } + + @Override + public TableName[] listTableNames(Pattern pattern) throws IOException { + return listTableNames(pattern, false); + } + + @Override + public TableName[] listTableNames(String regex) throws IOException { + return listTableNames(Pattern.compile(regex), false); + } + + @Override + public TableName[] listTableNames(final Pattern pattern, final boolean includeSysTables) + throws IOException { return executeCallable(new MasterCallable(getConnection()) { @Override public TableName[] call(int callTimeout) throws ServiceException { - return ProtobufUtil.getTableNameArray(master.getTableNames(null, - GetTableNamesRequest.newBuilder().build()) - .getTableNamesList()); + GetTableNamesRequest req = + RequestConverter.buildGetTableNamesRequest(pattern, includeSysTables); + return ProtobufUtil.getTableNameArray(master.getTableNames(null, req) + .getTableNamesList()); } }); } + @Override + public TableName[] listTableNames(final String regex, final boolean includeSysTables) + throws IOException { + return listTableNames(Pattern.compile(regex), includeSysTables); + } + /** * Method for getting the tableDescriptor * @param tableName as a byte [] @@ -2669,7 +2672,7 @@ public class HBaseAdmin implements Admin { } /** - * Roll the log writer. I.e. when using a file system based write ahead log, + * Roll the log writer. I.e. when using a file system based write ahead log, * start writing log messages to a new file. * * Note that when talking to a version 1.0+ HBase deployment, the rolling is asynchronous. diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java index 7add87b289d..9a4ef6923dc 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnection.java @@ -258,13 +258,6 @@ public interface HConnection extends Connection { @Deprecated HTableDescriptor[] listTables() throws IOException; - /** - * List all the userspace tables matching the pattern. - * @return - returns an array of HTableDescriptors - * @throws IOException if a remote or network exception occurs - */ - HTableDescriptor[] listTables(String pattern) 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 diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/RequestConverter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/RequestConverter.java index 2d8c53ec7f8..d23aa023464 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/RequestConverter.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/protobuf/RequestConverter.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.protobuf; import java.io.IOException; import java.util.List; +import java.util.regex.Pattern; import org.apache.hadoop.hbase.CellScannable; import org.apache.hadoop.hbase.DoNotRetryIOException; @@ -88,6 +89,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.EnableTableReques import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetClusterStatusRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetSchemaAlterStatusRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableStateRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsCatalogJanitorEnabledRequest; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.IsMasterRunningRequest; @@ -1229,11 +1231,30 @@ public final class RequestConverter { /** * Creates a protocol buffer GetTableDescriptorsRequest * + * @param pattern The compiled regular expression to match against + * @param includeSysTables False to match only against userspace tables * @return a GetTableDescriptorsRequest */ - public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final String pattern) { + public static GetTableDescriptorsRequest buildGetTableDescriptorsRequest(final Pattern pattern, + boolean includeSysTables) { GetTableDescriptorsRequest.Builder builder = GetTableDescriptorsRequest.newBuilder(); - builder.setRegex(pattern); + if (pattern != null) builder.setRegex(pattern.toString()); + builder.setIncludeSysTables(includeSysTables); + return builder.build(); + } + + /** + * Creates a protocol buffer GetTableNamesRequest + * + * @param pattern The compiled regular expression to match against + * @param includeSysTables False to match only against userspace tables + * @return a GetTableNamesRequest + */ + public static GetTableNamesRequest buildGetTableNamesRequest(final Pattern pattern, + boolean includeSysTables) { + GetTableNamesRequest.Builder builder = GetTableNamesRequest.newBuilder(); + if (pattern != null) builder.setRegex(pattern.toString()); + builder.setIncludeSysTables(includeSysTables); return builder.build(); } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java index ae43c170b11..521c58b065d 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/access/AccessControlClient.java @@ -178,7 +178,7 @@ public class AccessControlClient { String namespace = tableRegex.substring(1); permList = ProtobufUtil.getUserPermissions(protocol, Bytes.toBytes(namespace)); } else { - htds = admin.listTables(Pattern.compile(tableRegex)); + htds = admin.listTables(Pattern.compile(tableRegex), true); for (HTableDescriptor hd : htds) { permList.addAll(ProtobufUtil.getUserPermissions(protocol, hd.getTableName())); } diff --git a/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/MasterProtos.java b/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/MasterProtos.java index caeea871501..90d576434bb 100644 --- a/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/MasterProtos.java +++ b/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/MasterProtos.java @@ -34196,6 +34196,16 @@ public final class MasterProtos { */ com.google.protobuf.ByteString getRegexBytes(); + + // optional bool include_sys_tables = 3 [default = false]; + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + boolean hasIncludeSysTables(); + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + boolean getIncludeSysTables(); } /** * Protobuf type {@code GetTableDescriptorsRequest} @@ -34261,6 +34271,11 @@ public final class MasterProtos { regex_ = input.readBytes(); break; } + case 24: { + bitField0_ |= 0x00000002; + includeSysTables_ = input.readBool(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -34383,9 +34398,26 @@ public final class MasterProtos { } } + // optional bool include_sys_tables = 3 [default = false]; + public static final int INCLUDE_SYS_TABLES_FIELD_NUMBER = 3; + private boolean includeSysTables_; + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + public boolean hasIncludeSysTables() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + public boolean getIncludeSysTables() { + return includeSysTables_; + } + private void initFields() { tableNames_ = java.util.Collections.emptyList(); regex_ = ""; + includeSysTables_ = false; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -34411,6 +34443,9 @@ public final class MasterProtos { if (((bitField0_ & 0x00000001) == 0x00000001)) { output.writeBytes(2, getRegexBytes()); } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(3, includeSysTables_); + } getUnknownFields().writeTo(output); } @@ -34428,6 +34463,10 @@ public final class MasterProtos { size += com.google.protobuf.CodedOutputStream .computeBytesSize(2, getRegexBytes()); } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, includeSysTables_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -34458,6 +34497,11 @@ public final class MasterProtos { result = result && getRegex() .equals(other.getRegex()); } + result = result && (hasIncludeSysTables() == other.hasIncludeSysTables()); + if (hasIncludeSysTables()) { + result = result && (getIncludeSysTables() + == other.getIncludeSysTables()); + } result = result && getUnknownFields().equals(other.getUnknownFields()); return result; @@ -34479,6 +34523,10 @@ public final class MasterProtos { hash = (37 * hash) + REGEX_FIELD_NUMBER; hash = (53 * hash) + getRegex().hashCode(); } + if (hasIncludeSysTables()) { + hash = (37 * hash) + INCLUDE_SYS_TABLES_FIELD_NUMBER; + hash = (53 * hash) + hashBoolean(getIncludeSysTables()); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -34597,6 +34645,8 @@ public final class MasterProtos { } regex_ = ""; bitField0_ = (bitField0_ & ~0x00000002); + includeSysTables_ = false; + bitField0_ = (bitField0_ & ~0x00000004); return this; } @@ -34638,6 +34688,10 @@ public final class MasterProtos { to_bitField0_ |= 0x00000001; } result.regex_ = regex_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000002; + } + result.includeSysTables_ = includeSysTables_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -34685,6 +34739,9 @@ public final class MasterProtos { regex_ = other.regex_; onChanged(); } + if (other.hasIncludeSysTables()) { + setIncludeSysTables(other.getIncludeSysTables()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -35032,6 +35089,39 @@ public final class MasterProtos { return this; } + // optional bool include_sys_tables = 3 [default = false]; + private boolean includeSysTables_ ; + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + public boolean hasIncludeSysTables() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + public boolean getIncludeSysTables() { + return includeSysTables_; + } + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + public Builder setIncludeSysTables(boolean value) { + bitField0_ |= 0x00000004; + includeSysTables_ = value; + onChanged(); + return this; + } + /** + * optional bool include_sys_tables = 3 [default = false]; + */ + public Builder clearIncludeSysTables() { + bitField0_ = (bitField0_ & ~0x00000004); + includeSysTables_ = false; + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:GetTableDescriptorsRequest) } @@ -35766,6 +35856,31 @@ public final class MasterProtos { public interface GetTableNamesRequestOrBuilder extends com.google.protobuf.MessageOrBuilder { + + // optional string regex = 1; + /** + * optional string regex = 1; + */ + boolean hasRegex(); + /** + * optional string regex = 1; + */ + java.lang.String getRegex(); + /** + * optional string regex = 1; + */ + com.google.protobuf.ByteString + getRegexBytes(); + + // optional bool include_sys_tables = 2 [default = false]; + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + boolean hasIncludeSysTables(); + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + boolean getIncludeSysTables(); } /** * Protobuf type {@code GetTableNamesRequest} @@ -35800,6 +35915,7 @@ public final class MasterProtos { com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { initFields(); + int mutable_bitField0_ = 0; com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet.newBuilder(); try { @@ -35817,6 +35933,16 @@ public final class MasterProtos { } break; } + case 10: { + bitField0_ |= 0x00000001; + regex_ = input.readBytes(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + includeSysTables_ = input.readBool(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -35856,7 +35982,69 @@ public final class MasterProtos { return PARSER; } + private int bitField0_; + // optional string regex = 1; + public static final int REGEX_FIELD_NUMBER = 1; + private java.lang.Object regex_; + /** + * optional string regex = 1; + */ + public boolean hasRegex() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string regex = 1; + */ + public java.lang.String getRegex() { + java.lang.Object ref = regex_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + regex_ = s; + } + return s; + } + } + /** + * optional string regex = 1; + */ + public com.google.protobuf.ByteString + getRegexBytes() { + java.lang.Object ref = regex_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + regex_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional bool include_sys_tables = 2 [default = false]; + public static final int INCLUDE_SYS_TABLES_FIELD_NUMBER = 2; + private boolean includeSysTables_; + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + public boolean hasIncludeSysTables() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + public boolean getIncludeSysTables() { + return includeSysTables_; + } + private void initFields() { + regex_ = ""; + includeSysTables_ = false; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -35870,6 +36058,12 @@ public final class MasterProtos { public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getRegexBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBool(2, includeSysTables_); + } getUnknownFields().writeTo(output); } @@ -35879,6 +36073,14 @@ public final class MasterProtos { if (size != -1) return size; size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getRegexBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, includeSysTables_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -35902,6 +36104,16 @@ public final class MasterProtos { org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest other = (org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest) obj; boolean result = true; + result = result && (hasRegex() == other.hasRegex()); + if (hasRegex()) { + result = result && getRegex() + .equals(other.getRegex()); + } + result = result && (hasIncludeSysTables() == other.hasIncludeSysTables()); + if (hasIncludeSysTables()) { + result = result && (getIncludeSysTables() + == other.getIncludeSysTables()); + } result = result && getUnknownFields().equals(other.getUnknownFields()); return result; @@ -35915,6 +36127,14 @@ public final class MasterProtos { } int hash = 41; hash = (19 * hash) + getDescriptorForType().hashCode(); + if (hasRegex()) { + hash = (37 * hash) + REGEX_FIELD_NUMBER; + hash = (53 * hash) + getRegex().hashCode(); + } + if (hasIncludeSysTables()) { + hash = (37 * hash) + INCLUDE_SYS_TABLES_FIELD_NUMBER; + hash = (53 * hash) + hashBoolean(getIncludeSysTables()); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -36024,6 +36244,10 @@ public final class MasterProtos { public Builder clear() { super.clear(); + regex_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + includeSysTables_ = false; + bitField0_ = (bitField0_ & ~0x00000002); return this; } @@ -36050,6 +36274,17 @@ public final class MasterProtos { public org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest buildPartial() { org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest result = new org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.regex_ = regex_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.includeSysTables_ = includeSysTables_; + result.bitField0_ = to_bitField0_; onBuilt(); return result; } @@ -36065,6 +36300,14 @@ public final class MasterProtos { public Builder mergeFrom(org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest other) { if (other == org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest.getDefaultInstance()) return this; + if (other.hasRegex()) { + bitField0_ |= 0x00000001; + regex_ = other.regex_; + onChanged(); + } + if (other.hasIncludeSysTables()) { + setIncludeSysTables(other.getIncludeSysTables()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -36090,6 +36333,114 @@ public final class MasterProtos { } return this; } + private int bitField0_; + + // optional string regex = 1; + private java.lang.Object regex_ = ""; + /** + * optional string regex = 1; + */ + public boolean hasRegex() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string regex = 1; + */ + public java.lang.String getRegex() { + java.lang.Object ref = regex_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + regex_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string regex = 1; + */ + public com.google.protobuf.ByteString + getRegexBytes() { + java.lang.Object ref = regex_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + regex_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string regex = 1; + */ + public Builder setRegex( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + regex_ = value; + onChanged(); + return this; + } + /** + * optional string regex = 1; + */ + public Builder clearRegex() { + bitField0_ = (bitField0_ & ~0x00000001); + regex_ = getDefaultInstance().getRegex(); + onChanged(); + return this; + } + /** + * optional string regex = 1; + */ + public Builder setRegexBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + regex_ = value; + onChanged(); + return this; + } + + // optional bool include_sys_tables = 2 [default = false]; + private boolean includeSysTables_ ; + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + public boolean hasIncludeSysTables() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + public boolean getIncludeSysTables() { + return includeSysTables_; + } + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + public Builder setIncludeSysTables(boolean value) { + bitField0_ |= 0x00000002; + includeSysTables_ = value; + onChanged(); + return this; + } + /** + * optional bool include_sys_tables = 2 [default = false]; + */ + public Builder clearIncludeSysTables() { + bitField0_ = (bitField0_ & ~0x00000002); + includeSysTables_ = false; + onChanged(); + return this; + } // @@protoc_insertion_point(builder_scope:GetTableNamesRequest) } @@ -47998,113 +48349,115 @@ public final class MasterProtos { "equest\022\036\n\ntable_name\030\001 \002(\0132\n.TableName\"T", "\n\034GetSchemaAlterStatusResponse\022\035\n\025yet_to" + "_update_regions\030\001 \001(\r\022\025\n\rtotal_regions\030\002" + - " \001(\r\"L\n\032GetTableDescriptorsRequest\022\037\n\013ta" + + " \001(\r\"o\n\032GetTableDescriptorsRequest\022\037\n\013ta" + "ble_names\030\001 \003(\0132\n.TableName\022\r\n\005regex\030\002 \001" + - "(\t\"A\n\033GetTableDescriptorsResponse\022\"\n\014tab" + - "le_schema\030\001 \003(\0132\014.TableSchema\"\026\n\024GetTabl" + - "eNamesRequest\"8\n\025GetTableNamesResponse\022\037" + - "\n\013table_names\030\001 \003(\0132\n.TableName\"6\n\024GetTa" + - "bleStateRequest\022\036\n\ntable_name\030\001 \002(\0132\n.Ta" + - "bleName\"9\n\025GetTableStateResponse\022 \n\013tabl", - "e_state\030\001 \002(\0132\013.TableState\"\031\n\027GetCluster" + - "StatusRequest\"B\n\030GetClusterStatusRespons" + - "e\022&\n\016cluster_status\030\001 \002(\0132\016.ClusterStatu" + - "s\"\030\n\026IsMasterRunningRequest\"4\n\027IsMasterR" + - "unningResponse\022\031\n\021is_master_running\030\001 \002(" + - "\010\"@\n\024ExecProcedureRequest\022(\n\tprocedure\030\001" + - " \002(\0132\025.ProcedureDescription\"F\n\025ExecProce" + - "dureResponse\022\030\n\020expected_timeout\030\001 \001(\003\022\023" + - "\n\013return_data\030\002 \001(\014\"B\n\026IsProcedureDoneRe" + - "quest\022(\n\tprocedure\030\001 \001(\0132\025.ProcedureDesc", - "ription\"W\n\027IsProcedureDoneResponse\022\023\n\004do" + - "ne\030\001 \001(\010:\005false\022\'\n\010snapshot\030\002 \001(\0132\025.Proc" + - "edureDescription\"\273\001\n\017SetQuotaRequest\022\021\n\t" + - "user_name\030\001 \001(\t\022\022\n\nuser_group\030\002 \001(\t\022\021\n\tn" + - "amespace\030\003 \001(\t\022\036\n\ntable_name\030\004 \001(\0132\n.Tab" + - "leName\022\022\n\nremove_all\030\005 \001(\010\022\026\n\016bypass_glo" + - "bals\030\006 \001(\010\022\"\n\010throttle\030\007 \001(\0132\020.ThrottleR" + - "equest\"\022\n\020SetQuotaResponse2\346\030\n\rMasterSer" + - "vice\022S\n\024GetSchemaAlterStatus\022\034.GetSchema" + - "AlterStatusRequest\032\035.GetSchemaAlterStatu", - "sResponse\022P\n\023GetTableDescriptors\022\033.GetTa" + - "bleDescriptorsRequest\032\034.GetTableDescript" + - "orsResponse\022>\n\rGetTableNames\022\025.GetTableN" + - "amesRequest\032\026.GetTableNamesResponse\022G\n\020G" + - "etClusterStatus\022\030.GetClusterStatusReques" + - "t\032\031.GetClusterStatusResponse\022D\n\017IsMaster" + - "Running\022\027.IsMasterRunningRequest\032\030.IsMas" + - "terRunningResponse\0222\n\tAddColumn\022\021.AddCol" + - "umnRequest\032\022.AddColumnResponse\022;\n\014Delete" + - "Column\022\024.DeleteColumnRequest\032\025.DeleteCol", - "umnResponse\022;\n\014ModifyColumn\022\024.ModifyColu" + - "mnRequest\032\025.ModifyColumnResponse\0225\n\nMove" + - "Region\022\022.MoveRegionRequest\032\023.MoveRegionR" + - "esponse\022Y\n\026DispatchMergingRegions\022\036.Disp" + - "atchMergingRegionsRequest\032\037.DispatchMerg" + - "ingRegionsResponse\022;\n\014AssignRegion\022\024.Ass" + - "ignRegionRequest\032\025.AssignRegionResponse\022" + - "A\n\016UnassignRegion\022\026.UnassignRegionReques" + - "t\032\027.UnassignRegionResponse\022>\n\rOfflineReg" + - "ion\022\025.OfflineRegionRequest\032\026.OfflineRegi", - "onResponse\0228\n\013DeleteTable\022\023.DeleteTableR" + - "equest\032\024.DeleteTableResponse\022>\n\rtruncate" + - "Table\022\025.TruncateTableRequest\032\026.TruncateT" + - "ableResponse\0228\n\013EnableTable\022\023.EnableTabl" + - "eRequest\032\024.EnableTableResponse\022;\n\014Disabl" + - "eTable\022\024.DisableTableRequest\032\025.DisableTa" + - "bleResponse\0228\n\013ModifyTable\022\023.ModifyTable" + - "Request\032\024.ModifyTableResponse\0228\n\013CreateT" + - "able\022\023.CreateTableRequest\032\024.CreateTableR" + - "esponse\022/\n\010Shutdown\022\020.ShutdownRequest\032\021.", - "ShutdownResponse\0225\n\nStopMaster\022\022.StopMas" + - "terRequest\032\023.StopMasterResponse\022,\n\007Balan" + - "ce\022\017.BalanceRequest\032\020.BalanceResponse\022M\n" + - "\022SetBalancerRunning\022\032.SetBalancerRunning" + - "Request\032\033.SetBalancerRunningResponse\022A\n\016" + - "RunCatalogScan\022\026.RunCatalogScanRequest\032\027" + - ".RunCatalogScanResponse\022S\n\024EnableCatalog" + - "Janitor\022\034.EnableCatalogJanitorRequest\032\035." + - "EnableCatalogJanitorResponse\022\\\n\027IsCatalo" + - "gJanitorEnabled\022\037.IsCatalogJanitorEnable", - "dRequest\032 .IsCatalogJanitorEnabledRespon" + - "se\022L\n\021ExecMasterService\022\032.CoprocessorSer" + - "viceRequest\032\033.CoprocessorServiceResponse" + - "\022/\n\010Snapshot\022\020.SnapshotRequest\032\021.Snapsho" + - "tResponse\022V\n\025GetCompletedSnapshots\022\035.Get" + - "CompletedSnapshotsRequest\032\036.GetCompleted" + - "SnapshotsResponse\022A\n\016DeleteSnapshot\022\026.De" + - "leteSnapshotRequest\032\027.DeleteSnapshotResp" + - "onse\022A\n\016IsSnapshotDone\022\026.IsSnapshotDoneR" + - "equest\032\027.IsSnapshotDoneResponse\022D\n\017Resto", - "reSnapshot\022\027.RestoreSnapshotRequest\032\030.Re" + - "storeSnapshotResponse\022V\n\025IsRestoreSnapsh" + - "otDone\022\035.IsRestoreSnapshotDoneRequest\032\036." + - "IsRestoreSnapshotDoneResponse\022>\n\rExecPro" + - "cedure\022\025.ExecProcedureRequest\032\026.ExecProc" + - "edureResponse\022E\n\024ExecProcedureWithRet\022\025." + - "ExecProcedureRequest\032\026.ExecProcedureResp" + - "onse\022D\n\017IsProcedureDone\022\027.IsProcedureDon" + - "eRequest\032\030.IsProcedureDoneResponse\022D\n\017Mo" + - "difyNamespace\022\027.ModifyNamespaceRequest\032\030", - ".ModifyNamespaceResponse\022D\n\017CreateNamesp" + - "ace\022\027.CreateNamespaceRequest\032\030.CreateNam" + - "espaceResponse\022D\n\017DeleteNamespace\022\027.Dele" + - "teNamespaceRequest\032\030.DeleteNamespaceResp" + - "onse\022Y\n\026GetNamespaceDescriptor\022\036.GetName" + - "spaceDescriptorRequest\032\037.GetNamespaceDes" + - "criptorResponse\022_\n\030ListNamespaceDescript" + - "ors\022 .ListNamespaceDescriptorsRequest\032!." + - "ListNamespaceDescriptorsResponse\022t\n\037List" + - "TableDescriptorsByNamespace\022\'.ListTableD", - "escriptorsByNamespaceRequest\032(.ListTable" + - "DescriptorsByNamespaceResponse\022b\n\031ListTa" + - "bleNamesByNamespace\022!.ListTableNamesByNa" + - "mespaceRequest\032\".ListTableNamesByNamespa" + - "ceResponse\022>\n\rGetTableState\022\025.GetTableSt" + - "ateRequest\032\026.GetTableStateResponse\022/\n\010Se" + - "tQuota\022\020.SetQuotaRequest\032\021.SetQuotaRespo" + - "nseBB\n*org.apache.hadoop.hbase.protobuf." + - "generatedB\014MasterProtosH\001\210\001\001\240\001\001" + "(\t\022!\n\022include_sys_tables\030\003 \001(\010:\005false\"A\n" + + "\033GetTableDescriptorsResponse\022\"\n\014table_sc" + + "hema\030\001 \003(\0132\014.TableSchema\"H\n\024GetTableName" + + "sRequest\022\r\n\005regex\030\001 \001(\t\022!\n\022include_sys_t" + + "ables\030\002 \001(\010:\005false\"8\n\025GetTableNamesRespo" + + "nse\022\037\n\013table_names\030\001 \003(\0132\n.TableName\"6\n\024", + "GetTableStateRequest\022\036\n\ntable_name\030\001 \002(\013" + + "2\n.TableName\"9\n\025GetTableStateResponse\022 \n" + + "\013table_state\030\001 \002(\0132\013.TableState\"\031\n\027GetCl" + + "usterStatusRequest\"B\n\030GetClusterStatusRe" + + "sponse\022&\n\016cluster_status\030\001 \002(\0132\016.Cluster" + + "Status\"\030\n\026IsMasterRunningRequest\"4\n\027IsMa" + + "sterRunningResponse\022\031\n\021is_master_running" + + "\030\001 \002(\010\"@\n\024ExecProcedureRequest\022(\n\tproced" + + "ure\030\001 \002(\0132\025.ProcedureDescription\"F\n\025Exec" + + "ProcedureResponse\022\030\n\020expected_timeout\030\001 ", + "\001(\003\022\023\n\013return_data\030\002 \001(\014\"B\n\026IsProcedureD" + + "oneRequest\022(\n\tprocedure\030\001 \001(\0132\025.Procedur" + + "eDescription\"W\n\027IsProcedureDoneResponse\022" + + "\023\n\004done\030\001 \001(\010:\005false\022\'\n\010snapshot\030\002 \001(\0132\025" + + ".ProcedureDescription\"\273\001\n\017SetQuotaReques" + + "t\022\021\n\tuser_name\030\001 \001(\t\022\022\n\nuser_group\030\002 \001(\t" + + "\022\021\n\tnamespace\030\003 \001(\t\022\036\n\ntable_name\030\004 \001(\0132" + + "\n.TableName\022\022\n\nremove_all\030\005 \001(\010\022\026\n\016bypas" + + "s_globals\030\006 \001(\010\022\"\n\010throttle\030\007 \001(\0132\020.Thro" + + "ttleRequest\"\022\n\020SetQuotaResponse2\346\030\n\rMast", + "erService\022S\n\024GetSchemaAlterStatus\022\034.GetS" + + "chemaAlterStatusRequest\032\035.GetSchemaAlter" + + "StatusResponse\022P\n\023GetTableDescriptors\022\033." + + "GetTableDescriptorsRequest\032\034.GetTableDes" + + "criptorsResponse\022>\n\rGetTableNames\022\025.GetT" + + "ableNamesRequest\032\026.GetTableNamesResponse" + + "\022G\n\020GetClusterStatus\022\030.GetClusterStatusR" + + "equest\032\031.GetClusterStatusResponse\022D\n\017IsM" + + "asterRunning\022\027.IsMasterRunningRequest\032\030." + + "IsMasterRunningResponse\0222\n\tAddColumn\022\021.A", + "ddColumnRequest\032\022.AddColumnResponse\022;\n\014D" + + "eleteColumn\022\024.DeleteColumnRequest\032\025.Dele" + + "teColumnResponse\022;\n\014ModifyColumn\022\024.Modif" + + "yColumnRequest\032\025.ModifyColumnResponse\0225\n" + + "\nMoveRegion\022\022.MoveRegionRequest\032\023.MoveRe" + + "gionResponse\022Y\n\026DispatchMergingRegions\022\036" + + ".DispatchMergingRegionsRequest\032\037.Dispatc" + + "hMergingRegionsResponse\022;\n\014AssignRegion\022" + + "\024.AssignRegionRequest\032\025.AssignRegionResp" + + "onse\022A\n\016UnassignRegion\022\026.UnassignRegionR", + "equest\032\027.UnassignRegionResponse\022>\n\rOffli" + + "neRegion\022\025.OfflineRegionRequest\032\026.Offlin" + + "eRegionResponse\0228\n\013DeleteTable\022\023.DeleteT" + + "ableRequest\032\024.DeleteTableResponse\022>\n\rtru" + + "ncateTable\022\025.TruncateTableRequest\032\026.Trun" + + "cateTableResponse\0228\n\013EnableTable\022\023.Enabl" + + "eTableRequest\032\024.EnableTableResponse\022;\n\014D" + + "isableTable\022\024.DisableTableRequest\032\025.Disa" + + "bleTableResponse\0228\n\013ModifyTable\022\023.Modify" + + "TableRequest\032\024.ModifyTableResponse\0228\n\013Cr", + "eateTable\022\023.CreateTableRequest\032\024.CreateT" + + "ableResponse\022/\n\010Shutdown\022\020.ShutdownReque" + + "st\032\021.ShutdownResponse\0225\n\nStopMaster\022\022.St" + + "opMasterRequest\032\023.StopMasterResponse\022,\n\007" + + "Balance\022\017.BalanceRequest\032\020.BalanceRespon" + + "se\022M\n\022SetBalancerRunning\022\032.SetBalancerRu" + + "nningRequest\032\033.SetBalancerRunningRespons" + + "e\022A\n\016RunCatalogScan\022\026.RunCatalogScanRequ" + + "est\032\027.RunCatalogScanResponse\022S\n\024EnableCa" + + "talogJanitor\022\034.EnableCatalogJanitorReque", + "st\032\035.EnableCatalogJanitorResponse\022\\\n\027IsC" + + "atalogJanitorEnabled\022\037.IsCatalogJanitorE" + + "nabledRequest\032 .IsCatalogJanitorEnabledR" + + "esponse\022L\n\021ExecMasterService\022\032.Coprocess" + + "orServiceRequest\032\033.CoprocessorServiceRes" + + "ponse\022/\n\010Snapshot\022\020.SnapshotRequest\032\021.Sn" + + "apshotResponse\022V\n\025GetCompletedSnapshots\022" + + "\035.GetCompletedSnapshotsRequest\032\036.GetComp" + + "letedSnapshotsResponse\022A\n\016DeleteSnapshot" + + "\022\026.DeleteSnapshotRequest\032\027.DeleteSnapsho", + "tResponse\022A\n\016IsSnapshotDone\022\026.IsSnapshot" + + "DoneRequest\032\027.IsSnapshotDoneResponse\022D\n\017" + + "RestoreSnapshot\022\027.RestoreSnapshotRequest" + + "\032\030.RestoreSnapshotResponse\022V\n\025IsRestoreS" + + "napshotDone\022\035.IsRestoreSnapshotDoneReque" + + "st\032\036.IsRestoreSnapshotDoneResponse\022>\n\rEx" + + "ecProcedure\022\025.ExecProcedureRequest\032\026.Exe" + + "cProcedureResponse\022E\n\024ExecProcedureWithR" + + "et\022\025.ExecProcedureRequest\032\026.ExecProcedur" + + "eResponse\022D\n\017IsProcedureDone\022\027.IsProcedu", + "reDoneRequest\032\030.IsProcedureDoneResponse\022" + + "D\n\017ModifyNamespace\022\027.ModifyNamespaceRequ" + + "est\032\030.ModifyNamespaceResponse\022D\n\017CreateN" + + "amespace\022\027.CreateNamespaceRequest\032\030.Crea" + + "teNamespaceResponse\022D\n\017DeleteNamespace\022\027" + + ".DeleteNamespaceRequest\032\030.DeleteNamespac" + + "eResponse\022Y\n\026GetNamespaceDescriptor\022\036.Ge" + + "tNamespaceDescriptorRequest\032\037.GetNamespa" + + "ceDescriptorResponse\022_\n\030ListNamespaceDes" + + "criptors\022 .ListNamespaceDescriptorsReque", + "st\032!.ListNamespaceDescriptorsResponse\022t\n" + + "\037ListTableDescriptorsByNamespace\022\'.ListT" + + "ableDescriptorsByNamespaceRequest\032(.List" + + "TableDescriptorsByNamespaceResponse\022b\n\031L" + + "istTableNamesByNamespace\022!.ListTableName" + + "sByNamespaceRequest\032\".ListTableNamesByNa" + + "mespaceResponse\022>\n\rGetTableState\022\025.GetTa" + + "bleStateRequest\032\026.GetTableStateResponse\022" + + "/\n\010SetQuota\022\020.SetQuotaRequest\032\021.SetQuota" + + "ResponseBB\n*org.apache.hadoop.hbase.prot", + "obuf.generatedB\014MasterProtosH\001\210\001\001\240\001\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -48536,7 +48889,7 @@ public final class MasterProtos { internal_static_GetTableDescriptorsRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_GetTableDescriptorsRequest_descriptor, - new java.lang.String[] { "TableNames", "Regex", }); + new java.lang.String[] { "TableNames", "Regex", "IncludeSysTables", }); internal_static_GetTableDescriptorsResponse_descriptor = getDescriptor().getMessageTypes().get(71); internal_static_GetTableDescriptorsResponse_fieldAccessorTable = new @@ -48548,7 +48901,7 @@ public final class MasterProtos { internal_static_GetTableNamesRequest_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_GetTableNamesRequest_descriptor, - new java.lang.String[] { }); + new java.lang.String[] { "Regex", "IncludeSysTables", }); internal_static_GetTableNamesResponse_descriptor = getDescriptor().getMessageTypes().get(73); internal_static_GetTableNamesResponse_fieldAccessorTable = new diff --git a/hbase-protocol/src/main/protobuf/Master.proto b/hbase-protocol/src/main/protobuf/Master.proto index 5d60e556140..82104f5ecdd 100644 --- a/hbase-protocol/src/main/protobuf/Master.proto +++ b/hbase-protocol/src/main/protobuf/Master.proto @@ -315,6 +315,7 @@ message GetSchemaAlterStatusResponse { message GetTableDescriptorsRequest { repeated TableName table_names = 1; optional string regex = 2; + optional bool include_sys_tables = 3 [default=false]; } message GetTableDescriptorsResponse { @@ -322,6 +323,8 @@ message GetTableDescriptorsResponse { } message GetTableNamesRequest { + optional string regex = 1; + optional bool include_sys_tables = 2 [default=false]; } message GetTableNamesResponse { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java index afc6ecfd9c3..9d702fafb4d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterAndRegionObserver.java @@ -418,23 +418,23 @@ public abstract class BaseMasterAndRegionObserver extends BaseRegionObserver @Override public void preGetTableDescriptors(ObserverContext ctx, - List tableNamesList, List descriptors) - throws IOException { - } - - @Override - public void preGetTableDescriptors(ObserverContext ctx, - List tableNamesList, List descriptors, String regex) - throws IOException { + List tableNamesList, List descriptors, + String regex) throws IOException { } @Override public void postGetTableDescriptors(ObserverContext ctx, - List descriptors) throws IOException { + List tableNamesList, List descriptors, + String regex) throws IOException { } @Override - public void postGetTableDescriptors(ObserverContext ctx, + public void preGetTableNames(ObserverContext ctx, + List descriptors, String regex) throws IOException { + } + + @Override + public void postGetTableNames(ObserverContext ctx, List descriptors, String regex) throws IOException { } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java index 3f0ffc21b0c..b26e7d4988d 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseMasterObserver.java @@ -409,11 +409,6 @@ public class BaseMasterObserver implements MasterObserver { final SnapshotDescription snapshot) throws IOException { } - @Override - public void preGetTableDescriptors(ObserverContext ctx, - List tableNamesList, List descriptors) throws IOException { - } - @Override public void preGetTableDescriptors(ObserverContext ctx, List tableNamesList, List descriptors, String regex) @@ -422,11 +417,17 @@ public class BaseMasterObserver implements MasterObserver { @Override public void postGetTableDescriptors(ObserverContext ctx, - List descriptors) throws IOException { + List tableNamesList, List descriptors, + String regex) throws IOException { } @Override - public void postGetTableDescriptors(ObserverContext ctx, + public void preGetTableNames(ObserverContext ctx, + List descriptors, String regex) throws IOException { + } + + @Override + public void postGetTableNames(ObserverContext ctx, List descriptors, String regex) throws IOException { } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java index 1e002109587..50912b36abe 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/MasterObserver.java @@ -688,18 +688,6 @@ public interface MasterObserver extends Coprocessor { void postDeleteSnapshot(final ObserverContext ctx, final SnapshotDescription snapshot) throws IOException; - /** - * Called before a getTableDescriptors request has been processed. - * @param ctx the environment to interact with the framework and master - * @param tableNamesList the list of table names, or null if querying for all - * @param descriptors an empty list, can be filled with what to return if bypassing - * @throws IOException - * @deprecated Use preGetTableDescriptors with regex instead. - */ - @Deprecated - void preGetTableDescriptors(ObserverContext ctx, - List tableNamesList, List descriptors) throws IOException; - /** * Called before a getTableDescriptors request has been processed. * @param ctx the environment to interact with the framework and master @@ -715,24 +703,37 @@ public interface MasterObserver extends Coprocessor { /** * Called after a getTableDescriptors request has been processed. * @param ctx the environment to interact with the framework and master - * @param descriptors the list of descriptors about to be returned - * @throws IOException - * @deprecated Use postGetTableDescriptors with regex instead. - */ - @Deprecated - void postGetTableDescriptors(ObserverContext ctx, - List descriptors) throws IOException; - - /** - * Called after a getTableDescriptors request has been processed. - * @param ctx the environment to interact with the framework and master + * @param tableNamesList the list of table names, or null if querying for all * @param descriptors the list of descriptors about to be returned * @param regex regular expression used for filtering the table names * @throws IOException */ void postGetTableDescriptors(ObserverContext ctx, + List tableNamesList, List descriptors, + String regex) throws IOException; + + /** + * Called before a getTableNames request has been processed. + * @param ctx the environment to interact with the framework and master + * @param descriptors an empty list, can be filled with what to return if bypassing + * @param regex regular expression used for filtering the table names + * @throws IOException + */ + void preGetTableNames(ObserverContext ctx, List descriptors, String regex) throws IOException; + /** + * Called after a getTableNames request has been processed. + * @param ctx the environment to interact with the framework and master + * @param descriptors the list of descriptors about to be returned + * @param regex regular expression used for filtering the table names + * @throws IOException + */ + void postGetTableNames(ObserverContext ctx, + List descriptors, String regex) throws IOException; + + + /** * Called before a new namespace is created by * {@link org.apache.hadoop.hbase.master.HMaster}. diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index af4abb02d07..9e7a679a33f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -27,13 +27,16 @@ import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -304,7 +307,7 @@ public class HMaster extends HRegionServer implements MasterServices, Server { this.preLoadTableDescriptors = conf.getBoolean("hbase.master.preload.tabledescriptors", true); // Do we publish the status? - + boolean shouldPublish = conf.getBoolean(HConstants.STATUS_PUBLISHED, HConstants.STATUS_PUBLISHED_DEFAULT); Class publisherClass = @@ -1997,4 +2000,116 @@ public class HMaster extends HRegionServer implements MasterServices, Server { } return tableNames; } + + /** + * Returns the list of table descriptors that match the specified request + * + * @param regex The regular expression to match against, or null if querying for all + * @param tableNameList the list of table names, or null if querying for all + * @param includeSysTables False to match only against userspace tables + * @return the list of table descriptors + */ + public List listTableDescriptors(final String regex, + final List tableNameList, final boolean includeSysTables) + throws IOException { + final List descriptors = new ArrayList(); + + boolean bypass = false; + if (cpHost != null) { + bypass = cpHost.preGetTableDescriptors(tableNameList, descriptors, regex); + } + + if (!bypass) { + if (tableNameList == null || tableNameList.size() == 0) { + // request for all TableDescriptors + Collection htds = tableDescriptors.getAll().values(); + for (HTableDescriptor desc: htds) { + if (includeSysTables || !desc.getTableName().isSystemTable()) { + descriptors.add(desc); + } + } + } else { + for (TableName s: tableNameList) { + HTableDescriptor desc = tableDescriptors.get(s); + if (desc != null) { + descriptors.add(desc); + } + } + } + + // Retains only those matched by regular expression. + if (regex != null) { + filterTablesByRegex(descriptors, Pattern.compile(regex)); + } + + if (cpHost != null) { + cpHost.postGetTableDescriptors(tableNameList, descriptors, regex); + } + } + return descriptors; + } + + /** + * Returns the list of table names that match the specified request + * @param regex The regular expression to match against, or null if querying for all + * @param includeSysTables False to match only against userspace tables + * @return the list of table names + */ + public List listTableNames(final String regex, final boolean includeSysTables) + throws IOException { + final List descriptors = new ArrayList(); + + boolean bypass = false; + if (cpHost != null) { + bypass = cpHost.preGetTableNames(descriptors, regex); + } + + if (!bypass) { + // get all descriptors + Collection htds = tableDescriptors.getAll().values(); + for (HTableDescriptor htd: htds) { + if (includeSysTables || !htd.getTableName().isSystemTable()) { + descriptors.add(htd); + } + } + + // Retains only those matched by regular expression. + if (regex != null) { + filterTablesByRegex(descriptors, Pattern.compile(regex)); + } + + if (cpHost != null) { + cpHost.postGetTableNames(descriptors, regex); + } + } + + List result = new ArrayList(descriptors.size()); + for (HTableDescriptor htd: descriptors) { + result.add(htd.getTableName()); + } + return result; + } + + + /** + * Removes the table descriptors that don't match the pattern. + * @param descriptors list of table descriptors to filter + * @param pattern the regex to use + */ + private static void filterTablesByRegex(final Collection descriptors, + final Pattern pattern) { + final String defaultNS = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR; + Iterator itr = descriptors.iterator(); + while (itr.hasNext()) { + HTableDescriptor htd = itr.next(); + String tableName = htd.getTableName().getNameAsString(); + boolean matched = pattern.matcher(tableName).matches(); + if (!matched && htd.getTableName().getNamespaceAsString().equals(defaultNS)) { + matched = pattern.matcher(defaultNS + TableName.NAMESPACE_DELIM + tableName).matches(); + } + if (!matched) { + itr.remove(); + } + } + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java index 31a5dabcfa1..cdddbfaa848 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterCoprocessorHost.java @@ -811,17 +811,6 @@ public class MasterCoprocessorHost }); } - public boolean preGetTableDescriptors(final List tableNamesList, - final List descriptors) throws IOException { - return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { - @Override - public void call(MasterObserver oserver, ObserverContext ctx) - throws IOException { - oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors); - } - }); - } - public boolean preGetTableDescriptors(final List tableNamesList, final List descriptors, final String regex) throws IOException { return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { @@ -833,24 +822,35 @@ public class MasterCoprocessorHost }); } - public void postGetTableDescriptors(final List descriptors) - throws IOException { + public void postGetTableDescriptors(final List tableNamesList, + final List descriptors, final String regex) throws IOException { execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { @Override public void call(MasterObserver oserver, ObserverContext ctx) throws IOException { - oserver.postGetTableDescriptors(ctx, descriptors); + oserver.postGetTableDescriptors(ctx, tableNamesList, descriptors, regex); } }); } - public void postGetTableDescriptors(final List descriptors, final String regex) - throws IOException { + public boolean preGetTableNames(final List descriptors, + final String regex) throws IOException { + return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { + @Override + public void call(MasterObserver oserver, ObserverContext ctx) + throws IOException { + oserver.preGetTableNames(ctx, descriptors, regex); + } + }); + } + + public void postGetTableNames(final List descriptors, + final String regex) throws IOException { execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { @Override public void call(MasterObserver oserver, ObserverContext ctx) throws IOException { - oserver.postGetTableDescriptors(ctx, descriptors, regex); + oserver.postGetTableNames(ctx, descriptors, regex); } }); } 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 470e8e30a7c..1c413689289 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 @@ -21,11 +21,8 @@ package org.apache.hadoop.hbase.master; import java.io.IOException; import java.net.InetAddress; import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -788,90 +785,30 @@ public class MasterRpcServices extends RSRpcServices GetTableDescriptorsRequest req) throws ServiceException { try { master.checkInitialized(); - } catch (IOException e) { - throw new ServiceException(e); - } - List descriptors = new ArrayList(); - List tableNameList = new ArrayList(); - for(HBaseProtos.TableName tableNamePB: req.getTableNamesList()) { - tableNameList.add(ProtobufUtil.toTableName(tableNamePB)); - } - boolean bypass = false; - String regex = req.hasRegex() ? req.getRegex() : null; - if (master.cpHost != null) { - try { - bypass = master.cpHost.preGetTableDescriptors(tableNameList, descriptors); - // method required for AccessController. - bypass |= master.cpHost.preGetTableDescriptors(tableNameList, descriptors, regex); - } catch (IOException ioe) { - throw new ServiceException(ioe); - } - } - - if (!bypass) { - if (req.getTableNamesCount() == 0) { - // request for all TableDescriptors - Map descriptorMap = null; - try { - descriptorMap = master.getTableDescriptors().getAll(); - } catch (IOException e) { - LOG.warn("Failed getting all descriptors", e); - } - if (descriptorMap != null) { - for(HTableDescriptor desc: descriptorMap.values()) { - if(!desc.getTableName().isSystemTable()) { - descriptors.add(desc); - } - } - } - } else { - for (TableName s: tableNameList) { - try { - HTableDescriptor desc = master.getTableDescriptors().get(s); - if (desc != null) { - descriptors.add(desc); - } - } catch (IOException e) { - LOG.warn("Failed getting descriptor for " + s, e); - } + final String regex = req.hasRegex() ? req.getRegex() : null; + List tableNameList = null; + if (req.getTableNamesCount() > 0) { + tableNameList = new ArrayList(req.getTableNamesCount()); + for (HBaseProtos.TableName tableNamePB: req.getTableNamesList()) { + tableNameList.add(ProtobufUtil.toTableName(tableNamePB)); } } - // Retains only those matched by regular expression. - if(regex != null) { - Pattern pat = Pattern.compile(regex); - for (Iterator itr = descriptors.iterator(); itr.hasNext(); ) { - HTableDescriptor htd = itr.next(); - String tableName = htd.getTableName().getNameAsString(); - String defaultNameSpace = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR; - boolean matched = pat.matcher(tableName).matches(); - if(!matched && htd.getTableName().getNamespaceAsString().equals(defaultNameSpace)) { - matched = pat.matcher(defaultNameSpace + TableName.NAMESPACE_DELIM + tableName) - .matches(); - } - if (!matched) - itr.remove(); - } - } + List descriptors = master.listTableDescriptors(regex, tableNameList, + req.getIncludeSysTables()); - if (master.cpHost != null) { - try { - master.cpHost.postGetTableDescriptors(descriptors); - // method required for AccessController. - master.cpHost.postGetTableDescriptors(descriptors, regex); - } catch (IOException ioe) { - throw new ServiceException(ioe); + GetTableDescriptorsResponse.Builder builder = GetTableDescriptorsResponse.newBuilder(); + if (descriptors != null && descriptors.size() > 0) { + // Add the table descriptors to the response + for (HTableDescriptor htd: descriptors) { + builder.addTableSchema(htd.convert()); } } + return builder.build(); + } catch (IOException ioe) { + throw new ServiceException(ioe); } - - - GetTableDescriptorsResponse.Builder builder = GetTableDescriptorsResponse.newBuilder(); - for (HTableDescriptor htd: descriptors) { - builder.addTableSchema(htd.convert()); - } - return builder.build(); } /** @@ -886,13 +823,16 @@ public class MasterRpcServices extends RSRpcServices GetTableNamesRequest req) throws ServiceException { try { master.checkServiceStarted(); - Collection descriptors = master.getTableDescriptors().getAll().values(); + + final String regex = req.hasRegex() ? req.getRegex() : null; + List tableNames = master.listTableNames(regex, req.getIncludeSysTables()); + GetTableNamesResponse.Builder builder = GetTableNamesResponse.newBuilder(); - for (HTableDescriptor descriptor: descriptors) { - if (descriptor.getTableName().isSystemTable()) { - continue; + if (tableNames != null && tableNames.size() > 0) { + // Add the table names to the response + for (TableName table: tableNames) { + builder.addTableNames(ProtobufUtil.toProtoTableName(table)); } - builder.addTableNames(ProtobufUtil.toProtoTableName(descriptor.getTableName())); } return builder.build(); } catch (IOException e) { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java index a9e530298c3..728669c69eb 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java @@ -430,6 +430,36 @@ public class AccessController extends BaseMasterAndRegionObserver } } + /** + * Authorizes that the current user has any of the given permissions to access the table. + * + * @param tableName Table requested + * @param permissions Actions being requested + * @throws IOException if obtaining the current user fails + * @throws AccessDeniedException if user has no authorization + */ + private void requireAccess(String request, TableName tableName, + Action... permissions) throws IOException { + User user = getActiveUser(); + AuthResult result = null; + + for (Action permission : permissions) { + if (authManager.hasAccess(user, tableName, permission)) { + result = AuthResult.allow(request, "Table permission granted", user, + permission, tableName, null, null); + break; + } else { + // rest of the world + result = AuthResult.deny(request, "Insufficient permissions", user, + permission, tableName, null, null); + } + } + logResult(result); + if (!result.isAllowed()) { + throw new AccessDeniedException("Insufficient permissions " + result.toContextString()); + } + } + /** * Authorizes that the current user has global privileges for the given action. * @param perm The action being requested @@ -976,7 +1006,7 @@ public class AccessController extends BaseMasterAndRegionObserver TableName tableName, final HTableDescriptor htd) throws IOException { final Configuration conf = c.getEnvironment().getConfiguration(); // default the table owner to current user, if not specified. - final String owner = (htd.getOwnerString() != null) ? htd.getOwnerString() : + final String owner = (htd.getOwnerString() != null) ? htd.getOwnerString() : getActiveUser().getShortName(); User.runAsLoginUser(new PrivilegedExceptionAction() { @Override @@ -2255,51 +2285,56 @@ public class AccessController extends BaseMasterAndRegionObserver List tableNamesList, List descriptors, String regex) throws IOException { // We are delegating the authorization check to postGetTableDescriptors as we don't have - // any concrete set of table names when regex is present. - if(regex == null) { - // If the list is empty, this is a request for all table descriptors and requires GLOBAL - // ADMIN privs. - if (tableNamesList == null || tableNamesList.isEmpty()) { - requireGlobalPermission("getTableDescriptors", Action.ADMIN, null, null); - } + // any concrete set of table names when a regex is present or the full list is requested. + if (regex == null && tableNamesList != null && !tableNamesList.isEmpty()) { // Otherwise, if the requestor has ADMIN or CREATE privs for all listed tables, the // request can be granted. - else { - MasterServices masterServices = ctx.getEnvironment().getMasterServices(); - for (TableName tableName: tableNamesList) { - // Skip checks for a table that does not exist - if (!masterServices.getTableStateManager().isTablePresent(tableName)) - continue; - requirePermission("getTableDescriptors", tableName, null, null, - Action.ADMIN, Action.CREATE); - } + MasterServices masterServices = ctx.getEnvironment().getMasterServices(); + for (TableName tableName: tableNamesList) { + // Skip checks for a table that does not exist + if (!masterServices.getTableStateManager().isTablePresent(tableName)) + continue; + requirePermission("getTableDescriptors", tableName, null, null, + Action.ADMIN, Action.CREATE); } } } @Override public void postGetTableDescriptors(ObserverContext ctx, - List descriptors, String regex) throws IOException { + List tableNamesList, List descriptors, + String regex) throws IOException { // Skipping as checks in this case are already done by preGetTableDescriptors. - if (regex == null) { + if (regex == null && tableNamesList != null && !tableNamesList.isEmpty()) { return; } - int numMatchedTables = descriptors.size(); + // Retains only those which passes authorization checks, as the checks weren't done as part // of preGetTableDescriptors. - for(Iterator itr = descriptors.iterator(); itr.hasNext();) { + Iterator itr = descriptors.iterator(); + while (itr.hasNext()) { HTableDescriptor htd = itr.next(); try { requirePermission("getTableDescriptors", htd.getTableName(), null, null, Action.ADMIN, Action.CREATE); - } catch(AccessDeniedException exception) { + } catch (AccessDeniedException e) { itr.remove(); } } + } - // Throws exception if none of the matched tables are authorized for the user. - if(numMatchedTables > 0 && descriptors.size() == 0) { - throw new AccessDeniedException("Insufficient permissions for accessing tables"); + @Override + public void postGetTableNames(ObserverContext ctx, + List descriptors, String regex) throws IOException { + // Retains only those which passes authorization checks. + Iterator itr = descriptors.iterator(); + while (itr.hasNext()) { + HTableDescriptor htd = itr.next(); + try { + requireAccess("getTableNames", htd.getTableName(), Action.values()); + } catch (AccessDeniedException e) { + itr.remove(); + } } } @@ -2369,7 +2404,7 @@ public class AccessController extends BaseMasterAndRegionObserver final String namespace, final Quotas quotas) throws IOException { requirePermission("setNamespaceQuota", Action.ADMIN); } - + @Override public ReplicationEndpoint postCreateReplicationEndPoint( ObserverContext ctx, ReplicationEndpoint endpoint) { diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/TableAuthManager.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/TableAuthManager.java index ae4af260405..4ed81dc7aca 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/TableAuthManager.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/TableAuthManager.java @@ -223,7 +223,7 @@ public class TableAuthManager { * Updates the internal permissions cache for a single table, splitting * the permissions listed into separate caches for users and groups to optimize * group lookups. - * + * * @param table * @param tablePerms */ @@ -349,6 +349,20 @@ public class TableAuthManager { return false; } + private boolean hasAccess(List perms, + TableName table, Permission.Action action) { + if (perms != null) { + for (TablePermission p : perms) { + if (p.implies(action)) { + return true; + } + } + } else if (LOG.isDebugEnabled()) { + LOG.debug("No permissions found for table="+table); + } + return false; + } + /** * Authorize a user for a given KV. This is called from AccessControlFilter. */ @@ -442,7 +456,7 @@ public class TableAuthManager { byte[] qualifier, Permission.Action action) { if (table == null) table = AccessControlLists.ACL_TABLE_NAME; // Global and namespace authorizations supercede table level - if (authorize(user, table.getNamespaceAsString(), action)) { + if (authorize(user, table.getNamespaceAsString(), action)) { return true; } // Check table permissions @@ -450,6 +464,25 @@ public class TableAuthManager { qualifier, action); } + /** + * Checks if the user has access to the full table or at least a family/qualifier + * for the specified action. + * + * @param user + * @param table + * @param action + * @return true if the user has access to the table, false otherwise + */ + public boolean userHasAccess(User user, TableName table, Permission.Action action) { + if (table == null) table = AccessControlLists.ACL_TABLE_NAME; + // Global and namespace authorizations supercede table level + if (authorize(user, table.getNamespaceAsString(), action)) { + return true; + } + // Check table permissions + return hasAccess(getTablePermissions(table).getUser(user.getShortName()), table, action); + } + /** * Checks global authorization for a given action for a group, based on the stored * permissions. @@ -460,7 +493,7 @@ public class TableAuthManager { /** * Checks authorization to a given table and column family for a group, based - * on the stored permissions. + * on the stored permissions. * @param groupName * @param table * @param family @@ -483,6 +516,29 @@ public class TableAuthManager { return authorize(getTablePermissions(table).getGroup(groupName), table, family, action); } + /** + * Checks if the user has access to the full table or at least a family/qualifier + * for the specified action. + * @param groupName + * @param table + * @param action + * @return true if the group has access to the table, false otherwise + */ + public boolean groupHasAccess(String groupName, TableName table, Permission.Action action) { + // Global authorization supercedes table level + if (authorizeGroup(groupName, action)) { + return true; + } + if (table == null) table = AccessControlLists.ACL_TABLE_NAME; + // Namespace authorization supercedes table level + if (hasAccess(getNamespacePermissions(table.getNamespaceAsString()).getGroup(groupName), + table, action)) { + return true; + } + // Check table level + return hasAccess(getTablePermissions(table).getGroup(groupName), table, action); + } + public boolean authorize(User user, TableName table, byte[] family, byte[] qualifier, Permission.Action action) { if (authorizeUser(user, table, family, qualifier, action)) { @@ -500,6 +556,22 @@ public class TableAuthManager { return false; } + public boolean hasAccess(User user, TableName table, Permission.Action action) { + if (userHasAccess(user, table, action)) { + return true; + } + + String[] groups = user.getGroupNames(); + if (groups != null) { + for (String group : groups) { + if (groupHasAccess(group, table, action)) { + return true; + } + } + } + return false; + } + public boolean authorize(User user, TableName table, byte[] family, Permission.Action action) { return authorize(user, table, family, null, action); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java index 8fc4471142b..d3593cdf829 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestMasterObserver.java @@ -54,6 +54,7 @@ import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.RequestConverter; import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription; import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsRequest; +import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableNamesRequest; import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas; import org.apache.hadoop.hbase.regionserver.HRegionServer; import org.apache.hadoop.hbase.testclassification.CoprocessorTests; @@ -150,6 +151,8 @@ public class TestMasterObserver { private boolean postModifyTableHandlerCalled; private boolean preGetTableDescriptorsCalled; private boolean postGetTableDescriptorsCalled; + private boolean postGetTableNamesCalled; + private boolean preGetTableNamesCalled; public void enableBypass(boolean bypass) { this.bypass = bypass; @@ -224,6 +227,8 @@ public class TestMasterObserver { postModifyTableHandlerCalled = false; preGetTableDescriptorsCalled = false; postGetTableDescriptorsCalled = false; + postGetTableNamesCalled = false; + preGetTableNamesCalled = false; } @Override @@ -773,11 +778,6 @@ public class TestMasterObserver { postDeleteSnapshotCalled = true; } - @Override - public void preGetTableDescriptors(ObserverContext ctx, - List tableNamesList, List descriptors) throws IOException { - } - public boolean wasDeleteSnapshotCalled() { return preDeleteSnapshotCalled && postDeleteSnapshotCalled; } @@ -1018,12 +1018,8 @@ public class TestMasterObserver { @Override public void postGetTableDescriptors(ObserverContext ctx, - List descriptors) throws IOException { - } - - @Override - public void postGetTableDescriptors(ObserverContext ctx, - List descriptors, String regex) throws IOException { + List tableNamesList, List descriptors, + String regex) throws IOException { postGetTableDescriptorsCalled = true; } @@ -1031,6 +1027,22 @@ public class TestMasterObserver { return preGetTableDescriptorsCalled && postGetTableDescriptorsCalled; } + @Override + public void preGetTableNames(ObserverContext ctx, + List descriptors, String regex) throws IOException { + preGetTableNamesCalled = true; + } + + @Override + public void postGetTableNames(ObserverContext ctx, + List descriptors, String regex) throws IOException { + postGetTableNamesCalled = true; + } + + public boolean wasGetTableNamesCalled() { + return preGetTableNamesCalled && postGetTableNamesCalled; + } + @Override public void preTableFlush(ObserverContext ctx, TableName tableName) throws IOException { @@ -1552,4 +1564,19 @@ public class TestMasterObserver { cp.wasGetTableDescriptorsCalled()); } + @Test + public void testTableNamesEnumeration() throws Exception { + MiniHBaseCluster cluster = UTIL.getHBaseCluster(); + + HMaster master = cluster.getMaster(); + MasterCoprocessorHost host = master.getMasterCoprocessorHost(); + CPMasterObserver cp = (CPMasterObserver)host.findCoprocessor( + CPMasterObserver.class.getName()); + cp.resetStates(); + + master.getMasterRpcServices().getTableNames(null, + GetTableNamesRequest.newBuilder().build()); + assertTrue("Coprocessor should be called on table names request", + cp.wasGetTableNamesCalled()); + } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java index 9f268c90e9d..fb7af84e155 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java @@ -26,6 +26,7 @@ import static org.junit.Assert.fail; import java.io.IOException; import java.security.PrivilegedAction; +import java.util.Arrays; import java.util.List; import org.apache.commons.logging.Log; @@ -264,7 +265,7 @@ public class TestAccessController extends SecureTestUtil { try { assertEquals(4, AccessControlClient.getUserPermissions(conf, TEST_TABLE.toString()).size()); } catch (Throwable e) { - LOG.error("error during call of AccessControlClient.getUserPermissions. " + e.getStackTrace()); + LOG.error("error during call of AccessControlClient.getUserPermissions. ", e); } } @@ -2059,11 +2060,14 @@ public class TestAccessController extends SecureTestUtil { AccessTestAction listTablesAction = new AccessTestAction() { @Override public Object run() throws Exception { - Admin admin = TEST_UTIL.getHBaseAdmin(); + Connection unmanagedConnection = + ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); + Admin admin = unmanagedConnection.getAdmin(); try { admin.listTables(); } finally { admin.close(); + unmanagedConnection.close(); } return null; } @@ -2072,23 +2076,47 @@ public class TestAccessController extends SecureTestUtil { AccessTestAction getTableDescAction = new AccessTestAction() { @Override public Object run() throws Exception { - Admin admin = TEST_UTIL.getHBaseAdmin(); + Connection unmanagedConnection = + ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); + Admin admin = unmanagedConnection.getAdmin(); try { admin.getTableDescriptor(TEST_TABLE.getTableName()); } finally { admin.close(); + unmanagedConnection.close(); } return null; } }; - verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN); - verifyDenied(listTablesAction, USER_CREATE, USER_RW, USER_RO, USER_NONE, TABLE_ADMIN); + verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN, USER_CREATE, TABLE_ADMIN); + verifyDenied(listTablesAction, USER_RW, USER_RO, USER_NONE); verifyAllowed(getTableDescAction, SUPERUSER, USER_ADMIN, USER_CREATE, TABLE_ADMIN); verifyDenied(getTableDescAction, USER_RW, USER_RO, USER_NONE); } + @Test + public void testTableNameEnumeration() throws Exception { + AccessTestAction listTablesAction = new AccessTestAction() { + @Override + public Object run() throws Exception { + Connection unmanagedConnection = + ConnectionFactory.createConnection(TEST_UTIL.getConfiguration()); + Admin admin = unmanagedConnection.getAdmin(); + try { + return Arrays.asList(admin.listTableNames()); + } finally { + admin.close(); + unmanagedConnection.close(); + } + } + }; + + verifyAllowed(listTablesAction, SUPERUSER, USER_ADMIN, USER_CREATE, USER_RW, USER_RO); + verifyDenied(listTablesAction, USER_NONE); + } + @Test public void testTableDeletion() throws Exception { User TABLE_ADMIN = User.createUserForTesting(conf, "TestUser", new String[0]); @@ -2166,7 +2194,7 @@ public class TestAccessController extends SecureTestUtil { grantOnTableUsingAccessControlClient(TEST_UTIL, conf, testGrantRevoke.getShortName(), TEST_TABLE.getTableName(), null, null, Permission.Action.READ); } catch (Throwable e) { - LOG.error("error during call of AccessControlClient.grant. " + e.getStackTrace()); + LOG.error("error during call of AccessControlClient.grant. ", e); } // Now testGrantRevoke should be able to read also @@ -2177,7 +2205,7 @@ public class TestAccessController extends SecureTestUtil { revokeFromTableUsingAccessControlClient(TEST_UTIL, conf, testGrantRevoke.getShortName(), TEST_TABLE.getTableName(), null, null, Permission.Action.READ); } catch (Throwable e) { - LOG.error("error during call of AccessControlClient.revoke " + e.getStackTrace()); + LOG.error("error during call of AccessControlClient.revoke ", e); } // Now testGrantRevoke shouldn't be able read @@ -2207,7 +2235,7 @@ public class TestAccessController extends SecureTestUtil { grantOnNamespaceUsingAccessControlClient(TEST_UTIL, conf, testNS.getShortName(), TEST_TABLE.getTableName().getNamespaceAsString(), Permission.Action.READ); } catch (Throwable e) { - LOG.error("error during call of AccessControlClient.grant. " + e.getStackTrace()); + LOG.error("error during call of AccessControlClient.grant. ", e); } // Now testNS should be able to read also @@ -2218,7 +2246,7 @@ public class TestAccessController extends SecureTestUtil { revokeFromNamespaceUsingAccessControlClient(TEST_UTIL, conf, testNS.getShortName(), TEST_TABLE.getTableName().getNamespaceAsString(), Permission.Action.READ); } catch (Throwable e) { - LOG.error("error during call of AccessControlClient.revoke " + e.getStackTrace()); + LOG.error("error during call of AccessControlClient.revoke ", e); } // Now testNS shouldn't be able read @@ -2451,8 +2479,7 @@ public class TestAccessController extends SecureTestUtil { try { return AccessControlClient.getUserPermissions(conf, regex); } catch (Throwable e) { - LOG.error("error during call of AccessControlClient.getUserPermissions. " - + e.getStackTrace()); + LOG.error("error during call of AccessControlClient.getUserPermissions.", e); return null; } } @@ -2462,10 +2489,12 @@ public class TestAccessController extends SecureTestUtil { @Test public void testAccessControlClientUserPerms() throws Exception { // adding default prefix explicitly as it is not included in the table name. - final String regex = TEST_TABLE.getTableName().getNamespaceAsString() + ":" - + TEST_TABLE.getTableName().getNameAsString(); + assertEquals(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR, + TEST_TABLE.getTableName().getNamespaceAsString()); + final String regex = NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR + + TableName.NAMESPACE_DELIM + TEST_TABLE.getTableName().getNameAsString(); User testUserPerms = User.createUserForTesting(conf, "testUserPerms", new String[0]); - assertNull(testUserPerms.runAs(getPrivilegedAction(regex))); + assertEquals(0, testUserPerms.runAs(getPrivilegedAction(regex)).size()); // Grant TABLE ADMIN privs to testUserPerms grantOnTable(TEST_UTIL, testUserPerms.getShortName(), TEST_TABLE.getTableName(), null, null, Action.ADMIN); @@ -2475,12 +2504,12 @@ public class TestAccessController extends SecureTestUtil { assertEquals(5, perms.size()); } - - @Test - public void testAccessControllerRegexHandling() throws Exception { + public void testAccessControllerUserPermsRegexHandling() throws Exception { User testRegexHandler = User.createUserForTesting(conf, "testRegexHandling", new String[0]); - String tableName = "testRegex"; + + final String REGEX_ALL_TABLES = ".*"; + final String tableName = "testRegex"; final TableName table1 = TableName.valueOf(tableName); final byte[] family = Bytes.toBytes("f1"); @@ -2494,20 +2523,32 @@ public class TestAccessController extends SecureTestUtil { // creating the ns and table in it String ns = "testNamespace"; NamespaceDescriptor desc = NamespaceDescriptor.create(ns).build(); - final TableName table2 = TableName.valueOf(ns + ":" + tableName); + final TableName table2 = TableName.valueOf(ns, tableName); TEST_UTIL.getMiniHBaseCluster().getMaster().createNamespace(desc); htd = new HTableDescriptor(table2); htd.addFamily(new HColumnDescriptor(family)); admin.createTable(htd); + TEST_UTIL.waitUntilAllRegionsAssigned(table2); + + // Verify that we can read sys-tables + String aclTableName = AccessControlLists.ACL_TABLE_NAME.getNameAsString(); + assertEquals(1, SUPERUSER.runAs(getPrivilegedAction(aclTableName)).size()); + assertEquals(0, testRegexHandler.runAs(getPrivilegedAction(aclTableName)).size()); // Grant TABLE ADMIN privs to testUserPerms + assertEquals(0, testRegexHandler.runAs(getPrivilegedAction(REGEX_ALL_TABLES)).size()); grantOnTable(TEST_UTIL, testRegexHandler.getShortName(), table1, null, null, Action.ADMIN); + assertEquals(2, testRegexHandler.runAs(getPrivilegedAction(REGEX_ALL_TABLES)).size()); grantOnTable(TEST_UTIL, testRegexHandler.getShortName(), table2, null, null, Action.ADMIN); + assertEquals(4, testRegexHandler.runAs(getPrivilegedAction(REGEX_ALL_TABLES)).size()); // USER_ADMIN, testUserPerms must have a row each. assertEquals(2, testRegexHandler.runAs(getPrivilegedAction(tableName)).size()); - assertEquals(2, testRegexHandler.runAs(getPrivilegedAction("default:" + tableName)).size()); - assertEquals(2, testRegexHandler.runAs(getPrivilegedAction(ns + ":" + tableName)).size()); + assertEquals(2, testRegexHandler.runAs(getPrivilegedAction( + NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR + TableName.NAMESPACE_DELIM + tableName) + ).size()); + assertEquals(2, testRegexHandler.runAs(getPrivilegedAction( + ns + TableName.NAMESPACE_DELIM + tableName)).size()); assertEquals(0, testRegexHandler.runAs(getPrivilegedAction("notMatchingAny")).size()); TEST_UTIL.deleteTable(table1); diff --git a/hbase-shell/src/main/ruby/hbase/admin.rb b/hbase-shell/src/main/ruby/hbase/admin.rb index 2c8828e2a4f..748a41ccb02 100644 --- a/hbase-shell/src/main/ruby/hbase/admin.rb +++ b/hbase-shell/src/main/ruby/hbase/admin.rb @@ -43,7 +43,7 @@ module Hbase #---------------------------------------------------------------------------------------------- # Returns a list of tables in hbase def list(regex = ".*") - @admin.getTableNames(regex).to_a + @admin.listTableNames(regex).map { |t| t.getNameAsString } end #----------------------------------------------------------------------------------------------