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  package org.apache.hadoop.hbase.quotas;
12  
13  import java.util.ArrayList;
14  import java.util.List;
15  import java.util.concurrent.TimeUnit;
16  
17  import org.apache.hadoop.hbase.TableName;
18  import org.apache.hadoop.hbase.classification.InterfaceAudience;
19  import org.apache.hadoop.hbase.classification.InterfaceStability;
20  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
21  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.SetQuotaRequest;
22  import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos;
23  import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
24  
25  @InterfaceAudience.Public
26  @InterfaceStability.Evolving
27  public class QuotaSettingsFactory {
28    private QuotaSettingsFactory() {
29      // Utility class
30    }
31  
32    static class QuotaGlobalsSettingsBypass extends QuotaSettings {
33      private final boolean bypassGlobals;
34  
35      QuotaGlobalsSettingsBypass(final String userName, final TableName tableName,
36          final String namespace, final boolean bypassGlobals) {
37        super(userName, tableName, namespace);
38        this.bypassGlobals = bypassGlobals;
39      }
40  
41      @Override
42      public QuotaType getQuotaType() {
43        return QuotaType.GLOBAL_BYPASS;
44      }
45  
46      @Override
47      protected void setupSetQuotaRequest(SetQuotaRequest.Builder builder) {
48        builder.setBypassGlobals(bypassGlobals);
49      }
50  
51      @Override
52      public String toString() {
53        return "GLOBAL_BYPASS => " + bypassGlobals;
54      }
55    }
56  
57    /*
58     * ========================================================================== QuotaSettings from
59     * the Quotas object
60     */
61    static List<QuotaSettings> fromUserQuotas(final String userName, final Quotas quotas) {
62      return fromQuotas(userName, null, null, quotas);
63    }
64  
65    static List<QuotaSettings> fromUserQuotas(final String userName, final TableName tableName,
66        final Quotas quotas) {
67      return fromQuotas(userName, tableName, null, quotas);
68    }
69  
70    static List<QuotaSettings> fromUserQuotas(final String userName, final String namespace,
71        final Quotas quotas) {
72      return fromQuotas(userName, null, namespace, quotas);
73    }
74  
75    static List<QuotaSettings> fromTableQuotas(final TableName tableName, final Quotas quotas) {
76      return fromQuotas(null, tableName, null, quotas);
77    }
78  
79    static List<QuotaSettings> fromNamespaceQuotas(final String namespace, final Quotas quotas) {
80      return fromQuotas(null, null, namespace, quotas);
81    }
82  
83    private static List<QuotaSettings> fromQuotas(final String userName, final TableName tableName,
84        final String namespace, final Quotas quotas) {
85      List<QuotaSettings> settings = new ArrayList<QuotaSettings>();
86      if (quotas.hasThrottle()) {
87        settings.addAll(fromThrottle(userName, tableName, namespace, quotas.getThrottle()));
88      }
89      if (quotas.getBypassGlobals() == true) {
90        settings.add(new QuotaGlobalsSettingsBypass(userName, tableName, namespace, true));
91      }
92      return settings;
93    }
94  
95    private static List<QuotaSettings> fromThrottle(final String userName, final TableName tableName,
96        final String namespace, final QuotaProtos.Throttle throttle) {
97      List<QuotaSettings> settings = new ArrayList<QuotaSettings>();
98      if (throttle.hasReqNum()) {
99        settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
100         ThrottleType.REQUEST_NUMBER, throttle.getReqNum()));
101     }
102     if (throttle.hasReqSize()) {
103       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
104         ThrottleType.REQUEST_SIZE, throttle.getReqSize()));
105     }
106     if (throttle.hasWriteNum()) {
107       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
108           ThrottleType.WRITE_NUMBER, throttle.getWriteNum()));
109     }
110     if (throttle.hasWriteSize()) {
111       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
112           ThrottleType.WRITE_SIZE, throttle.getWriteSize()));
113     }
114     if (throttle.hasReadNum()) {
115       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
116           ThrottleType.READ_NUMBER, throttle.getReadNum()));
117     }
118     if (throttle.hasReadSize()) {
119       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
120           ThrottleType.READ_SIZE, throttle.getReadSize()));
121     }
122     if (throttle.hasReqCapacityUnit()) {
123       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
124         ThrottleType.REQUEST_CAPACITY_UNIT, throttle.getReqCapacityUnit()));
125     }
126     if (throttle.hasReadCapacityUnit()) {
127       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
128         ThrottleType.READ_CAPACITY_UNIT, throttle.getReadCapacityUnit()));
129     }
130     if (throttle.hasWriteCapacityUnit()) {
131       settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace,
132         ThrottleType.WRITE_CAPACITY_UNIT, throttle.getWriteCapacityUnit()));
133     }
134     return settings;
135   }
136 
137   /*
138    * ========================================================================== RPC Throttle
139    */
140 
141   /**
142    * Throttle the specified user.
143    * @param userName the user to throttle
144    * @param type the type of throttling
145    * @param limit the allowed number of request/data per timeUnit
146    * @param timeUnit the limit time unit
147    * @return the quota settings
148    */
149   public static QuotaSettings throttleUser(final String userName, final ThrottleType type,
150       final long limit, final TimeUnit timeUnit) {
151     return throttle(userName, null, null, type, limit, timeUnit);
152   }
153 
154   /**
155    * Throttle the specified user on the specified table.
156    * @param userName the user to throttle
157    * @param tableName the table to throttle
158    * @param type the type of throttling
159    * @param limit the allowed number of request/data per timeUnit
160    * @param timeUnit the limit time unit
161    * @return the quota settings
162    */
163   public static QuotaSettings throttleUser(final String userName, final TableName tableName,
164       final ThrottleType type, final long limit, final TimeUnit timeUnit) {
165     return throttle(userName, tableName, null, type, limit, timeUnit);
166   }
167 
168   /**
169    * Throttle the specified user on the specified namespace.
170    * @param userName the user to throttle
171    * @param namespace the namespace to throttle
172    * @param type the type of throttling
173    * @param limit the allowed number of request/data per timeUnit
174    * @param timeUnit the limit time unit
175    * @return the quota settings
176    */
177   public static QuotaSettings throttleUser(final String userName, final String namespace,
178       final ThrottleType type, final long limit, final TimeUnit timeUnit) {
179     return throttle(userName, null, namespace, type, limit, timeUnit);
180   }
181 
182   /**
183    * Remove the throttling for the specified user.
184    * @param userName the user
185    * @return the quota settings
186    */
187   public static QuotaSettings unthrottleUser(final String userName) {
188     return throttle(userName, null, null, null, 0, null);
189   }
190 
191   /**
192    * Remove the throttling for the specified user on the specified table.
193    * @param userName the user
194    * @param tableName the table
195    * @return the quota settings
196    */
197   public static QuotaSettings unthrottleUser(final String userName, final TableName tableName) {
198     return throttle(userName, tableName, null, null, 0, null);
199   }
200 
201   /**
202    * Remove the throttling for the specified user on the specified namespace.
203    * @param userName the user
204    * @param namespace the namespace
205    * @return the quota settings
206    */
207   public static QuotaSettings unthrottleUser(final String userName, final String namespace) {
208     return throttle(userName, null, namespace, null, 0, null);
209   }
210 
211   /**
212    * Throttle the specified table.
213    * @param tableName the table to throttle
214    * @param type the type of throttling
215    * @param limit the allowed number of request/data per timeUnit
216    * @param timeUnit the limit time unit
217    * @return the quota settings
218    */
219   public static QuotaSettings throttleTable(final TableName tableName, final ThrottleType type,
220       final long limit, final TimeUnit timeUnit) {
221     return throttle(null, tableName, null, type, limit, timeUnit);
222   }
223 
224   /**
225    * Remove the throttling for the specified table.
226    * @param tableName the table
227    * @return the quota settings
228    */
229   public static QuotaSettings unthrottleTable(final TableName tableName) {
230     return throttle(null, tableName, null, null, 0, null);
231   }
232 
233   /**
234    * Throttle the specified namespace.
235    * @param namespace the namespace to throttle
236    * @param type the type of throttling
237    * @param limit the allowed number of request/data per timeUnit
238    * @param timeUnit the limit time unit
239    * @return the quota settings
240    */
241   public static QuotaSettings throttleNamespace(final String namespace, final ThrottleType type,
242       final long limit, final TimeUnit timeUnit) {
243     return throttle(null, null, namespace, type, limit, timeUnit);
244   }
245 
246   /**
247    * Remove the throttling for the specified namespace.
248    * @param namespace the namespace
249    * @return the quota settings
250    */
251   public static QuotaSettings unthrottleNamespace(final String namespace) {
252     return throttle(null, null, namespace, null, 0, null);
253   }
254 
255   /* Throttle helper */
256   private static QuotaSettings throttle(final String userName, final TableName tableName,
257       final String namespace, final ThrottleType type, final long limit, final TimeUnit timeUnit) {
258     QuotaProtos.ThrottleRequest.Builder builder = QuotaProtos.ThrottleRequest.newBuilder();
259     if (type != null) {
260       builder.setType(ProtobufUtil.toProtoThrottleType(type));
261     }
262     if (timeUnit != null) {
263       builder.setTimedQuota(ProtobufUtil.toTimedQuota(limit, timeUnit, QuotaScope.MACHINE));
264     }
265     return new ThrottleSettings(userName, tableName, namespace, builder.build());
266   }
267 
268   /*
269    * ========================================================================== Global Settings
270    */
271 
272   /**
273    * Set the "bypass global settings" for the specified user
274    * @param userName the user to throttle
275    * @param bypassGlobals true if the global settings should be bypassed
276    * @return the quota settings
277    */
278   public static QuotaSettings bypassGlobals(final String userName, final boolean bypassGlobals) {
279     return new QuotaGlobalsSettingsBypass(userName, null, null, bypassGlobals);
280   }
281 }