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