View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional information regarding
4    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
8    * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
9    * for the specific language governing permissions and limitations under the License.
10   */
11  
12  package org.apache.hadoop.hbase.quotas;
13  
14  import static org.junit.Assert.assertEquals;
15  
16  import java.io.IOException;
17  import java.util.concurrent.TimeUnit;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.apache.hadoop.hbase.HBaseTestingUtility;
22  import org.apache.hadoop.hbase.HConstants;
23  import org.apache.hadoop.hbase.TableName;
24  import org.apache.hadoop.hbase.client.Connection;
25  import org.apache.hadoop.hbase.client.ConnectionFactory;
26  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
27  import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
28  import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Throttle;
29  import org.apache.hadoop.hbase.testclassification.MediumTests;
30  import org.junit.After;
31  import org.junit.AfterClass;
32  import org.junit.Before;
33  import org.junit.BeforeClass;
34  import org.junit.Test;
35  import org.junit.experimental.categories.Category;
36  
37  /**
38   * Test the quota table helpers (e.g. CRUD operations)
39   */
40  @Category({ MediumTests.class })
41  public class TestQuotaTableUtil {
42    private static final Log LOG = LogFactory.getLog(TestQuotaTableUtil.class);
43  
44    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
45    private Connection connection;
46  
47    @BeforeClass
48    public static void setUpBeforeClass() throws Exception {
49      TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
50      TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, 2000);
51      TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
52      TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
53      TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
54      TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
55      TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
56      TEST_UTIL.startMiniCluster(1);
57      TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
58    }
59  
60    @AfterClass
61    public static void tearDownAfterClass() throws Exception {
62      TEST_UTIL.shutdownMiniCluster();
63    }
64  
65    @Before
66    public void before() throws IOException {
67      this.connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
68    }
69  
70    @After
71    public void after() throws IOException {
72      this.connection.close();
73    }
74  
75    @Test
76    public void testTableQuotaUtil() throws Exception {
77      final TableName table = TableName.valueOf("testTableQuotaUtilTable");
78  
79      Quotas quota =
80          Quotas
81              .newBuilder()
82              .setThrottle(
83                Throttle
84                    .newBuilder()
85                    .setReqNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
86                    .setWriteNum(ProtobufUtil.toTimedQuota(600, TimeUnit.SECONDS, QuotaScope.MACHINE))
87                    .setReadSize(
88                      ProtobufUtil.toTimedQuota(8192, TimeUnit.SECONDS, QuotaScope.MACHINE)).build())
89              .build();
90  
91      // Add user quota and verify it
92      QuotaUtil.addTableQuota(this.connection, table, quota);
93      Quotas resQuota = QuotaUtil.getTableQuota(this.connection, table);
94      assertEquals(quota, resQuota);
95  
96      // Remove user quota and verify it
97      QuotaUtil.deleteTableQuota(this.connection, table);
98      resQuota = QuotaUtil.getTableQuota(this.connection, table);
99      assertEquals(null, resQuota);
100   }
101 
102   @Test
103   public void testNamespaceQuotaUtil() throws Exception {
104     final String namespace = "testNamespaceQuotaUtilNS";
105 
106     Quotas quota =
107         Quotas
108             .newBuilder()
109             .setThrottle(
110               Throttle
111                   .newBuilder()
112                   .setReqNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
113                   .setWriteNum(ProtobufUtil.toTimedQuota(600, TimeUnit.SECONDS, QuotaScope.MACHINE))
114                   .setReadSize(
115                     ProtobufUtil.toTimedQuota(8192, TimeUnit.SECONDS, QuotaScope.MACHINE)).build())
116             .build();
117 
118     // Add user quota and verify it
119     QuotaUtil.addNamespaceQuota(this.connection, namespace, quota);
120     Quotas resQuota = QuotaUtil.getNamespaceQuota(this.connection, namespace);
121     assertEquals(quota, resQuota);
122 
123     // Remove user quota and verify it
124     QuotaUtil.deleteNamespaceQuota(this.connection, namespace);
125     resQuota = QuotaUtil.getNamespaceQuota(this.connection, namespace);
126     assertEquals(null, resQuota);
127   }
128 
129   @Test
130   public void testUserQuotaUtil() throws Exception {
131     final TableName table = TableName.valueOf("testUserQuotaUtilTable");
132     final String namespace = "testNS";
133     final String user = "testUser";
134 
135     Quotas quotaNamespace =
136         Quotas
137             .newBuilder()
138             .setThrottle(
139               Throttle
140                   .newBuilder()
141                   .setReqNum(ProtobufUtil.toTimedQuota(50000, TimeUnit.SECONDS, QuotaScope.MACHINE))
142                   .build()).build();
143     Quotas quotaTable =
144         Quotas
145             .newBuilder()
146             .setThrottle(
147               Throttle
148                   .newBuilder()
149                   .setReqNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
150                   .setWriteNum(ProtobufUtil.toTimedQuota(600, TimeUnit.SECONDS, QuotaScope.MACHINE))
151                   .setReadSize(
152                     ProtobufUtil.toTimedQuota(10000, TimeUnit.SECONDS, QuotaScope.MACHINE)).build())
153             .build();
154     Quotas quota =
155         Quotas
156             .newBuilder()
157             .setThrottle(
158               Throttle
159                   .newBuilder()
160                   .setReqSize(ProtobufUtil.toTimedQuota(8192, TimeUnit.SECONDS, QuotaScope.MACHINE))
161                   .setWriteSize(
162                     ProtobufUtil.toTimedQuota(4096, TimeUnit.SECONDS, QuotaScope.MACHINE))
163                   .setReadNum(ProtobufUtil.toTimedQuota(1000, TimeUnit.SECONDS, QuotaScope.MACHINE))
164                   .build()).build();
165 
166     // Add user global quota
167     QuotaUtil.addUserQuota(this.connection, user, quota);
168     Quotas resQuota = QuotaUtil.getUserQuota(this.connection, user);
169     assertEquals(quota, resQuota);
170 
171     // Add user quota for table
172     QuotaUtil.addUserQuota(this.connection, user, table, quotaTable);
173     Quotas resQuotaTable = QuotaUtil.getUserQuota(this.connection, user, table);
174     assertEquals(quotaTable, resQuotaTable);
175 
176     // Add user quota for namespace
177     QuotaUtil.addUserQuota(this.connection, user, namespace, quotaNamespace);
178     Quotas resQuotaNS = QuotaUtil.getUserQuota(this.connection, user, namespace);
179     assertEquals(quotaNamespace, resQuotaNS);
180 
181     // Delete user global quota
182     QuotaUtil.deleteUserQuota(this.connection, user);
183     resQuota = QuotaUtil.getUserQuota(this.connection, user);
184     assertEquals(null, resQuota);
185 
186     // Delete user quota for table
187     QuotaUtil.deleteUserQuota(this.connection, user, table);
188     resQuotaTable = QuotaUtil.getUserQuota(this.connection, user, table);
189     assertEquals(null, resQuotaTable);
190 
191     // Delete user quota for namespace
192     QuotaUtil.deleteUserQuota(this.connection, user, namespace);
193     resQuotaNS = QuotaUtil.getUserQuota(this.connection, user, namespace);
194     assertEquals(null, resQuotaNS);
195   }
196 }