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