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.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doGets; 021import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doPuts; 022import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerExceedThrottleQuotaCacheRefresh; 023import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerNamespaceCacheRefresh; 024import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerRegionServerCacheRefresh; 025import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerTableCacheRefresh; 026import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerUserCacheRefresh; 027import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.waitMinuteQuota; 028import static org.junit.Assert.assertEquals; 029import static org.junit.Assert.assertTrue; 030 031import java.io.IOException; 032import java.util.List; 033import java.util.concurrent.TimeUnit; 034import org.apache.hadoop.hbase.HBaseClassTestRule; 035import org.apache.hadoop.hbase.HBaseTestingUtil; 036import org.apache.hadoop.hbase.HConstants; 037import org.apache.hadoop.hbase.TableName; 038import org.apache.hadoop.hbase.client.Admin; 039import org.apache.hadoop.hbase.client.Get; 040import org.apache.hadoop.hbase.client.Table; 041import org.apache.hadoop.hbase.security.User; 042import org.apache.hadoop.hbase.testclassification.MediumTests; 043import org.apache.hadoop.hbase.testclassification.RegionServerTests; 044import org.apache.hadoop.hbase.util.Bytes; 045import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 046import org.junit.After; 047import org.junit.AfterClass; 048import org.junit.BeforeClass; 049import org.junit.ClassRule; 050import org.junit.Ignore; 051import org.junit.Test; 052import org.junit.experimental.categories.Category; 053import org.slf4j.Logger; 054import org.slf4j.LoggerFactory; 055 056// This tests breaks monotonic WAL numbering after HBASE-20746 because of how it 057// manipulates the EnvironmentEdge. 058@Ignore("See HBASE-27243") 059@Category({ RegionServerTests.class, MediumTests.class }) 060public class TestQuotaThrottle { 061 062 @ClassRule 063 public static final HBaseClassTestRule CLASS_RULE = 064 HBaseClassTestRule.forClass(TestQuotaThrottle.class); 065 066 private final static Logger LOG = LoggerFactory.getLogger(TestQuotaThrottle.class); 067 068 private final static int REFRESH_TIME = 30 * 60000; 069 070 private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 071 private final static byte[] FAMILY = Bytes.toBytes("cf"); 072 private final static byte[] QUALIFIER = Bytes.toBytes("q"); 073 074 private final static TableName[] TABLE_NAMES = 075 new TableName[] { TableName.valueOf("TestQuotaAdmin0"), TableName.valueOf("TestQuotaAdmin1"), 076 TableName.valueOf("TestQuotaAdmin2") }; 077 078 private static Table[] tables; 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, REFRESH_TIME); 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 QuotaCache.TEST_FORCE_REFRESH = true; 092 093 tables = new Table[TABLE_NAMES.length]; 094 for (int i = 0; i < TABLE_NAMES.length; ++i) { 095 tables[i] = TEST_UTIL.createTable(TABLE_NAMES[i], FAMILY); 096 } 097 } 098 099 @AfterClass 100 public static void tearDownAfterClass() throws Exception { 101 EnvironmentEdgeManager.reset(); 102 for (int i = 0; i < tables.length; ++i) { 103 if (tables[i] != null) { 104 tables[i].close(); 105 TEST_UTIL.deleteTable(TABLE_NAMES[i]); 106 } 107 } 108 109 TEST_UTIL.shutdownMiniCluster(); 110 } 111 112 @After 113 public void tearDown() throws Exception { 114 ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL); 115 } 116 117 @Test 118 public void testUserGlobalThrottle() throws Exception { 119 final Admin admin = TEST_UTIL.getAdmin(); 120 final String userName = User.getCurrent().getShortName(); 121 122 // Add 6req/min limit 123 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6, 124 TimeUnit.MINUTES)); 125 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES); 126 127 // should execute at max 6 requests 128 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables)); 129 130 // wait a minute and you should get other 6 requests executed 131 waitMinuteQuota(); 132 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables)); 133 134 // Remove all the limits 135 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 136 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 137 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 138 assertEquals(60, doGets(60, tables)); 139 } 140 141 @Test 142 public void testUserGlobalReadAndWriteThrottle() throws Exception { 143 final Admin admin = TEST_UTIL.getAdmin(); 144 final String userName = User.getCurrent().getShortName(); 145 146 // Add 6req/min limit for read request 147 admin.setQuota( 148 QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES)); 149 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES); 150 151 // not limit for write request and should execute at max 6 read requests 152 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 153 assertEquals(6, doGets(100, tables)); 154 155 waitMinuteQuota(); 156 157 // Add 6req/min limit for write request 158 admin.setQuota( 159 QuotaSettingsFactory.throttleUser(userName, ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES)); 160 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES); 161 162 // should execute at max 6 read requests and at max 6 write write requests 163 assertEquals(6, doGets(100, tables)); 164 assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables)); 165 166 // Remove all the limits 167 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 168 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 169 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 170 assertEquals(60, doGets(60, tables)); 171 } 172 173 @Test 174 public void testUserTableThrottle() throws Exception { 175 final Admin admin = TEST_UTIL.getAdmin(); 176 final String userName = User.getCurrent().getShortName(); 177 178 // Add 6req/min limit 179 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 180 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 181 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 182 183 // should execute at max 6 requests on tables[0] and have no limit on tables[1] 184 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 185 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 186 187 // wait a minute and you should get other 6 requests executed 188 waitMinuteQuota(); 189 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 190 191 // Remove all the limits 192 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0])); 193 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 194 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 195 assertEquals(60, doGets(60, tables)); 196 } 197 198 @Test 199 public void testUserTableReadAndWriteThrottle() throws Exception { 200 final Admin admin = TEST_UTIL.getAdmin(); 201 final String userName = User.getCurrent().getShortName(); 202 203 // Add 6req/min limit for write request on tables[0] 204 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 205 ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES)); 206 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 207 208 // should execute at max 6 write requests and have no limit for read request 209 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 210 assertEquals(60, doGets(60, tables[0])); 211 212 // no limit on tables[1] 213 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[1])); 214 assertEquals(60, doGets(60, tables[1])); 215 216 // wait a minute and you should get other 6 write requests executed 217 waitMinuteQuota(); 218 219 // Add 6req/min limit for read request on tables[0] 220 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 221 ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES)); 222 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 223 224 // should execute at max 6 read requests and at max 6 write requests 225 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 226 assertEquals(6, doGets(60, tables[0])); 227 228 // no limit on tables[1] 229 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 230 assertEquals(30, doGets(30, tables[1])); 231 232 // Remove all the limits 233 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0])); 234 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 235 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 236 assertEquals(60, doGets(60, tables)); 237 } 238 239 @Test 240 public void testUserNamespaceThrottle() throws Exception { 241 final Admin admin = TEST_UTIL.getAdmin(); 242 final String userName = User.getCurrent().getShortName(); 243 final String NAMESPACE = "default"; 244 245 // Add 6req/min limit 246 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, 247 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 248 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 249 250 // should execute at max 6 requests on tables[0] and have no limit on tables[1] 251 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 252 253 // wait a minute and you should get other 6 requests executed 254 waitMinuteQuota(); 255 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1])); 256 257 // Remove all the limits 258 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE)); 259 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 260 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 261 assertEquals(60, doGets(60, tables)); 262 } 263 264 @Test 265 public void testUserNamespaceReadAndWriteThrottle() throws Exception { 266 final Admin admin = TEST_UTIL.getAdmin(); 267 final String userName = User.getCurrent().getShortName(); 268 final String NAMESPACE = "default"; 269 270 // Add 6req/min limit for read request 271 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.READ_NUMBER, 272 6, TimeUnit.MINUTES)); 273 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 274 275 // should execute at max 6 read requests and have no limit for write request 276 assertEquals(6, doGets(60, tables[0])); 277 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[0])); 278 279 waitMinuteQuota(); 280 281 // Add 6req/min limit for write request, too 282 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.WRITE_NUMBER, 283 6, TimeUnit.MINUTES)); 284 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 285 286 // should execute at max 6 read requests and at max 6 write requests 287 assertEquals(6, doGets(60, tables[0])); 288 assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables[0])); 289 290 // Remove all the limits 291 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE)); 292 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 293 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 294 assertEquals(60, doGets(60, tables)); 295 } 296 297 @Test 298 public void testTableGlobalThrottle() throws Exception { 299 final Admin admin = TEST_UTIL.getAdmin(); 300 301 // Add 6req/min limit 302 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 303 6, TimeUnit.MINUTES)); 304 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 305 306 // should execute at max 6 requests 307 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 308 // should have no limits 309 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 310 311 // wait a minute and you should get other 6 requests executed 312 waitMinuteQuota(); 313 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 314 315 // Remove all the limits 316 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 317 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 318 assertEquals(80, doGets(80, tables[0], tables[1])); 319 } 320 321 @Test 322 public void testTableGlobalReadAndWriteThrottle() throws Exception { 323 final Admin admin = TEST_UTIL.getAdmin(); 324 325 // Add 6req/min limit for read request 326 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.READ_NUMBER, 6, 327 TimeUnit.MINUTES)); 328 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 329 330 // should execute at max 6 read requests and have no limit for write request 331 assertEquals(6, doGets(100, tables[0])); 332 assertEquals(100, doPuts(100, FAMILY, QUALIFIER, tables[0])); 333 // should have no limits on tables[1] 334 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 335 assertEquals(30, doGets(30, tables[1])); 336 337 // wait a minute and you should get other 6 requests executed 338 waitMinuteQuota(); 339 340 // Add 6req/min limit for write request, too 341 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 6, 342 TimeUnit.MINUTES)); 343 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 344 345 // should execute at max 6 read requests and at max 6 write requests 346 assertEquals(6, doGets(100, tables[0])); 347 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 348 // should have no limits on tables[1] 349 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 350 assertEquals(30, doGets(30, tables[1])); 351 352 // Remove all the limits 353 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 354 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 355 assertEquals(80, doGets(80, tables[0], tables[1])); 356 } 357 358 @Test 359 public void testNamespaceGlobalThrottle() throws Exception { 360 final Admin admin = TEST_UTIL.getAdmin(); 361 final String NAMESPACE = "default"; 362 363 // Add 6req/min limit 364 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 6, 365 TimeUnit.MINUTES)); 366 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 367 368 // should execute at max 6 requests 369 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 370 371 // wait a minute and you should get other 6 requests executed 372 waitMinuteQuota(); 373 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1])); 374 375 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE)); 376 triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 377 assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0])); 378 } 379 380 @Test 381 public void testNamespaceGlobalReadAndWriteThrottle() throws Exception { 382 final Admin admin = TEST_UTIL.getAdmin(); 383 final String NAMESPACE = "default"; 384 385 // Add 6req/min limit for write request 386 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.WRITE_NUMBER, 6, 387 TimeUnit.MINUTES)); 388 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 389 390 // should execute at max 6 write requests and no limit for read request 391 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 392 assertEquals(100, doGets(100, tables[0])); 393 394 // wait a minute and you should get other 6 requests executed 395 waitMinuteQuota(); 396 397 // Add 6req/min limit for read request, too 398 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.READ_NUMBER, 6, 399 TimeUnit.MINUTES)); 400 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 401 402 // should execute at max 6 write requests and at max 6 read requests 403 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 404 assertEquals(6, doGets(100, tables[0])); 405 406 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE)); 407 triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 408 assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0])); 409 } 410 411 @Test 412 public void testUserAndTableThrottle() throws Exception { 413 final Admin admin = TEST_UTIL.getAdmin(); 414 final String userName = User.getCurrent().getShortName(); 415 416 // Add 6req/min limit for the user on tables[0] 417 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 418 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 419 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 420 // Add 12req/min limit for the user 421 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 12, 422 TimeUnit.MINUTES)); 423 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1], TABLE_NAMES[2]); 424 // Add 8req/min limit for the tables[1] 425 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER, 426 8, TimeUnit.MINUTES)); 427 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]); 428 // Add a lower table level throttle on tables[0] 429 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 430 3, TimeUnit.MINUTES)); 431 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 432 433 // should execute at max 12 requests 434 assertEquals(12, doGets(100, tables[2])); 435 436 // should execute at max 8 requests 437 waitMinuteQuota(); 438 assertEquals(8, doGets(100, tables[1])); 439 440 // should execute at max 3 requests 441 waitMinuteQuota(); 442 assertEquals(3, doPuts(100, FAMILY, QUALIFIER, tables[0])); 443 444 // Remove all the throttling rules 445 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0])); 446 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 447 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0], TABLE_NAMES[1]); 448 449 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[1])); 450 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]); 451 waitMinuteQuota(); 452 assertEquals(40, doGets(40, tables[1])); 453 454 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 455 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 456 waitMinuteQuota(); 457 assertEquals(40, doGets(40, tables[0])); 458 } 459 460 @Test 461 public void testUserGlobalBypassThrottle() throws Exception { 462 final Admin admin = TEST_UTIL.getAdmin(); 463 final String userName = User.getCurrent().getShortName(); 464 final String NAMESPACE = "default"; 465 466 // Add 6req/min limit for tables[0] 467 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 468 6, TimeUnit.MINUTES)); 469 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 470 // Add 13req/min limit for the user 471 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 472 13, TimeUnit.MINUTES)); 473 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]); 474 475 // should execute at max 6 requests on table[0] and (13 - 6) on table[1] 476 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 477 assertEquals(7, doGets(100, tables[1])); 478 waitMinuteQuota(); 479 480 // Set the global bypass for the user 481 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true)); 482 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[2], 483 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 484 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[2]); 485 assertEquals(30, doGets(30, tables[0])); 486 assertEquals(30, doGets(30, tables[1])); 487 waitMinuteQuota(); 488 489 // Remove the global bypass 490 // should execute at max 6 requests on table[0] and (13 - 6) on table[1] 491 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false)); 492 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[2])); 493 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[2]); 494 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 495 assertEquals(7, doGets(100, tables[1])); 496 497 // unset throttle 498 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 499 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE)); 500 waitMinuteQuota(); 501 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 502 triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]); 503 assertEquals(30, doGets(30, tables[0])); 504 assertEquals(30, doGets(30, tables[1])); 505 } 506 507 @Test 508 public void testTableWriteCapacityUnitThrottle() throws Exception { 509 final Admin admin = TEST_UTIL.getAdmin(); 510 511 // Add 6CU/min limit 512 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], 513 ThrottleType.WRITE_CAPACITY_UNIT, 6, TimeUnit.MINUTES)); 514 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 515 516 // should execute at max 6 capacity units because each put size is 1 capacity unit 517 assertEquals(6, doPuts(20, 10, FAMILY, QUALIFIER, tables[0])); 518 519 // wait a minute and you should execute at max 3 capacity units because each put size is 2 520 // capacity unit 521 waitMinuteQuota(); 522 assertEquals(3, doPuts(20, 1025, FAMILY, QUALIFIER, tables[0])); 523 524 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 525 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 526 } 527 528 @Test 529 public void testTableReadCapacityUnitThrottle() throws Exception { 530 final Admin admin = TEST_UTIL.getAdmin(); 531 532 // Add 6CU/min limit 533 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], 534 ThrottleType.READ_CAPACITY_UNIT, 6, TimeUnit.MINUTES)); 535 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 536 537 assertEquals(20, doPuts(20, 10, FAMILY, QUALIFIER, tables[0])); 538 // should execute at max 6 capacity units because each get size is 1 capacity unit 539 assertEquals(6, doGets(20, tables[0])); 540 541 assertEquals(20, doPuts(20, 2015, FAMILY, QUALIFIER, tables[0])); 542 // wait a minute and you should execute at max 3 capacity units because each get size is 2 543 // capacity unit on tables[0] 544 waitMinuteQuota(); 545 assertEquals(3, doGets(20, tables[0])); 546 547 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 548 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 549 } 550 551 @Test 552 public void testTableExistsGetThrottle() throws Exception { 553 final Admin admin = TEST_UTIL.getAdmin(); 554 555 // Add throttle quota 556 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 557 100, TimeUnit.MINUTES)); 558 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 559 560 Table table = TEST_UTIL.getConnection().getTable(TABLE_NAMES[0]); 561 // An exists call when having throttle quota 562 table.exists(new Get(Bytes.toBytes("abc"))); 563 564 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 565 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 566 } 567 568 @Test 569 public void testRegionServerThrottle() throws Exception { 570 final Admin admin = TEST_UTIL.getAdmin(); 571 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5, 572 TimeUnit.MINUTES)); 573 574 // requests are throttled by table quota 575 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 576 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 7, TimeUnit.MINUTES)); 577 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 578 triggerRegionServerCacheRefresh(TEST_UTIL, false); 579 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 580 triggerRegionServerCacheRefresh(TEST_UTIL, false); 581 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 582 583 // requests are throttled by region server quota 584 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 585 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES)); 586 triggerRegionServerCacheRefresh(TEST_UTIL, false); 587 assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0])); 588 triggerRegionServerCacheRefresh(TEST_UTIL, false); 589 assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0])); 590 591 // unthrottle 592 admin.setQuota( 593 QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY)); 594 triggerRegionServerCacheRefresh(TEST_UTIL, true); 595 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 596 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 597 triggerRegionServerCacheRefresh(TEST_UTIL, true); 598 } 599 600 @Test 601 public void testExceedThrottleQuota() throws Exception { 602 final Admin admin = TEST_UTIL.getAdmin(); 603 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5, 604 TimeUnit.MINUTES)); 605 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 606 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 607 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS)); 608 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 609 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.READ_NUMBER, 10, TimeUnit.SECONDS)); 610 triggerRegionServerCacheRefresh(TEST_UTIL, false); 611 612 // enable exceed throttle quota 613 admin.exceedThrottleQuotaSwitch(true); 614 // exceed table limit and allowed by region server limit 615 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true); 616 waitMinuteQuota(); 617 assertEquals(10, doPuts(10, FAMILY, QUALIFIER, tables[0])); 618 // exceed table limit and throttled by region server limit 619 waitMinuteQuota(); 620 assertEquals(20, doPuts(25, FAMILY, QUALIFIER, tables[0])); 621 622 // set region server limiter is lower than table limiter 623 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 624 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 2, TimeUnit.SECONDS)); 625 triggerRegionServerCacheRefresh(TEST_UTIL, false); 626 // throttled by region server limiter 627 waitMinuteQuota(); 628 assertEquals(2, doPuts(10, FAMILY, QUALIFIER, tables[0])); 629 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 630 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS)); 631 triggerRegionServerCacheRefresh(TEST_UTIL, false); 632 633 // disable exceed throttle quota 634 admin.exceedThrottleQuotaSwitch(false); 635 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false); 636 waitMinuteQuota(); 637 // throttled by table limit 638 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 639 640 // enable exceed throttle quota and unthrottle region server 641 admin.exceedThrottleQuotaSwitch(true); 642 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true); 643 waitMinuteQuota(); 644 admin.setQuota( 645 QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY)); 646 triggerRegionServerCacheRefresh(TEST_UTIL, true); 647 waitMinuteQuota(); 648 // throttled by table limit 649 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 650 651 // disable exceed throttle quota 652 admin.exceedThrottleQuotaSwitch(false); 653 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false); 654 // unthrottle table 655 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 656 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 657 } 658 659 @Test 660 public void testSetAndGetAllThrottleTypes() throws Exception { 661 for (ThrottleType throttleType : ThrottleType.values()) { 662 canSetAndGetUserThrottle(throttleType); 663 } 664 } 665 666 private void canSetAndGetUserThrottle(ThrottleType throttleType) throws IOException { 667 final Admin admin = TEST_UTIL.getAdmin(); 668 final String userName = User.getCurrent().getShortName(); 669 670 QuotaSettings setQuota = 671 QuotaSettingsFactory.throttleUser(userName, throttleType, 123, TimeUnit.SECONDS); 672 admin.setQuota(setQuota); 673 674 boolean found = false; 675 List<QuotaSettings> quotaSettings = admin.getQuota(new QuotaFilter().setUserFilter(userName)); 676 for (QuotaSettings settings : quotaSettings) { 677 if (settings instanceof ThrottleSettings) { 678 ThrottleSettings throttle = (ThrottleSettings) settings; 679 if ( 680 userName.equals(throttle.getUserName()) && throttle.getThrottleType() == throttleType 681 && throttle.getSoftLimit() == 123 && throttle.getTimeUnit() == TimeUnit.SECONDS 682 ) { 683 found = true; 684 break; 685 } 686 } 687 } 688 689 assertTrue("Expected to find " + throttleType.name() + " quota for user " + userName, found); 690 admin.setQuota(QuotaSettingsFactory.unthrottleUserByThrottleType(userName, throttleType)); 691 } 692 693}