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 { QuotaSettingsFactory()28 private QuotaSettingsFactory() { 29 // Utility class 30 } 31 32 static class QuotaGlobalsSettingsBypass extends QuotaSettings { 33 private final boolean bypassGlobals; 34 QuotaGlobalsSettingsBypass(final String userName, final TableName tableName, final String namespace, final boolean bypassGlobals)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 getQuotaType()42 public QuotaType getQuotaType() { 43 return QuotaType.GLOBAL_BYPASS; 44 } 45 46 @Override setupSetQuotaRequest(SetQuotaRequest.Builder builder)47 protected void setupSetQuotaRequest(SetQuotaRequest.Builder builder) { 48 builder.setBypassGlobals(bypassGlobals); 49 } 50 51 @Override toString()52 public String toString() { 53 return "GLOBAL_BYPASS => " + bypassGlobals; 54 } 55 } 56 57 /* 58 * ========================================================================== QuotaSettings from 59 * the Quotas object 60 */ fromUserQuotas(final String userName, final Quotas quotas)61 static List<QuotaSettings> fromUserQuotas(final String userName, final Quotas quotas) { 62 return fromQuotas(userName, null, null, quotas); 63 } 64 fromUserQuotas(final String userName, final TableName tableName, final Quotas quotas)65 static List<QuotaSettings> fromUserQuotas(final String userName, final TableName tableName, 66 final Quotas quotas) { 67 return fromQuotas(userName, tableName, null, quotas); 68 } 69 fromUserQuotas(final String userName, final String namespace, final Quotas quotas)70 static List<QuotaSettings> fromUserQuotas(final String userName, final String namespace, 71 final Quotas quotas) { 72 return fromQuotas(userName, null, namespace, quotas); 73 } 74 fromTableQuotas(final TableName tableName, final Quotas quotas)75 static List<QuotaSettings> fromTableQuotas(final TableName tableName, final Quotas quotas) { 76 return fromQuotas(null, tableName, null, quotas); 77 } 78 fromNamespaceQuotas(final String namespace, final Quotas quotas)79 static List<QuotaSettings> fromNamespaceQuotas(final String namespace, final Quotas quotas) { 80 return fromQuotas(null, null, namespace, quotas); 81 } 82 fromQuotas(final String userName, final TableName tableName, final String namespace, final Quotas quotas)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 fromThrottle(final String userName, final TableName tableName, final String namespace, final QuotaProtos.Throttle throttle)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 */ throttleUser(final String userName, final ThrottleType type, final long limit, final TimeUnit timeUnit)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 */ throttleUser(final String userName, final TableName tableName, final ThrottleType type, final long limit, final TimeUnit timeUnit)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 */ throttleUser(final String userName, final String namespace, final ThrottleType type, final long limit, final TimeUnit timeUnit)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 */ unthrottleUser(final String userName)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 */ unthrottleUser(final String userName, final TableName tableName)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 */ unthrottleUser(final String userName, final String namespace)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 */ throttleTable(final TableName tableName, final ThrottleType type, final long limit, final TimeUnit timeUnit)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 */ unthrottleTable(final TableName tableName)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 */ throttleNamespace(final String namespace, final ThrottleType type, final long limit, final TimeUnit timeUnit)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 */ unthrottleNamespace(final String namespace)239 public static QuotaSettings unthrottleNamespace(final String namespace) { 240 return throttle(null, null, namespace, null, 0, null); 241 } 242 243 /* Throttle helper */ throttle(final String userName, final TableName tableName, final String namespace, final ThrottleType type, final long limit, final TimeUnit timeUnit)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 */ bypassGlobals(final String userName, final boolean bypassGlobals)266 public static QuotaSettings bypassGlobals(final String userName, final boolean bypassGlobals) { 267 return new QuotaGlobalsSettingsBypass(userName, null, null, bypassGlobals); 268 } 269 } 270