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