001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.quotas;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertNull;
023import static org.junit.Assert.assertTrue;
024import static org.junit.Assert.fail;
025
026import java.io.IOException;
027import java.util.ArrayList;
028import java.util.List;
029import java.util.Objects;
030import java.util.concurrent.TimeUnit;
031import org.apache.hadoop.hbase.Cell;
032import org.apache.hadoop.hbase.CellScanner;
033import org.apache.hadoop.hbase.HBaseClassTestRule;
034import org.apache.hadoop.hbase.HBaseTestingUtility;
035import org.apache.hadoop.hbase.HConstants;
036import org.apache.hadoop.hbase.TableName;
037import org.apache.hadoop.hbase.client.Admin;
038import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
039import org.apache.hadoop.hbase.client.Put;
040import org.apache.hadoop.hbase.client.Result;
041import org.apache.hadoop.hbase.client.ResultScanner;
042import org.apache.hadoop.hbase.client.Scan;
043import org.apache.hadoop.hbase.client.Table;
044import org.apache.hadoop.hbase.client.TableDescriptor;
045import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
046import org.apache.hadoop.hbase.security.User;
047import org.apache.hadoop.hbase.testclassification.ClientTests;
048import org.apache.hadoop.hbase.testclassification.LargeTests;
049import org.apache.hadoop.hbase.util.Bytes;
050import org.apache.hadoop.hbase.util.JVMClusterUtil;
051import org.junit.After;
052import org.junit.AfterClass;
053import org.junit.Assert;
054import org.junit.BeforeClass;
055import org.junit.ClassRule;
056import org.junit.Test;
057import org.junit.experimental.categories.Category;
058import org.slf4j.Logger;
059import org.slf4j.LoggerFactory;
060
061import org.apache.hbase.thirdparty.com.google.common.collect.Iterables;
062
063import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
064import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos;
065import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas;
066import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceLimitRequest;
067
068/**
069 * minicluster tests that validate that quota entries are properly set in the quota table
070 */
071@Category({ ClientTests.class, LargeTests.class })
072public class TestQuotaAdmin {
073
074  @ClassRule
075  public static final HBaseClassTestRule CLASS_RULE =
076    HBaseClassTestRule.forClass(TestQuotaAdmin.class);
077
078  private static final Logger LOG = LoggerFactory.getLogger(TestQuotaAdmin.class);
079
080  private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
081
082  private final static TableName[] TABLE_NAMES =
083    new TableName[] { TableName.valueOf("TestQuotaAdmin0"), TableName.valueOf("TestQuotaAdmin1"),
084      TableName.valueOf("TestQuotaAdmin2") };
085
086  private final static String[] NAMESPACES =
087    new String[] { "NAMESPACE01", "NAMESPACE02", "NAMESPACE03" };
088
089  @BeforeClass
090  public static void setUpBeforeClass() throws Exception {
091    TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
092    TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, 2000);
093    TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
094    TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
095    TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
096    TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
097    TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
098    TEST_UTIL.startMiniCluster(1);
099    TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
100  }
101
102  @After
103  public void clearQuotaTable() throws Exception {
104    if (TEST_UTIL.getAdmin().tableExists(QuotaUtil.QUOTA_TABLE_NAME)) {
105      TEST_UTIL.getAdmin().disableTable(QuotaUtil.QUOTA_TABLE_NAME);
106      TEST_UTIL.getAdmin().truncateTable(QuotaUtil.QUOTA_TABLE_NAME, false);
107    }
108  }
109
110  @AfterClass
111  public static void tearDownAfterClass() throws Exception {
112    TEST_UTIL.shutdownMiniCluster();
113  }
114
115  @Test
116  public void testThrottleType() throws Exception {
117    Admin admin = TEST_UTIL.getAdmin();
118    String userName = User.getCurrent().getShortName();
119
120    admin.setQuota(
121      QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
122    admin.setQuota(
123      QuotaSettingsFactory.throttleUser(userName, ThrottleType.WRITE_NUMBER, 12, TimeUnit.MINUTES));
124    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true));
125
126    try (QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration())) {
127      int countThrottle = 0;
128      int countGlobalBypass = 0;
129      for (QuotaSettings settings : scanner) {
130        switch (settings.getQuotaType()) {
131          case THROTTLE:
132            ThrottleSettings throttle = (ThrottleSettings) settings;
133            if (throttle.getSoftLimit() == 6) {
134              assertEquals(ThrottleType.READ_NUMBER, throttle.getThrottleType());
135            } else if (throttle.getSoftLimit() == 12) {
136              assertEquals(ThrottleType.WRITE_NUMBER, throttle.getThrottleType());
137            } else {
138              fail("should not come here, because don't set quota with this limit");
139            }
140            assertEquals(userName, throttle.getUserName());
141            assertEquals(null, throttle.getTableName());
142            assertEquals(null, throttle.getNamespace());
143            assertEquals(TimeUnit.MINUTES, throttle.getTimeUnit());
144            countThrottle++;
145            break;
146          case GLOBAL_BYPASS:
147            countGlobalBypass++;
148            break;
149          default:
150            fail("unexpected settings type: " + settings.getQuotaType());
151        }
152      }
153      assertEquals(2, countThrottle);
154      assertEquals(1, countGlobalBypass);
155    }
156
157    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
158    assertNumResults(1, null);
159    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false));
160    assertNumResults(0, null);
161  }
162
163  @Test
164  public void testSimpleScan() throws Exception {
165    Admin admin = TEST_UTIL.getAdmin();
166    String userName = User.getCurrent().getShortName();
167
168    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6,
169      TimeUnit.MINUTES));
170    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true));
171
172    try (QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration())) {
173      int countThrottle = 0;
174      int countGlobalBypass = 0;
175      for (QuotaSettings settings : scanner) {
176        LOG.debug(Objects.toString(settings));
177        switch (settings.getQuotaType()) {
178          case THROTTLE:
179            ThrottleSettings throttle = (ThrottleSettings) settings;
180            assertEquals(userName, throttle.getUserName());
181            assertEquals(null, throttle.getTableName());
182            assertEquals(null, throttle.getNamespace());
183            assertEquals(null, throttle.getRegionServer());
184            assertEquals(6, throttle.getSoftLimit());
185            assertEquals(TimeUnit.MINUTES, throttle.getTimeUnit());
186            countThrottle++;
187            break;
188          case GLOBAL_BYPASS:
189            countGlobalBypass++;
190            break;
191          default:
192            fail("unexpected settings type: " + settings.getQuotaType());
193        }
194      }
195      assertEquals(1, countThrottle);
196      assertEquals(1, countGlobalBypass);
197    }
198
199    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
200    assertNumResults(1, null);
201    admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false));
202    assertNumResults(0, null);
203  }
204
205  @Test
206  public void testMultiQuotaThrottling() throws Exception {
207    byte[] FAMILY = Bytes.toBytes("testFamily");
208    byte[] ROW = Bytes.toBytes("testRow");
209    byte[] QUALIFIER = Bytes.toBytes("testQualifier");
210    byte[] VALUE = Bytes.toBytes("testValue");
211
212    Admin admin = TEST_UTIL.getAdmin();
213    TableName tableName = TableName.valueOf("testMultiQuotaThrottling");
214    TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
215      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).build();
216    admin.createTable(desc);
217
218    // Set up the quota.
219    admin.setQuota(QuotaSettingsFactory.throttleTable(tableName, ThrottleType.WRITE_NUMBER, 6,
220      TimeUnit.SECONDS));
221
222    Thread.sleep(1000);
223    TEST_UTIL.getRSForFirstRegionInTable(tableName).getRegionServerRpcQuotaManager().getQuotaCache()
224      .triggerCacheRefresh();
225    Thread.sleep(1000);
226
227    Table t = TEST_UTIL.getConnection().getTable(tableName);
228    try {
229      int size = 5;
230      List actions = new ArrayList();
231      Object[] results = new Object[size];
232
233      for (int i = 0; i < size; i++) {
234        Put put1 = new Put(ROW);
235        put1.addColumn(FAMILY, QUALIFIER, VALUE);
236        actions.add(put1);
237      }
238      t.batch(actions, results);
239      t.batch(actions, results);
240    } catch (IOException e) {
241      fail("Not supposed to get ThrottlingExcepiton " + e);
242    } finally {
243      t.close();
244    }
245  }
246
247  @Test
248  public void testQuotaRetrieverFilter() throws Exception {
249    Admin admin = TEST_UTIL.getAdmin();
250    TableName[] tables = new TableName[] { TableName.valueOf("T0"), TableName.valueOf("T01"),
251      TableName.valueOf("NS0:T2"), };
252    String[] namespaces = new String[] { "NS0", "NS01", "NS2" };
253    String[] users = new String[] { "User0", "User01", "User2" };
254
255    for (String user : users) {
256      admin.setQuota(
257        QuotaSettingsFactory.throttleUser(user, ThrottleType.REQUEST_NUMBER, 1, TimeUnit.MINUTES));
258
259      for (TableName table : tables) {
260        admin.setQuota(QuotaSettingsFactory.throttleUser(user, table, ThrottleType.REQUEST_NUMBER,
261          2, TimeUnit.MINUTES));
262      }
263
264      for (String ns : namespaces) {
265        admin.setQuota(QuotaSettingsFactory.throttleUser(user, ns, ThrottleType.REQUEST_NUMBER, 3,
266          TimeUnit.MINUTES));
267      }
268    }
269    assertNumResults(21, null);
270
271    for (TableName table : tables) {
272      admin.setQuota(QuotaSettingsFactory.throttleTable(table, ThrottleType.REQUEST_NUMBER, 4,
273        TimeUnit.MINUTES));
274    }
275    assertNumResults(24, null);
276
277    for (String ns : namespaces) {
278      admin.setQuota(QuotaSettingsFactory.throttleNamespace(ns, ThrottleType.REQUEST_NUMBER, 5,
279        TimeUnit.MINUTES));
280    }
281    assertNumResults(27, null);
282
283    assertNumResults(7, new QuotaFilter().setUserFilter("User0"));
284    assertNumResults(0, new QuotaFilter().setUserFilter("User"));
285    assertNumResults(21, new QuotaFilter().setUserFilter("User.*"));
286    assertNumResults(3, new QuotaFilter().setUserFilter("User.*").setTableFilter("T0"));
287    assertNumResults(3, new QuotaFilter().setUserFilter("User.*").setTableFilter("NS.*"));
288    assertNumResults(0, new QuotaFilter().setUserFilter("User.*").setTableFilter("T"));
289    assertNumResults(6, new QuotaFilter().setUserFilter("User.*").setTableFilter("T.*"));
290    assertNumResults(3, new QuotaFilter().setUserFilter("User.*").setNamespaceFilter("NS0"));
291    assertNumResults(0, new QuotaFilter().setUserFilter("User.*").setNamespaceFilter("NS"));
292    assertNumResults(9, new QuotaFilter().setUserFilter("User.*").setNamespaceFilter("NS.*"));
293    assertNumResults(6,
294      new QuotaFilter().setUserFilter("User.*").setTableFilter("T0").setNamespaceFilter("NS0"));
295    assertNumResults(1, new QuotaFilter().setTableFilter("T0"));
296    assertNumResults(0, new QuotaFilter().setTableFilter("T"));
297    assertNumResults(2, new QuotaFilter().setTableFilter("T.*"));
298    assertNumResults(3, new QuotaFilter().setTableFilter(".*T.*"));
299    assertNumResults(1, new QuotaFilter().setNamespaceFilter("NS0"));
300    assertNumResults(0, new QuotaFilter().setNamespaceFilter("NS"));
301    assertNumResults(3, new QuotaFilter().setNamespaceFilter("NS.*"));
302
303    for (String user : users) {
304      admin.setQuota(QuotaSettingsFactory.unthrottleUser(user));
305      for (TableName table : tables) {
306        admin.setQuota(QuotaSettingsFactory.unthrottleUser(user, table));
307      }
308      for (String ns : namespaces) {
309        admin.setQuota(QuotaSettingsFactory.unthrottleUser(user, ns));
310      }
311    }
312    assertNumResults(6, null);
313
314    for (TableName table : tables) {
315      admin.setQuota(QuotaSettingsFactory.unthrottleTable(table));
316    }
317    assertNumResults(3, null);
318
319    for (String ns : namespaces) {
320      admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(ns));
321    }
322    assertNumResults(0, null);
323  }
324
325  @Test
326  public void testSetGetRemoveSpaceQuota() throws Exception {
327    Admin admin = TEST_UTIL.getAdmin();
328    final TableName tn = TableName.valueOf("sq_table1");
329    final long sizeLimit = 1024L * 1024L * 1024L * 1024L * 5L; // 5TB
330    final SpaceViolationPolicy violationPolicy = SpaceViolationPolicy.NO_WRITES;
331    QuotaSettings settings = QuotaSettingsFactory.limitTableSpace(tn, sizeLimit, violationPolicy);
332    admin.setQuota(settings);
333
334    // Verify the Quotas in the table
335    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) {
336      ResultScanner scanner = quotaTable.getScanner(new Scan());
337      try {
338        Result r = Iterables.getOnlyElement(scanner);
339        CellScanner cells = r.cellScanner();
340        assertTrue("Expected to find a cell", cells.advance());
341        assertSpaceQuota(sizeLimit, violationPolicy, cells.current());
342      } finally {
343        scanner.close();
344      }
345    }
346
347    // Verify we can retrieve it via the QuotaRetriever API
348    QuotaRetriever scanner = QuotaRetriever.open(admin.getConfiguration());
349    try {
350      assertSpaceQuota(sizeLimit, violationPolicy, Iterables.getOnlyElement(scanner));
351    } finally {
352      scanner.close();
353    }
354
355    // Now, remove the quota
356    QuotaSettings removeQuota = QuotaSettingsFactory.removeTableSpaceLimit(tn);
357    admin.setQuota(removeQuota);
358
359    // Verify that the record doesn't exist in the table
360    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) {
361      ResultScanner rs = quotaTable.getScanner(new Scan());
362      try {
363        assertNull("Did not expect to find a quota entry", rs.next());
364      } finally {
365        rs.close();
366      }
367    }
368
369    // Verify that we can also not fetch it via the API
370    scanner = QuotaRetriever.open(admin.getConfiguration());
371    try {
372      assertNull("Did not expect to find a quota entry", scanner.next());
373    } finally {
374      scanner.close();
375    }
376  }
377
378  @Test
379  public void testSetModifyRemoveSpaceQuota() throws Exception {
380    Admin admin = TEST_UTIL.getAdmin();
381    final TableName tn = TableName.valueOf("sq_table2");
382    final long originalSizeLimit = 1024L * 1024L * 1024L * 1024L * 5L; // 5TB
383    final SpaceViolationPolicy violationPolicy = SpaceViolationPolicy.NO_WRITES;
384    QuotaSettings settings =
385      QuotaSettingsFactory.limitTableSpace(tn, originalSizeLimit, violationPolicy);
386    admin.setQuota(settings);
387
388    // Verify the Quotas in the table
389    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) {
390      ResultScanner scanner = quotaTable.getScanner(new Scan());
391      try {
392        Result r = Iterables.getOnlyElement(scanner);
393        CellScanner cells = r.cellScanner();
394        assertTrue("Expected to find a cell", cells.advance());
395        assertSpaceQuota(originalSizeLimit, violationPolicy, cells.current());
396      } finally {
397        scanner.close();
398      }
399    }
400
401    // Verify we can retrieve it via the QuotaRetriever API
402    QuotaRetriever quotaScanner = QuotaRetriever.open(admin.getConfiguration());
403    try {
404      assertSpaceQuota(originalSizeLimit, violationPolicy, Iterables.getOnlyElement(quotaScanner));
405    } finally {
406      quotaScanner.close();
407    }
408
409    // Setting a new size and policy should be reflected
410    final long newSizeLimit = 1024L * 1024L * 1024L * 1024L; // 1TB
411    final SpaceViolationPolicy newViolationPolicy = SpaceViolationPolicy.NO_WRITES_COMPACTIONS;
412    QuotaSettings newSettings =
413      QuotaSettingsFactory.limitTableSpace(tn, newSizeLimit, newViolationPolicy);
414    admin.setQuota(newSettings);
415
416    // Verify the new Quotas in the table
417    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) {
418      ResultScanner scanner = quotaTable.getScanner(new Scan());
419      try {
420        Result r = Iterables.getOnlyElement(scanner);
421        CellScanner cells = r.cellScanner();
422        assertTrue("Expected to find a cell", cells.advance());
423        assertSpaceQuota(newSizeLimit, newViolationPolicy, cells.current());
424      } finally {
425        scanner.close();
426      }
427    }
428
429    // Verify we can retrieve the new quota via the QuotaRetriever API
430    quotaScanner = QuotaRetriever.open(admin.getConfiguration());
431    try {
432      assertSpaceQuota(newSizeLimit, newViolationPolicy, Iterables.getOnlyElement(quotaScanner));
433    } finally {
434      quotaScanner.close();
435    }
436
437    // Now, remove the quota
438    QuotaSettings removeQuota = QuotaSettingsFactory.removeTableSpaceLimit(tn);
439    admin.setQuota(removeQuota);
440
441    // Verify that the record doesn't exist in the table
442    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME)) {
443      ResultScanner scanner = quotaTable.getScanner(new Scan());
444      try {
445        assertNull("Did not expect to find a quota entry", scanner.next());
446      } finally {
447        scanner.close();
448      }
449    }
450
451    // Verify that we can also not fetch it via the API
452    quotaScanner = QuotaRetriever.open(admin.getConfiguration());
453    try {
454      assertNull("Did not expect to find a quota entry", quotaScanner.next());
455    } finally {
456      quotaScanner.close();
457    }
458  }
459
460  private void assertNumResults(int expected, final QuotaFilter filter) throws Exception {
461    assertEquals(expected, countResults(filter));
462  }
463
464  @Test
465  public void testSetGetRemoveRPCQuota() throws Exception {
466    testSetGetRemoveRPCQuota(ThrottleType.REQUEST_SIZE);
467    testSetGetRemoveRPCQuota(ThrottleType.REQUEST_CAPACITY_UNIT);
468  }
469
470  private void testSetGetRemoveRPCQuota(ThrottleType throttleType) throws Exception {
471    Admin admin = TEST_UTIL.getAdmin();
472    final TableName tn = TableName.valueOf("sq_table1");
473    QuotaSettings settings =
474      QuotaSettingsFactory.throttleTable(tn, throttleType, 2L, TimeUnit.HOURS);
475    admin.setQuota(settings);
476
477    // Verify the Quota in the table
478    verifyRecordPresentInQuotaTable(throttleType, 2L, TimeUnit.HOURS);
479
480    // Verify we can retrieve it via the QuotaRetriever API
481    verifyFetchableViaAPI(admin, throttleType, 2L, TimeUnit.HOURS);
482
483    // Now, remove the quota
484    QuotaSettings removeQuota = QuotaSettingsFactory.unthrottleTable(tn);
485    admin.setQuota(removeQuota);
486
487    // Verify that the record doesn't exist in the table
488    verifyRecordNotPresentInQuotaTable();
489
490    // Verify that we can also not fetch it via the API
491    verifyNotFetchableViaAPI(admin);
492  }
493
494  @Test
495  public void testSetModifyRemoveRPCQuota() throws Exception {
496    Admin admin = TEST_UTIL.getAdmin();
497    final TableName tn = TableName.valueOf("sq_table1");
498    QuotaSettings settings =
499      QuotaSettingsFactory.throttleTable(tn, ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS);
500    admin.setQuota(settings);
501
502    // Verify the Quota in the table
503    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS);
504
505    // Verify we can retrieve it via the QuotaRetriever API
506    verifyFetchableViaAPI(admin, ThrottleType.REQUEST_SIZE, 2L, TimeUnit.HOURS);
507
508    // Setting a limit and time unit should be reflected
509    QuotaSettings newSettings =
510      QuotaSettingsFactory.throttleTable(tn, ThrottleType.REQUEST_SIZE, 3L, TimeUnit.DAYS);
511    admin.setQuota(newSettings);
512
513    // Verify the new Quota in the table
514    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_SIZE, 3L, TimeUnit.DAYS);
515
516    // Verify we can retrieve the new quota via the QuotaRetriever API
517    verifyFetchableViaAPI(admin, ThrottleType.REQUEST_SIZE, 3L, TimeUnit.DAYS);
518
519    // Now, remove the quota
520    QuotaSettings removeQuota = QuotaSettingsFactory.unthrottleTable(tn);
521    admin.setQuota(removeQuota);
522
523    // Verify that the record doesn't exist in the table
524    verifyRecordNotPresentInQuotaTable();
525
526    // Verify that we can also not fetch it via the API
527    verifyNotFetchableViaAPI(admin);
528
529  }
530
531  @Test
532  public void testSetAndRemoveRegionServerQuota() throws Exception {
533    Admin admin = TEST_UTIL.getAdmin();
534    String regionServer = QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY;
535    QuotaFilter rsFilter = new QuotaFilter().setRegionServerFilter(regionServer);
536
537    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(regionServer,
538      ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES));
539    assertNumResults(1, rsFilter);
540    // Verify the Quota in the table
541    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES);
542
543    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(regionServer,
544      ThrottleType.REQUEST_NUMBER, 20, TimeUnit.MINUTES));
545    assertNumResults(1, rsFilter);
546    // Verify the Quota in the table
547    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 20, TimeUnit.MINUTES);
548
549    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(regionServer, ThrottleType.READ_NUMBER,
550      30, TimeUnit.SECONDS));
551    int count = 0;
552    QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration(), rsFilter);
553    try {
554      for (QuotaSettings settings : scanner) {
555        assertTrue(settings.getQuotaType() == QuotaType.THROTTLE);
556        ThrottleSettings throttleSettings = (ThrottleSettings) settings;
557        assertEquals(regionServer, throttleSettings.getRegionServer());
558        count++;
559        if (throttleSettings.getThrottleType() == ThrottleType.REQUEST_NUMBER) {
560          assertEquals(20, throttleSettings.getSoftLimit());
561          assertEquals(TimeUnit.MINUTES, throttleSettings.getTimeUnit());
562        } else if (throttleSettings.getThrottleType() == ThrottleType.READ_NUMBER) {
563          assertEquals(30, throttleSettings.getSoftLimit());
564          assertEquals(TimeUnit.SECONDS, throttleSettings.getTimeUnit());
565        }
566      }
567    } finally {
568      scanner.close();
569    }
570    assertEquals(2, count);
571
572    admin.setQuota(QuotaSettingsFactory.unthrottleRegionServer(regionServer));
573    assertNumResults(0, new QuotaFilter().setRegionServerFilter(regionServer));
574  }
575
576  @Test
577  public void testRpcThrottleWhenStartup() throws IOException, InterruptedException {
578    TEST_UTIL.getAdmin().switchRpcThrottle(false);
579    assertFalse(TEST_UTIL.getAdmin().isRpcThrottleEnabled());
580    TEST_UTIL.killMiniHBaseCluster();
581
582    TEST_UTIL.startMiniHBaseCluster();
583    assertFalse(TEST_UTIL.getAdmin().isRpcThrottleEnabled());
584    for (JVMClusterUtil.RegionServerThread rs : TEST_UTIL.getHBaseCluster()
585      .getRegionServerThreads()) {
586      RegionServerRpcQuotaManager quotaManager =
587        rs.getRegionServer().getRegionServerRpcQuotaManager();
588      assertFalse(quotaManager.isRpcThrottleEnabled());
589    }
590    // enable rpc throttle
591    TEST_UTIL.getAdmin().switchRpcThrottle(true);
592    assertTrue(TEST_UTIL.getAdmin().isRpcThrottleEnabled());
593  }
594
595  @Test
596  public void testSwitchRpcThrottle() throws IOException {
597    Admin admin = TEST_UTIL.getAdmin();
598    testSwitchRpcThrottle(admin, true, true);
599    testSwitchRpcThrottle(admin, true, false);
600    testSwitchRpcThrottle(admin, false, false);
601    testSwitchRpcThrottle(admin, false, true);
602  }
603
604  @Test
605  public void testSwitchExceedThrottleQuota() throws IOException {
606    String regionServer = QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY;
607    Admin admin = TEST_UTIL.getAdmin();
608
609    try {
610      admin.exceedThrottleQuotaSwitch(true);
611      fail("should not come here, because can't enable exceed throttle quota "
612        + "if there is no region server quota");
613    } catch (IOException e) {
614      LOG.warn("Expected exception", e);
615    }
616
617    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(regionServer,
618      ThrottleType.WRITE_NUMBER, 100, TimeUnit.SECONDS));
619    try {
620      admin.exceedThrottleQuotaSwitch(true);
621      fail("should not come here, because can't enable exceed throttle quota "
622        + "if there is no read region server quota");
623    } catch (IOException e) {
624      LOG.warn("Expected exception", e);
625    }
626
627    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(regionServer, ThrottleType.READ_NUMBER,
628      20, TimeUnit.MINUTES));
629    try {
630      admin.exceedThrottleQuotaSwitch(true);
631      fail("should not come here, because can't enable exceed throttle quota "
632        + "because not all region server quota are in seconds time unit");
633    } catch (IOException e) {
634      LOG.warn("Expected exception", e);
635    }
636    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(regionServer, ThrottleType.READ_NUMBER,
637      20, TimeUnit.SECONDS));
638
639    assertFalse(admin.exceedThrottleQuotaSwitch(true));
640    assertTrue(admin.exceedThrottleQuotaSwitch(true));
641    assertTrue(admin.exceedThrottleQuotaSwitch(false));
642    assertFalse(admin.exceedThrottleQuotaSwitch(false));
643    assertEquals(2, admin.getQuota(new QuotaFilter()).size());
644    admin.setQuota(QuotaSettingsFactory.unthrottleRegionServer(regionServer));
645  }
646
647  @Test
648  public void testQuotaScope() throws Exception {
649    Admin admin = TEST_UTIL.getAdmin();
650    String user = "user1";
651    String namespace = "testQuotaScope_ns";
652    TableName tableName = TableName.valueOf("testQuotaScope");
653    QuotaFilter filter = new QuotaFilter();
654
655    // set CLUSTER quota scope for namespace
656    admin.setQuota(QuotaSettingsFactory.throttleNamespace(namespace, ThrottleType.REQUEST_NUMBER,
657      10, TimeUnit.MINUTES, QuotaScope.CLUSTER));
658    assertNumResults(1, filter);
659    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES,
660      QuotaScope.CLUSTER);
661    admin.setQuota(QuotaSettingsFactory.throttleNamespace(namespace, ThrottleType.REQUEST_NUMBER,
662      10, TimeUnit.MINUTES, QuotaScope.MACHINE));
663    assertNumResults(1, filter);
664    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES,
665      QuotaScope.MACHINE);
666    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(namespace));
667    assertNumResults(0, filter);
668
669    // set CLUSTER quota scope for table
670    admin.setQuota(QuotaSettingsFactory.throttleTable(tableName, ThrottleType.REQUEST_NUMBER, 10,
671      TimeUnit.MINUTES, QuotaScope.CLUSTER));
672    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES,
673      QuotaScope.CLUSTER);
674    admin.setQuota(QuotaSettingsFactory.unthrottleTable(tableName));
675
676    // set CLUSTER quota scope for user
677    admin.setQuota(QuotaSettingsFactory.throttleUser(user, ThrottleType.REQUEST_NUMBER, 10,
678      TimeUnit.MINUTES, QuotaScope.CLUSTER));
679    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES,
680      QuotaScope.CLUSTER);
681    admin.setQuota(QuotaSettingsFactory.unthrottleUser(user));
682
683    // set CLUSTER quota scope for user and table
684    admin.setQuota(QuotaSettingsFactory.throttleUser(user, tableName, ThrottleType.REQUEST_NUMBER,
685      10, TimeUnit.MINUTES, QuotaScope.CLUSTER));
686    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES,
687      QuotaScope.CLUSTER);
688    admin.setQuota(QuotaSettingsFactory.unthrottleUser(user));
689
690    // set CLUSTER quota scope for user and namespace
691    admin.setQuota(QuotaSettingsFactory.throttleUser(user, namespace, ThrottleType.REQUEST_NUMBER,
692      10, TimeUnit.MINUTES, QuotaScope.CLUSTER));
693    verifyRecordPresentInQuotaTable(ThrottleType.REQUEST_NUMBER, 10, TimeUnit.MINUTES,
694      QuotaScope.CLUSTER);
695    admin.setQuota(QuotaSettingsFactory.unthrottleUser(user));
696  }
697
698  private void testSwitchRpcThrottle(Admin admin, boolean oldRpcThrottle, boolean newRpcThrottle)
699    throws IOException {
700    boolean state = admin.switchRpcThrottle(newRpcThrottle);
701    Assert.assertEquals(oldRpcThrottle, state);
702    Assert.assertEquals(newRpcThrottle, admin.isRpcThrottleEnabled());
703    TEST_UTIL.getHBaseCluster().getRegionServerThreads().stream()
704      .forEach(rs -> Assert.assertEquals(newRpcThrottle,
705        rs.getRegionServer().getRegionServerRpcQuotaManager().isRpcThrottleEnabled()));
706  }
707
708  private void verifyRecordPresentInQuotaTable(ThrottleType type, long limit, TimeUnit tu)
709    throws Exception {
710    verifyRecordPresentInQuotaTable(type, limit, tu, QuotaScope.MACHINE);
711  }
712
713  private void verifyRecordPresentInQuotaTable(ThrottleType type, long limit, TimeUnit tu,
714    QuotaScope scope) throws Exception {
715    // Verify the RPC Quotas in the table
716    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME);
717      ResultScanner scanner = quotaTable.getScanner(new Scan())) {
718      Result r = Iterables.getOnlyElement(scanner);
719      CellScanner cells = r.cellScanner();
720      assertTrue("Expected to find a cell", cells.advance());
721      assertRPCQuota(type, limit, tu, scope, cells.current());
722    }
723  }
724
725  private void verifyRecordNotPresentInQuotaTable() throws Exception {
726    // Verify that the record doesn't exist in the QuotaTableUtil.QUOTA_TABLE_NAME
727    try (Table quotaTable = TEST_UTIL.getConnection().getTable(QuotaTableUtil.QUOTA_TABLE_NAME);
728      ResultScanner scanner = quotaTable.getScanner(new Scan())) {
729      assertNull("Did not expect to find a quota entry", scanner.next());
730    }
731  }
732
733  private void verifyFetchableViaAPI(Admin admin, ThrottleType type, long limit, TimeUnit tu)
734    throws Exception {
735    // Verify we can retrieve the new quota via the QuotaRetriever API
736    try (QuotaRetriever quotaScanner = QuotaRetriever.open(admin.getConfiguration())) {
737      assertRPCQuota(type, limit, tu, Iterables.getOnlyElement(quotaScanner));
738    }
739  }
740
741  private void verifyNotFetchableViaAPI(Admin admin) throws Exception {
742    // Verify that we can also not fetch it via the API
743    try (QuotaRetriever quotaScanner = QuotaRetriever.open(admin.getConfiguration())) {
744      assertNull("Did not expect to find a quota entry", quotaScanner.next());
745    }
746  }
747
748  private void assertRPCQuota(ThrottleType type, long limit, TimeUnit tu, QuotaScope scope,
749    Cell cell) throws Exception {
750    Quotas q = QuotaTableUtil.quotasFromData(cell.getValueArray(), cell.getValueOffset(),
751      cell.getValueLength());
752    assertTrue("Quota should have rpc quota defined", q.hasThrottle());
753
754    QuotaProtos.Throttle rpcQuota = q.getThrottle();
755    QuotaProtos.TimedQuota t = null;
756
757    switch (type) {
758      case REQUEST_SIZE:
759        assertTrue(rpcQuota.hasReqSize());
760        t = rpcQuota.getReqSize();
761        break;
762      case READ_NUMBER:
763        assertTrue(rpcQuota.hasReadNum());
764        t = rpcQuota.getReadNum();
765        break;
766      case READ_SIZE:
767        assertTrue(rpcQuota.hasReadSize());
768        t = rpcQuota.getReadSize();
769        break;
770      case REQUEST_NUMBER:
771        assertTrue(rpcQuota.hasReqNum());
772        t = rpcQuota.getReqNum();
773        break;
774      case WRITE_NUMBER:
775        assertTrue(rpcQuota.hasWriteNum());
776        t = rpcQuota.getWriteNum();
777        break;
778      case WRITE_SIZE:
779        assertTrue(rpcQuota.hasWriteSize());
780        t = rpcQuota.getWriteSize();
781        break;
782      case REQUEST_CAPACITY_UNIT:
783        assertTrue(rpcQuota.hasReqCapacityUnit());
784        t = rpcQuota.getReqCapacityUnit();
785        break;
786      case READ_CAPACITY_UNIT:
787        assertTrue(rpcQuota.hasReadCapacityUnit());
788        t = rpcQuota.getReadCapacityUnit();
789        break;
790      case WRITE_CAPACITY_UNIT:
791        assertTrue(rpcQuota.hasWriteCapacityUnit());
792        t = rpcQuota.getWriteCapacityUnit();
793        break;
794      default:
795    }
796
797    assertEquals(scope, ProtobufUtil.toQuotaScope(t.getScope()));
798    assertEquals(t.getSoftLimit(), limit);
799    assertEquals(t.getTimeUnit(), ProtobufUtil.toProtoTimeUnit(tu));
800  }
801
802  private void assertRPCQuota(ThrottleType type, long limit, TimeUnit tu,
803    QuotaSettings actualSettings) throws Exception {
804    assertTrue("The actual QuotaSettings was not an instance of " + ThrottleSettings.class
805      + " but of " + actualSettings.getClass(), actualSettings instanceof ThrottleSettings);
806    QuotaProtos.ThrottleRequest throttleRequest = ((ThrottleSettings) actualSettings).getProto();
807    assertEquals(limit, throttleRequest.getTimedQuota().getSoftLimit());
808    assertEquals(ProtobufUtil.toProtoTimeUnit(tu), throttleRequest.getTimedQuota().getTimeUnit());
809    assertEquals(ProtobufUtil.toProtoThrottleType(type), throttleRequest.getType());
810  }
811
812  private void assertSpaceQuota(long sizeLimit, SpaceViolationPolicy violationPolicy, Cell cell)
813    throws Exception {
814    Quotas q = QuotaTableUtil.quotasFromData(cell.getValueArray(), cell.getValueOffset(),
815      cell.getValueLength());
816    assertTrue("Quota should have space quota defined", q.hasSpace());
817    QuotaProtos.SpaceQuota spaceQuota = q.getSpace();
818    assertEquals(sizeLimit, spaceQuota.getSoftLimit());
819    assertEquals(violationPolicy, ProtobufUtil.toViolationPolicy(spaceQuota.getViolationPolicy()));
820  }
821
822  private void assertSpaceQuota(long sizeLimit, SpaceViolationPolicy violationPolicy,
823    QuotaSettings actualSettings) {
824    assertTrue("The actual QuotaSettings was not an instance of " + SpaceLimitSettings.class
825      + " but of " + actualSettings.getClass(), actualSettings instanceof SpaceLimitSettings);
826    SpaceLimitRequest spaceLimitRequest = ((SpaceLimitSettings) actualSettings).getProto();
827    assertEquals(sizeLimit, spaceLimitRequest.getQuota().getSoftLimit());
828    assertEquals(violationPolicy,
829      ProtobufUtil.toViolationPolicy(spaceLimitRequest.getQuota().getViolationPolicy()));
830  }
831
832  private int countResults(final QuotaFilter filter) throws Exception {
833    QuotaRetriever scanner = QuotaRetriever.open(TEST_UTIL.getConfiguration(), filter);
834    try {
835      int count = 0;
836      for (QuotaSettings settings : scanner) {
837        LOG.debug(Objects.toString(settings));
838        count++;
839      }
840      return count;
841    } finally {
842      scanner.close();
843    }
844  }
845
846  @Test
847  public void testUserUnThrottleByType() throws Exception {
848    final Admin admin = TEST_UTIL.getAdmin();
849    final String userName = User.getCurrent().getShortName();
850    String userName01 = "user01";
851    // Add 6req/min limit
852    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6,
853      TimeUnit.MINUTES));
854    admin.setQuota(
855      QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
856    admin.setQuota(QuotaSettingsFactory.throttleUser(userName01, ThrottleType.REQUEST_NUMBER, 6,
857      TimeUnit.MINUTES));
858    admin.setQuota(QuotaSettingsFactory.throttleUser(userName01, ThrottleType.REQUEST_SIZE, 6,
859      TimeUnit.MINUTES));
860    admin.setQuota(
861      QuotaSettingsFactory.unthrottleUserByThrottleType(userName, ThrottleType.REQUEST_NUMBER));
862    assertEquals(3, getQuotaSettingCount(admin));
863    admin.setQuota(
864      QuotaSettingsFactory.unthrottleUserByThrottleType(userName, ThrottleType.REQUEST_SIZE));
865    assertEquals(2, getQuotaSettingCount(admin));
866    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName01));
867    assertEquals(0, getQuotaSettingCount(admin));
868  }
869
870  @Test
871  public void testUserTableUnThrottleByType() throws Exception {
872    final Admin admin = TEST_UTIL.getAdmin();
873    final String userName = User.getCurrent().getShortName();
874    String userName01 = "user01";
875    // Add 6req/min limit
876    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
877      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
878    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
879      ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
880    admin.setQuota(QuotaSettingsFactory.throttleUser(userName01, TABLE_NAMES[1],
881      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
882    admin.setQuota(QuotaSettingsFactory.throttleUser(userName01, TABLE_NAMES[1],
883      ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
884    admin.setQuota(QuotaSettingsFactory.unthrottleUserByThrottleType(userName, TABLE_NAMES[0],
885      ThrottleType.REQUEST_NUMBER));
886    assertEquals(3, getQuotaSettingCount(admin));
887    admin.setQuota(QuotaSettingsFactory.unthrottleUserByThrottleType(userName, TABLE_NAMES[0],
888      ThrottleType.REQUEST_SIZE));
889    assertEquals(2, getQuotaSettingCount(admin));
890    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName01));
891    assertEquals(0, getQuotaSettingCount(admin));
892  }
893
894  @Test
895  public void testUserNameSpaceUnThrottleByType() throws Exception {
896    final Admin admin = TEST_UTIL.getAdmin();
897    final String userName = User.getCurrent().getShortName();
898    String userName01 = "user01";
899    // Add 6req/min limit
900    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACES[0],
901      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
902    admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACES[0],
903      ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
904    admin.setQuota(QuotaSettingsFactory.throttleUser(userName01, NAMESPACES[1],
905      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
906    admin.setQuota(QuotaSettingsFactory.throttleUser(userName01, NAMESPACES[1],
907      ThrottleType.REQUEST_SIZE, 6, TimeUnit.MINUTES));
908    admin.setQuota(QuotaSettingsFactory.unthrottleUserByThrottleType(userName, NAMESPACES[0],
909      ThrottleType.REQUEST_NUMBER));
910    assertEquals(3, getQuotaSettingCount(admin));
911    admin.setQuota(QuotaSettingsFactory.unthrottleUserByThrottleType(userName, NAMESPACES[0],
912      ThrottleType.REQUEST_SIZE));
913    assertEquals(2, getQuotaSettingCount(admin));
914    admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName01));
915    assertEquals(0, getQuotaSettingCount(admin));
916  }
917
918  @Test
919  public void testTableUnThrottleByType() throws Exception {
920    final Admin admin = TEST_UTIL.getAdmin();
921    final String userName = User.getCurrent().getShortName();
922    // Add 6req/min limit
923    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
924      6, TimeUnit.MINUTES));
925    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_SIZE, 6,
926      TimeUnit.MINUTES));
927    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER,
928      6, TimeUnit.MINUTES));
929    admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_SIZE, 6,
930      TimeUnit.MINUTES));
931    admin.setQuota(QuotaSettingsFactory.unthrottleTableByThrottleType(TABLE_NAMES[0],
932      ThrottleType.REQUEST_NUMBER));
933    assertEquals(3, getQuotaSettingCount(admin));
934    admin.setQuota(QuotaSettingsFactory.unthrottleTableByThrottleType(TABLE_NAMES[0],
935      ThrottleType.REQUEST_SIZE));
936    assertEquals(2, getQuotaSettingCount(admin));
937    admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[1]));
938    assertEquals(0, getQuotaSettingCount(admin));
939  }
940
941  @Test
942  public void testNameSpaceUnThrottleByType() throws Exception {
943    final Admin admin = TEST_UTIL.getAdmin();
944    final String userName = User.getCurrent().getShortName();
945    // Add 6req/min limit
946    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACES[0],
947      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
948    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACES[0], ThrottleType.REQUEST_SIZE,
949      6, TimeUnit.MINUTES));
950    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACES[1],
951      ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
952    admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACES[1], ThrottleType.REQUEST_SIZE,
953      6, TimeUnit.MINUTES));
954    admin.setQuota(QuotaSettingsFactory.unthrottleNamespaceByThrottleType(NAMESPACES[0],
955      ThrottleType.REQUEST_NUMBER));
956    assertEquals(3, getQuotaSettingCount(admin));
957    admin.setQuota(QuotaSettingsFactory.unthrottleNamespaceByThrottleType(NAMESPACES[0],
958      ThrottleType.REQUEST_SIZE));
959    assertEquals(2, getQuotaSettingCount(admin));
960    admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACES[1]));
961    assertEquals(0, getQuotaSettingCount(admin));
962  }
963
964  @Test
965  public void testRegionServerUnThrottleByType() throws Exception {
966    final Admin admin = TEST_UTIL.getAdmin();
967    final String[] REGIONSERVER = { "RS01", "RS02" };
968
969    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(REGIONSERVER[0],
970      ThrottleType.READ_NUMBER, 4, TimeUnit.MINUTES));
971    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(REGIONSERVER[0],
972      ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
973    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(REGIONSERVER[1],
974      ThrottleType.READ_NUMBER, 4, TimeUnit.MINUTES));
975    admin.setQuota(QuotaSettingsFactory.throttleRegionServer(REGIONSERVER[1],
976      ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
977
978    admin.setQuota(QuotaSettingsFactory.unthrottleRegionServerByThrottleType(REGIONSERVER[0],
979      ThrottleType.READ_NUMBER));
980    assertEquals(3, getQuotaSettingCount(admin));
981    admin.setQuota(QuotaSettingsFactory.unthrottleRegionServerByThrottleType(REGIONSERVER[0],
982      ThrottleType.WRITE_NUMBER));
983    assertEquals(2, getQuotaSettingCount(admin));
984    admin.setQuota(QuotaSettingsFactory.unthrottleRegionServer(REGIONSERVER[1]));
985    assertEquals(0, getQuotaSettingCount(admin));
986  }
987
988  public int getQuotaSettingCount(Admin admin) throws IOException {
989    List<QuotaSettings> list_quotas = admin.getQuota(new QuotaFilter());
990    int quotaSettingCount = 0;
991    for (QuotaSettings setting : list_quotas) {
992      quotaSettingCount++;
993      LOG.info("Quota Setting:" + setting);
994    }
995    return quotaSettingCount;
996  }
997}