001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.security.visibility; 019 020import static org.awaitility.Awaitility.await; 021import static org.junit.jupiter.api.Assertions.assertEquals; 022import static org.junit.jupiter.api.Assertions.assertTrue; 023 024import java.io.IOException; 025import java.io.InterruptedIOException; 026import java.security.PrivilegedExceptionAction; 027import java.time.Duration; 028import java.util.ArrayList; 029import java.util.Arrays; 030import java.util.List; 031import java.util.Random; 032import org.apache.hadoop.hbase.Cell; 033import org.apache.hadoop.hbase.CellScanner; 034import org.apache.hadoop.hbase.CellUtil; 035import org.apache.hadoop.hbase.HConstants; 036import org.apache.hadoop.hbase.TableName; 037import org.apache.hadoop.hbase.TableNameTestExtension; 038import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 039import org.apache.hadoop.hbase.client.Connection; 040import org.apache.hadoop.hbase.client.ConnectionFactory; 041import org.apache.hadoop.hbase.client.Delete; 042import org.apache.hadoop.hbase.client.Get; 043import org.apache.hadoop.hbase.client.Put; 044import org.apache.hadoop.hbase.client.Result; 045import org.apache.hadoop.hbase.client.ResultScanner; 046import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException; 047import org.apache.hadoop.hbase.client.Scan; 048import org.apache.hadoop.hbase.client.Table; 049import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 050import org.apache.hadoop.hbase.regionserver.HRegion; 051import org.apache.hadoop.hbase.testclassification.LargeTests; 052import org.apache.hadoop.hbase.testclassification.SecurityTests; 053import org.apache.hadoop.hbase.util.Bytes; 054import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 055import org.junit.jupiter.api.Tag; 056import org.junit.jupiter.api.Test; 057import org.junit.jupiter.api.TestInfo; 058 059import org.apache.hadoop.hbase.shaded.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse; 060 061@Tag(SecurityTests.TAG) 062@Tag(LargeTests.TAG) 063public class TestVisibilityLabelsWithDeletes extends VisibilityLabelsWithDeletesTestBase { 064 065 @Override 066 protected Table createTable(byte[] fam, TestInfo testInfo) throws IOException { 067 TableName tableName = TableName 068 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 069 TEST_UTIL.getAdmin().createTable(TableDescriptorBuilder.newBuilder(tableName) 070 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam)).build()); 071 return TEST_UTIL.getConnection().getTable(tableName); 072 } 073 074 private TableName createTable(TestInfo testInfo) throws IOException { 075 return createTable(-1, testInfo); 076 } 077 078 private TableName createTable(int maxVersions, TestInfo testInfo) throws IOException { 079 TableName tableName = TableName 080 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 081 createTable(tableName, maxVersions); 082 return tableName; 083 } 084 085 private void createTable(TableName tableName, int maxVersions) throws IOException { 086 ColumnFamilyDescriptorBuilder builder = ColumnFamilyDescriptorBuilder.newBuilder(fam); 087 if (maxVersions > 0) { 088 builder.setMaxVersions(maxVersions); 089 } 090 TEST_UTIL.getAdmin().createTable( 091 TableDescriptorBuilder.newBuilder(tableName).setColumnFamily(builder.build()).build()); 092 } 093 094 @Test 095 public void testVisibilityLabelsWithDeleteColumnsWithMultipleVersions(TestInfo testInfo) 096 throws Exception { 097 setAuths(); 098 final TableName tableName = TableName 099 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 100 try (Table table = doPuts(tableName)) { 101 TEST_UTIL.getAdmin().flush(tableName); 102 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 103 @Override 104 public Void run() throws Exception { 105 try (Connection connection = ConnectionFactory.createConnection(conf); 106 Table table = connection.getTable(tableName)) { 107 Delete d = new Delete(row1); 108 d.setCellVisibility(new CellVisibility( 109 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 110 d.addColumns(fam, qual, 125L); 111 table.delete(d); 112 } catch (Throwable t) { 113 throw new IOException(t); 114 } 115 return null; 116 } 117 }; 118 SUPERUSER.runAs(actiona); 119 120 TEST_UTIL.getAdmin().flush(tableName); 121 Scan s = new Scan(); 122 s.readVersions(5); 123 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 124 ResultScanner scanner = table.getScanner(s); 125 Result[] next = scanner.next(3); 126 assertTrue(next.length == 2); 127 CellScanner cellScanner = next[0].cellScanner(); 128 cellScanner.advance(); 129 Cell current = cellScanner.current(); 130 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 131 row1, 0, row1.length)); 132 assertEquals(127L, current.getTimestamp()); 133 cellScanner.advance(); 134 current = cellScanner.current(); 135 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 136 row1, 0, row1.length)); 137 assertEquals(126L, current.getTimestamp()); 138 cellScanner.advance(); 139 current = cellScanner.current(); 140 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 141 row1, 0, row1.length)); 142 assertEquals(125L, current.getTimestamp()); 143 cellScanner = next[1].cellScanner(); 144 cellScanner.advance(); 145 current = cellScanner.current(); 146 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 147 row2, 0, row2.length)); 148 } 149 } 150 151 @Test 152 public void testVisibilityLabelsWithDeleteColumnsWithMultipleVersionsNoTimestamp( 153 TestInfo testInfo) throws Exception { 154 setAuths(); 155 final TableName tableName = TableName 156 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 157 try (Table table = doPuts(tableName)) { 158 TEST_UTIL.getAdmin().flush(tableName); 159 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 160 @Override 161 public Void run() throws Exception { 162 try (Connection connection = ConnectionFactory.createConnection(conf); 163 Table table = connection.getTable(tableName)) { 164 Delete d1 = new Delete(row1); 165 d1.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 166 d1.addColumns(fam, qual); 167 168 table.delete(d1); 169 170 Delete d2 = new Delete(row1); 171 d2.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 172 d2.addColumns(fam, qual); 173 table.delete(d2); 174 175 Delete d3 = new Delete(row1); 176 d3.setCellVisibility(new CellVisibility( 177 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 178 d3.addColumns(fam, qual); 179 table.delete(d3); 180 } catch (Throwable t) { 181 throw new IOException(t); 182 } 183 return null; 184 } 185 }; 186 SUPERUSER.runAs(actiona); 187 Scan s = new Scan(); 188 s.readVersions(5); 189 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 190 ResultScanner scanner = table.getScanner(s); 191 Result[] next = scanner.next(3); 192 assertEquals(1, next.length); 193 CellScanner cellScanner = next[0].cellScanner(); 194 cellScanner.advance(); 195 Cell current = cellScanner.current(); 196 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 197 row2, 0, row2.length)); 198 } 199 } 200 201 @Test 202 public void testVisibilityLabelsWithDeleteColumnsNoMatchVisExpWithMultipleVersionsNoTimestamp( 203 TestInfo testInfo) throws Exception { 204 setAuths(); 205 final TableName tableName = TableName 206 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 207 try (Table table = doPuts(tableName)) { 208 TEST_UTIL.getAdmin().flush(tableName); 209 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 210 @Override 211 public Void run() throws Exception { 212 try (Connection connection = ConnectionFactory.createConnection(conf); 213 Table table = connection.getTable(tableName)) { 214 Delete d = new Delete(row1); 215 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 216 d.addColumns(fam, qual); 217 table.delete(d); 218 219 d = new Delete(row1); 220 d.setCellVisibility(new CellVisibility(SECRET)); 221 d.addColumns(fam, qual); 222 table.delete(d); 223 224 d = new Delete(row1); 225 d.setCellVisibility(new CellVisibility( 226 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 227 d.addColumns(fam, qual); 228 table.delete(d); 229 } catch (Throwable t) { 230 throw new IOException(t); 231 } 232 return null; 233 } 234 }; 235 SUPERUSER.runAs(actiona); 236 Scan s = new Scan(); 237 s.readVersions(5); 238 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 239 ResultScanner scanner = table.getScanner(s); 240 Result[] next = scanner.next(3); 241 assertTrue(next.length == 2); 242 CellScanner cellScanner = next[0].cellScanner(); 243 cellScanner.advance(); 244 Cell current = cellScanner.current(); 245 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 246 row1, 0, row1.length)); 247 cellScanner = next[1].cellScanner(); 248 cellScanner.advance(); 249 current = cellScanner.current(); 250 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 251 row2, 0, row2.length)); 252 } 253 } 254 255 @Test 256 public void testVisibilityLabelsWithDeleteFamilyWithMultipleVersionsNoTimestamp(TestInfo testInfo) 257 throws Exception { 258 setAuths(); 259 final TableName tableName = TableName 260 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 261 try (Table table = doPuts(tableName)) { 262 TEST_UTIL.getAdmin().flush(tableName); 263 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 264 @Override 265 public Void run() throws Exception { 266 try (Connection connection = ConnectionFactory.createConnection(conf); 267 Table table = connection.getTable(tableName)) { 268 Delete d1 = new Delete(row1); 269 d1.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 270 d1.addFamily(fam); 271 table.delete(d1); 272 273 Delete d2 = new Delete(row1); 274 d2.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 275 d2.addFamily(fam); 276 table.delete(d2); 277 278 Delete d3 = new Delete(row1); 279 d3.setCellVisibility(new CellVisibility( 280 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 281 d3.addFamily(fam); 282 table.delete(d3); 283 } catch (Throwable t) { 284 throw new IOException(t); 285 } 286 return null; 287 } 288 }; 289 SUPERUSER.runAs(actiona); 290 Scan s = new Scan(); 291 s.readVersions(5); 292 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 293 ResultScanner scanner = table.getScanner(s); 294 Result[] next = scanner.next(3); 295 assertEquals(1, next.length); 296 CellScanner cellScanner = next[0].cellScanner(); 297 cellScanner.advance(); 298 Cell current = cellScanner.current(); 299 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 300 row2, 0, row2.length)); 301 } 302 } 303 304 @Test 305 public void testDeleteColumnsWithoutAndWithVisibilityLabels(TestInfo testInfo) throws Exception { 306 TableName tableName = createTable(testInfo); 307 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 308 Put put = new Put(row1); 309 put.addColumn(fam, qual, value); 310 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 311 table.put(put); 312 Delete d = new Delete(row1); 313 // without visibility 314 d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP); 315 table.delete(d); 316 PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() { 317 @Override 318 public Void run() throws Exception { 319 try (Connection connection = ConnectionFactory.createConnection(conf); 320 Table table = connection.getTable(tableName)) { 321 Scan s = new Scan(); 322 ResultScanner scanner = table.getScanner(s); 323 Result[] next = scanner.next(3); 324 assertEquals(1, next.length); 325 } 326 return null; 327 } 328 }; 329 SUPERUSER.runAs(scanAction); 330 d = new Delete(row1); 331 // with visibility 332 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 333 d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP); 334 table.delete(d); 335 scanAction = new PrivilegedExceptionAction<Void>() { 336 @Override 337 public Void run() throws Exception { 338 try (Connection connection = ConnectionFactory.createConnection(conf); 339 Table table = connection.getTable(tableName)) { 340 Scan s = new Scan(); 341 ResultScanner scanner = table.getScanner(s); 342 Result[] next = scanner.next(3); 343 assertEquals(0, next.length); 344 } 345 return null; 346 } 347 }; 348 SUPERUSER.runAs(scanAction); 349 } 350 } 351 352 @Test 353 public void testDeleteColumnsWithAndWithoutVisibilityLabels(TestInfo testInfo) throws Exception { 354 TableName tableName = createTable(testInfo); 355 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 356 Put put = new Put(row1); 357 put.addColumn(fam, qual, value); 358 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 359 table.put(put); 360 Delete d = new Delete(row1); 361 // with visibility 362 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 363 d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP); 364 table.delete(d); 365 PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() { 366 @Override 367 public Void run() throws Exception { 368 try (Connection connection = ConnectionFactory.createConnection(conf); 369 Table table = connection.getTable(tableName)) { 370 Scan s = new Scan(); 371 ResultScanner scanner = table.getScanner(s); 372 Result[] next = scanner.next(3); 373 assertEquals(0, next.length); 374 } 375 return null; 376 } 377 }; 378 SUPERUSER.runAs(scanAction); 379 d = new Delete(row1); 380 // without visibility 381 d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP); 382 table.delete(d); 383 scanAction = new PrivilegedExceptionAction<Void>() { 384 @Override 385 public Void run() throws Exception { 386 try (Connection connection = ConnectionFactory.createConnection(conf); 387 Table table = connection.getTable(tableName)) { 388 Scan s = new Scan(); 389 ResultScanner scanner = table.getScanner(s); 390 Result[] next = scanner.next(3); 391 assertEquals(0, next.length); 392 } 393 return null; 394 } 395 }; 396 SUPERUSER.runAs(scanAction); 397 } 398 } 399 400 @Test 401 public void testDeleteFamiliesWithoutAndWithVisibilityLabels(TestInfo testInfo) throws Exception { 402 TableName tableName = createTable(testInfo); 403 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 404 Put put = new Put(row1); 405 put.addColumn(fam, qual, value); 406 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 407 table.put(put); 408 Delete d = new Delete(row1); 409 // without visibility 410 d.addFamily(fam); 411 table.delete(d); 412 PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() { 413 @Override 414 public Void run() throws Exception { 415 try (Connection connection = ConnectionFactory.createConnection(conf); 416 Table table = connection.getTable(tableName)) { 417 Scan s = new Scan(); 418 ResultScanner scanner = table.getScanner(s); 419 Result[] next = scanner.next(3); 420 assertEquals(1, next.length); 421 } 422 return null; 423 } 424 }; 425 SUPERUSER.runAs(scanAction); 426 d = new Delete(row1); 427 // with visibility 428 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 429 d.addFamily(fam); 430 table.delete(d); 431 scanAction = new PrivilegedExceptionAction<Void>() { 432 @Override 433 public Void run() throws Exception { 434 try (Connection connection = ConnectionFactory.createConnection(conf); 435 Table table = connection.getTable(tableName)) { 436 Scan s = new Scan(); 437 ResultScanner scanner = table.getScanner(s); 438 Result[] next = scanner.next(3); 439 assertEquals(0, next.length); 440 } 441 return null; 442 } 443 }; 444 SUPERUSER.runAs(scanAction); 445 } 446 } 447 448 @Test 449 public void testDeleteFamiliesWithAndWithoutVisibilityLabels(TestInfo testInfo) throws Exception { 450 TableName tableName = createTable(testInfo); 451 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 452 Put put = new Put(row1); 453 put.addColumn(fam, qual, value); 454 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 455 table.put(put); 456 Delete d = new Delete(row1); 457 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 458 // with visibility 459 d.addFamily(fam); 460 table.delete(d); 461 PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() { 462 @Override 463 public Void run() throws Exception { 464 try (Connection connection = ConnectionFactory.createConnection(conf); 465 Table table = connection.getTable(tableName)) { 466 Scan s = new Scan(); 467 ResultScanner scanner = table.getScanner(s); 468 Result[] next = scanner.next(3); 469 assertEquals(0, next.length); 470 } 471 return null; 472 } 473 }; 474 SUPERUSER.runAs(scanAction); 475 d = new Delete(row1); 476 // without visibility 477 d.addFamily(fam); 478 table.delete(d); 479 scanAction = new PrivilegedExceptionAction<Void>() { 480 @Override 481 public Void run() throws Exception { 482 try (Connection connection = ConnectionFactory.createConnection(conf); 483 Table table = connection.getTable(tableName)) { 484 Scan s = new Scan(); 485 ResultScanner scanner = table.getScanner(s); 486 Result[] next = scanner.next(3); 487 assertEquals(0, next.length); 488 } 489 return null; 490 } 491 }; 492 SUPERUSER.runAs(scanAction); 493 } 494 } 495 496 @Test 497 public void testDeletesWithoutAndWithVisibilityLabels(TestInfo testInfo) throws Exception { 498 TableName tableName = createTable(testInfo); 499 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 500 Put put = new Put(row1); 501 put.addColumn(fam, qual, value); 502 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 503 table.put(put); 504 Delete d = new Delete(row1); 505 // without visibility 506 d.addColumn(fam, qual); 507 table.delete(d); 508 PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() { 509 @Override 510 public Void run() throws Exception { 511 try (Connection connection = ConnectionFactory.createConnection(conf); 512 Table table = connection.getTable(tableName)) { 513 Scan s = new Scan(); 514 ResultScanner scanner = table.getScanner(s); 515 // The delete would not be able to apply it because of visibility mismatch 516 Result[] next = scanner.next(3); 517 assertEquals(1, next.length); 518 } 519 return null; 520 } 521 }; 522 SUPERUSER.runAs(scanAction); 523 d = new Delete(row1); 524 // with visibility 525 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 526 d.addColumn(fam, qual); 527 table.delete(d); 528 scanAction = new PrivilegedExceptionAction<Void>() { 529 @Override 530 public Void run() throws Exception { 531 try (Connection connection = ConnectionFactory.createConnection(conf); 532 Table table = connection.getTable(tableName)) { 533 Scan s = new Scan(); 534 ResultScanner scanner = table.getScanner(s); 535 Result[] next = scanner.next(3); 536 // this will alone match 537 assertEquals(0, next.length); 538 } 539 return null; 540 } 541 }; 542 SUPERUSER.runAs(scanAction); 543 } 544 } 545 546 @Test 547 public void testVisibilityLabelsWithDeleteFamilyWithPutsReAppearing(TestInfo testInfo) 548 throws Exception { 549 TableName tableName = createTable(5, testInfo); 550 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 551 Put put = new Put(Bytes.toBytes("row1")); 552 put.addColumn(fam, qual, value); 553 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 554 table.put(put); 555 put = new Put(Bytes.toBytes("row1")); 556 put.addColumn(fam, qual, value); 557 put.setCellVisibility(new CellVisibility(SECRET)); 558 table.put(put); 559 TEST_UTIL.getAdmin().flush(tableName); 560 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 561 @Override 562 public Void run() throws Exception { 563 try (Connection connection = ConnectionFactory.createConnection(conf); 564 Table table = connection.getTable(tableName)) { 565 Delete d = new Delete(row1); 566 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 567 d.addFamily(fam); 568 table.delete(d); 569 } catch (Throwable t) { 570 throw new IOException(t); 571 } 572 return null; 573 } 574 }; 575 SUPERUSER.runAs(actiona); 576 Scan s = new Scan(); 577 s.readVersions(5); 578 s.setAuthorizations(new Authorizations(SECRET)); 579 ResultScanner scanner = table.getScanner(s); 580 Result[] next = scanner.next(3); 581 assertEquals(1, next.length); 582 put = new Put(Bytes.toBytes("row1")); 583 put.addColumn(fam, qual, value1); 584 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 585 table.put(put); 586 actiona = new PrivilegedExceptionAction<Void>() { 587 @Override 588 public Void run() throws Exception { 589 try (Connection connection = ConnectionFactory.createConnection(conf); 590 Table table = connection.getTable(tableName)) { 591 Delete d = new Delete(row1); 592 d.setCellVisibility(new CellVisibility(SECRET)); 593 d.addFamily(fam); 594 table.delete(d); 595 } catch (Throwable t) { 596 throw new IOException(t); 597 } 598 return null; 599 } 600 }; 601 SUPERUSER.runAs(actiona); 602 s = new Scan(); 603 s.readVersions(5); 604 s.setAuthorizations(new Authorizations(CONFIDENTIAL)); 605 scanner = table.getScanner(s); 606 next = scanner.next(3); 607 assertEquals(1, next.length); 608 s = new Scan(); 609 s.readVersions(5); 610 s.setAuthorizations(new Authorizations(SECRET)); 611 scanner = table.getScanner(s); 612 Result[] next1 = scanner.next(3); 613 assertEquals(0, next1.length); 614 } 615 } 616 617 @Test 618 public void testVisibilityLabelsWithDeleteColumnsWithPutsReAppearing(TestInfo testInfo) 619 throws Exception { 620 TableName tableName = createTable(5, testInfo); 621 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 622 Put put = new Put(Bytes.toBytes("row1")); 623 put.addColumn(fam, qual, value); 624 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 625 table.put(put); 626 put = new Put(Bytes.toBytes("row1")); 627 put.addColumn(fam, qual, value); 628 put.setCellVisibility(new CellVisibility(SECRET)); 629 table.put(put); 630 TEST_UTIL.getAdmin().flush(tableName); 631 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 632 @Override 633 public Void run() throws Exception { 634 try (Connection connection = ConnectionFactory.createConnection(conf); 635 Table table = connection.getTable(tableName)) { 636 Delete d = new Delete(row1); 637 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 638 d.addColumns(fam, qual); 639 table.delete(d); 640 } catch (Throwable t) { 641 throw new IOException(t); 642 } 643 return null; 644 } 645 }; 646 SUPERUSER.runAs(actiona); 647 Scan s = new Scan(); 648 s.readVersions(5); 649 s.setAuthorizations(new Authorizations(SECRET)); 650 ResultScanner scanner = table.getScanner(s); 651 Result[] next = scanner.next(3); 652 assertEquals(1, next.length); 653 put = new Put(Bytes.toBytes("row1")); 654 put.addColumn(fam, qual, value1); 655 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 656 table.put(put); 657 actiona = new PrivilegedExceptionAction<Void>() { 658 @Override 659 public Void run() throws Exception { 660 try (Connection connection = ConnectionFactory.createConnection(conf); 661 Table table = connection.getTable(tableName)) { 662 Delete d = new Delete(row1); 663 d.setCellVisibility(new CellVisibility(SECRET)); 664 d.addColumns(fam, qual); 665 table.delete(d); 666 } catch (Throwable t) { 667 throw new IOException(t); 668 } 669 return null; 670 } 671 }; 672 SUPERUSER.runAs(actiona); 673 s = new Scan(); 674 s.readVersions(5); 675 s.setAuthorizations(new Authorizations(CONFIDENTIAL)); 676 scanner = table.getScanner(s); 677 next = scanner.next(3); 678 assertEquals(1, next.length); 679 s = new Scan(); 680 s.readVersions(5); 681 s.setAuthorizations(new Authorizations(SECRET)); 682 scanner = table.getScanner(s); 683 Result[] next1 = scanner.next(3); 684 assertEquals(0, next1.length); 685 } 686 } 687 688 @Test 689 public void testVisibilityCombinations(TestInfo testInfo) throws Exception { 690 TableName tableName = createTable(5, testInfo); 691 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 692 Put put = new Put(Bytes.toBytes("row1")); 693 put.addColumn(fam, qual, 123L, value); 694 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 695 table.put(put); 696 put = new Put(Bytes.toBytes("row1")); 697 put.addColumn(fam, qual, 124L, value1); 698 put.setCellVisibility(new CellVisibility(SECRET)); 699 table.put(put); 700 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 701 @Override 702 public Void run() throws Exception { 703 try (Connection connection = ConnectionFactory.createConnection(conf); 704 Table table = connection.getTable(tableName)) { 705 Delete d = new Delete(row1); 706 d.setCellVisibility(new CellVisibility(SECRET)); 707 d.addColumns(fam, qual, 126L); 708 table.delete(d); 709 } catch (Throwable t) { 710 throw new IOException(t); 711 } 712 713 try (Connection connection = ConnectionFactory.createConnection(conf); 714 Table table = connection.getTable(tableName)) { 715 Delete d = new Delete(row1); 716 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 717 d.addColumn(fam, qual, 123L); 718 table.delete(d); 719 } catch (Throwable t) { 720 throw new IOException(t); 721 } 722 return null; 723 } 724 }; 725 SUPERUSER.runAs(actiona); 726 Scan s = new Scan(); 727 s.readVersions(5); 728 s.setAuthorizations(new Authorizations(CONFIDENTIAL, SECRET)); 729 ResultScanner scanner = table.getScanner(s); 730 Result[] next = scanner.next(3); 731 assertEquals(0, next.length); 732 } 733 } 734 735 @Test 736 public void testVisibilityLabelsWithDeleteColumnWithSpecificVersionWithPutsReAppearing( 737 TestInfo testInfo) throws Exception { 738 TableName tableName = createTable(5, testInfo); 739 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 740 Put put1 = new Put(Bytes.toBytes("row1")); 741 put1.addColumn(fam, qual, 123L, value); 742 put1.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 743 744 Put put2 = new Put(Bytes.toBytes("row1")); 745 put2.addColumn(fam, qual, 123L, value1); 746 put2.setCellVisibility(new CellVisibility(SECRET)); 747 table.put(createList(put1, put2)); 748 749 Scan s = new Scan(); 750 s.readVersions(5); 751 s.setAuthorizations(new Authorizations(CONFIDENTIAL, SECRET)); 752 753 ResultScanner scanner = table.getScanner(s); 754 assertEquals(1, scanner.next(3).length); 755 scanner.close(); 756 757 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 758 @Override 759 public Void run() throws Exception { 760 try (Connection connection = ConnectionFactory.createConnection(conf); 761 Table table = connection.getTable(tableName)) { 762 Delete d = new Delete(row1); 763 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 764 d.addColumn(fam, qual, 123L); 765 table.delete(d); 766 } 767 768 try (Connection connection = ConnectionFactory.createConnection(conf); 769 Table table = connection.getTable(tableName)) { 770 Delete d = new Delete(row1); 771 d.setCellVisibility(new CellVisibility(SECRET)); 772 d.addColumn(fam, qual, 123L); 773 table.delete(d); 774 } catch (Throwable t) { 775 throw new IOException(t); 776 } 777 return null; 778 } 779 }; 780 SUPERUSER.runAs(actiona); 781 s = new Scan(); 782 s.readVersions(5); 783 s.setAuthorizations(new Authorizations(CONFIDENTIAL)); 784 scanner = table.getScanner(s); 785 assertEquals(0, scanner.next(3).length); 786 scanner.close(); 787 } 788 } 789 790 @Test 791 public void testVisibilityLabelsWithDeleteFamilyNoMatchingVisExpWithMultipleVersionsNoTimestamp( 792 TestInfo testInfo) throws Exception { 793 setAuths(); 794 final TableName tableName = TableName 795 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 796 try (Table table = doPuts(tableName)) { 797 TEST_UTIL.getAdmin().flush(tableName); 798 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 799 @Override 800 public Void run() throws Exception { 801 Delete d1 = new Delete(row1); 802 d1.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 803 d1.addFamily(fam); 804 805 Delete d2 = new Delete(row1); 806 d2.setCellVisibility(new CellVisibility(SECRET)); 807 d2.addFamily(fam); 808 809 Delete d3 = new Delete(row1); 810 d3.setCellVisibility(new CellVisibility( 811 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 812 d3.addFamily(fam); 813 814 try (Connection connection = ConnectionFactory.createConnection(conf); 815 Table table = connection.getTable(tableName)) { 816 table.delete(createList(d1, d2, d3)); 817 } catch (Throwable t) { 818 throw new IOException(t); 819 } 820 return null; 821 } 822 }; 823 SUPERUSER.runAs(actiona); 824 Scan s = new Scan(); 825 s.readVersions(5); 826 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 827 ResultScanner scanner = table.getScanner(s); 828 Result[] next = scanner.next(3); 829 assertTrue(next.length == 2); 830 CellScanner cellScanner = next[0].cellScanner(); 831 cellScanner.advance(); 832 Cell current = cellScanner.current(); 833 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 834 row1, 0, row1.length)); 835 cellScanner = next[1].cellScanner(); 836 cellScanner.advance(); 837 current = cellScanner.current(); 838 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 839 row2, 0, row2.length)); 840 scanner.close(); 841 } 842 } 843 844 @Test 845 public void testDeleteFamilyAndDeleteColumnsWithAndWithoutVisibilityExp(TestInfo testInfo) 846 throws Exception { 847 setAuths(); 848 final TableName tableName = TableName 849 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 850 try (Table table = doPuts(tableName)) { 851 TEST_UTIL.getAdmin().flush(tableName); 852 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 853 @Override 854 public Void run() throws Exception { 855 Delete d1 = new Delete(row1); 856 d1.addFamily(fam); 857 858 Delete d2 = new Delete(row1); 859 d2.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 860 d2.addColumns(fam, qual); 861 try (Connection connection = ConnectionFactory.createConnection(conf); 862 Table table = connection.getTable(tableName)) { 863 table.delete(createList(d1, d2)); 864 } catch (Throwable t) { 865 throw new IOException(t); 866 } 867 return null; 868 } 869 }; 870 SUPERUSER.runAs(actiona); 871 Scan s = new Scan(); 872 s.readVersions(5); 873 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 874 ResultScanner scanner = table.getScanner(s); 875 Result[] next = scanner.next(3); 876 assertTrue(next.length == 2); 877 CellScanner cellScanner = next[0].cellScanner(); 878 cellScanner.advance(); 879 Cell current = cellScanner.current(); 880 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 881 row1, 0, row1.length)); 882 assertEquals(127L, current.getTimestamp()); 883 cellScanner.advance(); 884 current = cellScanner.current(); 885 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 886 row1, 0, row1.length)); 887 assertEquals(126L, current.getTimestamp()); 888 cellScanner.advance(); 889 current = cellScanner.current(); 890 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 891 row1, 0, row1.length)); 892 assertEquals(124L, current.getTimestamp()); 893 cellScanner.advance(); 894 current = cellScanner.current(); 895 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 896 row1, 0, row1.length)); 897 assertEquals(123L, current.getTimestamp()); 898 cellScanner = next[1].cellScanner(); 899 cellScanner.advance(); 900 current = cellScanner.current(); 901 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 902 row2, 0, row2.length)); 903 scanner.close(); 904 } 905 } 906 907 private Table doPuts(TableName tableName) throws IOException, InterruptedIOException, 908 RetriesExhaustedWithDetailsException, InterruptedException { 909 createTable(tableName, 5); 910 911 List<Put> puts = new ArrayList<>(5); 912 Put put = new Put(Bytes.toBytes("row1")); 913 put.addColumn(fam, qual, 123L, value); 914 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 915 puts.add(put); 916 917 put = new Put(Bytes.toBytes("row1")); 918 put.addColumn(fam, qual, 124L, value); 919 put.setCellVisibility(new CellVisibility( 920 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 921 puts.add(put); 922 923 put = new Put(Bytes.toBytes("row1")); 924 put.addColumn(fam, qual, 125L, value); 925 put.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 926 puts.add(put); 927 928 put = new Put(Bytes.toBytes("row1")); 929 put.addColumn(fam, qual, 126L, value); 930 put.setCellVisibility(new CellVisibility( 931 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 932 puts.add(put); 933 934 put = new Put(Bytes.toBytes("row1")); 935 put.addColumn(fam, qual, 127L, value); 936 put.setCellVisibility(new CellVisibility( 937 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 938 puts.add(put); 939 940 TEST_UTIL.getAdmin().flush(tableName); 941 put = new Put(Bytes.toBytes("row2")); 942 put.addColumn(fam, qual, 127L, value); 943 put.setCellVisibility(new CellVisibility( 944 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 945 puts.add(put); 946 947 Table table = TEST_UTIL.getConnection().getTable(tableName); 948 table.put(puts); 949 return table; 950 } 951 952 private Table doPutsWithDiffCols(TableName tableName) throws IOException, InterruptedIOException, 953 RetriesExhaustedWithDetailsException, InterruptedException { 954 createTable(tableName, 5); 955 956 List<Put> puts = new ArrayList<>(5); 957 Put put = new Put(Bytes.toBytes("row1")); 958 put.addColumn(fam, qual, 123L, value); 959 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 960 puts.add(put); 961 962 put = new Put(Bytes.toBytes("row1")); 963 put.addColumn(fam, qual, 124L, value); 964 put.setCellVisibility(new CellVisibility( 965 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 966 puts.add(put); 967 968 put = new Put(Bytes.toBytes("row1")); 969 put.addColumn(fam, qual, 125L, value); 970 put.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 971 puts.add(put); 972 973 put = new Put(Bytes.toBytes("row1")); 974 put.addColumn(fam, qual1, 126L, value); 975 put.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 976 puts.add(put); 977 978 put = new Put(Bytes.toBytes("row1")); 979 put.addColumn(fam, qual2, 127L, value); 980 put.setCellVisibility(new CellVisibility( 981 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 982 puts.add(put); 983 984 Table table = TEST_UTIL.getConnection().getTable(tableName); 985 table.put(puts); 986 return table; 987 } 988 989 private Table doPutsWithoutVisibility(TableName tableName) throws IOException, 990 InterruptedIOException, RetriesExhaustedWithDetailsException, InterruptedException { 991 createTable(tableName, 5); 992 List<Put> puts = new ArrayList<>(5); 993 Put put = new Put(Bytes.toBytes("row1")); 994 put.addColumn(fam, qual, 123L, value); 995 puts.add(put); 996 997 put = new Put(Bytes.toBytes("row1")); 998 put.addColumn(fam, qual, 124L, value); 999 puts.add(put); 1000 1001 put = new Put(Bytes.toBytes("row1")); 1002 put.addColumn(fam, qual, 125L, value); 1003 puts.add(put); 1004 1005 put = new Put(Bytes.toBytes("row1")); 1006 put.addColumn(fam, qual, 126L, value); 1007 puts.add(put); 1008 1009 put = new Put(Bytes.toBytes("row1")); 1010 put.addColumn(fam, qual, 127L, value); 1011 puts.add(put); 1012 1013 Table table = TEST_UTIL.getConnection().getTable(tableName); 1014 table.put(puts); 1015 1016 TEST_UTIL.getAdmin().flush(tableName); 1017 1018 put = new Put(Bytes.toBytes("row2")); 1019 put.addColumn(fam, qual, 127L, value); 1020 table.put(put); 1021 1022 return table; 1023 } 1024 1025 @Test 1026 public void testDeleteColumnWithSpecificTimeStampUsingMultipleVersionsUnMatchingVisExpression( 1027 TestInfo testInfo) throws Exception { 1028 setAuths(); 1029 final TableName tableName = TableName 1030 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1031 try (Table table = doPuts(tableName)) { 1032 TEST_UTIL.getAdmin().flush(tableName); 1033 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1034 @Override 1035 public Void run() throws Exception { 1036 try (Connection connection = ConnectionFactory.createConnection(conf); 1037 Table table = connection.getTable(tableName)) { 1038 Delete d = new Delete(row1); 1039 d.setCellVisibility(new CellVisibility( 1040 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 1041 d.addColumn(fam, qual, 125L); 1042 table.delete(d); 1043 } catch (Throwable t) { 1044 throw new IOException(t); 1045 } 1046 return null; 1047 } 1048 }; 1049 SUPERUSER.runAs(actiona); 1050 1051 TEST_UTIL.getAdmin().flush(tableName); 1052 Scan s = new Scan(); 1053 s.readVersions(5); 1054 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1055 ResultScanner scanner = table.getScanner(s); 1056 Result[] next = scanner.next(3); 1057 assertTrue(next.length == 2); 1058 CellScanner cellScanner = next[0].cellScanner(); 1059 cellScanner.advance(); 1060 Cell current = cellScanner.current(); 1061 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1062 row1, 0, row1.length)); 1063 assertEquals(127L, current.getTimestamp()); 1064 cellScanner.advance(); 1065 current = cellScanner.current(); 1066 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1067 row1, 0, row1.length)); 1068 assertEquals(126L, current.getTimestamp()); 1069 cellScanner.advance(); 1070 current = cellScanner.current(); 1071 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1072 row1, 0, row1.length)); 1073 assertEquals(125L, current.getTimestamp()); 1074 cellScanner.advance(); 1075 current = cellScanner.current(); 1076 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1077 row1, 0, row1.length)); 1078 assertEquals(124L, current.getTimestamp()); 1079 cellScanner.advance(); 1080 current = cellScanner.current(); 1081 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1082 row1, 0, row1.length)); 1083 assertEquals(123L, current.getTimestamp()); 1084 cellScanner = next[1].cellScanner(); 1085 cellScanner.advance(); 1086 current = cellScanner.current(); 1087 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1088 row2, 0, row2.length)); 1089 } 1090 } 1091 1092 @Test 1093 public void testDeleteColumnWithLatestTimeStampUsingMultipleVersions(TestInfo testInfo) 1094 throws Exception { 1095 setAuths(); 1096 final TableName tableName = TableName 1097 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1098 try (Table table = doPuts(tableName)) { 1099 TEST_UTIL.getAdmin().flush(tableName); 1100 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1101 @Override 1102 public Void run() throws Exception { 1103 try (Connection connection = ConnectionFactory.createConnection(conf); 1104 Table table = connection.getTable(tableName)) { 1105 Delete d = new Delete(row1); 1106 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1107 d.addColumn(fam, qual); 1108 table.delete(d); 1109 } catch (Throwable t) { 1110 throw new IOException(t); 1111 } 1112 return null; 1113 } 1114 }; 1115 SUPERUSER.runAs(actiona); 1116 1117 TEST_UTIL.getAdmin().flush(tableName); 1118 Scan s = new Scan(); 1119 s.readVersions(5); 1120 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1121 ResultScanner scanner = table.getScanner(s); 1122 Result[] next = scanner.next(3); 1123 assertTrue(next.length == 2); 1124 CellScanner cellScanner = next[0].cellScanner(); 1125 cellScanner.advance(); 1126 Cell current = cellScanner.current(); 1127 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1128 row1, 0, row1.length)); 1129 assertEquals(127L, current.getTimestamp()); 1130 cellScanner.advance(); 1131 current = cellScanner.current(); 1132 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1133 row1, 0, row1.length)); 1134 assertEquals(126L, current.getTimestamp()); 1135 cellScanner.advance(); 1136 current = cellScanner.current(); 1137 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1138 row1, 0, row1.length)); 1139 assertEquals(124L, current.getTimestamp()); 1140 cellScanner.advance(); 1141 current = cellScanner.current(); 1142 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1143 row1, 0, row1.length)); 1144 assertEquals(123L, current.getTimestamp()); 1145 cellScanner = next[1].cellScanner(); 1146 cellScanner.advance(); 1147 current = cellScanner.current(); 1148 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1149 row2, 0, row2.length)); 1150 } 1151 } 1152 1153 @Test 1154 public void testDeleteColumnWithLatestTimeStampWhenNoVersionMatches(TestInfo testInfo) 1155 throws Exception { 1156 setAuths(); 1157 final TableName tableName = TableName 1158 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1159 try (Table table = doPuts(tableName)) { 1160 TEST_UTIL.getAdmin().flush(tableName); 1161 Put put = new Put(Bytes.toBytes("row1")); 1162 put.addColumn(fam, qual, 128L, value); 1163 put.setCellVisibility(new CellVisibility(TOPSECRET)); 1164 table.put(put); 1165 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1166 @Override 1167 public Void run() throws Exception { 1168 try (Connection connection = ConnectionFactory.createConnection(conf); 1169 Table table = connection.getTable(tableName)) { 1170 Delete d = new Delete(row1); 1171 d.setCellVisibility(new CellVisibility(SECRET)); 1172 d.addColumn(fam, qual); 1173 table.delete(d); 1174 } catch (Throwable t) { 1175 throw new IOException(t); 1176 } 1177 return null; 1178 } 1179 }; 1180 SUPERUSER.runAs(actiona); 1181 1182 TEST_UTIL.getAdmin().flush(tableName); 1183 Scan s = new Scan(); 1184 s.readVersions(5); 1185 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1186 ResultScanner scanner = table.getScanner(s); 1187 Result[] next = scanner.next(3); 1188 assertTrue(next.length == 2); 1189 CellScanner cellScanner = next[0].cellScanner(); 1190 cellScanner.advance(); 1191 Cell current = cellScanner.current(); 1192 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1193 row1, 0, row1.length)); 1194 assertEquals(128L, current.getTimestamp()); 1195 cellScanner.advance(); 1196 current = cellScanner.current(); 1197 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1198 row1, 0, row1.length)); 1199 assertEquals(127L, current.getTimestamp()); 1200 cellScanner.advance(); 1201 current = cellScanner.current(); 1202 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1203 row1, 0, row1.length)); 1204 assertEquals(126L, current.getTimestamp()); 1205 cellScanner.advance(); 1206 current = cellScanner.current(); 1207 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1208 row1, 0, row1.length)); 1209 assertEquals(125L, current.getTimestamp()); 1210 cellScanner.advance(); 1211 current = cellScanner.current(); 1212 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1213 row1, 0, row1.length)); 1214 assertEquals(124L, current.getTimestamp()); 1215 cellScanner = next[1].cellScanner(); 1216 cellScanner.advance(); 1217 current = cellScanner.current(); 1218 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1219 row2, 0, row2.length)); 1220 1221 put = new Put(Bytes.toBytes("row1")); 1222 put.addColumn(fam, qual, 129L, value); 1223 put.setCellVisibility(new CellVisibility(SECRET)); 1224 table.put(put); 1225 1226 TEST_UTIL.getAdmin().flush(tableName); 1227 s = new Scan(); 1228 s.readVersions(5); 1229 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1230 scanner = table.getScanner(s); 1231 next = scanner.next(3); 1232 assertTrue(next.length == 2); 1233 cellScanner = next[0].cellScanner(); 1234 cellScanner.advance(); 1235 current = cellScanner.current(); 1236 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1237 row1, 0, row1.length)); 1238 assertEquals(129L, current.getTimestamp()); 1239 } 1240 } 1241 1242 @Test 1243 public void testDeleteColumnWithLatestTimeStampUsingMultipleVersionsAfterCompaction( 1244 TestInfo testInfo) throws Exception { 1245 setAuths(); 1246 final TableName tableName = TableName 1247 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1248 try (Table table = doPuts(tableName)) { 1249 TEST_UTIL.getAdmin().flush(tableName); 1250 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1251 @Override 1252 public Void run() throws Exception { 1253 try (Connection connection = ConnectionFactory.createConnection(conf); 1254 Table table = connection.getTable(tableName)) { 1255 Delete d = new Delete(row1); 1256 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1257 d.addColumn(fam, qual); 1258 table.delete(d); 1259 } catch (Throwable t) { 1260 throw new IOException(t); 1261 } 1262 return null; 1263 } 1264 }; 1265 SUPERUSER.runAs(actiona); 1266 TEST_UTIL.getAdmin().flush(tableName); 1267 Put put = new Put(Bytes.toBytes("row3")); 1268 put.addColumn(fam, qual, 127L, value); 1269 put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "&" + PRIVATE)); 1270 table.put(put); 1271 TEST_UTIL.getAdmin().flush(tableName); 1272 TEST_UTIL.getAdmin().majorCompact(tableName); 1273 // Sleep to ensure compaction happens. Need to do it in a better way 1274 Thread.sleep(5000); 1275 Scan s = new Scan(); 1276 s.readVersions(5); 1277 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1278 ResultScanner scanner = table.getScanner(s); 1279 Result[] next = scanner.next(3); 1280 assertTrue(next.length == 3); 1281 CellScanner cellScanner = next[0].cellScanner(); 1282 cellScanner.advance(); 1283 Cell current = cellScanner.current(); 1284 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1285 row1, 0, row1.length)); 1286 assertEquals(127L, current.getTimestamp()); 1287 cellScanner.advance(); 1288 current = cellScanner.current(); 1289 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1290 row1, 0, row1.length)); 1291 assertEquals(126L, current.getTimestamp()); 1292 cellScanner.advance(); 1293 current = cellScanner.current(); 1294 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1295 row1, 0, row1.length)); 1296 assertEquals(124L, current.getTimestamp()); 1297 cellScanner.advance(); 1298 current = cellScanner.current(); 1299 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1300 row1, 0, row1.length)); 1301 assertEquals(123L, current.getTimestamp()); 1302 cellScanner = next[1].cellScanner(); 1303 cellScanner.advance(); 1304 current = cellScanner.current(); 1305 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1306 row2, 0, row2.length)); 1307 } 1308 } 1309 1310 @Test 1311 public void testDeleteFamilyLatestTimeStampWithMulipleVersions(TestInfo testInfo) 1312 throws Exception { 1313 setAuths(); 1314 final TableName tableName = TableName 1315 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1316 try (Table table = doPuts(tableName)) { 1317 TEST_UTIL.getAdmin().flush(tableName); 1318 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1319 @Override 1320 public Void run() throws Exception { 1321 try (Connection connection = ConnectionFactory.createConnection(conf); 1322 Table table = connection.getTable(tableName)) { 1323 Delete d = new Delete(row1); 1324 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1325 d.addFamily(fam); 1326 table.delete(d); 1327 } catch (Throwable t) { 1328 throw new IOException(t); 1329 } 1330 return null; 1331 } 1332 }; 1333 SUPERUSER.runAs(actiona); 1334 1335 TEST_UTIL.getAdmin().flush(tableName); 1336 Scan s = new Scan(); 1337 s.readVersions(5); 1338 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1339 ResultScanner scanner = table.getScanner(s); 1340 Result[] next = scanner.next(3); 1341 assertTrue(next.length == 2); 1342 CellScanner cellScanner = next[0].cellScanner(); 1343 cellScanner.advance(); 1344 Cell current = cellScanner.current(); 1345 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1346 row1, 0, row1.length)); 1347 assertEquals(127L, current.getTimestamp()); 1348 cellScanner.advance(); 1349 current = cellScanner.current(); 1350 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1351 row1, 0, row1.length)); 1352 assertEquals(126L, current.getTimestamp()); 1353 cellScanner = next[1].cellScanner(); 1354 cellScanner.advance(); 1355 current = cellScanner.current(); 1356 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1357 row2, 0, row2.length)); 1358 } 1359 } 1360 1361 @Test 1362 public void testDeleteColumnswithMultipleColumnsWithMultipleVersions(TestInfo testInfo) 1363 throws Exception { 1364 setAuths(); 1365 final TableName tableName = TableName 1366 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1367 try (Table table = doPutsWithDiffCols(tableName)) { 1368 TEST_UTIL.getAdmin().flush(tableName); 1369 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1370 @Override 1371 public Void run() throws Exception { 1372 Delete d = new Delete(row1); 1373 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1374 d.addColumns(fam, qual, 125L); 1375 try (Connection connection = ConnectionFactory.createConnection(conf); 1376 Table table = connection.getTable(tableName)) { 1377 table.delete(d); 1378 } catch (Throwable t) { 1379 throw new IOException(t); 1380 } 1381 return null; 1382 } 1383 }; 1384 SUPERUSER.runAs(actiona); 1385 1386 TEST_UTIL.getAdmin().flush(tableName); 1387 Scan s = new Scan(); 1388 s.readVersions(5); 1389 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1390 ResultScanner scanner = table.getScanner(s); 1391 Result[] next = scanner.next(3); 1392 assertTrue(next.length == 1); 1393 CellScanner cellScanner = next[0].cellScanner(); 1394 cellScanner.advance(); 1395 Cell current = cellScanner.current(); 1396 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1397 row1, 0, row1.length)); 1398 assertEquals(124L, current.getTimestamp()); 1399 cellScanner.advance(); 1400 current = cellScanner.current(); 1401 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1402 row1, 0, row1.length)); 1403 assertEquals(123L, current.getTimestamp()); 1404 cellScanner.advance(); 1405 current = cellScanner.current(); 1406 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1407 row1, 0, row1.length)); 1408 assertTrue(Bytes.equals(current.getQualifierArray(), current.getQualifierOffset(), 1409 current.getQualifierLength(), qual1, 0, qual1.length)); 1410 assertEquals(126L, current.getTimestamp()); 1411 cellScanner.advance(); 1412 current = cellScanner.current(); 1413 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1414 row1, 0, row1.length)); 1415 assertEquals(127L, current.getTimestamp()); 1416 assertTrue(Bytes.equals(current.getQualifierArray(), current.getQualifierOffset(), 1417 current.getQualifierLength(), qual2, 0, qual2.length)); 1418 } 1419 } 1420 1421 @Test 1422 public void testDeleteColumnsWithDiffColsAndTags(TestInfo testInfo) throws Exception { 1423 TableName tableName = createTable(5, testInfo); 1424 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 1425 Put put = new Put(Bytes.toBytes("row1")); 1426 put.addColumn(fam, qual1, 125L, value); 1427 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 1428 table.put(put); 1429 put = new Put(Bytes.toBytes("row1")); 1430 put.addColumn(fam, qual1, 126L, value); 1431 put.setCellVisibility(new CellVisibility(SECRET)); 1432 table.put(put); 1433 TEST_UTIL.getAdmin().flush(tableName); 1434 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1435 @Override 1436 public Void run() throws Exception { 1437 Delete d1 = new Delete(row1); 1438 d1.setCellVisibility(new CellVisibility(SECRET)); 1439 d1.addColumns(fam, qual, 126L); 1440 1441 Delete d2 = new Delete(row1); 1442 d2.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 1443 d2.addColumns(fam, qual1, 125L); 1444 1445 try (Connection connection = ConnectionFactory.createConnection(conf); 1446 Table table = connection.getTable(tableName)) { 1447 table.delete(createList(d1, d2)); 1448 } catch (Throwable t) { 1449 throw new IOException(t); 1450 } 1451 return null; 1452 } 1453 }; 1454 SUPERUSER.runAs(actiona); 1455 Scan s = new Scan(); 1456 s.readVersions(5); 1457 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL)); 1458 ResultScanner scanner = table.getScanner(s); 1459 Result[] next = scanner.next(3); 1460 assertEquals(1, next.length); 1461 } 1462 } 1463 1464 @Test 1465 public void testDeleteColumnsWithDiffColsAndTags1(TestInfo testInfo) throws Exception { 1466 TableName tableName = createTable(5, testInfo); 1467 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 1468 Put put = new Put(Bytes.toBytes("row1")); 1469 put.addColumn(fam, qual1, 125L, value); 1470 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 1471 table.put(put); 1472 put = new Put(Bytes.toBytes("row1")); 1473 put.addColumn(fam, qual1, 126L, value); 1474 put.setCellVisibility(new CellVisibility(SECRET)); 1475 table.put(put); 1476 TEST_UTIL.getAdmin().flush(tableName); 1477 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1478 @Override 1479 public Void run() throws Exception { 1480 Delete d1 = new Delete(row1); 1481 d1.setCellVisibility(new CellVisibility(SECRET)); 1482 d1.addColumns(fam, qual, 126L); 1483 1484 Delete d2 = new Delete(row1); 1485 d2.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 1486 d2.addColumns(fam, qual1, 126L); 1487 1488 try (Connection connection = ConnectionFactory.createConnection(conf); 1489 Table table = connection.getTable(tableName)) { 1490 table.delete(createList(d1, d2)); 1491 } catch (Throwable t) { 1492 throw new IOException(t); 1493 } 1494 return null; 1495 } 1496 }; 1497 SUPERUSER.runAs(actiona); 1498 Scan s = new Scan(); 1499 s.readVersions(5); 1500 s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL)); 1501 ResultScanner scanner = table.getScanner(s); 1502 Result[] next = scanner.next(3); 1503 assertEquals(1, next.length); 1504 } 1505 } 1506 1507 @Test 1508 public void testDeleteFamilyWithoutCellVisibilityWithMulipleVersions(TestInfo testInfo) 1509 throws Exception { 1510 setAuths(); 1511 final TableName tableName = TableName 1512 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1513 try (Table table = doPutsWithoutVisibility(tableName)) { 1514 TEST_UTIL.getAdmin().flush(tableName); 1515 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1516 @Override 1517 public Void run() throws Exception { 1518 try (Connection connection = ConnectionFactory.createConnection(conf); 1519 Table table = connection.getTable(tableName)) { 1520 Delete d = new Delete(row1); 1521 d.addFamily(fam); 1522 table.delete(d); 1523 } catch (Throwable t) { 1524 throw new IOException(t); 1525 } 1526 return null; 1527 } 1528 }; 1529 SUPERUSER.runAs(actiona); 1530 1531 TEST_UTIL.getAdmin().flush(tableName); 1532 Scan s = new Scan(); 1533 s.readVersions(5); 1534 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1535 ResultScanner scanner = table.getScanner(s); 1536 Result[] next = scanner.next(3); 1537 assertTrue(next.length == 1); 1538 // All cells wrt row1 should be deleted as we are not passing the Cell Visibility 1539 CellScanner cellScanner = next[0].cellScanner(); 1540 cellScanner.advance(); 1541 Cell current = cellScanner.current(); 1542 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1543 row2, 0, row2.length)); 1544 } 1545 } 1546 1547 @Test 1548 public void testDeleteFamilyLatestTimeStampWithMulipleVersionsWithoutCellVisibilityInPuts( 1549 TestInfo testInfo) throws Exception { 1550 setAuths(); 1551 final TableName tableName = TableName 1552 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1553 try (Table table = doPutsWithoutVisibility(tableName)) { 1554 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1555 @Override 1556 public Void run() throws Exception { 1557 try (Connection connection = ConnectionFactory.createConnection(conf); 1558 Table table = connection.getTable(tableName)) { 1559 Delete d = new Delete(row1); 1560 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1561 d.addFamily(fam); 1562 table.delete(d); 1563 } catch (Throwable t) { 1564 throw new IOException(t); 1565 } 1566 return null; 1567 } 1568 }; 1569 SUPERUSER.runAs(actiona); 1570 TEST_UTIL.getAdmin().flush(tableName); 1571 Scan s = new Scan(); 1572 s.readVersions(5); 1573 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1574 ResultScanner scanner = table.getScanner(s); 1575 Result[] next = scanner.next(3); 1576 assertTrue(next.length == 2); 1577 CellScanner cellScanner = next[0].cellScanner(); 1578 cellScanner.advance(); 1579 Cell current = cellScanner.current(); 1580 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1581 row1, 0, row1.length)); 1582 assertEquals(127L, current.getTimestamp()); 1583 cellScanner.advance(); 1584 current = cellScanner.current(); 1585 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1586 row1, 0, row1.length)); 1587 assertEquals(126L, current.getTimestamp()); 1588 cellScanner.advance(); 1589 current = cellScanner.current(); 1590 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1591 row1, 0, row1.length)); 1592 assertEquals(125L, current.getTimestamp()); 1593 cellScanner.advance(); 1594 current = cellScanner.current(); 1595 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1596 row1, 0, row1.length)); 1597 assertEquals(124L, current.getTimestamp()); 1598 cellScanner.advance(); 1599 current = cellScanner.current(); 1600 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1601 row1, 0, row1.length)); 1602 assertEquals(123L, current.getTimestamp()); 1603 cellScanner = next[1].cellScanner(); 1604 cellScanner.advance(); 1605 current = cellScanner.current(); 1606 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1607 row2, 0, row2.length)); 1608 } 1609 } 1610 1611 @Test 1612 public void testDeleteFamilySpecificTimeStampWithMulipleVersions(TestInfo testInfo) 1613 throws Exception { 1614 setAuths(); 1615 final TableName tableName = TableName 1616 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1617 try (Table table = doPuts(tableName)) { 1618 TEST_UTIL.getAdmin().flush(tableName); 1619 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1620 @Override 1621 public Void run() throws Exception { 1622 try (Connection connection = ConnectionFactory.createConnection(conf); 1623 Table table = connection.getTable(tableName)) { 1624 Delete d = new Delete(row1); 1625 d.setCellVisibility(new CellVisibility( 1626 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 1627 d.addFamily(fam, 126L); 1628 table.delete(d); 1629 } catch (Throwable t) { 1630 throw new IOException(t); 1631 } 1632 return null; 1633 } 1634 }; 1635 SUPERUSER.runAs(actiona); 1636 1637 TEST_UTIL.getAdmin().flush(tableName); 1638 Scan s = new Scan(); 1639 s.readVersions(5); 1640 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1641 ResultScanner scanner = table.getScanner(s); 1642 Result[] next = scanner.next(6); 1643 assertTrue(next.length == 2); 1644 CellScanner cellScanner = next[0].cellScanner(); 1645 cellScanner.advance(); 1646 Cell current = cellScanner.current(); 1647 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1648 row1, 0, row1.length)); 1649 assertEquals(127L, current.getTimestamp()); 1650 cellScanner.advance(); 1651 current = cellScanner.current(); 1652 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1653 row1, 0, row1.length)); 1654 assertEquals(125L, current.getTimestamp()); 1655 cellScanner.advance(); 1656 current = cellScanner.current(); 1657 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1658 row1, 0, row1.length)); 1659 assertEquals(123L, current.getTimestamp()); 1660 cellScanner = next[1].cellScanner(); 1661 cellScanner.advance(); 1662 current = cellScanner.current(); 1663 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1664 row2, 0, row2.length)); 1665 } 1666 } 1667 1668 @Test 1669 public void testScanAfterCompaction(TestInfo testInfo) throws Exception { 1670 setAuths(); 1671 final TableName tableName = TableName 1672 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1673 try (Table table = doPuts(tableName)) { 1674 TEST_UTIL.getAdmin().flush(tableName); 1675 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1676 @Override 1677 public Void run() throws Exception { 1678 try (Connection connection = ConnectionFactory.createConnection(conf); 1679 Table table = connection.getTable(tableName)) { 1680 Delete d = new Delete(row1); 1681 d.setCellVisibility(new CellVisibility( 1682 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + SECRET + "&" + TOPSECRET + ")")); 1683 d.addFamily(fam, 126L); 1684 table.delete(d); 1685 } catch (Throwable t) { 1686 throw new IOException(t); 1687 } 1688 return null; 1689 } 1690 }; 1691 SUPERUSER.runAs(actiona); 1692 1693 TEST_UTIL.getAdmin().flush(tableName); 1694 Put put = new Put(Bytes.toBytes("row3")); 1695 put.addColumn(fam, qual, 127L, value); 1696 put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "&" + PRIVATE)); 1697 table.put(put); 1698 TEST_UTIL.getAdmin().flush(tableName); 1699 TEST_UTIL.getAdmin().compact(tableName); 1700 Thread.sleep(5000); 1701 // Sleep to ensure compaction happens. Need to do it in a better way 1702 Scan s = new Scan(); 1703 s.readVersions(5); 1704 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1705 ResultScanner scanner = table.getScanner(s); 1706 Result[] next = scanner.next(3); 1707 assertTrue(next.length == 3); 1708 CellScanner cellScanner = next[0].cellScanner(); 1709 cellScanner.advance(); 1710 Cell current = cellScanner.current(); 1711 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1712 row1, 0, row1.length)); 1713 assertEquals(127L, current.getTimestamp()); 1714 cellScanner = next[1].cellScanner(); 1715 cellScanner.advance(); 1716 current = cellScanner.current(); 1717 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1718 row2, 0, row2.length)); 1719 } 1720 } 1721 1722 /** 1723 * On a cell-visibility table, two DeleteColumn markers carrying different labels shadow disjoint 1724 * cells, so neither is redundant w.r.t. the other. A minor compaction must not drop the 1725 * lower-timestamp marker just because a higher-timestamp marker of a different label was tracked 1726 * first; doing so would resurrect data that must stay deleted. This is the end-to-end regression 1727 * guard for {@link VisibilityScanDeleteTracker#isRedundantDelete}. 1728 * <p> 1729 * The big put is larger than {@code hbase.hstore.compaction.max.size}, so minor compaction 1730 * excludes its file and merges only the two small delete-marker files (isAllFiles=false, hence 1731 * COMPACT_RETAIN_DELETES and MinorCompactionScanQueryMatcher, the path that calls 1732 * isRedundantDelete). The put's data stays in its own file, so dropping the SECRET marker would 1733 * make it visible again. 1734 */ 1735 @Test 1736 public void testDifferentLabelDeleteMarkersSurviveMinorCompaction(TestInfo testInfo) 1737 throws Exception { 1738 setAuths(); 1739 final TableName tableName = TableName 1740 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1741 // Minor compaction merges at most two files and skips any file larger than 64KB. 1742 ColumnFamilyDescriptorBuilder cfd = ColumnFamilyDescriptorBuilder.newBuilder(fam) 1743 .setMaxVersions(5).setConfiguration("hbase.hstore.compaction.min", "2") 1744 .setConfiguration("hbase.hstore.compaction.max", "2") 1745 .setConfiguration("hbase.hstore.compaction.max.size", "65536"); 1746 // Disable automatic compaction while the three HFiles are laid down, so the minor compaction 1747 // under test is exactly the one triggered explicitly below (no racing background compaction). 1748 TEST_UTIL.getAdmin().createTable(TableDescriptorBuilder.newBuilder(tableName) 1749 .setCompactionEnabled(false).setColumnFamily(cfd.build()).build()); 1750 1751 SUPERUSER.runAs((PrivilegedExceptionAction<Void>) () -> { 1752 try (Connection connection = ConnectionFactory.createConnection(conf); 1753 Table table = connection.getTable(tableName)) { 1754 // Big SECRET-visible put at ts=40. Random bytes keep the file above max.size so it is 1755 // excluded from the minor compaction and retains the data the SECRET delete shadows. 1756 byte[] big = new byte[200 * 1024]; 1757 new Random(1).nextBytes(big); 1758 Put put = new Put(row1); 1759 put.addColumn(fam, qual, 40L, big); 1760 put.setCellVisibility(new CellVisibility(SECRET)); 1761 table.put(put); 1762 TEST_UTIL.getAdmin().flush(tableName); 1763 // SECRET DeleteColumn at ts=50 shadows the SECRET put. 1764 Delete dSecret = new Delete(row1); 1765 dSecret.setCellVisibility(new CellVisibility(SECRET)); 1766 dSecret.addColumns(fam, qual, 50L); 1767 table.delete(dSecret); 1768 TEST_UTIL.getAdmin().flush(tableName); 1769 // Newer CONFIDENTIAL DeleteColumn at ts=100 shadows disjoint (CONFIDENTIAL) cells. 1770 Delete dConf = new Delete(row1); 1771 dConf.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 1772 dConf.addColumns(fam, qual, 100L); 1773 table.delete(dConf); 1774 TEST_UTIL.getAdmin().flush(tableName); 1775 } 1776 return null; 1777 }); 1778 1779 // Before compaction the SECRET put is correctly hidden by the SECRET delete. 1780 assertEquals(0, countCells(tableName, SECRET)); 1781 1782 // Synchronously minor-compact the two small delete files (the big put file is excluded). 1783 HRegion region = TEST_UTIL.getHBaseCluster().getRegions(tableName).get(0); 1784 region.compact(false); 1785 // Two files remain: the untouched big put file plus the single merged delete file. This both 1786 // confirms a minor compaction happened and that the big file was not swept into a major one. 1787 await().atMost(Duration.ofSeconds(60)) 1788 .untilAsserted(() -> assertEquals(2, region.getStore(fam).getStorefilesCount())); 1789 1790 // The SECRET delete must still shadow the SECRET put: no resurrection. 1791 assertEquals(0, countCells(tableName, SECRET)); 1792 } 1793 1794 private int countCells(TableName tableName, String... auths) throws Exception { 1795 return SUPERUSER.runAs((PrivilegedExceptionAction<Integer>) () -> { 1796 try (Connection connection = ConnectionFactory.createConnection(conf); 1797 Table table = connection.getTable(tableName)) { 1798 Scan s = new Scan(); 1799 s.readVersions(5); 1800 s.setAuthorizations(new Authorizations(auths)); 1801 try (ResultScanner scanner = table.getScanner(s)) { 1802 int count = 0; 1803 for (Result r : scanner) { 1804 count += r.size(); 1805 } 1806 return count; 1807 } 1808 } 1809 }); 1810 } 1811 1812 @Test 1813 public void testDeleteFamilySpecificTimeStampWithMulipleVersionsDoneTwice(TestInfo testInfo) 1814 throws Exception { 1815 setAuths(); 1816 final TableName tableName = TableName 1817 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1818 // Do not flush here. 1819 try (Table table = doPuts(tableName)) { 1820 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1821 @Override 1822 public Void run() throws Exception { 1823 try (Connection connection = ConnectionFactory.createConnection(conf); 1824 Table table = connection.getTable(tableName)) { 1825 Delete d = new Delete(row1); 1826 d.setCellVisibility(new CellVisibility( 1827 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + TOPSECRET + "&" + SECRET + ")")); 1828 d.addFamily(fam, 125L); 1829 table.delete(d); 1830 } catch (Throwable t) { 1831 throw new IOException(t); 1832 } 1833 return null; 1834 } 1835 }; 1836 SUPERUSER.runAs(actiona); 1837 1838 Scan s = new Scan(); 1839 s.readVersions(5); 1840 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1841 ResultScanner scanner = table.getScanner(s); 1842 Result[] next = scanner.next(3); 1843 assertTrue(next.length == 2); 1844 CellScanner cellScanner = next[0].cellScanner(); 1845 cellScanner.advance(); 1846 Cell current = cellScanner.current(); 1847 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1848 row1, 0, row1.length)); 1849 assertEquals(127L, current.getTimestamp()); 1850 cellScanner.advance(); 1851 current = cellScanner.current(); 1852 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1853 row1, 0, row1.length)); 1854 assertEquals(126L, current.getTimestamp()); 1855 cellScanner.advance(); 1856 current = cellScanner.current(); 1857 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1858 row1, 0, row1.length)); 1859 assertEquals(125L, current.getTimestamp()); 1860 cellScanner.advance(); 1861 current = cellScanner.current(); 1862 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1863 row1, 0, row1.length)); 1864 assertEquals(123L, current.getTimestamp()); 1865 cellScanner = next[1].cellScanner(); 1866 cellScanner.advance(); 1867 current = cellScanner.current(); 1868 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1869 row2, 0, row2.length)); 1870 1871 // Issue 2nd delete 1872 actiona = new PrivilegedExceptionAction<Void>() { 1873 @Override 1874 public Void run() throws Exception { 1875 try (Connection connection = ConnectionFactory.createConnection(conf); 1876 Table table = connection.getTable(tableName)) { 1877 Delete d = new Delete(row1); 1878 d.setCellVisibility(new CellVisibility( 1879 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 1880 d.addFamily(fam, 127L); 1881 table.delete(d); 1882 } catch (Throwable t) { 1883 throw new IOException(t); 1884 } 1885 return null; 1886 } 1887 }; 1888 SUPERUSER.runAs(actiona); 1889 s = new Scan(); 1890 s.readVersions(5); 1891 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1892 scanner = table.getScanner(s); 1893 next = scanner.next(3); 1894 assertTrue(next.length == 2); 1895 cellScanner = next[0].cellScanner(); 1896 cellScanner.advance(); 1897 current = cellScanner.current(); 1898 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1899 row1, 0, row1.length)); 1900 assertEquals(125L, current.getTimestamp()); 1901 cellScanner.advance(); 1902 current = cellScanner.current(); 1903 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1904 row1, 0, row1.length)); 1905 assertEquals(123L, current.getTimestamp()); 1906 cellScanner = next[1].cellScanner(); 1907 cellScanner.advance(); 1908 current = cellScanner.current(); 1909 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1910 row2, 0, row2.length)); 1911 assertEquals(127L, current.getTimestamp()); 1912 } 1913 } 1914 1915 @Test 1916 public void testMultipleDeleteFamilyVersionWithDiffLabels(TestInfo testInfo) throws Exception { 1917 PrivilegedExceptionAction<VisibilityLabelsResponse> action = 1918 new PrivilegedExceptionAction<VisibilityLabelsResponse>() { 1919 @Override 1920 public VisibilityLabelsResponse run() throws Exception { 1921 try (Connection conn = ConnectionFactory.createConnection(conf)) { 1922 return VisibilityClient.setAuths(conn, new String[] { CONFIDENTIAL, PRIVATE, SECRET }, 1923 SUPERUSER.getShortName()); 1924 } catch (Throwable e) { 1925 } 1926 return null; 1927 } 1928 }; 1929 SUPERUSER.runAs(action); 1930 final TableName tableName = TableName 1931 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1932 try (Table table = doPuts(tableName)) { 1933 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1934 @Override 1935 public Void run() throws Exception { 1936 try (Connection connection = ConnectionFactory.createConnection(conf); 1937 Table table = connection.getTable(tableName)) { 1938 Delete d = new Delete(row1); 1939 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 1940 d.addFamilyVersion(fam, 123L); 1941 table.delete(d); 1942 d = new Delete(row1); 1943 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1944 d.addFamilyVersion(fam, 125L); 1945 table.delete(d); 1946 } catch (Throwable t) { 1947 throw new IOException(t); 1948 } 1949 return null; 1950 } 1951 }; 1952 SUPERUSER.runAs(actiona); 1953 1954 TEST_UTIL.getAdmin().flush(tableName); 1955 Scan s = new Scan(); 1956 s.readVersions(5); 1957 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 1958 ResultScanner scanner = table.getScanner(s); 1959 Result[] next = scanner.next(5); 1960 assertTrue(next.length == 2); 1961 CellScanner cellScanner = next[0].cellScanner(); 1962 cellScanner.advance(); 1963 Cell current = cellScanner.current(); 1964 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1965 row1, 0, row1.length)); 1966 assertEquals(127L, current.getTimestamp()); 1967 cellScanner.advance(); 1968 current = cellScanner.current(); 1969 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1970 row1, 0, row1.length)); 1971 assertEquals(126L, current.getTimestamp()); 1972 cellScanner.advance(); 1973 current = cellScanner.current(); 1974 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 1975 row1, 0, row1.length)); 1976 assertEquals(124L, current.getTimestamp()); 1977 } 1978 } 1979 1980 @Test 1981 public void testSpecificDeletesFollowedByDeleteFamily(TestInfo testInfo) throws Exception { 1982 setAuths(); 1983 final TableName tableName = TableName 1984 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 1985 try (Table table = doPuts(tableName)) { 1986 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 1987 @Override 1988 public Void run() throws Exception { 1989 try (Connection connection = ConnectionFactory.createConnection(conf); 1990 Table table = connection.getTable(tableName)) { 1991 Delete d = new Delete(row1); 1992 d.setCellVisibility(new CellVisibility( 1993 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 1994 d.addColumn(fam, qual, 126L); 1995 table.delete(d); 1996 d = new Delete(row1); 1997 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 1998 d.addFamilyVersion(fam, 125L); 1999 table.delete(d); 2000 } catch (Throwable t) { 2001 throw new IOException(t); 2002 } 2003 return null; 2004 } 2005 }; 2006 SUPERUSER.runAs(actiona); 2007 2008 TEST_UTIL.getAdmin().flush(tableName); 2009 Scan s = new Scan(); 2010 s.readVersions(5); 2011 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2012 ResultScanner scanner = table.getScanner(s); 2013 Result[] next = scanner.next(5); 2014 assertTrue(next.length == 2); 2015 CellScanner cellScanner = next[0].cellScanner(); 2016 cellScanner.advance(); 2017 Cell current = cellScanner.current(); 2018 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2019 row1, 0, row1.length)); 2020 assertEquals(127L, current.getTimestamp()); 2021 cellScanner.advance(); 2022 current = cellScanner.current(); 2023 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2024 row1, 0, row1.length)); 2025 assertEquals(124L, current.getTimestamp()); 2026 cellScanner.advance(); 2027 current = cellScanner.current(); 2028 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2029 row1, 0, row1.length)); 2030 assertEquals(123L, current.getTimestamp()); 2031 // Issue 2nd delete 2032 actiona = new PrivilegedExceptionAction<Void>() { 2033 @Override 2034 public Void run() throws Exception { 2035 try (Connection connection = ConnectionFactory.createConnection(conf); 2036 Table table = connection.getTable(tableName)) { 2037 Delete d = new Delete(row1); 2038 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 2039 d.addFamily(fam); 2040 table.delete(d); 2041 } catch (Throwable t) { 2042 throw new IOException(t); 2043 } 2044 return null; 2045 } 2046 }; 2047 SUPERUSER.runAs(actiona); 2048 s = new Scan(); 2049 s.readVersions(5); 2050 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2051 scanner = table.getScanner(s); 2052 next = scanner.next(5); 2053 assertTrue(next.length == 2); 2054 cellScanner = next[0].cellScanner(); 2055 cellScanner.advance(); 2056 current = cellScanner.current(); 2057 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2058 row1, 0, row1.length)); 2059 assertEquals(127L, current.getTimestamp()); 2060 cellScanner.advance(); 2061 current = cellScanner.current(); 2062 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2063 row1, 0, row1.length)); 2064 assertEquals(124L, current.getTimestamp()); 2065 } 2066 } 2067 2068 @Test 2069 public void testSpecificDeletesFollowedByDeleteFamily1(TestInfo testInfo) throws Exception { 2070 PrivilegedExceptionAction<VisibilityLabelsResponse> action = 2071 new PrivilegedExceptionAction<VisibilityLabelsResponse>() { 2072 @Override 2073 public VisibilityLabelsResponse run() throws Exception { 2074 try (Connection conn = ConnectionFactory.createConnection(conf)) { 2075 return VisibilityClient.setAuths(conn, new String[] { CONFIDENTIAL, PRIVATE, SECRET }, 2076 SUPERUSER.getShortName()); 2077 } catch (Throwable e) { 2078 } 2079 return null; 2080 } 2081 }; 2082 SUPERUSER.runAs(action); 2083 final TableName tableName = TableName 2084 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2085 try (Table table = doPuts(tableName)) { 2086 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2087 @Override 2088 public Void run() throws Exception { 2089 try (Connection connection = ConnectionFactory.createConnection(conf); 2090 Table table = connection.getTable(tableName)) { 2091 Delete d = new Delete(row1); 2092 d.setCellVisibility(new CellVisibility( 2093 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2094 d.addColumn(fam, qual); 2095 table.delete(d); 2096 2097 d = new Delete(row1); 2098 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 2099 d.addFamilyVersion(fam, 125L); 2100 table.delete(d); 2101 } catch (Throwable t) { 2102 throw new IOException(t); 2103 } 2104 return null; 2105 } 2106 }; 2107 SUPERUSER.runAs(actiona); 2108 2109 TEST_UTIL.getAdmin().flush(tableName); 2110 Scan s = new Scan(); 2111 s.readVersions(5); 2112 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2113 ResultScanner scanner = table.getScanner(s); 2114 Result[] next = scanner.next(5); 2115 assertTrue(next.length == 2); 2116 CellScanner cellScanner = next[0].cellScanner(); 2117 cellScanner.advance(); 2118 Cell current = cellScanner.current(); 2119 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2120 row1, 0, row1.length)); 2121 assertEquals(126L, current.getTimestamp()); 2122 cellScanner.advance(); 2123 current = cellScanner.current(); 2124 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2125 row1, 0, row1.length)); 2126 assertEquals(124L, current.getTimestamp()); 2127 cellScanner.advance(); 2128 current = cellScanner.current(); 2129 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2130 row1, 0, row1.length)); 2131 assertEquals(123L, current.getTimestamp()); 2132 // Issue 2nd delete 2133 actiona = new PrivilegedExceptionAction<Void>() { 2134 @Override 2135 public Void run() throws Exception { 2136 try (Connection connection = ConnectionFactory.createConnection(conf); 2137 Table table = connection.getTable(tableName)) { 2138 Delete d = new Delete(row1); 2139 d.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 2140 d.addFamily(fam); 2141 table.delete(d); 2142 } catch (Throwable t) { 2143 throw new IOException(t); 2144 } 2145 return null; 2146 } 2147 }; 2148 SUPERUSER.runAs(actiona); 2149 s = new Scan(); 2150 s.readVersions(5); 2151 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2152 scanner = table.getScanner(s); 2153 next = scanner.next(5); 2154 assertTrue(next.length == 2); 2155 cellScanner = next[0].cellScanner(); 2156 cellScanner.advance(); 2157 current = cellScanner.current(); 2158 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2159 row1, 0, row1.length)); 2160 assertEquals(126L, current.getTimestamp()); 2161 cellScanner.advance(); 2162 current = cellScanner.current(); 2163 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2164 row1, 0, row1.length)); 2165 assertEquals(124L, current.getTimestamp()); 2166 } 2167 } 2168 2169 @Test 2170 public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice(TestInfo testInfo) 2171 throws Exception { 2172 setAuths(); 2173 final TableName tableName = TableName 2174 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2175 try (Table table = doPuts(tableName)) { 2176 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2177 @Override 2178 public Void run() throws Exception { 2179 try (Connection connection = ConnectionFactory.createConnection(conf); 2180 Table table = connection.getTable(tableName)) { 2181 Delete d = new Delete(row1); 2182 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 2183 d.addColumn(fam, qual, 125L); 2184 table.delete(d); 2185 } catch (Throwable t) { 2186 throw new IOException(t); 2187 } 2188 return null; 2189 } 2190 }; 2191 SUPERUSER.runAs(actiona); 2192 2193 Scan s = new Scan(); 2194 s.readVersions(5); 2195 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2196 ResultScanner scanner = table.getScanner(s); 2197 Result[] next = scanner.next(3); 2198 assertTrue(next.length == 2); 2199 CellScanner cellScanner = next[0].cellScanner(); 2200 cellScanner.advance(); 2201 Cell current = cellScanner.current(); 2202 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2203 row1, 0, row1.length)); 2204 assertEquals(127L, current.getTimestamp()); 2205 cellScanner.advance(); 2206 current = cellScanner.current(); 2207 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2208 row1, 0, row1.length)); 2209 assertEquals(126L, current.getTimestamp()); 2210 cellScanner.advance(); 2211 current = cellScanner.current(); 2212 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2213 row1, 0, row1.length)); 2214 assertEquals(124L, current.getTimestamp()); 2215 cellScanner.advance(); 2216 current = cellScanner.current(); 2217 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2218 row1, 0, row1.length)); 2219 assertEquals(123L, current.getTimestamp()); 2220 cellScanner = next[1].cellScanner(); 2221 cellScanner.advance(); 2222 current = cellScanner.current(); 2223 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2224 row2, 0, row2.length)); 2225 2226 // Issue 2nd delete 2227 actiona = new PrivilegedExceptionAction<Void>() { 2228 @Override 2229 public Void run() throws Exception { 2230 try (Connection connection = ConnectionFactory.createConnection(conf); 2231 Table table = connection.getTable(tableName)) { 2232 Delete d = new Delete(row1); 2233 d.setCellVisibility(new CellVisibility( 2234 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2235 d.addColumn(fam, qual, 127L); 2236 table.delete(d); 2237 } catch (Throwable t) { 2238 throw new IOException(t); 2239 } 2240 return null; 2241 } 2242 }; 2243 SUPERUSER.runAs(actiona); 2244 s = new Scan(); 2245 s.readVersions(5); 2246 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2247 scanner = table.getScanner(s); 2248 next = scanner.next(3); 2249 assertTrue(next.length == 2); 2250 cellScanner = next[0].cellScanner(); 2251 cellScanner.advance(); 2252 current = cellScanner.current(); 2253 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2254 row1, 0, row1.length)); 2255 assertEquals(126L, current.getTimestamp()); 2256 cellScanner.advance(); 2257 current = cellScanner.current(); 2258 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2259 row1, 0, row1.length)); 2260 assertEquals(124L, current.getTimestamp()); 2261 cellScanner.advance(); 2262 current = cellScanner.current(); 2263 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2264 row1, 0, row1.length)); 2265 assertEquals(123L, current.getTimestamp()); 2266 cellScanner = next[1].cellScanner(); 2267 cellScanner.advance(); 2268 current = cellScanner.current(); 2269 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2270 row2, 0, row2.length)); 2271 assertEquals(127L, current.getTimestamp()); 2272 } 2273 } 2274 2275 @Test 2276 public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice1(TestInfo testInfo) 2277 throws Exception { 2278 setAuths(); 2279 final TableName tableName = TableName 2280 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2281 // Do not flush here. 2282 try (Table table = doPuts(tableName)) { 2283 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2284 @Override 2285 public Void run() throws Exception { 2286 try (Connection connection = ConnectionFactory.createConnection(conf); 2287 Table table = connection.getTable(tableName)) { 2288 Delete d = new Delete(row1); 2289 d.setCellVisibility(new CellVisibility( 2290 "(" + CONFIDENTIAL + "&" + PRIVATE + ")" + "|(" + TOPSECRET + "&" + SECRET + ")")); 2291 d.addColumn(fam, qual, 127L); 2292 table.delete(d); 2293 } catch (Throwable t) { 2294 throw new IOException(t); 2295 } 2296 return null; 2297 } 2298 }; 2299 SUPERUSER.runAs(actiona); 2300 2301 Scan s = new Scan(); 2302 s.readVersions(5); 2303 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2304 ResultScanner scanner = table.getScanner(s); 2305 Result[] next = scanner.next(3); 2306 assertTrue(next.length == 2); 2307 CellScanner cellScanner = next[0].cellScanner(); 2308 cellScanner.advance(); 2309 Cell current = cellScanner.current(); 2310 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2311 row1, 0, row1.length)); 2312 assertEquals(126L, current.getTimestamp()); 2313 cellScanner.advance(); 2314 current = cellScanner.current(); 2315 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2316 row1, 0, row1.length)); 2317 assertEquals(125L, current.getTimestamp()); 2318 cellScanner.advance(); 2319 current = cellScanner.current(); 2320 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2321 row1, 0, row1.length)); 2322 assertEquals(124L, current.getTimestamp()); 2323 cellScanner.advance(); 2324 current = cellScanner.current(); 2325 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2326 row1, 0, row1.length)); 2327 assertEquals(123L, current.getTimestamp()); 2328 cellScanner = next[1].cellScanner(); 2329 cellScanner.advance(); 2330 current = cellScanner.current(); 2331 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2332 row2, 0, row2.length)); 2333 2334 // Issue 2nd delete 2335 actiona = new PrivilegedExceptionAction<Void>() { 2336 @Override 2337 public Void run() throws Exception { 2338 try (Connection connection = ConnectionFactory.createConnection(conf); 2339 Table table = connection.getTable(tableName)) { 2340 Delete d = new Delete(row1); 2341 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 2342 d.addColumn(fam, qual, 127L); 2343 table.delete(d); 2344 } catch (Throwable t) { 2345 throw new IOException(t); 2346 } 2347 return null; 2348 } 2349 }; 2350 SUPERUSER.runAs(actiona); 2351 s = new Scan(); 2352 s.readVersions(5); 2353 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2354 scanner = table.getScanner(s); 2355 next = scanner.next(3); 2356 assertTrue(next.length == 2); 2357 cellScanner = next[0].cellScanner(); 2358 cellScanner.advance(); 2359 current = cellScanner.current(); 2360 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2361 row1, 0, row1.length)); 2362 assertEquals(126L, current.getTimestamp()); 2363 cellScanner.advance(); 2364 current = cellScanner.current(); 2365 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2366 row1, 0, row1.length)); 2367 assertEquals(125L, current.getTimestamp()); 2368 cellScanner.advance(); 2369 current = cellScanner.current(); 2370 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2371 row1, 0, row1.length)); 2372 assertEquals(124L, current.getTimestamp()); 2373 cellScanner.advance(); 2374 current = cellScanner.current(); 2375 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2376 row1, 0, row1.length)); 2377 assertEquals(123L, current.getTimestamp()); 2378 cellScanner = next[1].cellScanner(); 2379 cellScanner.advance(); 2380 current = cellScanner.current(); 2381 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2382 row2, 0, row2.length)); 2383 assertEquals(127L, current.getTimestamp()); 2384 } 2385 } 2386 2387 @Test 2388 public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice2(TestInfo testInfo) 2389 throws Exception { 2390 setAuths(); 2391 final TableName tableName = TableName 2392 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2393 2394 // Do not flush here. 2395 try (Table table = doPuts(tableName)) { 2396 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2397 @Override 2398 public Void run() throws Exception { 2399 try (Connection connection = ConnectionFactory.createConnection(conf); 2400 Table table = connection.getTable(tableName)) { 2401 Delete d = new Delete(row1); 2402 d.setCellVisibility(new CellVisibility( 2403 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2404 d.addColumn(fam, qual, 125L); 2405 table.delete(d); 2406 } catch (Throwable t) { 2407 throw new IOException(t); 2408 } 2409 return null; 2410 } 2411 }; 2412 SUPERUSER.runAs(actiona); 2413 2414 Scan s = new Scan(); 2415 s.readVersions(5); 2416 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2417 ResultScanner scanner = table.getScanner(s); 2418 Result[] next = scanner.next(3); 2419 assertTrue(next.length == 2); 2420 CellScanner cellScanner = next[0].cellScanner(); 2421 cellScanner.advance(); 2422 Cell current = cellScanner.current(); 2423 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2424 row1, 0, row1.length)); 2425 assertEquals(127L, current.getTimestamp()); 2426 cellScanner.advance(); 2427 current = cellScanner.current(); 2428 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2429 row1, 0, row1.length)); 2430 assertEquals(126L, current.getTimestamp()); 2431 cellScanner.advance(); 2432 current = cellScanner.current(); 2433 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2434 row1, 0, row1.length)); 2435 assertEquals(125L, current.getTimestamp()); 2436 cellScanner.advance(); 2437 current = cellScanner.current(); 2438 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2439 row1, 0, row1.length)); 2440 assertEquals(124L, current.getTimestamp()); 2441 cellScanner.advance(); 2442 current = cellScanner.current(); 2443 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2444 row1, 0, row1.length)); 2445 assertEquals(123L, current.getTimestamp()); 2446 cellScanner = next[1].cellScanner(); 2447 cellScanner.advance(); 2448 current = cellScanner.current(); 2449 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2450 row2, 0, row2.length)); 2451 2452 // Issue 2nd delete 2453 actiona = new PrivilegedExceptionAction<Void>() { 2454 @Override 2455 public Void run() throws Exception { 2456 try (Connection connection = ConnectionFactory.createConnection(conf); 2457 Table table = connection.getTable(tableName)) { 2458 Delete d = new Delete(row1); 2459 d.setCellVisibility(new CellVisibility( 2460 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2461 d.addColumn(fam, qual, 127L); 2462 table.delete(d); 2463 } catch (Throwable t) { 2464 throw new IOException(t); 2465 } 2466 return null; 2467 } 2468 }; 2469 SUPERUSER.runAs(actiona); 2470 s = new Scan(); 2471 s.readVersions(5); 2472 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2473 scanner = table.getScanner(s); 2474 next = scanner.next(3); 2475 assertTrue(next.length == 2); 2476 cellScanner = next[0].cellScanner(); 2477 cellScanner.advance(); 2478 current = cellScanner.current(); 2479 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2480 row1, 0, row1.length)); 2481 assertEquals(126L, current.getTimestamp()); 2482 cellScanner.advance(); 2483 current = cellScanner.current(); 2484 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2485 row1, 0, row1.length)); 2486 assertEquals(125L, current.getTimestamp()); 2487 cellScanner.advance(); 2488 current = cellScanner.current(); 2489 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2490 row1, 0, row1.length)); 2491 assertEquals(124L, current.getTimestamp()); 2492 cellScanner.advance(); 2493 current = cellScanner.current(); 2494 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2495 row1, 0, row1.length)); 2496 assertEquals(123L, current.getTimestamp()); 2497 cellScanner = next[1].cellScanner(); 2498 cellScanner.advance(); 2499 current = cellScanner.current(); 2500 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2501 row2, 0, row2.length)); 2502 assertEquals(127L, current.getTimestamp()); 2503 } 2504 } 2505 2506 @Test 2507 public void testDeleteColumnAndDeleteFamilylSpecificTimeStampWithMulipleVersion(TestInfo testInfo) 2508 throws Exception { 2509 setAuths(); 2510 final TableName tableName = TableName 2511 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2512 // Do not flush here. 2513 try (Table table = doPuts(tableName)) { 2514 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2515 @Override 2516 public Void run() throws Exception { 2517 try (Connection connection = ConnectionFactory.createConnection(conf); 2518 Table table = connection.getTable(tableName)) { 2519 Delete d = new Delete(row1); 2520 d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET)); 2521 d.addColumn(fam, qual, 125L); 2522 table.delete(d); 2523 } catch (Throwable t) { 2524 throw new IOException(t); 2525 } 2526 return null; 2527 } 2528 }; 2529 SUPERUSER.runAs(actiona); 2530 2531 Scan s = new Scan(); 2532 s.readVersions(5); 2533 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2534 ResultScanner scanner = table.getScanner(s); 2535 Result[] next = scanner.next(3); 2536 assertTrue(next.length == 2); 2537 CellScanner cellScanner = next[0].cellScanner(); 2538 cellScanner.advance(); 2539 Cell current = cellScanner.current(); 2540 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2541 row1, 0, row1.length)); 2542 assertEquals(127L, current.getTimestamp()); 2543 cellScanner.advance(); 2544 current = cellScanner.current(); 2545 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2546 row1, 0, row1.length)); 2547 assertEquals(126L, current.getTimestamp()); 2548 cellScanner.advance(); 2549 current = cellScanner.current(); 2550 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2551 row1, 0, row1.length)); 2552 assertEquals(124L, current.getTimestamp()); 2553 cellScanner.advance(); 2554 current = cellScanner.current(); 2555 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2556 row1, 0, row1.length)); 2557 assertEquals(123L, current.getTimestamp()); 2558 cellScanner = next[1].cellScanner(); 2559 cellScanner.advance(); 2560 current = cellScanner.current(); 2561 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2562 row2, 0, row2.length)); 2563 2564 // Issue 2nd delete 2565 actiona = new PrivilegedExceptionAction<Void>() { 2566 @Override 2567 public Void run() throws Exception { 2568 try (Connection connection = ConnectionFactory.createConnection(conf); 2569 Table table = connection.getTable(tableName)) { 2570 Delete d = new Delete(row1); 2571 d.setCellVisibility(new CellVisibility( 2572 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2573 d.addFamily(fam, 124L); 2574 table.delete(d); 2575 } catch (Throwable t) { 2576 throw new IOException(t); 2577 } 2578 return null; 2579 } 2580 }; 2581 SUPERUSER.runAs(actiona); 2582 s = new Scan(); 2583 s.readVersions(5); 2584 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2585 scanner = table.getScanner(s); 2586 next = scanner.next(3); 2587 assertTrue(next.length == 2); 2588 cellScanner = next[0].cellScanner(); 2589 cellScanner.advance(); 2590 current = cellScanner.current(); 2591 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2592 row1, 0, row1.length)); 2593 assertEquals(127L, current.getTimestamp()); 2594 cellScanner.advance(); 2595 current = cellScanner.current(); 2596 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2597 row1, 0, row1.length)); 2598 assertEquals(126L, current.getTimestamp()); 2599 cellScanner = next[1].cellScanner(); 2600 cellScanner.advance(); 2601 current = cellScanner.current(); 2602 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2603 row2, 0, row2.length)); 2604 assertEquals(127L, current.getTimestamp()); 2605 } 2606 } 2607 2608 @Test 2609 public void testDiffDeleteTypesForTheSameCellUsingMultipleVersions(TestInfo testInfo) 2610 throws Exception { 2611 setAuths(); 2612 final TableName tableName = TableName 2613 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2614 try (Table table = doPuts(tableName)) { 2615 // Do not flush here. 2616 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2617 @Override 2618 public Void run() throws Exception { 2619 try (Connection connection = ConnectionFactory.createConnection(conf); 2620 Table table = connection.getTable(tableName)) { 2621 Delete d = new Delete(row1); 2622 d.setCellVisibility(new CellVisibility( 2623 "(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2624 d.addColumns(fam, qual, 125L); 2625 table.delete(d); 2626 } catch (Throwable t) { 2627 throw new IOException(t); 2628 } 2629 return null; 2630 } 2631 }; 2632 SUPERUSER.runAs(actiona); 2633 2634 Scan s = new Scan(); 2635 s.readVersions(5); 2636 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2637 ResultScanner scanner = table.getScanner(s); 2638 Result[] next = scanner.next(3); 2639 assertTrue(next.length == 2); 2640 CellScanner cellScanner = next[0].cellScanner(); 2641 cellScanner.advance(); 2642 Cell current = cellScanner.current(); 2643 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2644 row1, 0, row1.length)); 2645 assertEquals(127L, current.getTimestamp()); 2646 cellScanner.advance(); 2647 current = cellScanner.current(); 2648 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2649 row1, 0, row1.length)); 2650 assertEquals(126L, current.getTimestamp()); 2651 cellScanner.advance(); 2652 current = cellScanner.current(); 2653 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2654 row1, 0, row1.length)); 2655 assertEquals(125L, current.getTimestamp()); 2656 cellScanner.advance(); 2657 current = cellScanner.current(); 2658 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2659 row1, 0, row1.length)); 2660 assertEquals(123L, current.getTimestamp()); 2661 cellScanner = next[1].cellScanner(); 2662 cellScanner.advance(); 2663 current = cellScanner.current(); 2664 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2665 row2, 0, row2.length)); 2666 2667 // Issue 2nd delete 2668 actiona = new PrivilegedExceptionAction<Void>() { 2669 @Override 2670 public Void run() throws Exception { 2671 try (Connection connection = ConnectionFactory.createConnection(conf); 2672 Table table = connection.getTable(tableName)) { 2673 Delete d = new Delete(row1); 2674 d.setCellVisibility(new CellVisibility( 2675 "(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET + "&" + SECRET + ")")); 2676 d.addColumn(fam, qual, 127L); 2677 table.delete(d); 2678 } catch (Throwable t) { 2679 throw new IOException(t); 2680 } 2681 return null; 2682 } 2683 }; 2684 SUPERUSER.runAs(actiona); 2685 s = new Scan(); 2686 s.readVersions(5); 2687 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2688 scanner = table.getScanner(s); 2689 next = scanner.next(3); 2690 assertTrue(next.length == 2); 2691 cellScanner = next[0].cellScanner(); 2692 cellScanner.advance(); 2693 current = cellScanner.current(); 2694 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2695 row1, 0, row1.length)); 2696 assertEquals(126L, current.getTimestamp()); 2697 cellScanner.advance(); 2698 current = cellScanner.current(); 2699 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2700 row1, 0, row1.length)); 2701 assertEquals(125L, current.getTimestamp()); 2702 cellScanner.advance(); 2703 current = cellScanner.current(); 2704 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2705 row1, 0, row1.length)); 2706 assertEquals(123L, current.getTimestamp()); 2707 cellScanner = next[1].cellScanner(); 2708 cellScanner.advance(); 2709 current = cellScanner.current(); 2710 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2711 row2, 0, row2.length)); 2712 } 2713 } 2714 2715 @Test 2716 public void testDeleteColumnLatestWithNoCellVisibility(TestInfo testInfo) throws Exception { 2717 setAuths(); 2718 final TableName tableName = TableName 2719 .valueOf(TableNameTestExtension.cleanUpTestName(testInfo.getTestMethod().get().getName())); 2720 try (Table table = doPuts(tableName)) { 2721 TEST_UTIL.getAdmin().flush(tableName); 2722 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2723 @Override 2724 public Void run() throws Exception { 2725 try (Connection connection = ConnectionFactory.createConnection(conf); 2726 Table table = connection.getTable(tableName)) { 2727 Delete d = new Delete(row1); 2728 d.addColumn(fam, qual, 125L); 2729 table.delete(d); 2730 } catch (Throwable t) { 2731 throw new IOException(t); 2732 } 2733 return null; 2734 } 2735 }; 2736 SUPERUSER.runAs(actiona); 2737 2738 TEST_UTIL.getAdmin().flush(tableName); 2739 Scan s = new Scan(); 2740 s.readVersions(5); 2741 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2742 ResultScanner scanner = table.getScanner(s); 2743 Result[] next = scanner.next(3); 2744 assertTrue(next.length == 2); 2745 scanAll(next); 2746 actiona = new PrivilegedExceptionAction<Void>() { 2747 @Override 2748 public Void run() throws Exception { 2749 try (Connection connection = ConnectionFactory.createConnection(conf); 2750 Table table = connection.getTable(tableName)) { 2751 Delete d = new Delete(row1); 2752 d.addColumns(fam, qual, 125L); 2753 table.delete(d); 2754 } catch (Throwable t) { 2755 throw new IOException(t); 2756 } 2757 return null; 2758 } 2759 }; 2760 SUPERUSER.runAs(actiona); 2761 2762 TEST_UTIL.getAdmin().flush(tableName); 2763 s = new Scan(); 2764 s.readVersions(5); 2765 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2766 scanner = table.getScanner(s); 2767 next = scanner.next(3); 2768 assertTrue(next.length == 2); 2769 scanAll(next); 2770 2771 actiona = new PrivilegedExceptionAction<Void>() { 2772 @Override 2773 public Void run() throws Exception { 2774 try (Connection connection = ConnectionFactory.createConnection(conf); 2775 Table table = connection.getTable(tableName)) { 2776 Delete d = new Delete(row1); 2777 d.addFamily(fam, 125L); 2778 table.delete(d); 2779 } catch (Throwable t) { 2780 throw new IOException(t); 2781 } 2782 return null; 2783 } 2784 }; 2785 SUPERUSER.runAs(actiona); 2786 2787 TEST_UTIL.getAdmin().flush(tableName); 2788 s = new Scan(); 2789 s.readVersions(5); 2790 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2791 scanner = table.getScanner(s); 2792 next = scanner.next(3); 2793 assertTrue(next.length == 2); 2794 scanAll(next); 2795 2796 actiona = new PrivilegedExceptionAction<Void>() { 2797 @Override 2798 public Void run() throws Exception { 2799 try (Connection connection = ConnectionFactory.createConnection(conf); 2800 Table table = connection.getTable(tableName)) { 2801 Delete d = new Delete(row1); 2802 d.addFamily(fam); 2803 table.delete(d); 2804 } catch (Throwable t) { 2805 throw new IOException(t); 2806 } 2807 return null; 2808 } 2809 }; 2810 SUPERUSER.runAs(actiona); 2811 2812 TEST_UTIL.getAdmin().flush(tableName); 2813 s = new Scan(); 2814 s.readVersions(5); 2815 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2816 scanner = table.getScanner(s); 2817 next = scanner.next(3); 2818 assertTrue(next.length == 2); 2819 scanAll(next); 2820 2821 actiona = new PrivilegedExceptionAction<Void>() { 2822 @Override 2823 public Void run() throws Exception { 2824 try (Connection connection = ConnectionFactory.createConnection(conf); 2825 Table table = connection.getTable(tableName)) { 2826 Delete d = new Delete(row1); 2827 d.addColumns(fam, qual); 2828 table.delete(d); 2829 } catch (Throwable t) { 2830 throw new IOException(t); 2831 } 2832 return null; 2833 } 2834 }; 2835 SUPERUSER.runAs(actiona); 2836 2837 TEST_UTIL.getAdmin().flush(tableName); 2838 s = new Scan(); 2839 s.readVersions(5); 2840 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2841 scanner = table.getScanner(s); 2842 next = scanner.next(3); 2843 assertTrue(next.length == 2); 2844 scanAll(next); 2845 2846 actiona = new PrivilegedExceptionAction<Void>() { 2847 @Override 2848 public Void run() throws Exception { 2849 try (Connection connection = ConnectionFactory.createConnection(conf); 2850 Table table = connection.getTable(tableName)) { 2851 Delete d = new Delete(row1); 2852 d.addFamilyVersion(fam, 126L); 2853 table.delete(d); 2854 } catch (Throwable t) { 2855 throw new IOException(t); 2856 } 2857 return null; 2858 } 2859 }; 2860 SUPERUSER.runAs(actiona); 2861 2862 TEST_UTIL.getAdmin().flush(tableName); 2863 s = new Scan(); 2864 s.readVersions(5); 2865 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2866 scanner = table.getScanner(s); 2867 next = scanner.next(3); 2868 assertTrue(next.length == 2); 2869 scanAll(next); 2870 } 2871 } 2872 2873 private void scanAll(Result[] next) throws IOException { 2874 CellScanner cellScanner = next[0].cellScanner(); 2875 cellScanner.advance(); 2876 Cell current = cellScanner.current(); 2877 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2878 row1, 0, row1.length)); 2879 assertEquals(127L, current.getTimestamp()); 2880 cellScanner.advance(); 2881 current = cellScanner.current(); 2882 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2883 row1, 0, row1.length)); 2884 assertEquals(126L, current.getTimestamp()); 2885 cellScanner.advance(); 2886 current = cellScanner.current(); 2887 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2888 row1, 0, row1.length)); 2889 assertEquals(125L, current.getTimestamp()); 2890 cellScanner.advance(); 2891 current = cellScanner.current(); 2892 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2893 row1, 0, row1.length)); 2894 assertEquals(124L, current.getTimestamp()); 2895 cellScanner.advance(); 2896 current = cellScanner.current(); 2897 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2898 row1, 0, row1.length)); 2899 assertEquals(123L, current.getTimestamp()); 2900 cellScanner = next[1].cellScanner(); 2901 cellScanner.advance(); 2902 current = cellScanner.current(); 2903 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2904 row2, 0, row2.length)); 2905 } 2906 2907 @Test 2908 public void testVisibilityExpressionWithNotEqualORCondition(TestInfo testInfo) throws Exception { 2909 setAuths(); 2910 TableName tableName = createTable(5, testInfo); 2911 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 2912 Put put = new Put(Bytes.toBytes("row1")); 2913 put.addColumn(fam, qual, 123L, value); 2914 put.setCellVisibility(new CellVisibility(CONFIDENTIAL)); 2915 table.put(put); 2916 put = new Put(Bytes.toBytes("row1")); 2917 put.addColumn(fam, qual, 124L, value); 2918 put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "|" + PRIVATE)); 2919 table.put(put); 2920 TEST_UTIL.getAdmin().flush(tableName); 2921 PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() { 2922 @Override 2923 public Void run() throws Exception { 2924 try (Connection connection = ConnectionFactory.createConnection(conf); 2925 Table table = connection.getTable(tableName)) { 2926 Delete d = new Delete(row1); 2927 d.addColumn(fam, qual, 124L); 2928 d.setCellVisibility(new CellVisibility(PRIVATE)); 2929 table.delete(d); 2930 } catch (Throwable t) { 2931 throw new IOException(t); 2932 } 2933 return null; 2934 } 2935 }; 2936 SUPERUSER.runAs(actiona); 2937 2938 TEST_UTIL.getAdmin().flush(tableName); 2939 Scan s = new Scan(); 2940 s.readVersions(5); 2941 s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET)); 2942 ResultScanner scanner = table.getScanner(s); 2943 Result[] next = scanner.next(3); 2944 assertTrue(next.length == 1); 2945 CellScanner cellScanner = next[0].cellScanner(); 2946 cellScanner.advance(); 2947 Cell current = cellScanner.current(); 2948 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2949 row1, 0, row1.length)); 2950 assertEquals(124L, current.getTimestamp()); 2951 cellScanner.advance(); 2952 current = cellScanner.current(); 2953 assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(), 2954 row1, 0, row1.length)); 2955 assertEquals(123L, current.getTimestamp()); 2956 } 2957 } 2958 2959 @Test 2960 public void testDeleteWithNoVisibilitiesForPutsAndDeletes(TestInfo testInfo) throws Exception { 2961 TableName tableName = createTable(5, testInfo); 2962 Put p = new Put(Bytes.toBytes("row1")); 2963 p.addColumn(fam, qual, value); 2964 Table table = TEST_UTIL.getConnection().getTable(tableName); 2965 table.put(p); 2966 p = new Put(Bytes.toBytes("row1")); 2967 p.addColumn(fam, qual1, value); 2968 table.put(p); 2969 p = new Put(Bytes.toBytes("row2")); 2970 p.addColumn(fam, qual, value); 2971 table.put(p); 2972 p = new Put(Bytes.toBytes("row2")); 2973 p.addColumn(fam, qual1, value); 2974 table.put(p); 2975 Delete d = new Delete(Bytes.toBytes("row1")); 2976 table.delete(d); 2977 Get g = new Get(Bytes.toBytes("row1")); 2978 g.readAllVersions(); 2979 g.setAuthorizations(new Authorizations(SECRET, PRIVATE)); 2980 Result result = table.get(g); 2981 assertEquals(0, result.rawCells().length); 2982 2983 p = new Put(Bytes.toBytes("row1")); 2984 p.addColumn(fam, qual, value); 2985 table.put(p); 2986 result = table.get(g); 2987 assertEquals(1, result.rawCells().length); 2988 } 2989 2990 @Test 2991 public void testDeleteWithFamilyDeletesOfSameTsButDifferentVisibilities(TestInfo testInfo) 2992 throws Exception { 2993 TableName tableName = createTable(5, testInfo); 2994 Table table = TEST_UTIL.getConnection().getTable(tableName); 2995 long t1 = 1234L; 2996 CellVisibility cellVisibility1 = new CellVisibility(SECRET); 2997 CellVisibility cellVisibility2 = new CellVisibility(PRIVATE); 2998 // Cell row1:info:qual:1234 with visibility SECRET 2999 Put p = new Put(row1); 3000 p.addColumn(fam, qual, t1, value); 3001 p.setCellVisibility(cellVisibility1); 3002 table.put(p); 3003 3004 // Cell row1:info:qual1:1234 with visibility PRIVATE 3005 p = new Put(row1); 3006 p.addColumn(fam, qual1, t1, value); 3007 p.setCellVisibility(cellVisibility2); 3008 table.put(p); 3009 3010 Delete d = new Delete(row1); 3011 d.addFamily(fam, t1); 3012 d.setCellVisibility(cellVisibility2); 3013 table.delete(d); 3014 d = new Delete(row1); 3015 d.addFamily(fam, t1); 3016 d.setCellVisibility(cellVisibility1); 3017 table.delete(d); 3018 3019 Get g = new Get(row1); 3020 g.readAllVersions(); 3021 g.setAuthorizations(new Authorizations(SECRET, PRIVATE)); 3022 Result result = table.get(g); 3023 assertEquals(0, result.rawCells().length); 3024 3025 // Cell row2:info:qual:1234 with visibility SECRET 3026 p = new Put(row2); 3027 p.addColumn(fam, qual, t1, value); 3028 p.setCellVisibility(cellVisibility1); 3029 table.put(p); 3030 3031 // Cell row2:info:qual1:1234 with visibility PRIVATE 3032 p = new Put(row2); 3033 p.addColumn(fam, qual1, t1, value); 3034 p.setCellVisibility(cellVisibility2); 3035 table.put(p); 3036 3037 d = new Delete(row2); 3038 d.addFamilyVersion(fam, t1); 3039 d.setCellVisibility(cellVisibility2); 3040 table.delete(d); 3041 d = new Delete(row2); 3042 d.addFamilyVersion(fam, t1); 3043 d.setCellVisibility(cellVisibility1); 3044 table.delete(d); 3045 3046 g = new Get(row2); 3047 g.readAllVersions(); 3048 g.setAuthorizations(new Authorizations(SECRET, PRIVATE)); 3049 result = table.get(g); 3050 assertEquals(0, result.rawCells().length); 3051 } 3052 3053 @SafeVarargs 3054 public static <T> List<T> createList(T... ts) { 3055 return new ArrayList<>(Arrays.asList(ts)); 3056 } 3057 3058 private enum DeleteMark { 3059 ROW, 3060 FAMILY, 3061 FAMILY_VERSION, 3062 COLUMN, 3063 CELL 3064 } 3065 3066 private static Delete addDeleteMark(Delete d, DeleteMark mark, long now) { 3067 switch (mark) { 3068 case ROW: 3069 break; 3070 case FAMILY: 3071 d.addFamily(fam); 3072 break; 3073 case FAMILY_VERSION: 3074 d.addFamilyVersion(fam, now); 3075 break; 3076 case COLUMN: 3077 d.addColumns(fam, qual); 3078 break; 3079 case CELL: 3080 d.addColumn(fam, qual); 3081 break; 3082 default: 3083 break; 3084 } 3085 return d; 3086 } 3087 3088 @Test 3089 public void testDeleteCellWithoutVisibility(TestInfo testInfo) 3090 throws IOException, InterruptedException { 3091 for (DeleteMark mark : DeleteMark.values()) { 3092 testDeleteCellWithoutVisibility(mark); 3093 } 3094 } 3095 3096 private void testDeleteCellWithoutVisibility(DeleteMark mark) 3097 throws IOException, InterruptedException { 3098 setAuths(); 3099 TableName tableName = TableName.valueOf("testDeleteCellWithoutVisibility-" + mark.name()); 3100 createTable(tableName, 5); 3101 long now = EnvironmentEdgeManager.currentTime(); 3102 List<Put> puts = new ArrayList<>(1); 3103 Put put = new Put(row1); 3104 if (mark == DeleteMark.FAMILY_VERSION) { 3105 put.addColumn(fam, qual, now, value); 3106 } else { 3107 put.addColumn(fam, qual, value); 3108 } 3109 3110 puts.add(put); 3111 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 3112 table.put(puts); 3113 Result r = table.get(new Get(row1)); 3114 assertEquals(1, r.size()); 3115 assertEquals(Bytes.toString(value), Bytes.toString(CellUtil.cloneValue(r.rawCells()[0]))); 3116 3117 Delete d = addDeleteMark(new Delete(row1), mark, now); 3118 table.delete(d); 3119 r = table.get(new Get(row1)); 3120 assertEquals(0, r.size()); 3121 } 3122 } 3123 3124 @Test 3125 public void testDeleteCellWithVisibility(TestInfo testInfo) 3126 throws IOException, InterruptedException { 3127 for (DeleteMark mark : DeleteMark.values()) { 3128 testDeleteCellWithVisibility(mark); 3129 testDeleteCellWithVisibilityV2(mark); 3130 } 3131 } 3132 3133 private void testDeleteCellWithVisibility(DeleteMark mark) 3134 throws IOException, InterruptedException { 3135 setAuths(); 3136 TableName tableName = TableName.valueOf("testDeleteCellWithVisibility-" + mark.name()); 3137 createTable(tableName, 5); 3138 long now = EnvironmentEdgeManager.currentTime(); 3139 List<Put> puts = new ArrayList<>(2); 3140 Put put = new Put(row1); 3141 if (mark == DeleteMark.FAMILY_VERSION) { 3142 put.addColumn(fam, qual, now, value); 3143 } else { 3144 put.addColumn(fam, qual, value); 3145 } 3146 puts.add(put); 3147 put = new Put(row1); 3148 if (mark == DeleteMark.FAMILY_VERSION) { 3149 put.addColumn(fam, qual, now, value1); 3150 } else { 3151 put.addColumn(fam, qual, value1); 3152 } 3153 put.setCellVisibility(new CellVisibility(PRIVATE)); 3154 puts.add(put); 3155 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 3156 table.put(puts); 3157 Result r = table.get(new Get(row1)); 3158 assertEquals(0, r.size()); 3159 r = table.get(new Get(row1).setAuthorizations(new Authorizations(PRIVATE))); 3160 assertEquals(1, r.size()); 3161 assertEquals(Bytes.toString(value1), Bytes.toString(CellUtil.cloneValue(r.rawCells()[0]))); 3162 3163 Delete d = addDeleteMark(new Delete(row1), mark, now); 3164 table.delete(d); 3165 3166 r = table.get(new Get(row1)); 3167 assertEquals(0, r.size()); 3168 r = table.get(new Get(row1).setAuthorizations(new Authorizations(PRIVATE))); 3169 assertEquals(1, r.size()); 3170 assertEquals(Bytes.toString(value1), Bytes.toString(CellUtil.cloneValue(r.rawCells()[0]))); 3171 3172 d = addDeleteMark(new Delete(row1).setCellVisibility(new CellVisibility(PRIVATE)), mark, now); 3173 table.delete(d); 3174 3175 r = table.get(new Get(row1)); 3176 assertEquals(0, r.size()); 3177 r = table.get(new Get(row1).setAuthorizations(new Authorizations(PRIVATE))); 3178 assertEquals(0, r.size()); 3179 } 3180 } 3181 3182 private void testDeleteCellWithVisibilityV2(DeleteMark mark) 3183 throws IOException, InterruptedException { 3184 setAuths(); 3185 TableName tableName = TableName.valueOf("testDeleteCellWithVisibilityV2-" + mark.name()); 3186 createTable(tableName, 5); 3187 long now = EnvironmentEdgeManager.currentTime(); 3188 List<Put> puts = new ArrayList<>(2); 3189 Put put = new Put(row1); 3190 put.setCellVisibility(new CellVisibility(PRIVATE)); 3191 if (mark == DeleteMark.FAMILY_VERSION) { 3192 put.addColumn(fam, qual, now, value); 3193 } else { 3194 put.addColumn(fam, qual, value); 3195 } 3196 puts.add(put); 3197 put = new Put(row1); 3198 if (mark == DeleteMark.FAMILY_VERSION) { 3199 put.addColumn(fam, qual, now, value1); 3200 } else { 3201 put.addColumn(fam, qual, value1); 3202 } 3203 puts.add(put); 3204 try (Table table = TEST_UTIL.getConnection().getTable(tableName)) { 3205 table.put(puts); 3206 Result r = table.get(new Get(row1)); 3207 assertEquals(1, r.size()); 3208 assertEquals(Bytes.toString(value1), Bytes.toString(CellUtil.cloneValue(r.rawCells()[0]))); 3209 r = table.get(new Get(row1).setAuthorizations(new Authorizations(PRIVATE))); 3210 assertEquals(1, r.size()); 3211 assertEquals(Bytes.toString(value1), Bytes.toString(CellUtil.cloneValue(r.rawCells()[0]))); 3212 3213 Delete d = addDeleteMark(new Delete(row1), mark, now); 3214 table.delete(d); 3215 3216 r = table.get(new Get(row1)); 3217 assertEquals(0, r.size()); 3218 r = table.get(new Get(row1).setAuthorizations(new Authorizations(PRIVATE))); 3219 assertEquals(0, r.size()); 3220 3221 d = addDeleteMark(new Delete(row1).setCellVisibility(new CellVisibility(PRIVATE)), mark, now); 3222 table.delete(d); 3223 3224 r = table.get(new Get(row1)); 3225 assertEquals(0, r.size()); 3226 r = table.get(new Get(row1).setAuthorizations(new Authorizations(PRIVATE))); 3227 assertEquals(0, r.size()); 3228 } 3229 } 3230}