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.quotas; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNull; 022import static org.junit.Assert.assertTrue; 023import static org.junit.Assert.fail; 024 025import java.io.IOException; 026import java.util.ArrayList; 027import java.util.List; 028import java.util.Objects; 029import java.util.concurrent.TimeUnit; 030 031import org.apache.hadoop.hbase.Cell; 032import org.apache.hadoop.hbase.CellScanner; 033import org.apache.hadoop.hbase.HBaseClassTestRule; 034import org.apache.hadoop.hbase.HBaseTestingUtility; 035import org.apache.hadoop.hbase.HConstants; 036import org.apache.hadoop.hbase.TableName; 037import org.apache.hadoop.hbase.client.Admin; 038import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 039import org.apache.hadoop.hbase.client.Put; 040import org.apache.hadoop.hbase.client.Result; 041import org.apache.hadoop.hbase.client.ResultScanner; 042import org.apache.hadoop.hbase.client.Scan; 043import org.apache.hadoop.hbase.client.Table; 044import org.apache.hadoop.hbase.client.TableDescriptor; 045import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 046import org.apache.hadoop.hbase.security.User; 047import org.apache.hadoop.hbase.testclassification.ClientTests; 048import org.apache.hadoop.hbase.testclassification.MediumTests; 049import org.apache.hadoop.hbase.util.Bytes; 050import org.junit.After; 051import org.junit.AfterClass; 052import org.junit.BeforeClass; 053import org.junit.ClassRule; 054import org.junit.Test; 055import org.junit.experimental.categories.Category; 056import org.slf4j.Logger; 057import org.slf4j.LoggerFactory; 058 059import org.apache.hbase.thirdparty.com.google.common.collect.Iterables; 060 061import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 062import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; 063import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas; 064import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceLimitRequest; 065 066/** 067 * minicluster tests that validate that quota entries are properly set in the quota table 068 */ 069@Category({ClientTests.class, MediumTests.class}) 070public class TestQuotaAdmin { 071 072 @ClassRule 073 public static final HBaseClassTestRule CLASS_RULE = 074 HBaseClassTestRule.forClass(TestQuotaAdmin.class); 075 076 private static final Logger LOG = LoggerFactory.getLogger(TestQuotaAdmin.class); 077 078 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 079 080 @BeforeClass 081 public static void setUpBeforeClass() throws Exception { 082 TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true); 083 TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, 2000); 084 TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10); 085 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100); 086 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250); 087 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6); 088 TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true); 089 TEST_UTIL.startMiniCluster(1); 090 TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME); 091 } 092 093 @After 094 public void clearQuotaTable() throws Exception { 095 if (TEST_UTIL.getAdmin().tableExists(QuotaUtil.QUOTA_TABLE_NAME)) { 096 TEST_UTIL.getAdmin().disableTable(QuotaUtil.QUOTA_TABLE_NAME); 097 TEST_UTIL.getAdmin().truncateTable(QuotaUtil.QUOTA_TABLE_NAME, false); 098 } 099 } 100 101 @AfterClass 102 public static void tearDownAfterClass() throws Exception { 103 TEST_UTIL.shutdownMiniCluster(); 104 } 105 106 @Test 107 public void testThrottleType() throws Exception { 108 Admin admin = TEST_UTIL.getAdmin(); 109 String userName = User.getCurrent().getShortName(); 110 111 admin.setQuota( 112 QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES)); 113 admin.setQuota(QuotaSettingsFactory 114 .throttleUser(userName, ThrottleType.WRITE_NUMBER, 12, TimeUnit.MINUTES)); 115 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true)); 116 117 try (QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration())) { 118 int countThrottle = 0; 119 int countGlobalBypass = 0; 120 for (QuotaSettings settings: scanner) { 121 switch (settings.getQuotaType()) { 122 case THROTTLE: 123 ThrottleSettings throttle = (ThrottleSettings)settings; 124 if (throttle.getSoftLimit() == 6) { 125 assertEquals(ThrottleType.READ_NUMBER, throttle.getThrottleType()); 126 } else if (throttle.getSoftLimit() == 12) { 127 assertEquals(ThrottleType.WRITE_NUMBER, throttle.getThrottleType()); 128 } else { 129 fail("should not come here, because don't set quota with this limit"); 130 } 131 assertEquals(userName, throttle.getUserName()); 132 assertEquals(null, throttle.getTableName()); 133 assertEquals(null, throttle.getNamespace()); 134 assertEquals(TimeUnit.MINUTES, throttle.getTimeUnit()); 135 countThrottle++; 136 break; 137 case GLOBAL_BYPASS: 138 countGlobalBypass++; 139 break; 140 default: 141 fail("unexpected settings type: " + settings.getQuotaType()); 142 } 143 } 144 assertEquals(2, countThrottle); 145 assertEquals(1, countGlobalBypass); 146 } 147 148 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 149 assertNumResults(1, null); 150 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false)); 151 assertNumResults(0, null); 152 } 153 154 @Test 155 public void testSimpleScan() throws Exception { 156 Admin admin = TEST_UTIL.getAdmin(); 157 String userName = User.getCurrent().getShortName(); 158 159 admin.setQuota(QuotaSettingsFactory 160 .throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 161 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true)); 162 163 try (QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration())) { 164 int countThrottle = 0; 165 int countGlobalBypass = 0; 166 for (QuotaSettings settings: scanner) { 167 LOG.debug(Objects.toString(settings)); 168 switch (settings.getQuotaType()) { 169 case THROTTLE: 170 ThrottleSettings throttle = (ThrottleSettings)settings; 171 assertEquals(userName, throttle.getUserName()); 172 assertEquals(null, throttle.getTableName()); 173 assertEquals(null, throttle.getNamespace()); 174 assertEquals(6, throttle.getSoftLimit()); 175 assertEquals(TimeUnit.MINUTES, throttle.getTimeUnit()); 176 countThrottle++; 177 break; 178 case GLOBAL_BYPASS: 179 countGlobalBypass++; 180 break; 181 default: 182 fail("unexpected settings type: " + settings.getQuotaType()); 183 } 184 } 185 assertEquals(1, countThrottle); 186 assertEquals(1, countGlobalBypass); 187 } 188 189 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 190 assertNumResults(1, null); 191 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false)); 192 assertNumResults(0, null); 193 } 194 195 @Test 196 public void testMultiQuotaThrottling() throws Exception { 197 byte[] FAMILY = Bytes.toBytes("testFamily"); 198 byte[] ROW = Bytes.toBytes("testRow"); 199 byte[] QUALIFIER = Bytes.toBytes("testQualifier"); 200 byte[] VALUE = Bytes.toBytes("testValue"); 201 202 Admin admin = TEST_UTIL.getAdmin(); 203 TableName tableName = TableName.valueOf("testMultiQuotaThrottling"); 204 TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName) 205 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).build(); 206 admin.createTable(desc); 207 208 // Set up the quota. 209 admin.setQuota(QuotaSettingsFactory.throttleTable(tableName, ThrottleType.WRITE_NUMBER, 6, 210 TimeUnit.SECONDS)); 211 212 Thread.sleep(1000); 213 TEST_UTIL.getRSForFirstRegionInTable(tableName).getRegionServerRpcQuotaManager(). 214 getQuotaCache().triggerCacheRefresh(); 215 Thread.sleep(1000); 216 217 Table t = TEST_UTIL.getConnection().getTable(tableName); 218 try { 219 int size = 5; 220 List actions = new ArrayList(); 221 Object[] results = new Object[size]; 222 223 for (int i = 0; i < size; i++) { 224 Put put1 = new Put(ROW); 225 put1.addColumn(FAMILY, QUALIFIER, VALUE); 226 actions.add(put1); 227 } 228 t.batch(actions, results); 229 t.batch(actions, results); 230 } catch (IOException e) { 231 fail("Not supposed to get ThrottlingExcepiton " + e); 232 } finally { 233 t.close(); 234 } 235 } 236 237 238 @Test 239 public void testQuotaRetrieverFilter() throws Exception { 240 Admin admin = TEST_UTIL.getAdmin(); 241 TableName[] tables = new TableName[] { 242 TableName.valueOf("T0"), TableName.valueOf("T01"), TableName.valueOf("NS0:T2"), 243 }; 244 String[] namespaces = new String[] { "NS0", "NS01", "NS2" }; 245 String[] users = new String[] { "User0", "User01", "User2" }; 246 247 for (String user: users) { 248 admin.setQuota(QuotaSettingsFactory 249 .throttleUser(user, ThrottleType.REQUEST_NUMBER, 1, TimeUnit.MINUTES)); 250 251 for (TableName table: tables) { 252 admin.setQuota(QuotaSettingsFactory 253 .throttleUser(user, table, ThrottleType.REQUEST_NUMBER, 2, TimeUnit.MINUTES)); 254 } 255 256 for (String ns: namespaces) { 257 admin.setQuota(QuotaSettingsFactory 258 .throttleUser(user, ns, ThrottleType.REQUEST_NUMBER, 3, TimeUnit.MINUTES)); 259 } 260 } 261 assertNumResults(21, null); 262 263 for (TableName table: tables) { 264 admin.setQuota(QuotaSettingsFactory 265 .throttleTable(table, ThrottleType.REQUEST_NUMBER, 4, TimeUnit.MINUTES)); 266 } 267 assertNumResults(24, null); 268 269 for (String ns: namespaces) { 270 admin.setQuota(QuotaSettingsFactory 271 .throttleNamespace(ns, ThrottleType.REQUEST_NUMBER, 5, TimeUnit.MINUTES)); 272 } 273 assertNumResults(27, null); 274 275 assertNumResults(7, new QuotaFilter().setUserFilter("User0")); 276 assertNumResults(0, new QuotaFilter().setUserFilter("User")); 277 assertNumResults(21, new QuotaFilter().setUserFilter("User.*")); 278 assertNumResults(3, new QuotaFilter().setUserFilter("User.*").setTableFilter("T0")); 279 assertNumResults(3, new QuotaFilter().setUserFilter("User.*").setTableFilter("NS.*")); 280 assertNumResults(0, new QuotaFilter().setUserFilter("User.*").setTableFilter("T")); 281 assertNumResults(6, new QuotaFilter().setUserFilter("User.*").setTableFilter("T.*")); 282 assertNumResults(3, new QuotaFilter().setUserFilter("User.*").setNamespaceFilter("NS0")); 283 assertNumResults(0, new QuotaFilter().setUserFilter("User.*").setNamespaceFilter("NS")); 284 assertNumResults(9, new QuotaFilter().setUserFilter("User.*").setNamespaceFilter("NS.*")); 285 assertNumResults(6, new QuotaFilter().setUserFilter("User.*") 286 .setTableFilter("T0").setNamespaceFilter("NS0")); 287 assertNumResults(1, new QuotaFilter().setTableFilter("T0")); 288 assertNumResults(0, new QuotaFilter().setTableFilter("T")); 289 assertNumResults(2, new QuotaFilter().setTableFilter("T.*")); 290 assertNumResults(3, new QuotaFilter().setTableFilter(".*T.*")); 291 assertNumResults(1, new QuotaFilter().setNamespaceFilter("NS0")); 292 assertNumResults(0, new QuotaFilter().setNamespaceFilter("NS")); 293 assertNumResults(3, new QuotaFilter().setNamespaceFilter("NS.*")); 294 295 for (String user: users) { 296 admin.setQuota(QuotaSettingsFactory.unthrottleUser(user)); 297 for (TableName table: tables) { 298 admin.setQuota(QuotaSettingsFactory.unthrottleUser(user, table)); 299 } 300 for (String ns: namespaces) { 301 admin.setQuota(QuotaSettingsFactory.unthrottleUser(user, ns)); 302 } 303 } 304 assertNumResults(6, null); 305 306 for (TableName table: tables) { 307 admin.setQuota(QuotaSettingsFactory.unthrottleTable(table)); 308 } 309 assertNumResults(3, null); 310 311 for (String ns: namespaces) { 312 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(ns)); 313 } 314 assertNumResults(0, null); 315 } 316 317 @Test 318 public void testSetGetRemoveSpaceQuota() throws Exception { 319 Admin admin = TEST_UTIL.getAdmin(); 320 final TableName tn = TableName.valueOf("sq_table1"); 321 final long sizeLimit = 1024L * 1024L * 1024L * 1024L * 5L; // 5TB 322 final SpaceViolationPolicy violationPolicy = SpaceViolationPolicy.NO_WRITES; 323 QuotaSettings settings = QuotaSettingsFactory.limitTableSpace(tn, sizeLimit, violationPolicy); 324 admin.setQuota(settings); 325 326 // Verify the Quotas in the table 327 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) { 328 ResultScanner scanner = quotaTable.getScanner(new Scan()); 329 try { 330 Result r = Iterables.getOnlyElement(scanner); 331 CellScanner cells = r.cellScanner(); 332 assertTrue("Expected to find a cell", cells.advance()); 333 assertSpaceQuota(sizeLimit, violationPolicy, cells.current()); 334 } finally { 335 scanner.close(); 336 } 337 } 338 339 // Verify we can retrieve it via the QuotaRetriever API 340 QuotaRetriever scanner = QuotaRetriever.open(admin.getConfiguration()); 341 try { 342 assertSpaceQuota(sizeLimit, violationPolicy, Iterables.getOnlyElement(scanner)); 343 } finally { 344 scanner.close(); 345 } 346 347 // Now, remove the quota 348 QuotaSettings removeQuota = QuotaSettingsFactory.removeTableSpaceLimit(tn); 349 admin.setQuota(removeQuota); 350 351 // Verify that the record doesn't exist in the table 352 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) { 353 ResultScanner rs = quotaTable.getScanner(new Scan()); 354 try { 355 assertNull("Did not expect to find a quota entry", rs.next()); 356 } finally { 357 rs.close(); 358 } 359 } 360 361 // Verify that we can also not fetch it via the API 362 scanner = QuotaRetriever.open(admin.getConfiguration()); 363 try { 364 assertNull("Did not expect to find a quota entry", scanner.next()); 365 } finally { 366 scanner.close(); 367 } 368 } 369 370 @Test 371 public void testSetModifyRemoveSpaceQuota() throws Exception { 372 Admin admin = TEST_UTIL.getAdmin(); 373 final TableName tn = TableName.valueOf("sq_table2"); 374 final long originalSizeLimit = 1024L * 1024L * 1024L * 1024L * 5L; // 5TB 375 final SpaceViolationPolicy violationPolicy = SpaceViolationPolicy.NO_WRITES; 376 QuotaSettings settings = QuotaSettingsFactory.limitTableSpace(tn, originalSizeLimit, 377 violationPolicy); 378 admin.setQuota(settings); 379 380 // Verify the Quotas in the table 381 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) { 382 ResultScanner scanner = quotaTable.getScanner(new Scan()); 383 try { 384 Result r = Iterables.getOnlyElement(scanner); 385 CellScanner cells = r.cellScanner(); 386 assertTrue("Expected to find a cell", cells.advance()); 387 assertSpaceQuota(originalSizeLimit, violationPolicy, cells.current()); 388 } finally { 389 scanner.close(); 390 } 391 } 392 393 // Verify we can retrieve it via the QuotaRetriever API 394 QuotaRetriever quotaScanner = QuotaRetriever.open(admin.getConfiguration()); 395 try { 396 assertSpaceQuota(originalSizeLimit, violationPolicy, Iterables.getOnlyElement(quotaScanner)); 397 } finally { 398 quotaScanner.close(); 399 } 400 401 // Setting a new size and policy should be reflected 402 final long newSizeLimit = 1024L * 1024L * 1024L * 1024L; // 1TB 403 final SpaceViolationPolicy newViolationPolicy = SpaceViolationPolicy.NO_WRITES_COMPACTIONS; 404 QuotaSettings newSettings = QuotaSettingsFactory.limitTableSpace(tn, newSizeLimit, 405 newViolationPolicy); 406 admin.setQuota(newSettings); 407 408 // Verify the new Quotas in the table 409 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) { 410 ResultScanner scanner = quotaTable.getScanner(new Scan()); 411 try { 412 Result r = Iterables.getOnlyElement(scanner); 413 CellScanner cells = r.cellScanner(); 414 assertTrue("Expected to find a cell", cells.advance()); 415 assertSpaceQuota(newSizeLimit, newViolationPolicy, cells.current()); 416 } finally { 417 scanner.close(); 418 } 419 } 420 421 // Verify we can retrieve the new quota via the QuotaRetriever API 422 quotaScanner = QuotaRetriever.open(admin.getConfiguration()); 423 try { 424 assertSpaceQuota(newSizeLimit, newViolationPolicy, Iterables.getOnlyElement(quotaScanner)); 425 } finally { 426 quotaScanner.close(); 427 } 428 429 // Now, remove the quota 430 QuotaSettings removeQuota = QuotaSettingsFactory.removeTableSpaceLimit(tn); 431 admin.setQuota(removeQuota); 432 433 // Verify that the record doesn't exist in the table 434 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) { 435 ResultScanner scanner = quotaTable.getScanner(new Scan()); 436 try { 437 assertNull("Did not expect to find a quota entry", scanner.next()); 438 } finally { 439 scanner.close(); 440 } 441 } 442 443 // Verify that we can also not fetch it via the API 444 quotaScanner = QuotaRetriever.open(admin.getConfiguration()); 445 try { 446 assertNull("Did not expect to find a quota entry", quotaScanner.next()); 447 } finally { 448 quotaScanner.close(); 449 } 450 } 451 452 private void assertNumResults(int expected, final QuotaFilter filter) throws Exception { 453 assertEquals(expected, countResults(filter)); 454 } 455 456 @Test 457 public void testSetGetRemoveRPCQuota() throws Exception { 458 Admin admin = TEST_UTIL.getAdmin(); 459 final TableName tn = TableName.valueOf("sq_table1"); 460 QuotaSettings settings = 461 QuotaSettingsFactory.throttleTable(tn, ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS); 462 admin.setQuota(settings); 463 464 // Verify the Quota in the table 465 verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS); 466 467 // Verify we can retrieve it via the QuotaRetriever API 468 verifyFetchableViaAPI(admin, ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS); 469 470 // Now, remove the quota 471 QuotaSettings removeQuota = QuotaSettingsFactory.unthrottleTable(tn); 472 admin.setQuota(removeQuota); 473 474 // Verify that the record doesn't exist in the table 475 verifyRecordNotPresentInQuotaTable(); 476 477 // Verify that we can also not fetch it via the API 478 verifyNotFetchableViaAPI(admin); 479 } 480 481 @Test 482 public void testSetModifyRemoveRPCQuota() throws Exception { 483 Admin admin = TEST_UTIL.getAdmin(); 484 final TableName tn = TableName.valueOf("sq_table1"); 485 QuotaSettings settings = 486 QuotaSettingsFactory.throttleTable(tn, ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS); 487 admin.setQuota(settings); 488 489 // Verify the Quota in the table 490 verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS); 491 492 // Verify we can retrieve it via the QuotaRetriever API 493 verifyFetchableViaAPI(admin, ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS); 494 495 // Setting a limit and time unit should be reflected 496 QuotaSettings newSettings = 497 QuotaSettingsFactory.throttleTable(tn, ThrottleType.REQUEST_SIZE, 3L, TimeUnit.DAYS); 498 admin.setQuota(newSettings); 499 500 // Verify the new Quota in the table 501 verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_SIZE, 3L, TimeUnit.DAYS); 502 503 // Verify we can retrieve the new quota via the QuotaRetriever API 504 verifyFetchableViaAPI(admin, ThrottleType.REQUEST_SIZE, 3L, TimeUnit.DAYS); 505 506 // Now, remove the quota 507 QuotaSettings removeQuota = QuotaSettingsFactory.unthrottleTable(tn); 508 admin.setQuota(removeQuota); 509 510 // Verify that the record doesn't exist in the table 511 verifyRecordNotPresentInQuotaTable(); 512 513 // Verify that we can also not fetch it via the API 514 verifyNotFetchableViaAPI(admin); 515 516 } 517 518 private void verifyRecordPresentInQuotaTable(ThrottleType type, long limit, TimeUnit tu) 519 throws Exception { 520 // Verify the RPC Quotas in the table 521 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME); 522 ResultScanner scanner = quotaTable.getScanner(new Scan())) { 523 Result r = Iterables.getOnlyElement(scanner); 524 CellScanner cells = r.cellScanner(); 525 assertTrue("Expected to find a cell", cells.advance()); 526 assertRPCQuota(type, limit, tu, cells.current()); 527 } 528 } 529 530 private void verifyRecordNotPresentInQuotaTable() throws Exception { 531 // Verify that the record doesn't exist in the QuotaTableUtil.QUOTA_TABLE_NAME 532 try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME); 533 ResultScanner scanner = quotaTable.getScanner(new Scan())) { 534 assertNull("Did not expect to find a quota entry", scanner.next()); 535 } 536 } 537 538 private void verifyFetchableViaAPI(Admin admin, ThrottleType type, long limit, TimeUnit tu) 539 throws Exception { 540 // Verify we can retrieve the new quota via the QuotaRetriever API 541 try (QuotaRetriever quotaScanner = QuotaRetriever.open(admin.getConfiguration())) { 542 assertRPCQuota(type, limit, tu, Iterables.getOnlyElement(quotaScanner)); 543 } 544 } 545 546 private void verifyNotFetchableViaAPI(Admin admin) throws Exception { 547 // Verify that we can also not fetch it via the API 548 try (QuotaRetriever quotaScanner = QuotaRetriever.open(admin.getConfiguration())) { 549 assertNull("Did not expect to find a quota entry", quotaScanner.next()); 550 } 551 } 552 553 private void assertRPCQuota(ThrottleType type, long limit, TimeUnit tu, Cell cell) 554 throws Exception { 555 Quotas q = QuotaTableUtil 556 .quotasFromData(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); 557 assertTrue("Quota should have rpc quota defined", q.hasThrottle()); 558 559 QuotaProtos.Throttle rpcQuota = q.getThrottle(); 560 QuotaProtos.TimedQuota t = null; 561 562 switch (type) { 563 case REQUEST_SIZE: 564 assertTrue(rpcQuota.hasReqSize()); 565 t = rpcQuota.getReqSize(); 566 break; 567 case READ_NUMBER: 568 assertTrue(rpcQuota.hasReadNum()); 569 t = rpcQuota.getReadNum(); 570 break; 571 case READ_SIZE: 572 assertTrue(rpcQuota.hasReadSize()); 573 t = rpcQuota.getReadSize(); 574 break; 575 case REQUEST_NUMBER: 576 assertTrue(rpcQuota.hasReqNum()); 577 t = rpcQuota.getReqNum(); 578 break; 579 case WRITE_NUMBER: 580 assertTrue(rpcQuota.hasWriteNum()); 581 t = rpcQuota.getWriteNum(); 582 break; 583 case WRITE_SIZE: 584 assertTrue(rpcQuota.hasWriteSize()); 585 t = rpcQuota.getWriteSize(); 586 break; 587 } 588 589 assertEquals(t.getSoftLimit(), limit); 590 assertEquals(t.getTimeUnit(), ProtobufUtil.toProtoTimeUnit(tu)); 591 } 592 593 private void assertRPCQuota(ThrottleType type, long limit, TimeUnit tu, 594 QuotaSettings actualSettings) throws Exception { 595 assertTrue( 596 "The actual QuotaSettings was not an instance of " + ThrottleSettings.class + " but of " 597 + actualSettings.getClass(), actualSettings instanceof ThrottleSettings); 598 QuotaProtos.ThrottleRequest throttleRequest = ((ThrottleSettings) actualSettings).getProto(); 599 assertEquals(limit, throttleRequest.getTimedQuota().getSoftLimit()); 600 assertEquals(ProtobufUtil.toProtoTimeUnit(tu), throttleRequest.getTimedQuota().getTimeUnit()); 601 assertEquals(ProtobufUtil.toProtoThrottleType(type), throttleRequest.getType()); 602 } 603 604 private void assertSpaceQuota( 605 long sizeLimit, SpaceViolationPolicy violationPolicy, Cell cell) throws Exception { 606 Quotas q = QuotaTableUtil.quotasFromData( 607 cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); 608 assertTrue("Quota should have space quota defined", q.hasSpace()); 609 QuotaProtos.SpaceQuota spaceQuota = q.getSpace(); 610 assertEquals(sizeLimit, spaceQuota.getSoftLimit()); 611 assertEquals(violationPolicy, ProtobufUtil.toViolationPolicy(spaceQuota.getViolationPolicy())); 612 } 613 614 private void assertSpaceQuota( 615 long sizeLimit, SpaceViolationPolicy violationPolicy, QuotaSettings actualSettings) { 616 assertTrue("The actual QuotaSettings was not an instance of " + SpaceLimitSettings.class 617 + " but of " + actualSettings.getClass(), actualSettings instanceof SpaceLimitSettings); 618 SpaceLimitRequest spaceLimitRequest = ((SpaceLimitSettings) actualSettings).getProto(); 619 assertEquals(sizeLimit, spaceLimitRequest.getQuota().getSoftLimit()); 620 assertEquals(violationPolicy, 621 ProtobufUtil.toViolationPolicy(spaceLimitRequest.getQuota().getViolationPolicy())); 622 } 623 624 private int countResults(final QuotaFilter filter) throws Exception { 625 QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration(), filter); 626 try { 627 int count = 0; 628 for (QuotaSettings settings: scanner) { 629 LOG.debug(Objects.toString(settings)); 630 count++; 631 } 632 return count; 633 } finally { 634 scanner.close(); 635 } 636 } 637}