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.access; 019 020import static org.apache.hadoop.hbase.AuthUtil.toGroupEntry; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertFalse; 023import static org.junit.Assert.assertNotNull; 024import static org.junit.Assert.assertTrue; 025 026import java.util.Arrays; 027import java.util.List; 028import org.apache.hadoop.conf.Configuration; 029import org.apache.hadoop.hbase.Coprocessor; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.HBaseTestingUtil; 032import org.apache.hadoop.hbase.HConstants; 033import org.apache.hadoop.hbase.NamespaceDescriptor; 034import org.apache.hadoop.hbase.TableName; 035import org.apache.hadoop.hbase.TableNameTestRule; 036import org.apache.hadoop.hbase.TableNotFoundException; 037import org.apache.hadoop.hbase.client.Admin; 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.Put; 042import org.apache.hadoop.hbase.client.Result; 043import org.apache.hadoop.hbase.client.ResultScanner; 044import org.apache.hadoop.hbase.client.Scan; 045import org.apache.hadoop.hbase.client.Table; 046import org.apache.hadoop.hbase.client.TableDescriptor; 047import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 048import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 049import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment; 050import org.apache.hadoop.hbase.master.MasterCoprocessorHost; 051import org.apache.hadoop.hbase.regionserver.RegionServerCoprocessorHost; 052import org.apache.hadoop.hbase.security.User; 053import org.apache.hadoop.hbase.security.access.Permission.Action; 054import org.apache.hadoop.hbase.testclassification.MediumTests; 055import org.apache.hadoop.hbase.testclassification.SecurityTests; 056import org.apache.hadoop.hbase.util.Bytes; 057import org.apache.hadoop.hbase.zookeeper.ZKUtil; 058import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 059import org.junit.After; 060import org.junit.AfterClass; 061import org.junit.Before; 062import org.junit.BeforeClass; 063import org.junit.ClassRule; 064import org.junit.Rule; 065import org.junit.Test; 066import org.junit.experimental.categories.Category; 067import org.slf4j.Logger; 068import org.slf4j.LoggerFactory; 069 070@Category({ SecurityTests.class, MediumTests.class }) 071public class TestAccessController2 extends SecureTestUtil { 072 073 @ClassRule 074 public static final HBaseClassTestRule CLASS_RULE = 075 HBaseClassTestRule.forClass(TestAccessController2.class); 076 077 private static final Logger LOG = LoggerFactory.getLogger(TestAccessController2.class); 078 079 private static final byte[] TEST_ROW = Bytes.toBytes("test"); 080 private static final byte[] TEST_FAMILY = Bytes.toBytes("f"); 081 private static final byte[] TEST_QUALIFIER = Bytes.toBytes("q"); 082 private static final byte[] TEST_VALUE = Bytes.toBytes("value"); 083 084 private static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 085 private static Configuration conf; 086 087 /** 088 * The systemUserConnection created here is tied to the system user. In case, you are planning to 089 * create AccessTestAction, DON'T use this systemUserConnection as the 'doAs' user gets eclipsed 090 * by the system user. 091 */ 092 private static Connection systemUserConnection; 093 094 private final static byte[] Q1 = Bytes.toBytes("q1"); 095 private final static byte[] value1 = Bytes.toBytes("value1"); 096 097 private static byte[] TEST_FAMILY_2 = Bytes.toBytes("f2"); 098 private static byte[] TEST_ROW_2 = Bytes.toBytes("r2"); 099 private final static byte[] Q2 = Bytes.toBytes("q2"); 100 private final static byte[] value2 = Bytes.toBytes("value2"); 101 102 private static byte[] TEST_ROW_3 = Bytes.toBytes("r3"); 103 104 private static final String TESTGROUP_1 = "testgroup_1"; 105 private static final String TESTGROUP_2 = "testgroup_2"; 106 107 private static User TESTGROUP1_USER1; 108 private static User TESTGROUP2_USER1; 109 110 @Rule 111 public TableNameTestRule testTable = new TableNameTestRule(); 112 private String namespace = "testNamespace"; 113 private String tname = namespace + ":testtable1"; 114 private TableName tableName = TableName.valueOf(tname); 115 private static String TESTGROUP_1_NAME; 116 117 @BeforeClass 118 public static void setupBeforeClass() throws Exception { 119 conf = TEST_UTIL.getConfiguration(); 120 // Up the handlers; this test needs more than usual. 121 conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 10); 122 // Enable security 123 enableSecurity(conf); 124 // Verify enableSecurity sets up what we require 125 verifyConfiguration(conf); 126 TEST_UTIL.startMiniCluster(); 127 // Wait for the ACL table to become available 128 TEST_UTIL.waitUntilAllRegionsAssigned(PermissionStorage.ACL_TABLE_NAME); 129 130 TESTGROUP_1_NAME = toGroupEntry(TESTGROUP_1); 131 TESTGROUP1_USER1 = 132 User.createUserForTesting(conf, "testgroup1_user1", new String[] { TESTGROUP_1 }); 133 TESTGROUP2_USER1 = 134 User.createUserForTesting(conf, "testgroup2_user2", new String[] { TESTGROUP_2 }); 135 136 systemUserConnection = ConnectionFactory.createConnection(conf); 137 } 138 139 @Before 140 public void setUp() throws Exception { 141 createNamespace(TEST_UTIL, NamespaceDescriptor.create(namespace).build()); 142 try (Table table = 143 createTable(TEST_UTIL, tableName, new byte[][] { TEST_FAMILY, TEST_FAMILY_2 })) { 144 TEST_UTIL.waitTableEnabled(tableName); 145 146 // Ingesting test data. 147 table.put(Arrays.asList(new Put(TEST_ROW).addColumn(TEST_FAMILY, Q1, value1), 148 new Put(TEST_ROW_2).addColumn(TEST_FAMILY, Q2, value2), 149 new Put(TEST_ROW_3).addColumn(TEST_FAMILY_2, Q1, value1))); 150 } 151 152 assertEquals(1, PermissionStorage.getTablePermissions(conf, tableName).size()); 153 try { 154 assertEquals(1, 155 AccessControlClient.getUserPermissions(systemUserConnection, tableName.toString()).size()); 156 } catch (Throwable e) { 157 LOG.error("Error during call of AccessControlClient.getUserPermissions. ", e); 158 } 159 160 } 161 162 @AfterClass 163 public static void tearDownAfterClass() throws Exception { 164 systemUserConnection.close(); 165 TEST_UTIL.shutdownMiniCluster(); 166 } 167 168 @After 169 public void tearDown() throws Exception { 170 // Clean the _acl_ table 171 try { 172 deleteTable(TEST_UTIL, tableName); 173 } catch (TableNotFoundException ex) { 174 // Test deleted the table, no problem 175 LOG.info("Test deleted table " + tableName); 176 } 177 deleteNamespace(TEST_UTIL, namespace); 178 // Verify all table/namespace permissions are erased 179 assertEquals(0, PermissionStorage.getTablePermissions(conf, tableName).size()); 180 assertEquals(0, PermissionStorage.getNamespacePermissions(conf, namespace).size()); 181 } 182 183 @Test 184 public void testCreateWithCorrectOwner() throws Exception { 185 // Create a test user 186 final User testUser = 187 User.createUserForTesting(TEST_UTIL.getConfiguration(), "TestUser", new String[0]); 188 // Grant the test user the ability to create tables 189 SecureTestUtil.grantGlobal(TEST_UTIL, testUser.getShortName(), Action.CREATE); 190 verifyAllowed(new AccessTestAction() { 191 @Override 192 public Object run() throws Exception { 193 TableDescriptor tableDescriptor = 194 TableDescriptorBuilder.newBuilder(testTable.getTableName()) 195 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY)).build(); 196 try (Connection connection = 197 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration(), testUser)) { 198 try (Admin admin = connection.getAdmin()) { 199 createTable(TEST_UTIL, admin, tableDescriptor); 200 } 201 } 202 return null; 203 } 204 }, testUser); 205 TEST_UTIL.waitTableAvailable(testTable.getTableName()); 206 // Verify that owner permissions have been granted to the test user on the 207 // table just created 208 List<UserPermission> perms = PermissionStorage 209 .getTablePermissions(conf, testTable.getTableName()).get(testUser.getShortName()); 210 assertNotNull(perms); 211 assertFalse(perms.isEmpty()); 212 // Should be RWXCA 213 assertTrue(perms.get(0).getPermission().implies(Permission.Action.READ)); 214 assertTrue(perms.get(0).getPermission().implies(Permission.Action.WRITE)); 215 assertTrue(perms.get(0).getPermission().implies(Permission.Action.EXEC)); 216 assertTrue(perms.get(0).getPermission().implies(Permission.Action.CREATE)); 217 assertTrue(perms.get(0).getPermission().implies(Permission.Action.ADMIN)); 218 } 219 220 @Test 221 public void testCreateTableWithGroupPermissions() throws Exception { 222 grantGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.CREATE); 223 try { 224 AccessTestAction createAction = new AccessTestAction() { 225 @Override 226 public Object run() throws Exception { 227 TableDescriptor tableDescriptor = 228 TableDescriptorBuilder.newBuilder(testTable.getTableName()) 229 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(TEST_FAMILY)).build(); 230 try (Connection connection = 231 ConnectionFactory.createConnection(TEST_UTIL.getConfiguration())) { 232 try (Admin admin = connection.getAdmin()) { 233 admin.createTable(tableDescriptor); 234 } 235 } 236 return null; 237 } 238 }; 239 verifyAllowed(createAction, TESTGROUP1_USER1); 240 verifyDenied(createAction, TESTGROUP2_USER1); 241 } finally { 242 revokeGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.CREATE); 243 } 244 } 245 246 @Test 247 public void testACLTableAccess() throws Exception { 248 final Configuration conf = TEST_UTIL.getConfiguration(); 249 250 // Superuser 251 User superUser = User.createUserForTesting(conf, "admin", new String[] { "supergroup" }); 252 253 // Global users 254 User globalRead = User.createUserForTesting(conf, "globalRead", new String[0]); 255 User globalWrite = User.createUserForTesting(conf, "globalWrite", new String[0]); 256 User globalCreate = User.createUserForTesting(conf, "globalCreate", new String[0]); 257 User globalAdmin = User.createUserForTesting(conf, "globalAdmin", new String[0]); 258 SecureTestUtil.grantGlobal(TEST_UTIL, globalRead.getShortName(), Action.READ); 259 SecureTestUtil.grantGlobal(TEST_UTIL, globalWrite.getShortName(), Action.WRITE); 260 SecureTestUtil.grantGlobal(TEST_UTIL, globalCreate.getShortName(), Action.CREATE); 261 SecureTestUtil.grantGlobal(TEST_UTIL, globalAdmin.getShortName(), Action.ADMIN); 262 263 // Namespace users 264 User nsRead = User.createUserForTesting(conf, "nsRead", new String[0]); 265 User nsWrite = User.createUserForTesting(conf, "nsWrite", new String[0]); 266 User nsCreate = User.createUserForTesting(conf, "nsCreate", new String[0]); 267 User nsAdmin = User.createUserForTesting(conf, "nsAdmin", new String[0]); 268 SecureTestUtil.grantOnNamespace(TEST_UTIL, nsRead.getShortName(), 269 testTable.getTableName().getNamespaceAsString(), Action.READ); 270 SecureTestUtil.grantOnNamespace(TEST_UTIL, nsWrite.getShortName(), 271 testTable.getTableName().getNamespaceAsString(), Action.WRITE); 272 SecureTestUtil.grantOnNamespace(TEST_UTIL, nsCreate.getShortName(), 273 testTable.getTableName().getNamespaceAsString(), Action.CREATE); 274 SecureTestUtil.grantOnNamespace(TEST_UTIL, nsAdmin.getShortName(), 275 testTable.getTableName().getNamespaceAsString(), Action.ADMIN); 276 277 // Table users 278 User tableRead = User.createUserForTesting(conf, "tableRead", new String[0]); 279 User tableWrite = User.createUserForTesting(conf, "tableWrite", new String[0]); 280 User tableCreate = User.createUserForTesting(conf, "tableCreate", new String[0]); 281 User tableAdmin = User.createUserForTesting(conf, "tableAdmin", new String[0]); 282 SecureTestUtil.grantOnTable(TEST_UTIL, tableRead.getShortName(), testTable.getTableName(), null, 283 null, Action.READ); 284 SecureTestUtil.grantOnTable(TEST_UTIL, tableWrite.getShortName(), testTable.getTableName(), 285 null, null, Action.WRITE); 286 SecureTestUtil.grantOnTable(TEST_UTIL, tableCreate.getShortName(), testTable.getTableName(), 287 null, null, Action.CREATE); 288 SecureTestUtil.grantOnTable(TEST_UTIL, tableAdmin.getShortName(), testTable.getTableName(), 289 null, null, Action.ADMIN); 290 291 grantGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.WRITE); 292 try { 293 // Write tests 294 295 AccessTestAction writeAction = new AccessTestAction() { 296 @Override 297 public Object run() throws Exception { 298 299 try (Connection conn = ConnectionFactory.createConnection(conf); 300 Table t = conn.getTable(PermissionStorage.ACL_TABLE_NAME)) { 301 t.put(new Put(TEST_ROW).addColumn(PermissionStorage.ACL_LIST_FAMILY, TEST_QUALIFIER, 302 TEST_VALUE)); 303 return null; 304 } finally { 305 } 306 } 307 }; 308 309 // All writes to ACL table denied except for GLOBAL WRITE permission and superuser 310 311 verifyDenied(writeAction, globalAdmin, globalCreate, globalRead, TESTGROUP2_USER1); 312 verifyDenied(writeAction, nsAdmin, nsCreate, nsRead, nsWrite); 313 verifyDenied(writeAction, tableAdmin, tableCreate, tableRead, tableWrite); 314 verifyAllowed(writeAction, superUser, globalWrite, TESTGROUP1_USER1); 315 } finally { 316 revokeGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.WRITE); 317 } 318 319 grantGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.READ); 320 try { 321 // Read tests 322 323 AccessTestAction scanAction = new AccessTestAction() { 324 @Override 325 public Object run() throws Exception { 326 try (Connection conn = ConnectionFactory.createConnection(conf); 327 Table t = conn.getTable(PermissionStorage.ACL_TABLE_NAME)) { 328 ResultScanner s = t.getScanner(new Scan()); 329 try { 330 for (Result r = s.next(); r != null; r = s.next()) { 331 // do nothing 332 } 333 } finally { 334 s.close(); 335 } 336 return null; 337 } 338 } 339 }; 340 341 // All reads from ACL table denied except for GLOBAL READ and superuser 342 343 verifyDenied(scanAction, globalAdmin, globalCreate, globalWrite, TESTGROUP2_USER1); 344 verifyDenied(scanAction, nsCreate, nsAdmin, nsRead, nsWrite); 345 verifyDenied(scanAction, tableCreate, tableAdmin, tableRead, tableWrite); 346 verifyAllowed(scanAction, superUser, globalRead, TESTGROUP1_USER1); 347 } finally { 348 revokeGlobal(TEST_UTIL, TESTGROUP_1_NAME, Action.READ); 349 } 350 } 351 352 /* 353 * Test table scan operation at table, column family and column qualifier level. 354 */ 355 @Test 356 public void testPostGrantAndRevokeScanAction() throws Exception { 357 AccessTestAction scanTableActionForGroupWithTableLevelAccess = new AccessTestAction() { 358 @Override 359 public Void run() throws Exception { 360 try (Connection connection = ConnectionFactory.createConnection(conf); 361 Table table = connection.getTable(tableName)) { 362 Scan s1 = new Scan(); 363 try (ResultScanner scanner1 = table.getScanner(s1)) { 364 Result[] next1 = scanner1.next(5); 365 assertTrue("User having table level access should be able to scan all " 366 + "the data in the table.", next1.length == 3); 367 } 368 } 369 return null; 370 } 371 }; 372 373 AccessTestAction scanTableActionForGroupWithFamilyLevelAccess = new AccessTestAction() { 374 @Override 375 public Void run() throws Exception { 376 try (Connection connection = ConnectionFactory.createConnection(conf); 377 Table table = connection.getTable(tableName)) { 378 Scan s1 = new Scan(); 379 try (ResultScanner scanner1 = table.getScanner(s1)) { 380 Result[] next1 = scanner1.next(5); 381 assertTrue("User having column family level access should be able to scan all " 382 + "the data belonging to that family.", next1.length == 2); 383 } 384 } 385 return null; 386 } 387 }; 388 389 AccessTestAction scanFamilyActionForGroupWithFamilyLevelAccess = new AccessTestAction() { 390 @Override 391 public Void run() throws Exception { 392 try (Connection connection = ConnectionFactory.createConnection(conf); 393 Table table = connection.getTable(tableName)) { 394 Scan s1 = new Scan(); 395 s1.addFamily(TEST_FAMILY_2); 396 try (ResultScanner scanner1 = table.getScanner(s1)) { 397 scanner1.next(); 398 } 399 } 400 return null; 401 } 402 }; 403 404 AccessTestAction scanTableActionForGroupWithQualifierLevelAccess = new AccessTestAction() { 405 @Override 406 public Void run() throws Exception { 407 try (Connection connection = ConnectionFactory.createConnection(conf); 408 Table table = connection.getTable(tableName)) { 409 Scan s1 = new Scan(); 410 try (ResultScanner scanner1 = table.getScanner(s1)) { 411 Result[] next1 = scanner1.next(5); 412 assertTrue("User having column qualifier level access should be able to scan " 413 + "that column family qualifier data.", next1.length == 1); 414 } 415 } 416 return null; 417 } 418 }; 419 420 AccessTestAction scanFamilyActionForGroupWithQualifierLevelAccess = new AccessTestAction() { 421 @Override 422 public Void run() throws Exception { 423 try (Connection connection = ConnectionFactory.createConnection(conf); 424 Table table = connection.getTable(tableName)) { 425 Scan s1 = new Scan(); 426 s1.addFamily(TEST_FAMILY_2); 427 try (ResultScanner scanner1 = table.getScanner(s1)) { 428 scanner1.next(); 429 } 430 } 431 return null; 432 } 433 }; 434 435 AccessTestAction scanQualifierActionForGroupWithQualifierLevelAccess = new AccessTestAction() { 436 @Override 437 public Void run() throws Exception { 438 try (Connection connection = ConnectionFactory.createConnection(conf); 439 Table table = connection.getTable(tableName)) { 440 Scan s1 = new Scan(); 441 s1.addColumn(TEST_FAMILY, Q2); 442 try (ResultScanner scanner1 = table.getScanner(s1)) { 443 scanner1.next(); 444 } 445 } 446 return null; 447 } 448 }; 449 450 // Verify user from a group which has table level access can read all the data and group which 451 // has no access can't read any data. 452 grantOnTable(TEST_UTIL, TESTGROUP_1_NAME, tableName, null, null, Action.READ); 453 verifyAllowed(TESTGROUP1_USER1, scanTableActionForGroupWithTableLevelAccess); 454 verifyDenied(TESTGROUP2_USER1, scanTableActionForGroupWithTableLevelAccess); 455 456 // Verify user from a group whose table level access has been revoked can't read any data. 457 revokeFromTable(TEST_UTIL, TESTGROUP_1_NAME, tableName, null, null); 458 verifyDenied(TESTGROUP1_USER1, scanTableActionForGroupWithTableLevelAccess); 459 460 // Verify user from a group which has column family level access can read all the data 461 // belonging to that family and group which has no access can't read any data. 462 grantOnTable(TEST_UTIL, TESTGROUP_1_NAME, tableName, TEST_FAMILY, null, Permission.Action.READ); 463 verifyAllowed(TESTGROUP1_USER1, scanTableActionForGroupWithFamilyLevelAccess); 464 verifyDenied(TESTGROUP1_USER1, scanFamilyActionForGroupWithFamilyLevelAccess); 465 verifyDenied(TESTGROUP2_USER1, scanTableActionForGroupWithFamilyLevelAccess); 466 verifyDenied(TESTGROUP2_USER1, scanFamilyActionForGroupWithFamilyLevelAccess); 467 468 // Verify user from a group whose column family level access has been revoked can't read any 469 // data from that family. 470 revokeFromTable(TEST_UTIL, TESTGROUP_1_NAME, tableName, TEST_FAMILY, null); 471 verifyDenied(TESTGROUP1_USER1, scanTableActionForGroupWithFamilyLevelAccess); 472 473 // Verify user from a group which has column qualifier level access can read data that has this 474 // family and qualifier, and group which has no access can't read any data. 475 grantOnTable(TEST_UTIL, TESTGROUP_1_NAME, tableName, TEST_FAMILY, Q1, Action.READ); 476 verifyAllowed(TESTGROUP1_USER1, scanTableActionForGroupWithQualifierLevelAccess); 477 verifyDenied(TESTGROUP1_USER1, scanFamilyActionForGroupWithQualifierLevelAccess); 478 verifyDenied(TESTGROUP1_USER1, scanQualifierActionForGroupWithQualifierLevelAccess); 479 verifyDenied(TESTGROUP2_USER1, scanTableActionForGroupWithQualifierLevelAccess); 480 verifyDenied(TESTGROUP2_USER1, scanFamilyActionForGroupWithQualifierLevelAccess); 481 verifyDenied(TESTGROUP2_USER1, scanQualifierActionForGroupWithQualifierLevelAccess); 482 483 // Verify user from a group whose column qualifier level access has been revoked can't read the 484 // data having this column family and qualifier. 485 revokeFromTable(TEST_UTIL, TESTGROUP_1_NAME, tableName, TEST_FAMILY, Q1); 486 verifyDenied(TESTGROUP1_USER1, scanTableActionForGroupWithQualifierLevelAccess); 487 } 488 489 public static class MyAccessController extends AccessController { 490 } 491 492 @Test 493 public void testCoprocessorLoading() throws Exception { 494 MasterCoprocessorHost cpHost = 495 TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterCoprocessorHost(); 496 cpHost.load(MyAccessController.class, Coprocessor.PRIORITY_HIGHEST, conf); 497 AccessController ACCESS_CONTROLLER = cpHost.findCoprocessor(MyAccessController.class); 498 MasterCoprocessorEnvironment CP_ENV = 499 cpHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 500 RegionServerCoprocessorHost rsHost = 501 TEST_UTIL.getMiniHBaseCluster().getRegionServer(0).getRegionServerCoprocessorHost(); 502 RegionServerCoprocessorEnvironment RSCP_ENV = 503 rsHost.createEnvironment(ACCESS_CONTROLLER, Coprocessor.PRIORITY_HIGHEST, 1, conf); 504 } 505 506 @Test 507 public void testACLZNodeDeletion() throws Exception { 508 String baseAclZNode = "/hbase/acl/"; 509 String ns = "testACLZNodeDeletionNamespace"; 510 NamespaceDescriptor desc = NamespaceDescriptor.create(ns).build(); 511 createNamespace(TEST_UTIL, desc); 512 513 final TableName table = TableName.valueOf(ns, "testACLZNodeDeletionTable"); 514 final byte[] family = Bytes.toBytes("f1"); 515 TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(table) 516 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(family)).build(); 517 createTable(TEST_UTIL, tableDescriptor); 518 519 // Namespace needs this, as they follow the lazy creation of ACL znode. 520 grantOnNamespace(TEST_UTIL, TESTGROUP1_USER1.getShortName(), ns, Action.ADMIN); 521 ZKWatcher zkw = TEST_UTIL.getMiniHBaseCluster().getMaster().getZooKeeper(); 522 assertTrue("The acl znode for table should exist", 523 ZKUtil.checkExists(zkw, baseAclZNode + table.getNameAsString()) != -1); 524 assertTrue("The acl znode for namespace should exist", 525 ZKUtil.checkExists(zkw, baseAclZNode + convertToNamespace(ns)) != -1); 526 527 revokeFromNamespace(TEST_UTIL, TESTGROUP1_USER1.getShortName(), ns, Action.ADMIN); 528 deleteTable(TEST_UTIL, table); 529 deleteNamespace(TEST_UTIL, ns); 530 531 assertTrue("The acl znode for table should have been deleted", 532 ZKUtil.checkExists(zkw, baseAclZNode + table.getNameAsString()) == -1); 533 assertTrue("The acl znode for namespace should have been deleted", 534 ZKUtil.checkExists(zkw, baseAclZNode + convertToNamespace(ns)) == -1); 535 } 536}