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 java.io.IOException; 021import java.util.ArrayList; 022import java.util.List; 023import java.util.concurrent.TimeUnit; 024import org.apache.hadoop.hbase.TableName; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 028import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaRequest; 029import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; 030import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas; 031import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceQuota; 032 033@InterfaceAudience.Public 034public class QuotaSettingsFactory { 035 static class QuotaGlobalsSettingsBypass extends QuotaSettings { 036 private final boolean bypassGlobals; 037 038 QuotaGlobalsSettingsBypass(final String userName, final TableName tableName, 039 final String namespace, final String regionServer, final boolean bypassGlobals) { 040 super(userName, tableName, namespace, regionServer); 041 this.bypassGlobals = bypassGlobals; 042 } 043 044 @Override 045 public QuotaType getQuotaType() { 046 return QuotaType.GLOBAL_BYPASS; 047 } 048 049 @Override 050 protected void setupSetQuotaRequest(SetQuotaRequest.Builder builder) { 051 builder.setBypassGlobals(bypassGlobals); 052 } 053 054 @Override 055 public String toString() { 056 return "GLOBAL_BYPASS => " + bypassGlobals; 057 } 058 059 protected boolean getBypass() { 060 return bypassGlobals; 061 } 062 063 @Override 064 protected QuotaGlobalsSettingsBypass merge(QuotaSettings newSettings) throws IOException { 065 if (newSettings instanceof QuotaGlobalsSettingsBypass) { 066 QuotaGlobalsSettingsBypass other = (QuotaGlobalsSettingsBypass) newSettings; 067 068 validateQuotaTarget(other); 069 070 if (getBypass() != other.getBypass()) { 071 return other; 072 } 073 } 074 return this; 075 } 076 } 077 078 /* 079 * ========================================================================== QuotaSettings from 080 * the Quotas object 081 */ 082 static List<QuotaSettings> fromUserQuotas(final String userName, final Quotas quotas) { 083 return fromQuotas(userName, null, null, null, quotas); 084 } 085 086 static List<QuotaSettings> fromUserQuotas(final String userName, final TableName tableName, 087 final Quotas quotas) { 088 return fromQuotas(userName, tableName, null, null, quotas); 089 } 090 091 static List<QuotaSettings> fromUserQuotas(final String userName, final String namespace, 092 final Quotas quotas) { 093 return fromQuotas(userName, null, namespace, null, quotas); 094 } 095 096 static List<QuotaSettings> fromTableQuotas(final TableName tableName, final Quotas quotas) { 097 return fromQuotas(null, tableName, null, null, quotas); 098 } 099 100 static List<QuotaSettings> fromNamespaceQuotas(final String namespace, final Quotas quotas) { 101 return fromQuotas(null, null, namespace, null, quotas); 102 } 103 104 static List<QuotaSettings> fromRegionServerQuotas(final String regionServer, 105 final Quotas quotas) { 106 return fromQuotas(null, null, null, regionServer, quotas); 107 } 108 109 private static List<QuotaSettings> fromQuotas(final String userName, final TableName tableName, 110 final String namespace, final String regionServer, final Quotas quotas) { 111 List<QuotaSettings> settings = new ArrayList<>(); 112 if (quotas.hasThrottle()) { 113 settings 114 .addAll(fromThrottle(userName, tableName, namespace, regionServer, quotas.getThrottle())); 115 } 116 if (quotas.getBypassGlobals() == true) { 117 settings 118 .add(new QuotaGlobalsSettingsBypass(userName, tableName, namespace, regionServer, true)); 119 } 120 if (quotas.hasSpace()) { 121 settings.add(fromSpace(tableName, namespace, quotas.getSpace())); 122 } 123 return settings; 124 } 125 126 public static List<ThrottleSettings> fromTableThrottles(final TableName tableName, 127 final QuotaProtos.Throttle throttle) { 128 return fromThrottle(null, tableName, null, null, throttle); 129 } 130 131 protected static List<ThrottleSettings> fromThrottle(final String userName, 132 final TableName tableName, final String namespace, final String regionServer, 133 final QuotaProtos.Throttle throttle) { 134 List<ThrottleSettings> settings = new ArrayList<>(); 135 if (throttle.hasReqNum()) { 136 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 137 ThrottleType.REQUEST_NUMBER, throttle.getReqNum())); 138 } 139 if (throttle.hasReqSize()) { 140 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 141 ThrottleType.REQUEST_SIZE, throttle.getReqSize())); 142 } 143 if (throttle.hasWriteNum()) { 144 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 145 ThrottleType.WRITE_NUMBER, throttle.getWriteNum())); 146 } 147 if (throttle.hasWriteSize()) { 148 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 149 ThrottleType.WRITE_SIZE, throttle.getWriteSize())); 150 } 151 if (throttle.hasReadNum()) { 152 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 153 ThrottleType.READ_NUMBER, throttle.getReadNum())); 154 } 155 if (throttle.hasReadSize()) { 156 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 157 ThrottleType.READ_SIZE, throttle.getReadSize())); 158 } 159 if (throttle.hasReqCapacityUnit()) { 160 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 161 ThrottleType.REQUEST_CAPACITY_UNIT, throttle.getReqCapacityUnit())); 162 } 163 if (throttle.hasReadCapacityUnit()) { 164 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 165 ThrottleType.READ_CAPACITY_UNIT, throttle.getReadCapacityUnit())); 166 } 167 if (throttle.hasWriteCapacityUnit()) { 168 settings.add(ThrottleSettings.fromTimedQuota(userName, tableName, namespace, regionServer, 169 ThrottleType.WRITE_CAPACITY_UNIT, throttle.getWriteCapacityUnit())); 170 } 171 return settings; 172 } 173 174 static QuotaSettings fromSpace(TableName table, String namespace, SpaceQuota protoQuota) { 175 if (protoQuota == null) { 176 return null; 177 } 178 if ((table == null && namespace == null) || (table != null && namespace != null)) { 179 throw new IllegalArgumentException( 180 "Can only construct SpaceLimitSettings for a table or namespace."); 181 } 182 if (table != null) { 183 if (protoQuota.getRemove()) { 184 return new SpaceLimitSettings(table); 185 } 186 return SpaceLimitSettings.fromSpaceQuota(table, protoQuota); 187 } else { 188 if (protoQuota.getRemove()) { 189 return new SpaceLimitSettings(namespace); 190 } 191 // namespace must be non-null 192 return SpaceLimitSettings.fromSpaceQuota(namespace, protoQuota); 193 } 194 } 195 196 /* 197 * ========================================================================== RPC Throttle 198 */ 199 200 /** 201 * Throttle the specified user. 202 * @param userName the user to throttle 203 * @param type the type of throttling 204 * @param limit the allowed number of request/data per timeUnit 205 * @param timeUnit the limit time unit 206 * @return the quota settings 207 */ 208 public static QuotaSettings throttleUser(final String userName, final ThrottleType type, 209 final long limit, final TimeUnit timeUnit) { 210 return throttleUser(userName, type, limit, timeUnit, QuotaScope.MACHINE); 211 } 212 213 /** 214 * Throttle the specified user. 215 * @param userName the user to throttle 216 * @param type the type of throttling 217 * @param limit the allowed number of request/data per timeUnit 218 * @param timeUnit the limit time unit 219 * @param scope the scope of throttling 220 * @return the quota settings 221 */ 222 public static QuotaSettings throttleUser(final String userName, final ThrottleType type, 223 final long limit, final TimeUnit timeUnit, QuotaScope scope) { 224 return throttle(userName, null, null, null, type, limit, timeUnit, scope); 225 } 226 227 /** 228 * Throttle the specified user on the specified table. 229 * @param userName the user to throttle 230 * @param tableName the table to throttle 231 * @param type the type of throttling 232 * @param limit the allowed number of request/data per timeUnit 233 * @param timeUnit the limit time unit 234 * @return the quota settings 235 */ 236 public static QuotaSettings throttleUser(final String userName, final TableName tableName, 237 final ThrottleType type, final long limit, final TimeUnit timeUnit) { 238 return throttleUser(userName, tableName, type, limit, timeUnit, QuotaScope.MACHINE); 239 } 240 241 /** 242 * Throttle the specified user on the specified table. 243 * @param userName the user to throttle 244 * @param tableName the table to throttle 245 * @param type the type of throttling 246 * @param limit the allowed number of request/data per timeUnit 247 * @param timeUnit the limit time unit 248 * @param scope the scope of throttling 249 * @return the quota settings 250 */ 251 public static QuotaSettings throttleUser(final String userName, final TableName tableName, 252 final ThrottleType type, final long limit, final TimeUnit timeUnit, QuotaScope scope) { 253 return throttle(userName, tableName, null, null, type, limit, timeUnit, scope); 254 } 255 256 /** 257 * Throttle the specified user on the specified namespace. 258 * @param userName the user to throttle 259 * @param namespace the namespace to throttle 260 * @param type the type of throttling 261 * @param limit the allowed number of request/data per timeUnit 262 * @param timeUnit the limit time unit 263 * @return the quota settings 264 */ 265 public static QuotaSettings throttleUser(final String userName, final String namespace, 266 final ThrottleType type, final long limit, final TimeUnit timeUnit) { 267 return throttleUser(userName, namespace, type, limit, timeUnit, QuotaScope.MACHINE); 268 } 269 270 /** 271 * Throttle the specified user on the specified namespace. 272 * @param userName the user to throttle 273 * @param namespace the namespace to throttle 274 * @param type the type of throttling 275 * @param limit the allowed number of request/data per timeUnit 276 * @param timeUnit the limit time unit 277 * @param scope the scope of throttling 278 * @return the quota settings 279 */ 280 public static QuotaSettings throttleUser(final String userName, final String namespace, 281 final ThrottleType type, final long limit, final TimeUnit timeUnit, QuotaScope scope) { 282 return throttle(userName, null, namespace, null, type, limit, timeUnit, scope); 283 } 284 285 /** 286 * Remove the throttling for the specified user. 287 * @param userName the user 288 * @return the quota settings 289 */ 290 public static QuotaSettings unthrottleUser(final String userName) { 291 return throttle(userName, null, null, null, null, 0, null, QuotaScope.MACHINE); 292 } 293 294 /** 295 * Remove the throttling for the specified user. 296 * @param userName the user 297 * @param type the type of throttling 298 * @return the quota settings 299 */ 300 public static QuotaSettings unthrottleUserByThrottleType(final String userName, 301 final ThrottleType type) { 302 return throttle(userName, null, null, null, type, 0, null, QuotaScope.MACHINE); 303 } 304 305 /** 306 * Remove the throttling for the specified user on the specified table. 307 * @param userName the user 308 * @param tableName the table 309 * @return the quota settings 310 */ 311 public static QuotaSettings unthrottleUser(final String userName, final TableName tableName) { 312 return throttle(userName, tableName, null, null, null, 0, null, QuotaScope.MACHINE); 313 } 314 315 /** 316 * Remove the throttling for the specified user on the specified table. 317 * @param userName the user 318 * @param tableName the table 319 * @param type the type of throttling 320 * @return the quota settings 321 */ 322 public static QuotaSettings unthrottleUserByThrottleType(final String userName, 323 final TableName tableName, final ThrottleType type) { 324 return throttle(userName, tableName, null, null, type, 0, null, QuotaScope.MACHINE); 325 } 326 327 /** 328 * Remove the throttling for the specified user on the specified namespace. 329 * @param userName the user 330 * @param namespace the namespace 331 * @return the quota settings 332 */ 333 public static QuotaSettings unthrottleUser(final String userName, final String namespace) { 334 return throttle(userName, null, namespace, null, null, 0, null, QuotaScope.MACHINE); 335 } 336 337 /** 338 * Remove the throttling for the specified user on the specified namespace. 339 * @param userName the user 340 * @param namespace the namespace 341 * @param type the type of throttling 342 * @return the quota settings 343 */ 344 public static QuotaSettings unthrottleUserByThrottleType(final String userName, 345 final String namespace, final ThrottleType type) { 346 return throttle(userName, null, namespace, null, type, 0, null, QuotaScope.MACHINE); 347 } 348 349 /** 350 * Throttle the specified table. 351 * @param tableName the table to throttle 352 * @param type the type of throttling 353 * @param limit the allowed number of request/data per timeUnit 354 * @param timeUnit the limit time unit 355 * @return the quota settings 356 */ 357 public static QuotaSettings throttleTable(final TableName tableName, final ThrottleType type, 358 final long limit, final TimeUnit timeUnit) { 359 return throttleTable(tableName, type, limit, timeUnit, QuotaScope.MACHINE); 360 } 361 362 /** 363 * Throttle the specified table. 364 * @param tableName the table to throttle 365 * @param type the type of throttling 366 * @param limit the allowed number of request/data per timeUnit 367 * @param timeUnit the limit time unit 368 * @param scope the scope of throttling 369 * @return the quota settings 370 */ 371 public static QuotaSettings throttleTable(final TableName tableName, final ThrottleType type, 372 final long limit, final TimeUnit timeUnit, QuotaScope scope) { 373 return throttle(null, tableName, null, null, type, limit, timeUnit, scope); 374 } 375 376 /** 377 * Remove the throttling for the specified table. 378 * @param tableName the table 379 * @return the quota settings 380 */ 381 public static QuotaSettings unthrottleTable(final TableName tableName) { 382 return throttle(null, tableName, null, null, null, 0, null, QuotaScope.MACHINE); 383 } 384 385 /** 386 * Remove the throttling for the specified table. 387 * @param tableName the table 388 * @param type the type of throttling 389 * @return the quota settings 390 */ 391 public static QuotaSettings unthrottleTableByThrottleType(final TableName tableName, 392 final ThrottleType type) { 393 return throttle(null, tableName, null, null, type, 0, null, QuotaScope.MACHINE); 394 } 395 396 /** 397 * Throttle the specified namespace. 398 * @param namespace the namespace to throttle 399 * @param type the type of throttling 400 * @param limit the allowed number of request/data per timeUnit 401 * @param timeUnit the limit time unit 402 * @return the quota settings 403 */ 404 public static QuotaSettings throttleNamespace(final String namespace, final ThrottleType type, 405 final long limit, final TimeUnit timeUnit) { 406 return throttleNamespace(namespace, type, limit, timeUnit, QuotaScope.MACHINE); 407 } 408 409 /** 410 * Throttle the specified namespace. 411 * @param namespace the namespace to throttle 412 * @param type the type of throttling 413 * @param limit the allowed number of request/data per timeUnit 414 * @param timeUnit the limit time unit 415 * @param scope the scope of throttling 416 * @return the quota settings 417 */ 418 public static QuotaSettings throttleNamespace(final String namespace, final ThrottleType type, 419 final long limit, final TimeUnit timeUnit, QuotaScope scope) { 420 return throttle(null, null, namespace, null, type, limit, timeUnit, scope); 421 } 422 423 /** 424 * Remove the throttling for the specified namespace. 425 * @param namespace the namespace 426 * @return the quota settings 427 */ 428 public static QuotaSettings unthrottleNamespace(final String namespace) { 429 return throttle(null, null, namespace, null, null, 0, null, QuotaScope.MACHINE); 430 } 431 432 /** 433 * Remove the throttling for the specified namespace by throttle type. 434 * @param namespace the namespace 435 * @param type the type of throttling 436 * @return the quota settings 437 */ 438 public static QuotaSettings unthrottleNamespaceByThrottleType(final String namespace, 439 final ThrottleType type) { 440 return throttle(null, null, namespace, null, type, 0, null, QuotaScope.MACHINE); 441 } 442 443 /** 444 * Throttle the specified region server. 445 * @param regionServer the region server to throttle 446 * @param type the type of throttling 447 * @param limit the allowed number of request/data per timeUnit 448 * @param timeUnit the limit time unit 449 * @return the quota settings 450 */ 451 public static QuotaSettings throttleRegionServer(final String regionServer, 452 final ThrottleType type, final long limit, final TimeUnit timeUnit) { 453 return throttle(null, null, null, regionServer, type, limit, timeUnit, QuotaScope.MACHINE); 454 } 455 456 /** 457 * Remove the throttling for the specified region server. 458 * @param regionServer the region Server 459 * @return the quota settings 460 */ 461 public static QuotaSettings unthrottleRegionServer(final String regionServer) { 462 return throttle(null, null, null, regionServer, null, 0, null, QuotaScope.MACHINE); 463 } 464 465 /** 466 * Remove the throttling for the specified region server by throttle type. 467 * @param regionServer the region Server 468 * @param type the type of throttling 469 * @return the quota settings 470 */ 471 public static QuotaSettings unthrottleRegionServerByThrottleType(final String regionServer, 472 final ThrottleType type) { 473 return throttle(null, null, null, regionServer, type, 0, null, QuotaScope.MACHINE); 474 } 475 476 /* Throttle helper */ 477 private static QuotaSettings throttle(final String userName, final TableName tableName, 478 final String namespace, final String regionServer, final ThrottleType type, final long limit, 479 final TimeUnit timeUnit, QuotaScope scope) { 480 QuotaProtos.ThrottleRequest.Builder builder = QuotaProtos.ThrottleRequest.newBuilder(); 481 if (type != null) { 482 builder.setType(ProtobufUtil.toProtoThrottleType(type)); 483 } 484 if (timeUnit != null) { 485 builder.setTimedQuota(ProtobufUtil.toTimedQuota(limit, timeUnit, scope)); 486 } 487 return new ThrottleSettings(userName, tableName, namespace, regionServer, builder.build()); 488 } 489 490 /* 491 * ========================================================================== Global Settings 492 */ 493 494 /** 495 * Set the "bypass global settings" for the specified user 496 * @param userName the user to throttle 497 * @param bypassGlobals true if the global settings should be bypassed 498 * @return the quota settings 499 */ 500 public static QuotaSettings bypassGlobals(final String userName, final boolean bypassGlobals) { 501 return new QuotaGlobalsSettingsBypass(userName, null, null, null, bypassGlobals); 502 } 503 504 /* 505 * ========================================================================== FileSystem Space 506 * Settings 507 */ 508 509 /** 510 * Creates a {@link QuotaSettings} object to limit the FileSystem space usage for the given table 511 * to the given size in bytes. When the space usage is exceeded by the table, the provided 512 * {@link SpaceViolationPolicy} is enacted on the table. 513 * @param tableName The name of the table on which the quota should be applied. 514 * @param sizeLimit The limit of a table's size in bytes. 515 * @param violationPolicy The action to take when the quota is exceeded. 516 * @return An {@link QuotaSettings} object. 517 */ 518 public static QuotaSettings limitTableSpace(final TableName tableName, long sizeLimit, 519 final SpaceViolationPolicy violationPolicy) { 520 return new SpaceLimitSettings(tableName, sizeLimit, violationPolicy); 521 } 522 523 /** 524 * Creates a {@link QuotaSettings} object to remove the FileSystem space quota for the given 525 * table. 526 * @param tableName The name of the table to remove the quota for. 527 * @return A {@link QuotaSettings} object. 528 */ 529 public static QuotaSettings removeTableSpaceLimit(TableName tableName) { 530 return new SpaceLimitSettings(tableName); 531 } 532 533 /** 534 * Creates a {@link QuotaSettings} object to limit the FileSystem space usage for the given 535 * namespace to the given size in bytes. When the space usage is exceeded by all tables in the 536 * namespace, the provided {@link SpaceViolationPolicy} is enacted on all tables in the namespace. 537 * @param namespace The namespace on which the quota should be applied. 538 * @param sizeLimit The limit of the namespace's size in bytes. 539 * @param violationPolicy The action to take when the the quota is exceeded. 540 * @return An {@link QuotaSettings} object. 541 */ 542 public static QuotaSettings limitNamespaceSpace(final String namespace, long sizeLimit, 543 final SpaceViolationPolicy violationPolicy) { 544 return new SpaceLimitSettings(namespace, sizeLimit, violationPolicy); 545 } 546 547 /** 548 * Creates a {@link QuotaSettings} object to remove the FileSystem space quota for the given 549 * namespace. 550 * @param namespace The namespace to remove the quota on. 551 * @return A {@link QuotaSettings} object. 552 */ 553 public static QuotaSettings removeNamespaceSpaceLimit(String namespace) { 554 return new SpaceLimitSettings(namespace); 555 } 556}