HBASE-11438 - [Visibility Controller] Support UTF8 character as Visibility

Labels (ram)
This commit is contained in:
Ramkrishna 2014-08-14 12:41:16 +05:30
parent c60cfbc999
commit c1660a7962
9 changed files with 302 additions and 132 deletions

View File

@ -36,22 +36,11 @@ public class Authorizations {
public Authorizations(String... labels) {
this.labels = new ArrayList<String>(labels.length);
for (String label : labels) {
validateLabel(label);
this.labels.add(label);
}
}
private void validateLabel(String label) {
if (!VisibilityLabelsValidator.isValidLabel(label)) {
throw new IllegalArgumentException("Invalid authorization label : " + label
+ ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " and cannot be empty");
}
}
public Authorizations(List<String> labels) {
for (String label : labels) {
validateLabel(label);
}
this.labels = labels;
}

View File

@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.security.visibility;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.hbase.util.Bytes;
/**
* This contains a visibility expression which can be associated with a cell. When it is set with a
@ -46,4 +47,40 @@ public class CellVisibility {
public String toString() {
return this.expression;
}
/**
* Helps in quoting authentication Strings. Use this if unicode characters to
* be used in expression or special characters like '(', ')',
* '"','\','&','|','!'
*/
public static String quote(String auth) {
return quote(Bytes.toBytes(auth));
}
/**
* Helps in quoting authentication Strings. Use this if unicode characters to
* be used in expression or special characters like '(', ')',
* '"','\','&','|','!'
*/
public static String quote(byte[] auth) {
int escapeChars = 0;
for (int i = 0; i < auth.length; i++)
if (auth[i] == '"' || auth[i] == '\\')
escapeChars++;
byte[] escapedAuth = new byte[auth.length + escapeChars + 2];
int index = 1;
for (int i = 0; i < auth.length; i++) {
if (auth[i] == '"' || auth[i] == '\\') {
escapedAuth[index++] = '\\';
}
escapedAuth[index++] = auth[i];
}
escapedAuth[0] = '"';
escapedAuth[escapedAuth.length - 1] = '"';
return Bytes.toString(escapedAuth);
}
}

View File

