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