Repository: hbase
Updated Branches:
refs/heads/0.98 735a5bd87 -> 0ada8c0a7
HBASE-14761 Deletes with and without visibility expression do not delete
the matching mutation (Ram)
Conflicts:
hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityScanDeleteTracker.java
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/0ada8c0a
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/0ada8c0a
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/0ada8c0a
Branch: refs/heads/0.98
Commit: 0ada8c0a7ac645efe4843aba0a02ff4c9ee0dc20
Parents: 735a5bd
Author: ramkrishna <[email protected]>
Authored: Thu Nov 19 11:20:45 2015 +0530
Committer: ramkrishna <[email protected]>
Committed: Thu Nov 19 14:15:46 2015 +0530
----------------------------------------------------------------------
.../visibility/VisibilityScanDeleteTracker.java | 241 ++++++++--------
.../TestVisibilityLabelsWithDeletes.java | 287 +++++++++++++++++++
2 files changed, 415 insertions(+), 113 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/0ada8c0a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityScanDeleteTracker.java
----------------------------------------------------------------------
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityScanDeleteTracker.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityScanDeleteTracker.java
index 5288fe2..80de607 100644
---
a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityScanDeleteTracker.java
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityScanDeleteTracker.java
@@ -117,70 +117,58 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
// If tag is present in the delete
boolean hasVisTag = false;
if (delCell.getTagsLengthUnsigned() > 0) {
+ Byte deleteCellVisTagsFormat = null;
switch (type) {
- case DeleteFamily:
- List<Tag> delTags = new ArrayList<Tag>();
- if (visibilityTagsDeleteFamily != null) {
- Byte deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
- if (!delTags.isEmpty()) {
- visibilityTagsDeleteFamily.add(new Triple<List<Tag>, Byte, Long>(
- delTags, deleteCellVisTagsFormat, delCell.getTimestamp()));
- hasVisTag = true;
- }
- }
- break;
- case DeleteFamilyVersion:
- delTags = new ArrayList<Tag>();
- Byte deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
- if (!delTags.isEmpty()) {
- visibilityTagsDeleteFamilyVersion.add(new Triple<List<Tag>, Byte,
Long>(delTags,
- deleteCellVisTagsFormat, delCell.getTimestamp()));
- hasVisTag = true;
- }
- break;
- case DeleteColumn:
- if (visibilityTagsDeleteColumns == null) {
- visibilityTagsDeleteColumns = new ArrayList<Pair<List<Tag>,
Byte>>();
- }
- delTags = new ArrayList<Tag>();
- deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
- if (!delTags.isEmpty()) {
- visibilityTagsDeleteColumns.add(new Pair<List<Tag>, Byte>(delTags,
- deleteCellVisTagsFormat));
- hasVisTag = true;
- }
- break;
- case Delete:
- if (visiblityTagsDeleteColumnVersion == null) {
- visiblityTagsDeleteColumnVersion = new ArrayList<Pair<List<Tag>,
Byte>>();
- }
- delTags = new ArrayList<Tag>();
- deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
- if (!delTags.isEmpty()) {
- visiblityTagsDeleteColumnVersion.add(new Pair<List<Tag>,
Byte>(delTags,
- deleteCellVisTagsFormat));
- hasVisTag = true;
- }
- break;
- default:
- throw new IllegalArgumentException("Invalid delete type");
- }
- } else {
- switch (type) {
- case DeleteFamily:
- visibilityTagsDeleteFamily = null;
- break;
- case DeleteFamilyVersion:
- visibilityTagsDeleteFamilyVersion = null;
- break;
- case DeleteColumn:
- visibilityTagsDeleteColumns = null;
- break;
- case Delete:
- visiblityTagsDeleteColumnVersion = null;
- break;
- default:
- throw new IllegalArgumentException("Invalid delete type");
+ case DeleteFamily:
+ List<Tag> delTags = new ArrayList<Tag>();
+ if (visibilityTagsDeleteFamily == null) {
+ visibilityTagsDeleteFamily = new ArrayList<Triple<List<Tag>, Byte,
Long>>();
+ }
+ deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
+ if (!delTags.isEmpty()) {
+ visibilityTagsDeleteFamily.add(new Triple<List<Tag>, Byte,
Long>(delTags,
+ deleteCellVisTagsFormat, delCell.getTimestamp()));
+ hasVisTag = true;
+ }
+ break;
+ case DeleteFamilyVersion:
+ if(visibilityTagsDeleteFamilyVersion == null) {
+ visibilityTagsDeleteFamilyVersion = new ArrayList<Triple<List<Tag>,
Byte, Long>>();
+ }
+ delTags = new ArrayList<Tag>();
+ deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
+ if (!delTags.isEmpty()) {
+ visibilityTagsDeleteFamilyVersion.add(new Triple<List<Tag>, Byte,
Long>(delTags,
+ deleteCellVisTagsFormat, delCell.getTimestamp()));
+ hasVisTag = true;
+ }
+ break;
+ case DeleteColumn:
+ if (visibilityTagsDeleteColumns == null) {
+ visibilityTagsDeleteColumns = new ArrayList<Pair<List<Tag>, Byte>>();
+ }
+ delTags = new ArrayList<Tag>();
+ deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
+ if (!delTags.isEmpty()) {
+ visibilityTagsDeleteColumns.add(new Pair<List<Tag>, Byte>(delTags,
+ deleteCellVisTagsFormat));
+ hasVisTag = true;
+ }
+ break;
+ case Delete:
+ if (visiblityTagsDeleteColumnVersion == null) {
+ visiblityTagsDeleteColumnVersion = new ArrayList<Pair<List<Tag>,
Byte>>();
+ }
+ delTags = new ArrayList<Tag>();
+ deleteCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(delCell, delTags);
+ if (!delTags.isEmpty()) {
+ visiblityTagsDeleteColumnVersion.add(new Pair<List<Tag>,
Byte>(delTags,
+ deleteCellVisTagsFormat));
+ hasVisTag = true;
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid delete type");
}
}
return hasVisTag;
@@ -194,27 +182,35 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
try {
if (hasFamilyStamp) {
if (visibilityTagsDeleteFamily != null) {
- for (int i = 0; i < visibilityTagsDeleteFamily.size(); i++) {
- // visibilityTagsDeleteFamily is ArrayList
- Triple<List<Tag>, Byte, Long> triple =
visibilityTagsDeleteFamily.get(i);
- if (timestamp <= triple.getThird()) {
- List<Tag> putVisTags = new ArrayList<Tag>();
- Byte putCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(cell, putVisTags);
- boolean matchFound = VisibilityLabelServiceManager
- .getInstance().getVisibilityLabelService()
- .matchVisibility(putVisTags, putCellVisTagsFormat,
triple.getFirst(),
- triple.getSecond());
- if (matchFound) {
- // A return type of FAMILY_DELETED will cause skip for all
remaining cells from this
- // family. We would like to match visibility expression on
every put cells after
- // this and only remove those matching with the family delete
visibility. So we are
- // returning FAMILY_VERSION_DELETED from here.
- return DeleteResult.FAMILY_VERSION_DELETED;
+ if (!visibilityTagsDeleteFamily.isEmpty()) {
+ for (int i = 0; i < visibilityTagsDeleteFamily.size(); i++) {
+ // visibilityTagsDeleteFamily is ArrayList
+ Triple<List<Tag>, Byte, Long> triple =
visibilityTagsDeleteFamily.get(i);
+ if (timestamp <= triple.getThird()) {
+ List<Tag> putVisTags = new ArrayList<Tag>();
+ Byte putCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(cell, putVisTags);
+ boolean matchFound =
VisibilityLabelServiceManager.getInstance()
+ .getVisibilityLabelService().matchVisibility(putVisTags,
putCellVisTagsFormat,
+ triple.getFirst(), triple.getSecond());
+ if (matchFound) {
+ // A return type of FAMILY_DELETED will cause skip for all
remaining cells from
+ // this
+ // family. We would like to match visibility expression on
every put cells after
+ // this and only remove those matching with the family
delete visibility. So we
+ // are
+ // returning FAMILY_VERSION_DELETED from here.
+ return DeleteResult.FAMILY_VERSION_DELETED;
+ }
}
}
+ } else {
+ if (!VisibilityUtils.isVisibilityTagsPresent(cell) && timestamp <=
familyStamp) {
+ // No tags
+ return DeleteResult.FAMILY_VERSION_DELETED;
+ }
}
} else {
- if (!VisibilityUtils.isVisibilityTagsPresent(cell) &&
timestamp<=familyStamp) {
+ if (!VisibilityUtils.isVisibilityTagsPresent(cell) && timestamp <=
familyStamp) {
// No tags
return DeleteResult.FAMILY_VERSION_DELETED;
}
@@ -222,21 +218,26 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
}
if (familyVersionStamps.contains(Long.valueOf(timestamp))) {
if (visibilityTagsDeleteFamilyVersion != null) {
- for (int i = 0; i < visibilityTagsDeleteFamilyVersion.size(); i++) {
- // visibilityTagsDeleteFamilyVersion is ArrayList
- Triple<List<Tag>, Byte, Long> triple =
visibilityTagsDeleteFamilyVersion.get(i);
- if (timestamp == triple.getThird()) {
- List<Tag> putVisTags = new ArrayList<Tag>();
- Byte putCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(cell, putVisTags);
- boolean matchFound = VisibilityLabelServiceManager
- .getInstance()
- .getVisibilityLabelService()
- .matchVisibility(putVisTags, putCellVisTagsFormat,
triple.getFirst(),
- triple.getSecond());
- if (matchFound) {
- return DeleteResult.FAMILY_VERSION_DELETED;
+ if (!visibilityTagsDeleteFamilyVersion.isEmpty()) {
+ for (int i = 0; i < visibilityTagsDeleteFamilyVersion.size(); i++)
{
+ // visibilityTagsDeleteFamilyVersion is ArrayList
+ Triple<List<Tag>, Byte, Long> triple =
visibilityTagsDeleteFamilyVersion.get(i);
+ if (timestamp == triple.getThird()) {
+ List<Tag> putVisTags = new ArrayList<Tag>();
+ Byte putCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(cell, putVisTags);
+ boolean matchFound =
VisibilityLabelServiceManager.getInstance()
+ .getVisibilityLabelService().matchVisibility(putVisTags,
putCellVisTagsFormat,
+ triple.getFirst(), triple.getSecond());
+ if (matchFound) {
+ return DeleteResult.FAMILY_VERSION_DELETED;
+ }
}
}
+ } else {
+ if (!VisibilityUtils.isVisibilityTagsPresent(cell)) {
+ // No tags
+ return DeleteResult.FAMILY_VERSION_DELETED;
+ }
}
} else {
if (!VisibilityUtils.isVisibilityTagsPresent(cell)) {
@@ -252,15 +253,21 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
if (ret == 0) {
if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
if (visibilityTagsDeleteColumns != null) {
- for (Pair<List<Tag>, Byte> tags : visibilityTagsDeleteColumns) {
- List<Tag> putVisTags = new ArrayList<Tag>();
- Byte putCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(cell, putVisTags);
- boolean matchFound = VisibilityLabelServiceManager
- .getInstance()
- .getVisibilityLabelService()
- .matchVisibility(putVisTags, putCellVisTagsFormat,
tags.getFirst(),
- tags.getSecond());
- if (matchFound) {
+ if (!visibilityTagsDeleteColumns.isEmpty()) {
+ for (Pair<List<Tag>, Byte> tags : visibilityTagsDeleteColumns)
{
+ List<Tag> putVisTags = new ArrayList<Tag>();
+ Byte putCellVisTagsFormat =
+ VisibilityUtils.extractVisibilityTags(cell, putVisTags);
+ boolean matchFound =
VisibilityLabelServiceManager.getInstance()
+ .getVisibilityLabelService().matchVisibility(putVisTags,
putCellVisTagsFormat,
+ tags.getFirst(), tags.getSecond());
+ if (matchFound) {
+ return DeleteResult.VERSION_DELETED;
+ }
+ }
+ } else {
+ if (!VisibilityUtils.isVisibilityTagsPresent(cell)) {
+ // No tags
return DeleteResult.VERSION_DELETED;
}
}
@@ -275,15 +282,21 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
// If the timestamp is the same, keep this one
if (timestamp == deleteTimestamp) {
if (visiblityTagsDeleteColumnVersion != null) {
- for (Pair<List<Tag>, Byte> tags :
visiblityTagsDeleteColumnVersion) {
- List<Tag> putVisTags = new ArrayList<Tag>();
- Byte putCellVisTagsFormat =
VisibilityUtils.extractVisibilityTags(cell, putVisTags);
- boolean matchFound = VisibilityLabelServiceManager
- .getInstance()
- .getVisibilityLabelService()
- .matchVisibility(putVisTags, putCellVisTagsFormat,
tags.getFirst(),
- tags.getSecond());
- if (matchFound) {
+ if (!visiblityTagsDeleteColumnVersion.isEmpty()) {
+ for (Pair<List<Tag>, Byte> tags :
visiblityTagsDeleteColumnVersion) {
+ List<Tag> putVisTags = new ArrayList<Tag>();
+ Byte putCellVisTagsFormat =
+ VisibilityUtils.extractVisibilityTags(cell, putVisTags);
+ boolean matchFound =
VisibilityLabelServiceManager.getInstance()
+ .getVisibilityLabelService().matchVisibility(putVisTags,
putCellVisTagsFormat,
+ tags.getFirst(), tags.getSecond());
+ if (matchFound) {
+ return DeleteResult.VERSION_DELETED;
+ }
+ }
+ } else {
+ if (!VisibilityUtils.isVisibilityTagsPresent(cell)) {
+ // No tags
return DeleteResult.VERSION_DELETED;
}
}
@@ -297,6 +310,7 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
} else if (ret < 0) {
// Next column case.
deleteBuffer = null;
+ // Can nullify this because we are moving to the next column
visibilityTagsDeleteColumns = null;
visiblityTagsDeleteColumnVersion = null;
} else {
@@ -315,9 +329,10 @@ public class VisibilityScanDeleteTracker extends
ScanDeleteTracker {
@Override
public void reset() {
super.reset();
+ // clear only here
visibilityTagsDeleteColumns = null;
- visibilityTagsDeleteFamily = new ArrayList<Triple<List<Tag>, Byte,
Long>>();
- visibilityTagsDeleteFamilyVersion = new ArrayList<Triple<List<Tag>, Byte,
Long>>();
+ visibilityTagsDeleteFamily = null;
+ visibilityTagsDeleteFamilyVersion = null;
visiblityTagsDeleteColumnVersion = null;
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/0ada8c0a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabelsWithDeletes.java
----------------------------------------------------------------------
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabelsWithDeletes.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabelsWithDeletes.java
index 9693102..045e82c 100644
---
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabelsWithDeletes.java
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/visibility/TestVisibilityLabelsWithDeletes.java
@@ -515,6 +515,293 @@ public class TestVisibilityLabelsWithDeletes {
}
@Test
+ public void testDeleteColumnsWithoutAndWithVisibilityLabels() throws
Exception {
+ final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
+ HColumnDescriptor colDesc = new HColumnDescriptor(fam);
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ desc.addFamily(colDesc);
+ hBaseAdmin.createTable(desc);
+ try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+ Put put = new Put(row1);
+ put.addColumn(fam, qual, value);
+ put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ table.put(put);
+ Delete d = new Delete(row1);
+ // without visibility
+ d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
+ table.delete(d);
+ PrivilegedExceptionAction<Void> scanAction = new
PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 1);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ d = new Delete(row1);
+ // with visibility
+ d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
+ table.delete(d);
+ scanAction = new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ }
+ }
+
+ @Test
+ public void testDeleteColumnsWithAndWithoutVisibilityLabels() throws
Exception {
+ final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
+ HColumnDescriptor colDesc = new HColumnDescriptor(fam);
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ desc.addFamily(colDesc);
+ hBaseAdmin.createTable(desc);
+ try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+ Put put = new Put(row1);
+ put.addColumn(fam, qual, value);
+ put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ table.put(put);
+ Delete d = new Delete(row1);
+ // with visibility
+ d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
+ table.delete(d);
+ PrivilegedExceptionAction<Void> scanAction = new
PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ d = new Delete(row1);
+ // without visibility
+ d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
+ table.delete(d);
+ scanAction = new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ }
+ }
+
+ @Test
+ public void testDeleteFamiliesWithoutAndWithVisibilityLabels() throws
Exception {
+ final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
+ HColumnDescriptor colDesc = new HColumnDescriptor(fam);
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ desc.addFamily(colDesc);
+ hBaseAdmin.createTable(desc);
+ try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+ Put put = new Put(row1);
+ put.addColumn(fam, qual, value);
+ put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ table.put(put);
+ Delete d = new Delete(row1);
+ // without visibility
+ d.addFamily(fam);
+ table.delete(d);
+ PrivilegedExceptionAction<Void> scanAction = new
PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 1);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ d = new Delete(row1);
+ // with visibility
+ d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ d.addFamily(fam);
+ table.delete(d);
+ scanAction = new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ }
+ }
+
+ @Test
+ public void testDeleteFamiliesWithAndWithoutVisibilityLabels() throws
Exception {
+ final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
+ HColumnDescriptor colDesc = new HColumnDescriptor(fam);
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ desc.addFamily(colDesc);
+ hBaseAdmin.createTable(desc);
+ try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+ Put put = new Put(row1);
+ put.addColumn(fam, qual, value);
+ put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ table.put(put);
+ Delete d = new Delete(row1);
+ d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ // with visibility
+ d.addFamily(fam);
+ table.delete(d);
+ PrivilegedExceptionAction<Void> scanAction = new
PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ d = new Delete(row1);
+ // without visibility
+ d.addFamily(fam);
+ table.delete(d);
+ scanAction = new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ }
+ }
+
+ @Test
+ public void testDeletesWithoutAndWithVisibilityLabels() throws Exception {
+ final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
+ Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
+ HColumnDescriptor colDesc = new HColumnDescriptor(fam);
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ desc.addFamily(colDesc);
+ hBaseAdmin.createTable(desc);
+ try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+ Put put = new Put(row1);
+ put.addColumn(fam, qual, value);
+ put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ table.put(put);
+ Delete d = new Delete(row1);
+ // without visibility
+ d.addColumn(fam, qual);
+ table.delete(d);
+ PrivilegedExceptionAction<Void> scanAction = new
PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ // The delete would not be able to apply it because of visibility
mismatch
+ Result[] next = scanner.next(3);
+ assertEquals(next.length, 1);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ d = new Delete(row1);
+ // with visibility
+ d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
+ d.addColumn(fam, qual);
+ table.delete(d);
+ scanAction = new PrivilegedExceptionAction<Void>() {
+ @Override
+ public Void run() throws Exception {
+ try (Connection connection =
ConnectionFactory.createConnection(conf);
+ Table table = connection.getTable(tableName)) {
+ Scan s = new Scan();
+ ResultScanner scanner = table.getScanner(s);
+ Result[] next = scanner.next(3);
+ // this will alone match
+ assertEquals(next.length, 0);
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ return null;
+ }
+ };
+ SUPERUSER.runAs(scanAction);
+ }
+ }
+
+ @Test
public void testVisibilityLabelsWithDeleteFamilyWithPutsReAppearing() throws
Exception {
TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
HTable table = null;