@ -17,7 +17,6 @@
*/
package org.apache.hadoop.hbase.security.visibility;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.classification.InterfaceAudience;
@ -60,7 +59,7 @@ public class VisibilityLabelsValidator {
return validAuthChars[0xff & b];
}
static final boolean isValidLabel(byte[] label) {
public static final boolean isValidLabel(byte[] label) {
for (int i = 0; i < label.length; i++) {
if (!isValidAuthChar(label[i])) {
return false;
@ -68,9 +67,4 @@ public class VisibilityLabelsValidator {
}
return true;
}
public static final boolean isValidLabel(String label) {
Matcher matcher = pattern.matcher(label);
return matcher.matches();
}
}

View File

@ -114,56 +114,21 @@ public class TestScan {
@Test
public void testSetAuthorizations() {
Scan scan = new Scan();
scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a"));
try {
scan.setAuthorizations(new Authorizations("\u002b|\u0029"));
scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a"));
scan.setAuthorizations(new Authorizations("A|B"));
fail("Should have failed for A|B.");
} catch (IllegalArgumentException e) {
}
try {
scan.setAuthorizations(new Authorizations("A&B"));
fail("Should have failed for A&B.");
} catch (IllegalArgumentException e) {
}
try {
scan.setAuthorizations(new Authorizations("!B"));
fail("Should have failed for !B.");
} catch (IllegalArgumentException e) {
}
try {
scan.setAuthorizations(new Authorizations("A", "(A)"));
fail("Should have failed for (A).");
} catch (IllegalArgumentException e) {
}
try {
scan.setAuthorizations(new Authorizations("A", "{A"));
fail("Should have failed for {A.");
} catch (IllegalArgumentException e) {
}
try {
scan.setAuthorizations(new Authorizations(" "));
fail("Should have failed for empty");
} catch (IllegalArgumentException e) {
}
try {
scan.setAuthorizations(new Authorizations(":B"));
} catch (IllegalArgumentException e) {
fail("Should not have failed for :B");
}
try {
scan.setAuthorizations(new Authorizations("-B"));
} catch (IllegalArgumentException e) {
fail("Should not have failed for -B");
}
try {
scan.setAuthorizations(new Authorizations(".B"));
} catch (IllegalArgumentException e) {
fail("Should not have failed for .B");
}
try {
scan.setAuthorizations(new Authorizations("/B"));
} catch (IllegalArgumentException e) {
fail("Should not have failed for /B");
fail("should not throw exception");
}
}
}

View File

@ -70,12 +70,11 @@ import org.apache.hadoop.hbase.filter.WhileMatchFilter;
import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
import org.apache.hadoop.hbase.rest.protobuf.generated.ScannerMessage.Scanner;
import org.apache.hadoop.hbase.security.visibility.Authorizations;
import org.apache.hadoop.hbase.security.visibility.VisibilityLabelsValidator;
import org.apache.hadoop.hbase.util.Base64;
import org.apache.hadoop.hbase.util.ByteStringer;
import org.apache.hadoop.hbase.util.Bytes;
import com.google.protobuf.ByteString;
import org.apache.hadoop.hbase.util.ByteStringer;
import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext;
import com.sun.jersey.api.json.JSONMarshaller;
@ -527,11 +526,6 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
if (authorizations != null) {
List<String> labels = authorizations.getLabels();
for (String label : labels) {
if (!VisibilityLabelsValidator.isValidLabel(label)) {
throw new IllegalArgumentException("Invalid authorization label : " + label
+ ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " " +
"and cannot be empty");
}
model.addLabel(label);
}
}

View File

@ -17,6 +17,8 @@
*/
package org.apache.hadoop.hbase.security.visibility;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.apache.hadoop.classification.InterfaceAudience;
@ -35,49 +37,80 @@ public class ExpressionParser {
private static final char AND = '&';
private static final char NOT = '!';
private static final char SPACE = ' ';
private static final char DOUBLE_QUOTES = '"';
public ExpressionNode parse(String expS) throws ParseException {
expS = expS.trim();
Stack<ExpressionNode> expStack = new Stack<ExpressionNode>();
int index = 0;
int endPos = expS.length();
byte[] exp = Bytes.toBytes(expS);
int endPos = exp.length;
while (index < endPos) {
byte b = exp[index];
switch (b) {
case OPEN_PARAN:
processOpenParan(expStack, expS, index);
index = skipSpaces(exp, index);
break;
case CLOSE_PARAN:
processCloseParan(expStack, expS, index);
index = skipSpaces(exp, index);
break;
case AND:
case OR:
processANDorOROp(getOperator(b), expStack, expS, index);
index = skipSpaces(exp, index);
break;
case NOT:
processNOTOp(expStack, expS, index);
break;
default:
int labelOffset = index;
do {
if (!VisibilityLabelsValidator.isValidAuthChar(exp[index])) {
throw new ParseException("Error parsing expression " + expS + " at column : "
+ index);
case OPEN_PARAN:
processOpenParan(expStack, expS, index);
index = skipSpaces(exp, index);
break;
case CLOSE_PARAN:
processCloseParan(expStack, expS, index);
index = skipSpaces(exp, index);
break;
case AND:
case OR:
processANDorOROp(getOperator(b), expStack, expS, index);
index = skipSpaces(exp, index);
break;
case NOT:
processNOTOp(expStack, expS, index);
break;
case DOUBLE_QUOTES:
int labelOffset = ++index;
// We have to rewrite the expression within double quotes as incase of expressions
// with escape characters we may have to avoid them as the original expression did
// not have them
List<Byte> list = new ArrayList<Byte>();
while (index < endPos && !endDoubleQuotesFound(exp[index])) {
if (exp[index] == '\\') {
index++;
if (exp[index] != '\\' && exp[index] != '"')
throw new ParseException("invalid escaping with quotes " + expS + " at column : "
+ index);
}
list.add(exp[index]);
index++;
}
index++;
} while (index < endPos && !isEndOfLabel(exp[index]));
String leafExp = new String(exp, labelOffset, index - labelOffset).trim();
if (leafExp.isEmpty()) {
throw new ParseException("Error parsing expression " + expS + " at column : " + index);
}
processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index);
// We already crossed the label node index. So need to reduce 1 here.
index--;
index = skipSpaces(exp, index);
// The expression has come to the end. still no double quotes found
if(index == endPos) {
throw new ParseException("No terminating quotes " + expS + " at column : " + index);
}
// This could be costly. but do we have any alternative?
// If we don't do this way then we may have to handle while checking the authorizations.
// Better to do it here.
byte[] array = com.google.common.primitives.Bytes.toArray(list);
String leafExp = new String(array).trim();
if (leafExp.isEmpty()) {
throw new ParseException("Error parsing expression " + expS + " at column : " + index);
}
processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index);
index = skipSpaces(exp, index);
break;
default:
labelOffset = index;
do {
if (!VisibilityLabelsValidator.isValidAuthChar(exp[index])) {
throw new ParseException("Error parsing expression "
+ expS + " at column : " + index);
}
index++;
} while (index < endPos && !isEndOfLabel(exp[index]));
leafExp = new String(exp, labelOffset, index - labelOffset).trim();
if (leafExp.isEmpty()) {
throw new ParseException("Error parsing expression " + expS + " at column : " + index);
}
processLabelExpNode(new LeafExpressionNode(leafExp), expStack, expS, index);
// We already crossed the label node index. So need to reduce 1 here.
index--;
index = skipSpaces(exp, index);
}
index++;
}
@ -255,8 +288,12 @@ public class ExpressionParser {
expStack.push(new NonLeafExpressionNode(Operator.NOT));
}
private static boolean endDoubleQuotesFound(byte b) {
return (b == DOUBLE_QUOTES);
}
private static boolean isEndOfLabel(byte b) {
return (b == OPEN_PARAN || b == CLOSE_PARAN || b == OR || b == AND || b == NOT || b == SPACE);
return (b == OPEN_PARAN || b == CLOSE_PARAN || b == OR || b == AND ||
b == NOT || b == SPACE);
}
private static Operator getOperator(byte op) {

View File

@ -53,11 +53,11 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValue.Type;
import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.Tag;
import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.client.Append;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
@ -1149,13 +1149,6 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb
if (table.isSystemTable() && !table.equals(LABELS_TABLE_NAME)) {
return null;
}
} else {
for (String label : authorizations.getLabels()) {
if (!VisibilityLabelsValidator.isValidLabel(label)) {
throw new IllegalArgumentException("Invalid authorization label : " + label
+ ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " and cannot be empty");
}
}
}
Filter visibilityLabelFilter = null;
if (this.scanLabelGenerators != null) {
@ -1310,30 +1303,21 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb
for (VisibilityLabel visLabel : labels) {
byte[] label = visLabel.getLabel().toByteArray();
String labelStr = Bytes.toString(label);
if (VisibilityLabelsValidator.isValidLabel(label)) {
if (this.visibilityManager.getLabelOrdinal(labelStr) > 0) {
RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
failureResultBuilder.setException(ResponseConverter
.buildException(new LabelAlreadyExistsException("Label '" + labelStr
+ "' already exists")));
response.addResult(failureResultBuilder.build());
} else {
Put p = new Put(Bytes.toBytes(ordinalCounter));
p.addImmutable(
LABELS_TABLE_FAMILY, LABEL_QUALIFIER, label, LABELS_TABLE_TAGS);
if (LOG.isDebugEnabled()) {
LOG.debug("Adding the label "+labelStr);
}
puts.add(p);
ordinalCounter++;
response.addResult(successResult);
}
} else {
if (this.visibilityManager.getLabelOrdinal(labelStr) > 0) {
RegionActionResult.Builder failureResultBuilder = RegionActionResult.newBuilder();
failureResultBuilder.setException(ResponseConverter
.buildException(new InvalidLabelException("Invalid visibility label '" + labelStr
+ "'")));
.buildException(new LabelAlreadyExistsException("Label '" + labelStr
+ "' already exists")));
response.addResult(failureResultBuilder.build());
} else {
Put p = new Put(Bytes.toBytes(ordinalCounter));
p.addImmutable(LABELS_TABLE_FAMILY, LABEL_QUALIFIER, label, LABELS_TABLE_TAGS);
if (LOG.isDebugEnabled()) {
LOG.debug("Adding the label " + labelStr);
}
puts.add(p);
ordinalCounter++;
response.addResult(successResult);
}
}
OperationStatus[] opStatus = this.regionEnv.getRegion().batchMutate(

View File

@ -17,9 +17,9 @@
*/
package org.apache.hadoop.hbase.security.visibility;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.security.visibility.expression.ExpressionNode;
@ -308,6 +308,99 @@ public class TestExpressionParser {
executeNegativeCase("! a");
}
@Test
public void testNonAsciiCases() throws Exception {
ExpressionNode node = parser.parse(CellVisibility.quote("\u0027") + "&"
+ CellVisibility.quote("\u002b") + "|" + CellVisibility.quote("\u002d") + "&"
+ CellVisibility.quote("\u003f"));
assertTrue(node instanceof NonLeafExpressionNode);
NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u003f", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u002d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u002b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
node = parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\u002b") + "|"
+ CellVisibility.quote("\u002d") + "&" + CellVisibility.quote("\u003f"));
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u003f", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u002d", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u002b", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
}
@Test
public void testCasesSeperatedByDoubleQuotes() throws Exception {
ExpressionNode node = null;
try {
node = parser.parse("\u0027&\"|\u002b&\u003f");
fail("Excpetion must be thrown as there are special characters without quotes");
} catch (ParseException e) {
}
node = parser.parse(CellVisibility.quote("\u0027") + "&" + CellVisibility.quote("\"") + "|"
+ CellVisibility.quote("\u002b" + "&" + "\u003f"));
assertTrue(node instanceof NonLeafExpressionNode);
NonLeafExpressionNode nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u002b" + "&" + "\u003f",
((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\"", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertEquals("\u0027", ((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
try {
node = parser.parse(CellVisibility.quote("\u0027&\\") + "|"
+ CellVisibility.quote("\u002b" + "&" + "\\") + CellVisibility.quote("$$\""));
fail("Excpetion must be thrown as there is not operator");
} catch (ParseException e) {
}
node = parser.parse(CellVisibility.quote("\u0027" + "&" + "\\") + "|"
+ CellVisibility.quote("\u003f" + "&" + "\\") + "&" + CellVisibility.quote("$$\""));
assertTrue(node instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) node;
assertEquals(Operator.AND, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("$$\"", ((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
assertTrue(nlNode.getChildExps().get(0) instanceof NonLeafExpressionNode);
nlNode = (NonLeafExpressionNode) nlNode.getChildExps().get(0);
assertEquals(Operator.OR, nlNode.getOperator());
assertEquals(2, nlNode.getChildExps().size());
assertEquals("\u0027" + "&" + "\\",
((LeafExpressionNode) nlNode.getChildExps().get(0)).getIdentifier());
assertEquals("\u003f" + "&" + "\\",
((LeafExpressionNode) nlNode.getChildExps().get(1)).getIdentifier());
try {
node = parser.parse(CellVisibility.quote("\u002b&\\") + "|" + CellVisibility.quote("\u0027&\\") + "&"
+ "\"$$");
fail("Excpetion must be thrown as there is no end quote");
} catch (ParseException e) {
}
}
private void executeNegativeCase(String exp) {
try {
parser.parse(exp);

View File

@ -83,6 +83,12 @@ public class TestVisibilityLabels {
private static final String PRIVATE = "private";
private static final String CONFIDENTIAL = "confidential";
private static final String SECRET = "secret";
private static final String COPYRIGHT = "\u00A9ABC";
private static final String ACCENT = "\u0941";
private static final String UNICODE_VIS_TAG = COPYRIGHT + "\"" + ACCENT + "\\" + SECRET + "\""
+ "\u0027&\\";
private static final String UC1 = "\u0027\"\u002b";
private static final String UC2 = "\u002d\u003f";
public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private static final byte[] row1 = Bytes.toBytes("row1");
private static final byte[] row2 = Bytes.toBytes("row2");
@ -154,6 +160,77 @@ public class TestVisibilityLabels {
}
}
}
@Test
public void testSimpleVisibilityLabelsWithUniCodeCharacters() throws Exception {
TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
HTable table = createTableAndWriteDataWithLabels(tableName,
SECRET + "|" + CellVisibility.quote(COPYRIGHT), "(" + CellVisibility.quote(COPYRIGHT) + "&"
+ CellVisibility.quote(ACCENT) + ")|" + CONFIDENTIAL,
CellVisibility.quote(UNICODE_VIS_TAG) + "&" + SECRET);
try {
Scan s = new Scan();
s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL, PRIVATE, COPYRIGHT, ACCENT,
UNICODE_VIS_TAG));
ResultScanner scanner = table.getScanner(s);
Result[] next = scanner.next(3);
assertTrue(next.length == 3);
CellScanner cellScanner = next[0].cellScanner();
cellScanner.advance();
Cell current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
current.getRowLength(), row1, 0, row1.length));
cellScanner = next[1].cellScanner();
cellScanner.advance();
current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
current.getRowLength(), row2, 0, row2.length));
cellScanner = next[2].cellScanner();
cellScanner.advance();
current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
current.getRowLength(), row3, 0, row3.length));
} finally {
if (table != null) {
table.close();
}
}
}
@Test
public void testAuthorizationsWithSpecialUnicodeCharacters() throws Exception {
TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
HTable table = createTableAndWriteDataWithLabels(tableName,
CellVisibility.quote(UC1) + "|" + CellVisibility.quote(UC2), CellVisibility.quote(UC1),
CellVisibility.quote(UNICODE_VIS_TAG));
try {
Scan s = new Scan();
s.setAuthorizations(new Authorizations(UC1, UC2, ACCENT,
UNICODE_VIS_TAG));
ResultScanner scanner = table.getScanner(s);
Result[] next = scanner.next(3);
assertTrue(next.length == 3);
CellScanner cellScanner = next[0].cellScanner();
cellScanner.advance();
Cell current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
current.getRowLength(), row1, 0, row1.length));
cellScanner = next[1].cellScanner();
cellScanner.advance();
current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
current.getRowLength(), row2, 0, row2.length));
cellScanner = next[2].cellScanner();
cellScanner.advance();
current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
current.getRowLength(), row3, 0, row3.length));
} finally {
if (table != null) {
table.close();
}
}
}
@Test
public void testVisibilityLabelsWithComplexLabels() throws Exception {
@ -406,7 +483,7 @@ public class TestVisibilityLabels {
}
}
// One label is the "system" label.
Assert.assertEquals("The count should be 8", 8, i);
Assert.assertEquals("The count should be 13", 13, i);
}
private void waitForLabelsRegionAvailability(HRegionServer regionServer) {
@ -466,8 +543,7 @@ public class TestVisibilityLabels {
assertEquals("org.apache.hadoop.hbase.security.visibility.LabelAlreadyExistsException",
resultList.get(1).getException().getName());
assertTrue(resultList.get(2).getException().getValue().isEmpty());
assertEquals("org.apache.hadoop.hbase.security.visibility.InvalidLabelException",
resultList.get(3).getException().getName());
assertTrue(resultList.get(3).getException().getValue().isEmpty());
assertTrue(resultList.get(4).getException().getValue().isEmpty());
return null;
}
@ -929,7 +1005,8 @@ public class TestVisibilityLabels {
PrivilegedExceptionAction<VisibilityLabelsResponse> action =
new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
public VisibilityLabelsResponse run() throws Exception {
String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE };
String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE, COPYRIGHT, ACCENT,
UNICODE_VIS_TAG, UC1, UC2 };
try {
VisibilityClient.addLabels(conf, labels);
} catch (Throwable t) {