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