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.io.IOException;
031import java.util.List;
032import java.util.concurrent.TimeUnit;
033
034import org.apache.hadoop.hbase.HBaseClassTestRule;
035import org.apache.hadoop.hbase.HBaseTestingUtility;
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@Ignore // Disabled because flakey. Fails ~30% on a resource constrained GCE though not on Apache.
057@Category({RegionServerTests.class, MediumTests.class})
058public class TestQuotaThrottle {
059
060  @ClassRule
061  public static final HBaseClassTestRule CLASS_RULE =
062      HBaseClassTestRule.forClass(TestQuotaThrottle.class);
063
064  private final static Logger LOG = LoggerFactory.getLogger(TestQuotaThrottle.class);
065
066  private final static int REFRESH_TIME = 30 * 60000;
067
068  private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
069  private final static byte[] FAMILY = Bytes.toBytes("cf");
070  private final static byte[] QUALIFIER = Bytes.toBytes("q");
071
072  private final static TableName[] TABLE_NAMES = new TableName[] {
073    TableName.valueOf("TestQuotaAdmin0"),
074    TableName.valueOf("TestQuotaAdmin1"),
075    TableName.valueOf("TestQuotaAdmin2")
076  };
077
078  private final static String[] NAMESPACES = new String[] {
079    "NAMESPACE01",
080    "NAMESPACE02",
081    "NAMESPACE03"
082  };
083
084  private static Table[] tables;
085
086  @BeforeClass
087  public static void setUpBeforeClass() throws Exception {
088    TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
089    TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, REFRESH_TIME);
090    TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
091    TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
092    TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
093    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
094    TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
095    TEST_UTIL.startMiniCluster(1);
096    TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
097    QuotaCache.TEST_FORCE_REFRESH = true;
098
099    tables = new Table[TABLE_NAMES.length];
100    for (int i = 0; i < TABLE_NAMES.length; ++i) {
101      tables[i] = TEST_UTIL.createTable(TABLE_NAMES[i], FAMILY);
102    }
103  }
104
105  @AfterClass
106  public static void tearDownAfterClass() throws Exception {
107    EnvironmentEdgeManager.reset();
108    for (int i = 0; i < tables.length; ++i) {
109      if (tables[i] != null) {
110        tables[i].close();
111        TEST_UTIL.deleteTable(TABLE_NAMES[i]);
112      }
113    }
114
115    TEST_UTIL.shutdownMiniCluster();
116  }
117
118  @After
119  public void tearDown() throws Exception {
120    ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL);
121  }
122
123  @Test
124  public void testUserGlobalThrottle() throws Exception {
125    final Admin admin = TEST_UTIL.getAdmin();
126    final String userName = User.getCurrent().getShortName();
127
128    // Add 6req/min limit
129    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6,
130      TimeUnit.MINUTES));
131    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
132
133    // should execute at max 6 requests
134    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables));
135
136    // wait a minute and you should get other 6 requests executed
137    waitMinuteQuota();
138    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables));
139
140    // Remove all the limits
141    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
142    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
143    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
144    assertEquals(60, doGets(60, tables));
145  }
146
147  @Test
148  public void testUserGlobalReadAndWriteThrottle() throws Exception {
149    final Admin admin = TEST_UTIL.getAdmin();
150    final String userName = User.getCurrent().getShortName();
151
152    // Add 6req/min limit for read request
153    admin.setQuota(
154      QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
155    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
156
157    // not limit for write request and should execute at max 6 read requests
158    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
159    assertEquals(6, doGets(100, tables));
160
161    waitMinuteQuota();
162
163    // Add 6req/min limit for write request
164    admin.setQuota(
165      QuotaSettingsFactory.throttleUser(userName, ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES));
166    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
167
168    // should execute at max 6 read requests and at max 6 write write requests
169    assertEquals(6, doGets(100, tables));
170    assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables));
171
172    // Remove all the limits
173    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
174    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
175    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
176    assertEquals(60, doGets(60, tables));
177  }
178
179  @Test
180  public void testUserTableThrottle() throws Exception {
181    final Admin admin = TEST_UTIL.getAdmin();
182    final String userName = User.getCurrent().getShortName();
183
184    // Add 6req/min limit
185    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
186      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
187    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
188
189    // should execute at max 6 requests on tables[0] and have no limit on tables[1]
190    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
191    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
192
193    // wait a minute and you should get other 6 requests executed
194    waitMinuteQuota();
195    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
196
197    // Remove all the limits
198    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
199    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
200    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
201    assertEquals(60, doGets(60, tables));
202  }
203
204  @Test
205  public void testUserUnThrottleByType() throws Exception {
206    final Admin admin = TEST_UTIL.getAdmin();
207    final String userName = User.getCurrent().getShortName();
208    String userName01 = "user01";
209    // Add 6req/min limit
210    admin.setQuota(QuotaSettingsFactory
211        .throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
212    admin.setQuota(QuotaSettingsFactory
213        .throttleUser(userName, ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
214    admin.setQuota(QuotaSettingsFactory
215        .throttleUser(userName01, ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
216    admin.setQuota(QuotaSettingsFactory
217        .throttleUser(userName01, ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
218    admin.setQuota(
219        QuotaSettingsFactory.unthrottleUserByThrottleType(userName, ThrottleType.REQUEST_NUMBER));
220    assertEquals(3, getQuotaSettingCount(admin));
221    admin.setQuota(
222        QuotaSettingsFactory.unthrottleUserByThrottleType(userName, ThrottleType.REQUEST_SIZE));
223    assertEquals(2, getQuotaSettingCount(admin));
224  }
225
226  @Test
227  public void testUserTableUnThrottleByType() throws Exception {
228    final Admin admin = TEST_UTIL.getAdmin();
229    final String userName = User.getCurrent().getShortName();
230    String userName01 = "user01";
231    // Add 6req/min limit
232    admin.setQuota(QuotaSettingsFactory
233        .throttleUser(userName, TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
234    admin.setQuota(QuotaSettingsFactory
235        .throttleUser(userName, TABLE_NAMES[0], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
236    admin.setQuota(QuotaSettingsFactory
237        .throttleUser(userName01, TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER, 6,
238            TimeUnit.MINUTES));
239    admin.setQuota(QuotaSettingsFactory
240        .throttleUser(userName01, TABLE_NAMES[1], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
241    admin.setQuota(QuotaSettingsFactory
242        .unthrottleUserByThrottleType(userName, TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER));
243    assertEquals(3, getQuotaSettingCount(admin));
244    admin.setQuota(QuotaSettingsFactory
245        .unthrottleUserByThrottleType(userName, TABLE_NAMES[0], ThrottleType.REQUEST_SIZE));
246    assertEquals(2, getQuotaSettingCount(admin));
247  }
248
249  @Test
250  public void testUserNameSpaceUnThrottleByType() throws Exception {
251    final Admin admin = TEST_UTIL.getAdmin();
252    final String userName = User.getCurrent().getShortName();
253    String userName01 = "user01";
254    // Add 6req/min limit
255    admin.setQuota(QuotaSettingsFactory
256        .throttleUser(userName, NAMESPACES[0], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
257    admin.setQuota(QuotaSettingsFactory
258        .throttleUser(userName, NAMESPACES[0], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
259    admin.setQuota(QuotaSettingsFactory
260        .throttleUser(userName01, NAMESPACES[1], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
261    admin.setQuota(QuotaSettingsFactory
262        .throttleUser(userName01, NAMESPACES[1], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
263    admin.setQuota(QuotaSettingsFactory
264        .unthrottleUserByThrottleType(userName, NAMESPACES[0], ThrottleType.REQUEST_NUMBER));
265    assertEquals(3, getQuotaSettingCount(admin));
266    admin.setQuota(QuotaSettingsFactory
267        .unthrottleUserByThrottleType(userName, NAMESPACES[0], ThrottleType.REQUEST_SIZE));
268    assertEquals(2, getQuotaSettingCount(admin));
269  }
270
271  @Test
272  public void testTableUnThrottleByType() throws Exception {
273    final Admin admin = TEST_UTIL.getAdmin();
274    final String userName = User.getCurrent().getShortName();
275    // Add 6req/min limit
276    admin.setQuota(QuotaSettingsFactory
277        .throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
278    admin.setQuota(QuotaSettingsFactory
279        .throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
280    admin.setQuota(QuotaSettingsFactory
281        .throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
282    admin.setQuota(QuotaSettingsFactory
283        .throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
284    admin.setQuota(QuotaSettingsFactory
285        .unthrottleTableByThrottleType(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER));
286    assertEquals(3, getQuotaSettingCount(admin));
287    admin.setQuota(QuotaSettingsFactory
288        .unthrottleTableByThrottleType(TABLE_NAMES[0], ThrottleType.REQUEST_SIZE));
289    assertEquals(2, getQuotaSettingCount(admin));
290  }
291
292  @Test
293  public void testNameSpaceUnThrottleByType() throws Exception {
294    final Admin admin = TEST_UTIL.getAdmin();
295    final String userName = User.getCurrent().getShortName();
296    // Add 6req/min limit
297    admin.setQuota(QuotaSettingsFactory
298        .throttleNamespace(NAMESPACES[0], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
299    admin.setQuota(QuotaSettingsFactory
300        .throttleNamespace(NAMESPACES[0], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
301    admin.setQuota(QuotaSettingsFactory
302        .throttleNamespace(NAMESPACES[1], ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
303    admin.setQuota(QuotaSettingsFactory
304        .throttleNamespace(NAMESPACES[1], ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
305    admin.setQuota(QuotaSettingsFactory
306        .unthrottleNamespaceByThrottleType(NAMESPACES[0], ThrottleType.REQUEST_NUMBER));
307    assertEquals(3, getQuotaSettingCount(admin));
308    admin.setQuota(QuotaSettingsFactory
309        .unthrottleNamespaceByThrottleType(NAMESPACES[0], ThrottleType.REQUEST_SIZE));
310    assertEquals(2, getQuotaSettingCount(admin));
311  }
312
313  @Test
314  public void testRegionServerUnThrottleByType() throws Exception {
315    final Admin admin = TEST_UTIL.getAdmin();
316    final String[] REGIONSERVER = { "RS01", "RS02" };
317
318    admin.setQuota(QuotaSettingsFactory
319        .throttleRegionServer(REGIONSERVER[0], ThrottleType.READ_NUMBER, 4, TimeUnit.MINUTES));
320    admin.setQuota(QuotaSettingsFactory
321        .throttleRegionServer(REGIONSERVER[0], ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
322    admin.setQuota(QuotaSettingsFactory
323        .throttleRegionServer(REGIONSERVER[1], ThrottleType.READ_NUMBER, 4, TimeUnit.MINUTES));
324    admin.setQuota(QuotaSettingsFactory
325        .throttleRegionServer(REGIONSERVER[1], ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
326
327    admin.setQuota(QuotaSettingsFactory
328        .unthrottleRegionServerByThrottleType(REGIONSERVER[0], ThrottleType.READ_NUMBER));
329    assertEquals(3, getQuotaSettingCount(admin));
330    admin.setQuota(QuotaSettingsFactory
331        .unthrottleRegionServerByThrottleType(REGIONSERVER[0], ThrottleType.WRITE_NUMBER));
332    assertEquals(2, getQuotaSettingCount(admin));
333  }
334
335  public int getQuotaSettingCount(Admin admin) throws IOException {
336    List<QuotaSettings> list_quotas = admin.getQuota(new QuotaFilter());
337    int quotaSettingCount = 0;
338    for (QuotaSettings setting : list_quotas) {
339      quotaSettingCount++;
340      LOG.info("Quota Setting:" + setting);
341    }
342    return quotaSettingCount;
343  }
344
345  @Test
346  public void testUserTableReadAndWriteThrottle() throws Exception {
347    final Admin admin = TEST_UTIL.getAdmin();
348    final String userName = User.getCurrent().getShortName();
349
350    // Add 6req/min limit for write request on tables[0]
351    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
352      ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES));
353    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
354
355    // should execute at max 6 write requests and have no limit for read request
356    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
357    assertEquals(60, doGets(60, tables[0]));
358
359    // no limit on tables[1]
360    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[1]));
361    assertEquals(60, doGets(60, tables[1]));
362
363    // wait a minute and you should get other 6 write requests executed
364    waitMinuteQuota();
365
366    // Add 6req/min limit for read request on tables[0]
367    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
368      ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
369    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
370
371    // should execute at max 6 read requests and at max 6 write requests
372    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
373    assertEquals(6, doGets(60, tables[0]));
374
375    // no limit on tables[1]
376    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
377    assertEquals(30, doGets(30, tables[1]));
378
379    // Remove all the limits
380    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
381    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
382    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
383    assertEquals(60, doGets(60, tables));
384  }
385
386  @Test
387  public void testUserNamespaceThrottle() throws Exception {
388    final Admin admin = TEST_UTIL.getAdmin();
389    final String userName = User.getCurrent().getShortName();
390    final String NAMESPACE = "default";
391
392    // Add 6req/min limit
393    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE,
394      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
395    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
396
397    // should execute at max 6 requests on tables[0] and have no limit on tables[1]
398    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
399
400    // wait a minute and you should get other 6 requests executed
401    waitMinuteQuota();
402    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1]));
403
404    // Remove all the limits
405    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE));
406    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
407    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
408    assertEquals(60, doGets(60, tables));
409  }
410
411  @Test
412  public void testUserNamespaceReadAndWriteThrottle() throws Exception {
413    final Admin admin = TEST_UTIL.getAdmin();
414    final String userName = User.getCurrent().getShortName();
415    final String NAMESPACE = "default";
416
417    // Add 6req/min limit for read request
418    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.READ_NUMBER,
419      6, TimeUnit.MINUTES));
420    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
421
422    // should execute at max 6 read requests and have no limit for write request
423    assertEquals(6, doGets(60, tables[0]));
424    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[0]));
425
426    waitMinuteQuota();
427
428    // Add 6req/min limit for write request, too
429    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.WRITE_NUMBER,
430      6, TimeUnit.MINUTES));
431    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
432
433    // should execute at max 6 read requests and at max 6 write requests
434    assertEquals(6, doGets(60, tables[0]));
435    assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables[0]));
436
437    // Remove all the limits
438    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE));
439    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
440    assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
441    assertEquals(60, doGets(60, tables));
442  }
443
444  @Test
445  public void testTableGlobalThrottle() throws Exception {
446    final Admin admin = TEST_UTIL.getAdmin();
447
448    // Add 6req/min limit
449    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
450      6, TimeUnit.MINUTES));
451    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
452
453    // should execute at max 6 requests
454    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
455    // should have no limits
456    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
457
458    // wait a minute and you should get other 6 requests executed
459    waitMinuteQuota();
460    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
461
462    // Remove all the limits
463    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
464    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
465    assertEquals(80, doGets(80, tables[0], tables[1]));
466  }
467
468  @Test
469  public void testTableGlobalReadAndWriteThrottle() throws Exception {
470    final Admin admin = TEST_UTIL.getAdmin();
471
472    // Add 6req/min limit for read request
473    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.READ_NUMBER, 6,
474      TimeUnit.MINUTES));
475    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
476
477    // should execute at max 6 read requests and have no limit for write request
478    assertEquals(6, doGets(100, tables[0]));
479    assertEquals(100, doPuts(100, FAMILY, QUALIFIER, tables[0]));
480    // should have no limits on tables[1]
481    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
482    assertEquals(30, doGets(30, tables[1]));
483
484    // wait a minute and you should get other 6 requests executed
485    waitMinuteQuota();
486
487    // Add 6req/min limit for write request, too
488    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 6,
489      TimeUnit.MINUTES));
490    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
491
492    // should execute at max 6 read requests and at max 6 write requests
493    assertEquals(6, doGets(100, tables[0]));
494    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
495    // should have no limits on tables[1]
496    assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
497    assertEquals(30, doGets(30, tables[1]));
498
499    // Remove all the limits
500    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
501    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
502    assertEquals(80, doGets(80, tables[0], tables[1]));
503  }
504
505  @Test
506  public void testNamespaceGlobalThrottle() throws Exception {
507    final Admin admin = TEST_UTIL.getAdmin();
508    final String NAMESPACE = "default";
509
510    // Add 6req/min limit
511    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 6,
512      TimeUnit.MINUTES));
513    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
514
515    // should execute at max 6 requests
516    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
517
518    // wait a minute and you should get other 6 requests executed
519    waitMinuteQuota();
520    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1]));
521
522    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
523    triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
524    assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0]));
525  }
526
527  @Test
528  public void testNamespaceGlobalReadAndWriteThrottle() throws Exception {
529    final Admin admin = TEST_UTIL.getAdmin();
530    final String NAMESPACE = "default";
531
532    // Add 6req/min limit for write request
533    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.WRITE_NUMBER, 6,
534      TimeUnit.MINUTES));
535    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
536
537    // should execute at max 6 write requests and no limit for read request
538    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
539    assertEquals(100, doGets(100, tables[0]));
540
541    // wait a minute and you should get other 6 requests executed
542    waitMinuteQuota();
543
544    // Add 6req/min limit for read request, too
545    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.READ_NUMBER, 6,
546      TimeUnit.MINUTES));
547    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
548
549    // should execute at max 6 write requests and at max 6 read requests
550    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
551    assertEquals(6, doGets(100, tables[0]));
552
553    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
554    triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
555    assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0]));
556  }
557
558  @Test
559  public void testUserAndTableThrottle() throws Exception {
560    final Admin admin = TEST_UTIL.getAdmin();
561    final String userName = User.getCurrent().getShortName();
562
563    // Add 6req/min limit for the user on tables[0]
564    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
565      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
566    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
567    // Add 12req/min limit for the user
568    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 12,
569      TimeUnit.MINUTES));
570    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1], TABLE_NAMES[2]);
571    // Add 8req/min limit for the tables[1]
572    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER,
573      8, TimeUnit.MINUTES));
574    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]);
575    // Add a lower table level throttle on tables[0]
576    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
577      3, TimeUnit.MINUTES));
578    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
579
580    // should execute at max 12 requests
581    assertEquals(12, doGets(100, tables[2]));
582
583    // should execute at max 8 requests
584    waitMinuteQuota();
585    assertEquals(8, doGets(100, tables[1]));
586
587    // should execute at max 3 requests
588    waitMinuteQuota();
589    assertEquals(3, doPuts(100, FAMILY, QUALIFIER, tables[0]));
590
591    // Remove all the throttling rules
592    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
593    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
594    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0], TABLE_NAMES[1]);
595
596    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[1]));
597    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]);
598    waitMinuteQuota();
599    assertEquals(40, doGets(40, tables[1]));
600
601    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
602    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
603    waitMinuteQuota();
604    assertEquals(40, doGets(40, tables[0]));
605  }
606
607  @Test
608  public void testUserGlobalBypassThrottle() throws Exception {
609    final Admin admin = TEST_UTIL.getAdmin();
610    final String userName = User.getCurrent().getShortName();
611    final String NAMESPACE = "default";
612
613    // Add 6req/min limit for tables[0]
614    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
615      6, TimeUnit.MINUTES));
616    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
617    // Add 13req/min limit for the user
618    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER,
619      13, TimeUnit.MINUTES));
620    triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]);
621
622    // should execute at max 6 requests on table[0] and (13 - 6) on table[1]
623    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
624    assertEquals(7, doGets(100, tables[1]));
625    waitMinuteQuota();
626
627    // Set the global bypass for the user
628    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true));
629    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[2],
630      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
631    triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[2]);
632    assertEquals(30, doGets(30, tables[0]));
633    assertEquals(30, doGets(30, tables[1]));
634    waitMinuteQuota();
635
636    // Remove the global bypass
637    // should execute at max 6 requests on table[0] and (13 - 6) on table[1]
638    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false));
639    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[2]));
640    triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[2]);
641    assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
642    assertEquals(7, doGets(100, tables[1]));
643
644    // unset throttle
645    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
646    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
647    waitMinuteQuota();
648    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
649    triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]);
650    assertEquals(30, doGets(30, tables[0]));
651    assertEquals(30, doGets(30, tables[1]));
652  }
653
654  @Test
655  public void testTableWriteCapacityUnitThrottle() throws Exception {
656    final Admin admin = TEST_UTIL.getAdmin();
657
658    // Add 6CU/min limit
659    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0],
660      ThrottleType.WRITE_CAPACITY_UNIT, 6, TimeUnit.MINUTES));
661    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
662
663    // should execute at max 6 capacity units because each put size is 1 capacity unit
664    assertEquals(6, doPuts(20, 10, FAMILY, QUALIFIER, tables[0]));
665
666    // wait a minute and you should execute at max 3 capacity units because each put size is 2
667    // capacity unit
668    waitMinuteQuota();
669    assertEquals(3, doPuts(20, 1025, FAMILY, QUALIFIER, tables[0]));
670
671    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
672    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
673  }
674
675  @Test
676  public void testTableReadCapacityUnitThrottle() throws Exception {
677    final Admin admin = TEST_UTIL.getAdmin();
678
679    // Add 6CU/min limit
680    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0],
681      ThrottleType.READ_CAPACITY_UNIT, 6, TimeUnit.MINUTES));
682    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
683
684    assertEquals(20, doPuts(20, 10, FAMILY, QUALIFIER, tables[0]));
685    // should execute at max 6 capacity units because each get size is 1 capacity unit
686    assertEquals(6, doGets(20, tables[0]));
687
688    assertEquals(20, doPuts(20, 2015, FAMILY, QUALIFIER, tables[0]));
689    // wait a minute and you should execute at max 3 capacity units because each get size is 2
690    // capacity unit on tables[0]
691    waitMinuteQuota();
692    assertEquals(3, doGets(20, tables[0]));
693
694    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
695    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
696  }
697
698  @Test
699  public void testTableExistsGetThrottle() throws Exception {
700    final Admin admin = TEST_UTIL.getAdmin();
701
702    // Add throttle quota
703    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
704      100, TimeUnit.MINUTES));
705    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
706
707    Table table = TEST_UTIL.getConnection().getTable(TABLE_NAMES[0]);
708    // An exists call when having throttle quota
709    table.exists(new Get(Bytes.toBytes("abc")));
710
711    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
712    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
713  }
714
715  @Test
716  public void testRegionServerThrottle() throws Exception {
717    final Admin admin = TEST_UTIL.getAdmin();
718    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5,
719      TimeUnit.MINUTES));
720
721    // requests are throttled by table quota
722    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
723      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 7, TimeUnit.MINUTES));
724    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
725    triggerRegionServerCacheRefresh(TEST_UTIL, false);
726    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
727    triggerRegionServerCacheRefresh(TEST_UTIL, false);
728    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
729
730    // requests are throttled by region server quota
731    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
732      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
733    triggerRegionServerCacheRefresh(TEST_UTIL, false);
734    assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0]));
735    triggerRegionServerCacheRefresh(TEST_UTIL, false);
736    assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0]));
737
738    // unthrottle
739    admin.setQuota(
740      QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY));
741    triggerRegionServerCacheRefresh(TEST_UTIL, true);
742    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
743    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
744    triggerRegionServerCacheRefresh(TEST_UTIL, true);
745  }
746
747  @Test
748  public void testExceedThrottleQuota() throws Exception {
749    final Admin admin = TEST_UTIL.getAdmin();
750    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5,
751      TimeUnit.MINUTES));
752    triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
753    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
754      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS));
755    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
756      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.READ_NUMBER, 10, TimeUnit.SECONDS));
757    triggerRegionServerCacheRefresh(TEST_UTIL, false);
758
759    // enable exceed throttle quota
760    admin.exceedThrottleQuotaSwitch(true);
761    // exceed table limit and allowed by region server limit
762    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true);
763    waitMinuteQuota();
764    assertEquals(10, doPuts(10, FAMILY, QUALIFIER, tables[0]));
765    // exceed table limit and throttled by region server limit
766    waitMinuteQuota();
767    assertEquals(20, doPuts(25, FAMILY, QUALIFIER, tables[0]));
768
769    // set region server limiter is lower than table limiter
770    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
771      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 2, TimeUnit.SECONDS));
772    triggerRegionServerCacheRefresh(TEST_UTIL, false);
773    // throttled by region server limiter
774    waitMinuteQuota();
775    assertEquals(2, doPuts(10, FAMILY, QUALIFIER, tables[0]));
776    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
777      QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS));
778    triggerRegionServerCacheRefresh(TEST_UTIL, false);
779
780    // disable exceed throttle quota
781    admin.exceedThrottleQuotaSwitch(false);
782    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false);
783    waitMinuteQuota();
784    // throttled by table limit
785    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
786
787    // enable exceed throttle quota and unthrottle region server
788    admin.exceedThrottleQuotaSwitch(true);
789    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true);
790    waitMinuteQuota();
791    admin.setQuota(
792      QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY));
793    triggerRegionServerCacheRefresh(TEST_UTIL, true);
794    waitMinuteQuota();
795    // throttled by table limit
796    assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
797
798    // disable exceed throttle quota
799    admin.exceedThrottleQuotaSwitch(false);
800    triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false);
801    // unthrottle table
802    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
803    triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
804  }
805}