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 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 * 203 * @param userName the user to throttle 204 * @param type the type of throttling 205 * @param limit the allowed number of request/data per timeUnit 206 * @param timeUnit the limit time unit 207 * @return the quota settings 208 */ 209 public static QuotaSettings throttleUser(final String userName, final ThrottleType type, 210 final long limit, final TimeUnit timeUnit) { 211 return throttleUser(userName, type, limit, timeUnit, QuotaScope.MACHINE); 212 } 213 214 /** 215 * Throttle the specified user. 216 * @param userName the user to throttle 217 * @param type the type of throttling 218 * @param limit the allowed number of request/data per timeUnit 219 * @param timeUnit the limit time unit 220 * @param scope the scope of throttling 221 * @return the quota settings 222 */ 223 public static QuotaSettings throttleUser(final String userName, final ThrottleType type, 224 final long limit, final TimeUnit timeUnit, QuotaScope scope) { 225 return throttle(userName, null, null, null, type, limit, timeUnit, scope); 226 } 227 228 /** 229 * Throttle the specified user on the specified table. 230 * 231 * @param userName the user to throttle 232 * @param tableName the table to throttle 233 * @param type the type of throttling 234 * @param limit the allowed number of request/data per timeUnit 235 * @param timeUnit the limit time unit 236 * @return the quota settings 237 */ 238 public static QuotaSettings throttleUser(final String userName, final TableName tableName, 239 final ThrottleType type, final long limit, final TimeUnit timeUnit) { 240 return throttleUser(userName, tableName, type, limit, timeUnit, QuotaScope.MACHINE); 241 } 242 243 /** 244 * Throttle the specified user on the specified table. 245 * @param userName the user to throttle 246 * @param tableName the table to throttle 247 * @param type the type of throttling 248 * @param limit the allowed number of request/data per timeUnit 249 * @param timeUnit the limit time unit 250 * @param scope the scope of throttling 251 * @return the quota settings 252 */ 253 public static QuotaSettings throttleUser(final String userName, final TableName tableName, 254 final ThrottleType type, final long limit, final TimeUnit timeUnit, QuotaScope scope) { 255 return throttle(userName, tableName, null, null, type, limit, timeUnit, scope); 256 } 257 258 /** 259 * Throttle the specified user on the specified namespace. 260 * 261 * @param userName the user to throttle 262 * @param namespace the namespace to throttle 263 * @param type the type of throttling 264 * @param limit the allowed number of request/data per timeUnit 265 * @param timeUnit the limit time unit 266 * @return the quota settings 267 */ 268 public static QuotaSettings throttleUser(final String userName, final String namespace, 269 final ThrottleType type, final long limit, final TimeUnit timeUnit) { 270 return throttleUser(userName, namespace, type, limit, timeUnit, QuotaScope.MACHINE); 271 } 272 273 /** 274 * Throttle the specified user on the specified namespace. 275 * @param userName the user to throttle 276 * @param namespace the namespace to throttle 277 * @param type the type of throttling 278 * @param limit the allowed number of request/data per timeUnit 279 * @param timeUnit the limit time unit 280 * @param scope the scope of throttling 281 * @return the quota settings 282 */ 283 public static QuotaSettings throttleUser(final String userName, final String namespace, 284 final ThrottleType type, final long limit, final TimeUnit timeUnit, QuotaScope scope) { 285 return throttle(userName, null, namespace, null, type, limit, timeUnit, scope); 286 } 287 288 /** 289 * Remove the throttling for the specified user. 290 * 291 * @param userName the user 292 * @return the quota settings 293 */ 294 public static QuotaSettings unthrottleUser(final String userName) { 295 return throttle(userName, null, null, null, null, 0, null, QuotaScope.MACHINE); 296 } 297 298 /** 299 * Remove the throttling for the specified user. 300 * 301 * @param userName the user 302 * @param type the type of throttling 303 * @return the quota settings 304 */ 305 public static QuotaSettings unthrottleUserByThrottleType(final String userName, 306 final ThrottleType type) { 307 return throttle(userName, null, null, null, type, 0, null, QuotaScope.MACHINE); 308 } 309 310 /** 311 * Remove the throttling for the specified user on the specified table. 312 * 313 * @param userName the user 314 * @param tableName the table 315 * @return the quota settings 316 */ 317 public static QuotaSettings unthrottleUser(final String userName, final TableName tableName) { 318 return throttle(userName, tableName, null, null, null, 0, null, QuotaScope.MACHINE); 319 } 320 321 /** 322 * Remove the throttling for the specified user on the specified table. 323 * 324 * @param userName the user 325 * @param tableName the table 326 * @param type the type of throttling 327 * @return the quota settings 328 */ 329 public static QuotaSettings unthrottleUserByThrottleType(final String userName, 330 final TableName tableName, final ThrottleType type) { 331 return throttle(userName, tableName, null, null, type, 0, null, QuotaScope.MACHINE); 332 } 333 334 /** 335 * Remove the throttling for the specified user on the specified namespace. 336 * 337 * @param userName the user 338 * @param namespace the namespace 339 * @return the quota settings 340 */ 341 public static QuotaSettings unthrottleUser(final String userName, final String namespace) { 342 return throttle(userName, null, namespace, null, null, 0, null, QuotaScope.MACHINE); 343 } 344 345 /** 346 * Remove the throttling for the specified user on the specified namespace. 347 * 348 * @param userName the user 349 * @param namespace the namespace 350 * @param type the type of throttling 351 * @return the quota settings 352 */ 353 public static QuotaSettings unthrottleUserByThrottleType(final String userName, 354 final String namespace, final ThrottleType type) { 355 return throttle(userName, null, namespace, null, type, 0, null, QuotaScope.MACHINE); 356 } 357 358 /** 359 * Throttle the specified table. 360 * 361 * @param tableName the table to throttle 362 * @param type the type of throttling 363 * @param limit the allowed number of request/data per timeUnit 364 * @param timeUnit the limit time unit 365 * @return the quota settings 366 */ 367 public static QuotaSettings throttleTable(final TableName tableName, final ThrottleType type, 368 final long limit, final TimeUnit timeUnit) { 369 return throttleTable(tableName, type, limit, timeUnit, QuotaScope.MACHINE); 370 } 371 372 /** 373 * Throttle the specified table. 374 * @param tableName the table to throttle 375 * @param type the type of throttling 376 * @param limit the allowed number of request/data per timeUnit 377 * @param timeUnit the limit time unit 378 * @param scope the scope of throttling 379 * @return the quota settings 380 */ 381 public static QuotaSettings throttleTable(final TableName tableName, final ThrottleType type, 382 final long limit, final TimeUnit timeUnit, QuotaScope scope) { 383 return throttle(null, tableName, null, null, type, limit, timeUnit, scope); 384 } 385 386 /** 387 * Remove the throttling for the specified table. 388 * 389 * @param tableName the table 390 * @return the quota settings 391 */ 392 public static QuotaSettings unthrottleTable(final TableName tableName) { 393 return throttle(null, tableName, null, null, null, 0, null, QuotaScope.MACHINE); 394 } 395 396 /** 397 * Remove the throttling for the specified table. 398 * 399 * @param tableName the table 400 * @param type the type of throttling 401 * @return the quota settings 402 */ 403 public static QuotaSettings unthrottleTableByThrottleType(final TableName tableName, 404 final ThrottleType type) { 405 return throttle(null, tableName, null, null, type, 0, null, QuotaScope.MACHINE); 406 } 407 408 /** 409 * Throttle the specified namespace. 410 * 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 * @return the quota settings 416 */ 417 public static QuotaSettings throttleNamespace(final String namespace, final ThrottleType type, 418 final long limit, final TimeUnit timeUnit) { 419 return throttleNamespace(namespace, type, limit, timeUnit, QuotaScope.MACHINE); 420 } 421 422 /** 423 * Throttle the specified namespace. 424 * @param namespace the namespace to throttle 425 * @param type the type of throttling 426 * @param limit the allowed number of request/data per timeUnit 427 * @param timeUnit the limit time unit 428 * @param scope the scope of throttling 429 * @return the quota settings 430 */ 431 public static QuotaSettings throttleNamespace(final String namespace, final ThrottleType type, 432 final long limit, final TimeUnit timeUnit, QuotaScope scope) { 433 return throttle(null, null, namespace, null, type, limit, timeUnit, scope); 434 } 435 436 /** 437 * Remove the throttling for the specified namespace. 438 * 439 * @param namespace the namespace 440 * @return the quota settings 441 */ 442 public static QuotaSettings unthrottleNamespace(final String namespace) { 443 return throttle(null, null, namespace, null, null, 0, null, QuotaScope.MACHINE); 444 } 445 446 /** 447 * Remove the throttling for the specified namespace by throttle type. 448 * 449 * @param namespace the namespace 450 * @param type the type of throttling 451 * @return the quota settings 452 */ 453 public static QuotaSettings unthrottleNamespaceByThrottleType(final String namespace, 454 final ThrottleType type) { 455 return throttle(null, null, namespace, null, type, 0, null, QuotaScope.MACHINE); 456 } 457 458 /** 459 * Throttle the specified region server. 460 * 461 * @param regionServer the region server to throttle 462 * @param type the type of throttling 463 * @param limit the allowed number of request/data per timeUnit 464 * @param timeUnit the limit time unit 465 * @return the quota settings 466 */ 467 public static QuotaSettings throttleRegionServer(final String regionServer, 468 final ThrottleType type, final long limit, final TimeUnit timeUnit) { 469 return throttle(null, null, null, regionServer, type, limit, timeUnit, QuotaScope.MACHINE); 470 } 471 472 /** 473 * Remove the throttling for the specified region server. 474 * 475 * @param regionServer the region Server 476 * @return the quota settings 477 */ 478 public static QuotaSettings unthrottleRegionServer(final String regionServer) { 479 return throttle(null, null, null, regionServer, null, 0, null, QuotaScope.MACHINE); 480 } 481 482 /** 483 * Remove the throttling for the specified region server by throttle type. 484 * 485 * @param regionServer the region Server 486 * @param type the type of throttling 487 * @return the quota settings 488 */ 489 public static QuotaSettings unthrottleRegionServerByThrottleType(final String regionServer, 490 final ThrottleType type) { 491 return throttle(null, null, null, regionServer, type, 0, null, QuotaScope.MACHINE); 492 } 493 494 /* Throttle helper */ 495 private static QuotaSettings throttle(final String userName, final TableName tableName, 496 final String namespace, final String regionServer, final ThrottleType type, final long limit, 497 final TimeUnit timeUnit, QuotaScope scope) { 498 QuotaProtos.ThrottleRequest.Builder builder = QuotaProtos.ThrottleRequest.newBuilder(); 499 if (type != null) { 500 builder.setType(ProtobufUtil.toProtoThrottleType(type)); 501 } 502 if (timeUnit != null) { 503 builder.setTimedQuota(ProtobufUtil.toTimedQuota(limit, timeUnit, scope)); 504 } 505 return new ThrottleSettings(userName, tableName, namespace, regionServer, builder.build()); 506 } 507 508 /* ========================================================================== 509 * Global Settings 510 */ 511 512 /** 513 * Set the "bypass global settings" for the specified user 514 * 515 * @param userName the user to throttle 516 * @param bypassGlobals true if the global settings should be bypassed 517 * @return the quota settings 518 */ 519 public static QuotaSettings bypassGlobals(final String userName, final boolean bypassGlobals) { 520 return new QuotaGlobalsSettingsBypass(userName, null, null, null, bypassGlobals); 521 } 522 523 /* ========================================================================== 524 * FileSystem Space Settings 525 */ 526 527 /** 528 * Creates a {@link QuotaSettings} object to limit the FileSystem space usage for the given table 529 * to the given size in bytes. When the space usage is exceeded by the table, the provided 530 * {@link SpaceViolationPolicy} is enacted on the table. 531 * 532 * @param tableName The name of the table on which the quota should be applied. 533 * @param sizeLimit The limit of a table's size in bytes. 534 * @param violationPolicy The action to take when the quota is exceeded. 535 * @return An {@link QuotaSettings} object. 536 */ 537 public static QuotaSettings limitTableSpace( 538 final TableName tableName, long sizeLimit, final SpaceViolationPolicy violationPolicy) { 539 return new SpaceLimitSettings(tableName, sizeLimit, violationPolicy); 540 } 541 542 /** 543 * Creates a {@link QuotaSettings} object to remove the FileSystem space quota for the given 544 * table. 545 * 546 * @param tableName The name of the table to remove the quota for. 547 * @return A {@link QuotaSettings} object. 548 */ 549 public static QuotaSettings removeTableSpaceLimit(TableName tableName) { 550 return new SpaceLimitSettings(tableName); 551 } 552 553 /** 554 * Creates a {@link QuotaSettings} object to limit the FileSystem space usage for the given 555 * namespace to the given size in bytes. When the space usage is exceeded by all tables in the 556 * namespace, the provided {@link SpaceViolationPolicy} is enacted on all tables in the namespace. 557 * 558 * @param namespace The namespace on which the quota should be applied. 559 * @param sizeLimit The limit of the namespace's size in bytes. 560 * @param violationPolicy The action to take when the the quota is exceeded. 561 * @return An {@link QuotaSettings} object. 562 */ 563 public static QuotaSettings limitNamespaceSpace( 564 final String namespace, long sizeLimit, final SpaceViolationPolicy violationPolicy) { 565 return new SpaceLimitSettings(namespace, sizeLimit, violationPolicy); 566 } 567 568 /** 569 * Creates a {@link QuotaSettings} object to remove the FileSystem space quota for the given 570 * namespace. 571 * 572 * @param namespace The namespace to remove the quota on. 573 * @return A {@link QuotaSettings} object. 574 */ 575 public static QuotaSettings removeNamespaceSpaceLimit(String namespace) { 576 return new SpaceLimitSettings(namespace); 577 } 578}