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     return settings;
123   }
124 
125   /*
126    * ========================================================================== RPC Throttle
127    */
128 
129   /**
130    * Throttle the specified user.
131    * @param userName the user to throttle
132    * @param type the type of throttling
133    * @param limit the allowed number of request/data per timeUnit
134    * @param timeUnit the limit time unit
135    * @return the quota settings
136    */
137   public static QuotaSettings throttleUser(final String userName, final ThrottleType type,
138       final long limit, final TimeUnit timeUnit) {
139     return throttle(userName, null, null, type, limit, timeUnit);
140   }
141 
142   /**
143    * Throttle the specified user on the specified table.
144    * @param userName the user to throttle
145    * @param tableName the table to throttle
146    * @param type the type of throttling
147    * @param limit the allowed number of request/data per timeUnit
148    * @param timeUnit the limit time unit
149    * @return the quota settings
150    */
151   public static QuotaSettings throttleUser(final String userName, final TableName tableName,
152       final ThrottleType type, final long limit, final TimeUnit timeUnit) {
153     return throttle(userName, tableName, null, type, limit, timeUnit);
154   }
155 
156   /**
157    * Throttle the specified user on the specified namespace.
158    * @param userName the user to throttle
159    * @param namespace the namespace to throttle
160    * @param type the type of throttling
161    * @param limit the allowed number of request/data per timeUnit
162    * @param timeUnit the limit time unit
163    * @return the quota settings
164    */
165   public static QuotaSettings throttleUser(final String userName, final String namespace,
166       final ThrottleType type, final long limit, final TimeUnit timeUnit) {
167     return throttle(userName, null, namespace, type, limit, timeUnit);
168   }
169 
170   /**
171    * Remove the throttling for the specified user.
172    * @param userName the user
173    * @return the quota settings
174    */
175   public static QuotaSettings unthrottleUser(final String userName) {
176     return throttle(userName, null, null, null, 0, null);
177   }
178 
179   /**
180    * Remove the throttling for the specified user on the specified table.
181    * @param userName the user
182    * @param tableName the table
183    * @return the quota settings
184    */
185   public static QuotaSettings unthrottleUser(final String userName, final TableName tableName) {
186     return throttle(userName, tableName, null, null, 0, null);
187   }
188 
189   /**
190    * Remove the throttling for the specified user on the specified namespace.
191    * @param userName the user
192    * @param namespace the namespace
193    * @return the quota settings
194    */
195   public static QuotaSettings unthrottleUser(final String userName, final String namespace) {
196     return throttle(userName, null, namespace, null, 0, null);
197   }
198 
199   /**
200    * Throttle the specified table.
201    * @param tableName the table to throttle
202    * @param type the type of throttling
203    * @param limit the allowed number of request/data per timeUnit
204    * @param timeUnit the limit time unit
205    * @return the quota settings
206    */
207   public static QuotaSettings throttleTable(final TableName tableName, final ThrottleType type,
208       final long limit, final TimeUnit timeUnit) {
209     return throttle(null, tableName, null, type, limit, timeUnit);
210   }
211 
212   /**
213    * Remove the throttling for the specified table.
214    * @param tableName the table
215    * @return the quota settings
216    */
217   public static QuotaSettings unthrottleTable(final TableName tableName) {
218     return throttle(null, tableName, null, null, 0, null);
219   }
220 
221   /**
222    * Throttle the specified namespace.
223    * @param namespace the namespace to throttle
224    * @param type the type of throttling
225    * @param limit the allowed number of request/data per timeUnit
226    * @param timeUnit the limit time unit
227    * @return the quota settings
228    */
229   public static QuotaSettings throttleNamespace(final String namespace, final ThrottleType type,
230       final long limit, final TimeUnit timeUnit) {
231     return throttle(null, null, namespace, type, limit, timeUnit);
232   }
233 
234   /**
235    * Remove the throttling for the specified namespace.
236    * @param namespace the namespace
237    * @return the quota settings
238    */
239   public static QuotaSettings unthrottleNamespace(final String namespace) {
240     return throttle(null, null, namespace, null, 0, null);
241   }
242 
243   /* Throttle helper */
244   private static QuotaSettings throttle(final String userName, final TableName tableName,
245       final String namespace, final ThrottleType type, final long limit, final TimeUnit timeUnit) {
246     QuotaProtos.ThrottleRequest.Builder builder = QuotaProtos.ThrottleRequest.newBuilder();
247     if (type != null) {
248       builder.setType(ProtobufUtil.toProtoThrottleType(type));
249     }
250     if (timeUnit != null) {
251       builder.setTimedQuota(ProtobufUtil.toTimedQuota(limit, timeUnit, QuotaScope.MACHINE));
252     }
253     return new ThrottleSettings(userName, tableName, namespace, builder.build());
254   }
255 
256   /*
257    * ========================================================================== Global Settings
258    */
259 
260   /**
261    * Set the "bypass global settings" for the specified user
262    * @param userName the user to throttle
263    * @param bypassGlobals true if the global settings should be bypassed
264    * @return the quota settings
265    */
266   public static QuotaSettings bypassGlobals(final String userName, final boolean bypassGlobals) {
267     return new QuotaGlobalsSettingsBypass(userName, null, null, bypassGlobals);
268   }
269 }