HBASE-18873 Move protobufs to private implementation on GlobalQuotaSettings
A hack to "hide" the protobufs, but it's not going to be a trivial change to remove use of protobufs entirely as they're serialized into the hbase:quota table.
This commit is contained in:
parent
1e98ce2c8e
commit
3e0b90b949
|
@ -116,7 +116,7 @@ public class QuotaSettingsFactory {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<QuotaSettings> fromThrottle(final String userName, final TableName tableName,
|
protected static List<QuotaSettings> fromThrottle(final String userName, final TableName tableName,
|
||||||
final String namespace, final QuotaProtos.Throttle throttle) {
|
final String namespace, final QuotaProtos.Throttle throttle) {
|
||||||
List<QuotaSettings> settings = new ArrayList<>();
|
List<QuotaSettings> settings = new ArrayList<>();
|
||||||
if (throttle.hasReqNum()) {
|
if (throttle.hasReqNum()) {
|
||||||
|
|
|
@ -16,23 +16,12 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.hbase.quotas;
|
package org.apache.hadoop.hbase.quotas;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.util.List;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.DoNotRetryIOException;
|
|
||||||
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
|
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
|
||||||
import org.apache.hadoop.hbase.TableName;
|
import org.apache.hadoop.hbase.TableName;
|
||||||
import org.apache.hadoop.hbase.quotas.QuotaSettingsFactory.QuotaGlobalsSettingsBypass;
|
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaRequest.Builder;
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.SetQuotaRequest.Builder;
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas;
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas;
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceQuota;
|
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Throttle;
|
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.TimedQuota;
|
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
|
|
||||||
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos;
|
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
import org.apache.yetus.audience.InterfaceStability;
|
import org.apache.yetus.audience.InterfaceStability;
|
||||||
|
|
||||||
|
@ -43,28 +32,19 @@ import org.apache.yetus.audience.InterfaceStability;
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.LimitedPrivate({HBaseInterfaceAudience.COPROC})
|
@InterfaceAudience.LimitedPrivate({HBaseInterfaceAudience.COPROC})
|
||||||
@InterfaceStability.Evolving
|
@InterfaceStability.Evolving
|
||||||
public class GlobalQuotaSettings extends QuotaSettings {
|
public abstract class GlobalQuotaSettings extends QuotaSettings {
|
||||||
private final QuotaProtos.Throttle throttleProto;
|
|
||||||
private final Boolean bypassGlobals;
|
|
||||||
private final QuotaProtos.SpaceQuota spaceProto;
|
|
||||||
|
|
||||||
protected GlobalQuotaSettings(
|
protected GlobalQuotaSettings(String userName, TableName tableName, String namespace) {
|
||||||
String username, TableName tableName, String namespace, QuotaProtos.Quotas quotas) {
|
|
||||||
this(username, tableName, namespace,
|
|
||||||
(quotas != null && quotas.hasThrottle() ? quotas.getThrottle() : null),
|
|
||||||
(quotas != null && quotas.hasBypassGlobals() ? quotas.getBypassGlobals() : null),
|
|
||||||
(quotas != null && quotas.hasSpace() ? quotas.getSpace() : null));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected GlobalQuotaSettings(
|
|
||||||
String userName, TableName tableName, String namespace, QuotaProtos.Throttle throttleProto,
|
|
||||||
Boolean bypassGlobals, QuotaProtos.SpaceQuota spaceProto) {
|
|
||||||
super(userName, tableName, namespace);
|
super(userName, tableName, namespace);
|
||||||
this.throttleProto = throttleProto;
|
|
||||||
this.bypassGlobals = bypassGlobals;
|
|
||||||
this.spaceProto = spaceProto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes a list of QuotaSettings that present the complete quota state of the combination of
|
||||||
|
* this user, table, and/or namespace. Beware in calling this method repeatedly as the
|
||||||
|
* implementation of it may be costly.
|
||||||
|
*/
|
||||||
|
public abstract List<QuotaSettings> getQuotaSettings();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QuotaType getQuotaType() {
|
public QuotaType getQuotaType() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
@ -76,254 +56,4 @@ public class GlobalQuotaSettings extends QuotaSettings {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"This class should not be used to generate a SetQuotaRequest.");
|
"This class should not be used to generate a SetQuotaRequest.");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected QuotaProtos.Throttle getThrottleProto() {
|
|
||||||
return this.throttleProto;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Boolean getGlobalBypass() {
|
|
||||||
return this.bypassGlobals;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected QuotaProtos.SpaceQuota getSpaceProto() {
|
|
||||||
return this.spaceProto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new {@link Quotas} message from {@code this}.
|
|
||||||
*/
|
|
||||||
protected Quotas toQuotas() {
|
|
||||||
QuotaProtos.Quotas.Builder builder = QuotaProtos.Quotas.newBuilder();
|
|
||||||
if (getThrottleProto() != null) {
|
|
||||||
builder.setThrottle(getThrottleProto());
|
|
||||||
}
|
|
||||||
if (getGlobalBypass() != null) {
|
|
||||||
builder.setBypassGlobals(getGlobalBypass());
|
|
||||||
}
|
|
||||||
if (getSpaceProto() != null) {
|
|
||||||
builder.setSpace(getSpaceProto());
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected GlobalQuotaSettings merge(QuotaSettings other) throws IOException {
|
|
||||||
// Validate the quota subject
|
|
||||||
validateQuotaTarget(other);
|
|
||||||
|
|
||||||
// Propagate the Throttle
|
|
||||||
QuotaProtos.Throttle.Builder throttleBuilder = (throttleProto == null
|
|
||||||
? null : throttleProto.toBuilder());
|
|
||||||
if (other instanceof ThrottleSettings) {
|
|
||||||
if (throttleBuilder == null) {
|
|
||||||
throttleBuilder = QuotaProtos.Throttle.newBuilder();
|
|
||||||
}
|
|
||||||
ThrottleSettings otherThrottle = (ThrottleSettings) other;
|
|
||||||
|
|
||||||
if (otherThrottle.proto.hasType()) {
|
|
||||||
QuotaProtos.ThrottleRequest otherProto = otherThrottle.proto;
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
validateTimedQuota(otherProto.getTimedQuota());
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (otherProto.getType()) {
|
|
||||||
case REQUEST_NUMBER:
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
throttleBuilder.setReqNum(otherProto.getTimedQuota());
|
|
||||||
} else {
|
|
||||||
throttleBuilder.clearReqNum();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REQUEST_SIZE:
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
throttleBuilder.setReqSize(otherProto.getTimedQuota());
|
|
||||||
} else {
|
|
||||||
throttleBuilder.clearReqSize();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WRITE_NUMBER:
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
throttleBuilder.setWriteNum(otherProto.getTimedQuota());
|
|
||||||
} else {
|
|
||||||
throttleBuilder.clearWriteNum();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WRITE_SIZE:
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
throttleBuilder.setWriteSize(otherProto.getTimedQuota());
|
|
||||||
} else {
|
|
||||||
throttleBuilder.clearWriteSize();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case READ_NUMBER:
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
throttleBuilder.setReadNum(otherProto.getTimedQuota());
|
|
||||||
} else {
|
|
||||||
throttleBuilder.clearReqNum();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case READ_SIZE:
|
|
||||||
if (otherProto.hasTimedQuota()) {
|
|
||||||
throttleBuilder.setReadSize(otherProto.getTimedQuota());
|
|
||||||
} else {
|
|
||||||
throttleBuilder.clearReadSize();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clearThrottleBuilder(throttleBuilder);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clearThrottleBuilder(throttleBuilder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Propagate the space quota portion
|
|
||||||
QuotaProtos.SpaceQuota.Builder spaceBuilder = (spaceProto == null
|
|
||||||
? null : spaceProto.toBuilder());
|
|
||||||
if (other instanceof SpaceLimitSettings) {
|
|
||||||
if (spaceBuilder == null) {
|
|
||||||
spaceBuilder = QuotaProtos.SpaceQuota.newBuilder();
|
|
||||||
}
|
|
||||||
SpaceLimitSettings settingsToMerge = (SpaceLimitSettings) other;
|
|
||||||
|
|
||||||
QuotaProtos.SpaceLimitRequest spaceRequest = settingsToMerge.getProto();
|
|
||||||
|
|
||||||
// The message contained the expect SpaceQuota object
|
|
||||||
if (spaceRequest.hasQuota()) {
|
|
||||||
SpaceQuota quotaToMerge = spaceRequest.getQuota();
|
|
||||||
// Validate that the two settings are for the same target.
|
|
||||||
// SpaceQuotas either apply to a table or a namespace (no user spacequota).
|
|
||||||
if (!Objects.equals(getTableName(), settingsToMerge.getTableName())
|
|
||||||
&& !Objects.equals(getNamespace(), settingsToMerge.getNamespace())) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Cannot merge " + settingsToMerge + " into " + this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quotaToMerge.getRemove()) {
|
|
||||||
// Update the builder to propagate the removal
|
|
||||||
spaceBuilder.setRemove(true).clearSoftLimit().clearViolationPolicy();
|
|
||||||
} else {
|
|
||||||
// Add the new settings to the existing settings
|
|
||||||
spaceBuilder.mergeFrom(quotaToMerge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Boolean bypassGlobals = this.bypassGlobals;
|
|
||||||
if (other instanceof QuotaGlobalsSettingsBypass) {
|
|
||||||
bypassGlobals = ((QuotaGlobalsSettingsBypass) other).getBypass();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (throttleBuilder == null &&
|
|
||||||
(spaceBuilder == null || (spaceBuilder.hasRemove() && spaceBuilder.getRemove()))
|
|
||||||
&& bypassGlobals == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new GlobalQuotaSettings(
|
|
||||||
getUserName(), getTableName(), getNamespace(),
|
|
||||||
(throttleBuilder == null ? null : throttleBuilder.build()), bypassGlobals,
|
|
||||||
(spaceBuilder == null ? null : spaceBuilder.build()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateTimedQuota(final TimedQuota timedQuota) throws IOException {
|
|
||||||
if (timedQuota.getSoftLimit() < 1) {
|
|
||||||
throw new DoNotRetryIOException(new UnsupportedOperationException(
|
|
||||||
"The throttle limit must be greater then 0, got " + timedQuota.getSoftLimit()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
builder.append("GlobalQuota: ");
|
|
||||||
if (throttleProto != null) {
|
|
||||||
Map<ThrottleType,TimedQuota> throttleQuotas = buildThrottleQuotas(throttleProto);
|
|
||||||
builder.append(" { TYPE => THROTTLE ");
|
|
||||||
for (Entry<ThrottleType,TimedQuota> entry : throttleQuotas.entrySet()) {
|
|
||||||
final ThrottleType type = entry.getKey();
|
|
||||||
final TimedQuota timedQuota = entry.getValue();
|
|
||||||
builder.append("{THROTTLE_TYPE => ").append(type.name()).append(", LIMIT => ");
|
|
||||||
if (timedQuota.hasSoftLimit()) {
|
|
||||||
switch (type) {
|
|
||||||
case REQUEST_NUMBER:
|
|
||||||
case WRITE_NUMBER:
|
|
||||||
case READ_NUMBER:
|
|
||||||
builder.append(String.format("%dreq", timedQuota.getSoftLimit()));
|
|
||||||
break;
|
|
||||||
case REQUEST_SIZE:
|
|
||||||
case WRITE_SIZE:
|
|
||||||
case READ_SIZE:
|
|
||||||
builder.append(sizeToString(timedQuota.getSoftLimit()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (timedQuota.hasShare()) {
|
|
||||||
builder.append(String.format("%.2f%%", timedQuota.getShare()));
|
|
||||||
}
|
|
||||||
builder.append('/');
|
|
||||||
builder.append(timeToString(ProtobufUtil.toTimeUnit(timedQuota.getTimeUnit())));
|
|
||||||
if (timedQuota.hasScope()) {
|
|
||||||
builder.append(", SCOPE => ");
|
|
||||||
builder.append(timedQuota.getScope().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.append( "} } ");
|
|
||||||
} else {
|
|
||||||
builder.append(" {} ");
|
|
||||||
}
|
|
||||||
if (bypassGlobals != null) {
|
|
||||||
builder.append(" { GLOBAL_BYPASS => " + bypassGlobals + " } ");
|
|
||||||
}
|
|
||||||
if (spaceProto != null) {
|
|
||||||
builder.append(" { TYPE => SPACE");
|
|
||||||
if (getTableName() != null) {
|
|
||||||
builder.append(", TABLE => ").append(getTableName());
|
|
||||||
}
|
|
||||||
if (getNamespace() != null) {
|
|
||||||
builder.append(", NAMESPACE => ").append(getNamespace());
|
|
||||||
}
|
|
||||||
if (spaceProto.getRemove()) {
|
|
||||||
builder.append(", REMOVE => ").append(spaceProto.getRemove());
|
|
||||||
} else {
|
|
||||||
builder.append(", LIMIT => ").append(spaceProto.getSoftLimit());
|
|
||||||
builder.append(", VIOLATION_POLICY => ").append(spaceProto.getViolationPolicy());
|
|
||||||
}
|
|
||||||
builder.append(" } ");
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<ThrottleType,TimedQuota> buildThrottleQuotas(Throttle proto) {
|
|
||||||
HashMap<ThrottleType,TimedQuota> quotas = new HashMap<>();
|
|
||||||
if (proto.hasReadNum()) {
|
|
||||||
quotas.put(ThrottleType.READ_NUMBER, proto.getReadNum());
|
|
||||||
}
|
|
||||||
if (proto.hasReadSize()) {
|
|
||||||
quotas.put(ThrottleType.READ_SIZE, proto.getReadSize());
|
|
||||||
}
|
|
||||||
if (proto.hasReqNum()) {
|
|
||||||
quotas.put(ThrottleType.REQUEST_NUMBER, proto.getReqNum());
|
|
||||||
}
|
|
||||||
if (proto.hasReqSize()) {
|
|
||||||
quotas.put(ThrottleType.REQUEST_SIZE, proto.getReqSize());
|
|
||||||
}
|
|
||||||
if (proto.hasWriteNum()) {
|
|
||||||
quotas.put(ThrottleType.WRITE_NUMBER, proto.getWriteNum());
|
|
||||||
}
|
|
||||||
if (proto.hasWriteSize()) {
|
|
||||||
quotas.put(ThrottleType.WRITE_SIZE, proto.getWriteSize());
|
|
||||||
}
|
|
||||||
return quotas;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearThrottleBuilder(QuotaProtos.Throttle.Builder builder) {
|
|
||||||
builder.clearReadNum();
|
|
||||||
builder.clearReadSize();
|
|
||||||
builder.clearReqNum();
|
|
||||||
builder.clearReqSize();
|
|
||||||
builder.clearWriteNum();
|
|
||||||
builder.clearWriteSize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,332 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to you under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.hbase.quotas;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.DoNotRetryIOException;
|
||||||
|
import org.apache.hadoop.hbase.TableName;
|
||||||
|
import org.apache.hadoop.hbase.quotas.QuotaSettingsFactory.QuotaGlobalsSettingsBypass;
|
||||||
|
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
|
||||||
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos;
|
||||||
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas;
|
||||||
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.SpaceQuota;
|
||||||
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Throttle;
|
||||||
|
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.TimedQuota;
|
||||||
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link GlobalQuotaSettings} to hide the Protobuf messages we use internally.
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Private
|
||||||
|
public class GlobalQuotaSettingsImpl extends GlobalQuotaSettings {
|
||||||
|
|
||||||
|
private final QuotaProtos.Throttle throttleProto;
|
||||||
|
private final Boolean bypassGlobals;
|
||||||
|
private final QuotaProtos.SpaceQuota spaceProto;
|
||||||
|
|
||||||
|
protected GlobalQuotaSettingsImpl(
|
||||||
|
String username, TableName tableName, String namespace, QuotaProtos.Quotas quotas) {
|
||||||
|
this(username, tableName, namespace,
|
||||||
|
(quotas != null && quotas.hasThrottle() ? quotas.getThrottle() : null),
|
||||||
|
(quotas != null && quotas.hasBypassGlobals() ? quotas.getBypassGlobals() : null),
|
||||||
|
(quotas != null && quotas.hasSpace() ? quotas.getSpace() : null));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected GlobalQuotaSettingsImpl(
|
||||||
|
String userName, TableName tableName, String namespace, QuotaProtos.Throttle throttleProto,
|
||||||
|
Boolean bypassGlobals, QuotaProtos.SpaceQuota spaceProto) {
|
||||||
|
super(userName, tableName, namespace);
|
||||||
|
this.throttleProto = throttleProto;
|
||||||
|
this.bypassGlobals = bypassGlobals;
|
||||||
|
this.spaceProto = spaceProto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<QuotaSettings> getQuotaSettings() {
|
||||||
|
// Very similar to QuotaSettingsFactory
|
||||||
|
List<QuotaSettings> settings = new ArrayList<>();
|
||||||
|
if (throttleProto != null) {
|
||||||
|
settings.addAll(QuotaSettingsFactory.fromThrottle(
|
||||||
|
getUserName(), getTableName(), getNamespace(), throttleProto));
|
||||||
|
}
|
||||||
|
if (bypassGlobals != null && bypassGlobals.booleanValue()) {
|
||||||
|
settings.add(new QuotaGlobalsSettingsBypass(
|
||||||
|
getUserName(), getTableName(), getNamespace(), true));
|
||||||
|
}
|
||||||
|
if (spaceProto != null) {
|
||||||
|
settings.add(QuotaSettingsFactory.fromSpace(getTableName(), getNamespace(), spaceProto));
|
||||||
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected QuotaProtos.Throttle getThrottleProto() {
|
||||||
|
return this.throttleProto;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Boolean getBypassGlobals() {
|
||||||
|
return this.bypassGlobals;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected QuotaProtos.SpaceQuota getSpaceProto() {
|
||||||
|
return this.spaceProto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link Quotas} message from {@code this}.
|
||||||
|
*/
|
||||||
|
protected Quotas toQuotas() {
|
||||||
|
QuotaProtos.Quotas.Builder builder = QuotaProtos.Quotas.newBuilder();
|
||||||
|
if (getThrottleProto() != null) {
|
||||||
|
builder.setThrottle(getThrottleProto());
|
||||||
|
}
|
||||||
|
if (getBypassGlobals() != null) {
|
||||||
|
builder.setBypassGlobals(getBypassGlobals());
|
||||||
|
}
|
||||||
|
if (getSpaceProto() != null) {
|
||||||
|
builder.setSpace(getSpaceProto());
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GlobalQuotaSettingsImpl merge(QuotaSettings other) throws IOException {
|
||||||
|
// Validate the quota subject
|
||||||
|
validateQuotaTarget(other);
|
||||||
|
|
||||||
|
// Propagate the Throttle
|
||||||
|
QuotaProtos.Throttle.Builder throttleBuilder = (throttleProto == null
|
||||||
|
? null : throttleProto.toBuilder());
|
||||||
|
if (other instanceof ThrottleSettings) {
|
||||||
|
if (throttleBuilder == null) {
|
||||||
|
throttleBuilder = QuotaProtos.Throttle.newBuilder();
|
||||||
|
}
|
||||||
|
ThrottleSettings otherThrottle = (ThrottleSettings) other;
|
||||||
|
|
||||||
|
if (otherThrottle.proto.hasType()) {
|
||||||
|
QuotaProtos.ThrottleRequest otherProto = otherThrottle.proto;
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
validateTimedQuota(otherProto.getTimedQuota());
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (otherProto.getType()) {
|
||||||
|
case REQUEST_NUMBER:
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
throttleBuilder.setReqNum(otherProto.getTimedQuota());
|
||||||
|
} else {
|
||||||
|
throttleBuilder.clearReqNum();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REQUEST_SIZE:
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
throttleBuilder.setReqSize(otherProto.getTimedQuota());
|
||||||
|
} else {
|
||||||
|
throttleBuilder.clearReqSize();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WRITE_NUMBER:
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
throttleBuilder.setWriteNum(otherProto.getTimedQuota());
|
||||||
|
} else {
|
||||||
|
throttleBuilder.clearWriteNum();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WRITE_SIZE:
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
throttleBuilder.setWriteSize(otherProto.getTimedQuota());
|
||||||
|
} else {
|
||||||
|
throttleBuilder.clearWriteSize();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_NUMBER:
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
throttleBuilder.setReadNum(otherProto.getTimedQuota());
|
||||||
|
} else {
|
||||||
|
throttleBuilder.clearReqNum();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case READ_SIZE:
|
||||||
|
if (otherProto.hasTimedQuota()) {
|
||||||
|
throttleBuilder.setReadSize(otherProto.getTimedQuota());
|
||||||
|
} else {
|
||||||
|
throttleBuilder.clearReadSize();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clearThrottleBuilder(throttleBuilder);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clearThrottleBuilder(throttleBuilder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Propagate the space quota portion
|
||||||
|
QuotaProtos.SpaceQuota.Builder spaceBuilder = (spaceProto == null
|
||||||
|
? null : spaceProto.toBuilder());
|
||||||
|
if (other instanceof SpaceLimitSettings) {
|
||||||
|
if (spaceBuilder == null) {
|
||||||
|
spaceBuilder = QuotaProtos.SpaceQuota.newBuilder();
|
||||||
|
}
|
||||||
|
SpaceLimitSettings settingsToMerge = (SpaceLimitSettings) other;
|
||||||
|
|
||||||
|
QuotaProtos.SpaceLimitRequest spaceRequest = settingsToMerge.getProto();
|
||||||
|
|
||||||
|
// The message contained the expect SpaceQuota object
|
||||||
|
if (spaceRequest.hasQuota()) {
|
||||||
|
SpaceQuota quotaToMerge = spaceRequest.getQuota();
|
||||||
|
// Validate that the two settings are for the same target.
|
||||||
|
// SpaceQuotas either apply to a table or a namespace (no user spacequota).
|
||||||
|
if (!Objects.equals(getTableName(), settingsToMerge.getTableName())
|
||||||
|
&& !Objects.equals(getNamespace(), settingsToMerge.getNamespace())) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot merge " + settingsToMerge + " into " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quotaToMerge.getRemove()) {
|
||||||
|
// Update the builder to propagate the removal
|
||||||
|
spaceBuilder.setRemove(true).clearSoftLimit().clearViolationPolicy();
|
||||||
|
} else {
|
||||||
|
// Add the new settings to the existing settings
|
||||||
|
spaceBuilder.mergeFrom(quotaToMerge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean bypassGlobals = this.bypassGlobals;
|
||||||
|
if (other instanceof QuotaGlobalsSettingsBypass) {
|
||||||
|
bypassGlobals = ((QuotaGlobalsSettingsBypass) other).getBypass();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throttleBuilder == null &&
|
||||||
|
(spaceBuilder == null || (spaceBuilder.hasRemove() && spaceBuilder.getRemove()))
|
||||||
|
&& bypassGlobals == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new GlobalQuotaSettingsImpl(
|
||||||
|
getUserName(), getTableName(), getNamespace(),
|
||||||
|
(throttleBuilder == null ? null : throttleBuilder.build()), bypassGlobals,
|
||||||
|
(spaceBuilder == null ? null : spaceBuilder.build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateTimedQuota(final TimedQuota timedQuota) throws IOException {
|
||||||
|
if (timedQuota.getSoftLimit() < 1) {
|
||||||
|
throw new DoNotRetryIOException(new UnsupportedOperationException(
|
||||||
|
"The throttle limit must be greater then 0, got " + timedQuota.getSoftLimit()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("GlobalQuota: ");
|
||||||
|
if (throttleProto != null) {
|
||||||
|
Map<ThrottleType,TimedQuota> throttleQuotas = buildThrottleQuotas(throttleProto);
|
||||||
|
builder.append(" { TYPE => THROTTLE ");
|
||||||
|
for (Entry<ThrottleType,TimedQuota> entry : throttleQuotas.entrySet()) {
|
||||||
|
final ThrottleType type = entry.getKey();
|
||||||
|
final TimedQuota timedQuota = entry.getValue();
|
||||||
|
builder.append("{THROTTLE_TYPE => ").append(type.name()).append(", LIMIT => ");
|
||||||
|
if (timedQuota.hasSoftLimit()) {
|
||||||
|
switch (type) {
|
||||||
|
case REQUEST_NUMBER:
|
||||||
|
case WRITE_NUMBER:
|
||||||
|
case READ_NUMBER:
|
||||||
|
builder.append(String.format("%dreq", timedQuota.getSoftLimit()));
|
||||||
|
break;
|
||||||
|
case REQUEST_SIZE:
|
||||||
|
case WRITE_SIZE:
|
||||||
|
case READ_SIZE:
|
||||||
|
builder.append(sizeToString(timedQuota.getSoftLimit()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (timedQuota.hasShare()) {
|
||||||
|
builder.append(String.format("%.2f%%", timedQuota.getShare()));
|
||||||
|
}
|
||||||
|
builder.append('/');
|
||||||
|
builder.append(timeToString(ProtobufUtil.toTimeUnit(timedQuota.getTimeUnit())));
|
||||||
|
if (timedQuota.hasScope()) {
|
||||||
|
builder.append(", SCOPE => ");
|
||||||
|
builder.append(timedQuota.getScope().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.append( "} } ");
|
||||||
|
} else {
|
||||||
|
builder.append(" {} ");
|
||||||
|
}
|
||||||
|
if (bypassGlobals != null) {
|
||||||
|
builder.append(" { GLOBAL_BYPASS => " + bypassGlobals + " } ");
|
||||||
|
}
|
||||||
|
if (spaceProto != null) {
|
||||||
|
builder.append(" { TYPE => SPACE");
|
||||||
|
if (getTableName() != null) {
|
||||||
|
builder.append(", TABLE => ").append(getTableName());
|
||||||
|
}
|
||||||
|
if (getNamespace() != null) {
|
||||||
|
builder.append(", NAMESPACE => ").append(getNamespace());
|
||||||
|
}
|
||||||
|
if (spaceProto.getRemove()) {
|
||||||
|
builder.append(", REMOVE => ").append(spaceProto.getRemove());
|
||||||
|
} else {
|
||||||
|
builder.append(", LIMIT => ").append(spaceProto.getSoftLimit());
|
||||||
|
builder.append(", VIOLATION_POLICY => ").append(spaceProto.getViolationPolicy());
|
||||||
|
}
|
||||||
|
builder.append(" } ");
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<ThrottleType,TimedQuota> buildThrottleQuotas(Throttle proto) {
|
||||||
|
HashMap<ThrottleType,TimedQuota> quotas = new HashMap<>();
|
||||||
|
if (proto.hasReadNum()) {
|
||||||
|
quotas.put(ThrottleType.READ_NUMBER, proto.getReadNum());
|
||||||
|
}
|
||||||
|
if (proto.hasReadSize()) {
|
||||||
|
quotas.put(ThrottleType.READ_SIZE, proto.getReadSize());
|
||||||
|
}
|
||||||
|
if (proto.hasReqNum()) {
|
||||||
|
quotas.put(ThrottleType.REQUEST_NUMBER, proto.getReqNum());
|
||||||
|
}
|
||||||
|
if (proto.hasReqSize()) {
|
||||||
|
quotas.put(ThrottleType.REQUEST_SIZE, proto.getReqSize());
|
||||||
|
}
|
||||||
|
if (proto.hasWriteNum()) {
|
||||||
|
quotas.put(ThrottleType.WRITE_NUMBER, proto.getWriteNum());
|
||||||
|
}
|
||||||
|
if (proto.hasWriteSize()) {
|
||||||
|
quotas.put(ThrottleType.WRITE_SIZE, proto.getWriteSize());
|
||||||
|
}
|
||||||
|
return quotas;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearThrottleBuilder(QuotaProtos.Throttle.Builder builder) {
|
||||||
|
builder.clearReadNum();
|
||||||
|
builder.clearReadSize();
|
||||||
|
builder.clearReqNum();
|
||||||
|
builder.clearReqSize();
|
||||||
|
builder.clearWriteNum();
|
||||||
|
builder.clearWriteSize();
|
||||||
|
}
|
||||||
|
}
|
|
@ -153,12 +153,12 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
setQuota(req, new SetQuotaOperations() {
|
setQuota(req, new SetQuotaOperations() {
|
||||||
@Override
|
@Override
|
||||||
public GlobalQuotaSettings fetch() throws IOException {
|
public GlobalQuotaSettingsImpl fetch() throws IOException {
|
||||||
return new GlobalQuotaSettings(req.getUserName(), null, null, QuotaUtil.getUserQuota(
|
return new GlobalQuotaSettingsImpl(req.getUserName(), null, null, QuotaUtil.getUserQuota(
|
||||||
masterServices.getConnection(), userName));
|
masterServices.getConnection(), userName));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void update(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void update(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
QuotaUtil.addUserQuota(masterServices.getConnection(), userName, quotaPojo.toQuotas());
|
QuotaUtil.addUserQuota(masterServices.getConnection(), userName, quotaPojo.toQuotas());
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -166,11 +166,11 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
QuotaUtil.deleteUserQuota(masterServices.getConnection(), userName);
|
QuotaUtil.deleteUserQuota(masterServices.getConnection(), userName);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void preApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void preApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().preSetUserQuota(userName, quotaPojo);
|
masterServices.getMasterCoprocessorHost().preSetUserQuota(userName, quotaPojo);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void postApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void postApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().postSetUserQuota(userName, quotaPojo);
|
masterServices.getMasterCoprocessorHost().postSetUserQuota(userName, quotaPojo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -180,12 +180,12 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
final SetQuotaRequest req) throws IOException, InterruptedException {
|
final SetQuotaRequest req) throws IOException, InterruptedException {
|
||||||
setQuota(req, new SetQuotaOperations() {
|
setQuota(req, new SetQuotaOperations() {
|
||||||
@Override
|
@Override
|
||||||
public GlobalQuotaSettings fetch() throws IOException {
|
public GlobalQuotaSettingsImpl fetch() throws IOException {
|
||||||
return new GlobalQuotaSettings(userName, table, null, QuotaUtil.getUserQuota(
|
return new GlobalQuotaSettingsImpl(userName, table, null, QuotaUtil.getUserQuota(
|
||||||
masterServices.getConnection(), userName, table));
|
masterServices.getConnection(), userName, table));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void update(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void update(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
QuotaUtil.addUserQuota(masterServices.getConnection(), userName, table,
|
QuotaUtil.addUserQuota(masterServices.getConnection(), userName, table,
|
||||||
quotaPojo.toQuotas());
|
quotaPojo.toQuotas());
|
||||||
}
|
}
|
||||||
|
@ -194,11 +194,11 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
QuotaUtil.deleteUserQuota(masterServices.getConnection(), userName, table);
|
QuotaUtil.deleteUserQuota(masterServices.getConnection(), userName, table);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void preApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void preApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().preSetUserQuota(userName, table, quotaPojo);
|
masterServices.getMasterCoprocessorHost().preSetUserQuota(userName, table, quotaPojo);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void postApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void postApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().postSetUserQuota(userName, table, quotaPojo);
|
masterServices.getMasterCoprocessorHost().postSetUserQuota(userName, table, quotaPojo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -208,12 +208,12 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
final SetQuotaRequest req) throws IOException, InterruptedException {
|
final SetQuotaRequest req) throws IOException, InterruptedException {
|
||||||
setQuota(req, new SetQuotaOperations() {
|
setQuota(req, new SetQuotaOperations() {
|
||||||
@Override
|
@Override
|
||||||
public GlobalQuotaSettings fetch() throws IOException {
|
public GlobalQuotaSettingsImpl fetch() throws IOException {
|
||||||
return new GlobalQuotaSettings(userName, null, namespace, QuotaUtil.getUserQuota(
|
return new GlobalQuotaSettingsImpl(userName, null, namespace, QuotaUtil.getUserQuota(
|
||||||
masterServices.getConnection(), userName, namespace));
|
masterServices.getConnection(), userName, namespace));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void update(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void update(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
QuotaUtil.addUserQuota(masterServices.getConnection(), userName, namespace,
|
QuotaUtil.addUserQuota(masterServices.getConnection(), userName, namespace,
|
||||||
quotaPojo.toQuotas());
|
quotaPojo.toQuotas());
|
||||||
}
|
}
|
||||||
|
@ -222,12 +222,12 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
QuotaUtil.deleteUserQuota(masterServices.getConnection(), userName, namespace);
|
QuotaUtil.deleteUserQuota(masterServices.getConnection(), userName, namespace);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void preApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void preApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().preSetUserQuota(
|
masterServices.getMasterCoprocessorHost().preSetUserQuota(
|
||||||
userName, namespace, quotaPojo);
|
userName, namespace, quotaPojo);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void postApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void postApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().postSetUserQuota(
|
masterServices.getMasterCoprocessorHost().postSetUserQuota(
|
||||||
userName, namespace, quotaPojo);
|
userName, namespace, quotaPojo);
|
||||||
}
|
}
|
||||||
|
@ -238,12 +238,12 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
setQuota(req, new SetQuotaOperations() {
|
setQuota(req, new SetQuotaOperations() {
|
||||||
@Override
|
@Override
|
||||||
public GlobalQuotaSettings fetch() throws IOException {
|
public GlobalQuotaSettingsImpl fetch() throws IOException {
|
||||||
return new GlobalQuotaSettings(null, table, null, QuotaUtil.getTableQuota(
|
return new GlobalQuotaSettingsImpl(null, table, null, QuotaUtil.getTableQuota(
|
||||||
masterServices.getConnection(), table));
|
masterServices.getConnection(), table));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void update(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void update(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
QuotaUtil.addTableQuota(masterServices.getConnection(), table, quotaPojo.toQuotas());
|
QuotaUtil.addTableQuota(masterServices.getConnection(), table, quotaPojo.toQuotas());
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -251,11 +251,11 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
QuotaUtil.deleteTableQuota(masterServices.getConnection(), table);
|
QuotaUtil.deleteTableQuota(masterServices.getConnection(), table);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void preApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void preApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().preSetTableQuota(table, quotaPojo);
|
masterServices.getMasterCoprocessorHost().preSetTableQuota(table, quotaPojo);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void postApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void postApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().postSetTableQuota(table, quotaPojo);
|
masterServices.getMasterCoprocessorHost().postSetTableQuota(table, quotaPojo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -265,25 +265,25 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
setQuota(req, new SetQuotaOperations() {
|
setQuota(req, new SetQuotaOperations() {
|
||||||
@Override
|
@Override
|
||||||
public GlobalQuotaSettings fetch() throws IOException {
|
public GlobalQuotaSettingsImpl fetch() throws IOException {
|
||||||
return new GlobalQuotaSettings(null, null, namespace, QuotaUtil.getNamespaceQuota(
|
return new GlobalQuotaSettingsImpl(null, null, namespace, QuotaUtil.getNamespaceQuota(
|
||||||
masterServices.getConnection(), namespace));
|
masterServices.getConnection(), namespace));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void update(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void update(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
QuotaUtil.addNamespaceQuota(masterServices.getConnection(), namespace,
|
QuotaUtil.addNamespaceQuota(masterServices.getConnection(), namespace,
|
||||||
((GlobalQuotaSettings) quotaPojo).toQuotas());
|
((GlobalQuotaSettingsImpl) quotaPojo).toQuotas());
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void delete() throws IOException {
|
public void delete() throws IOException {
|
||||||
QuotaUtil.deleteNamespaceQuota(masterServices.getConnection(), namespace);
|
QuotaUtil.deleteNamespaceQuota(masterServices.getConnection(), namespace);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void preApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void preApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().preSetNamespaceQuota(namespace, quotaPojo);
|
masterServices.getMasterCoprocessorHost().preSetNamespaceQuota(namespace, quotaPojo);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void postApply(GlobalQuotaSettings quotaPojo) throws IOException {
|
public void postApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException {
|
||||||
masterServices.getMasterCoprocessorHost().postSetNamespaceQuota(namespace, quotaPojo);
|
masterServices.getMasterCoprocessorHost().postSetNamespaceQuota(namespace, quotaPojo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -311,7 +311,7 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply quota changes
|
// Apply quota changes
|
||||||
GlobalQuotaSettings currentQuota = quotaOps.fetch();
|
GlobalQuotaSettingsImpl currentQuota = quotaOps.fetch();
|
||||||
if (LOG.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
LOG.trace(
|
LOG.trace(
|
||||||
"Current quota for request(" + TextFormat.shortDebugString(req)
|
"Current quota for request(" + TextFormat.shortDebugString(req)
|
||||||
|
@ -329,7 +329,7 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
//
|
//
|
||||||
// NB: while SetQuotaRequest technically allows for multi types of quotas to be set in one
|
// NB: while SetQuotaRequest technically allows for multi types of quotas to be set in one
|
||||||
// message, the Java API (in Admin/AsyncAdmin) does not. Assume there is only one type.
|
// message, the Java API (in Admin/AsyncAdmin) does not. Assume there is only one type.
|
||||||
GlobalQuotaSettings mergedQuota = currentQuota.merge(newQuota);
|
GlobalQuotaSettingsImpl mergedQuota = currentQuota.merge(newQuota);
|
||||||
if (LOG.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
LOG.trace("Computed merged quota from current quota and user request: " + mergedQuota);
|
LOG.trace("Computed merged quota from current quota and user request: " + mergedQuota);
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,7 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
/**
|
/**
|
||||||
* Fetches the current quota settings for the subject.
|
* Fetches the current quota settings for the subject.
|
||||||
*/
|
*/
|
||||||
GlobalQuotaSettings fetch() throws IOException;
|
GlobalQuotaSettingsImpl fetch() throws IOException;
|
||||||
/**
|
/**
|
||||||
* Deletes the quota for the subject.
|
* Deletes the quota for the subject.
|
||||||
*/
|
*/
|
||||||
|
@ -411,17 +411,17 @@ public class MasterQuotaManager implements RegionStateListener {
|
||||||
/**
|
/**
|
||||||
* Persist the given quota for the subject.
|
* Persist the given quota for the subject.
|
||||||
*/
|
*/
|
||||||
void update(GlobalQuotaSettings quotaPojo) throws IOException;
|
void update(GlobalQuotaSettingsImpl quotaPojo) throws IOException;
|
||||||
/**
|
/**
|
||||||
* Performs some action before {@link #update(GlobalQuotaSettings)} with the current quota
|
* Performs some action before {@link #update(GlobalQuotaSettingsImpl)} with the current
|
||||||
* for the subject.
|
* quota for the subject.
|
||||||
*/
|
*/
|
||||||
void preApply(GlobalQuotaSettings quotaPojo) throws IOException;
|
void preApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException;
|
||||||
/**
|
/**
|
||||||
* Performs some action after {@link #update(GlobalQuotaSettings)} with the resulting quota
|
* Performs some action after {@link #update(GlobalQuotaSettingsImpl)} with the resulting
|
||||||
* from the request action for the subject.
|
* quota from the request action for the subject.
|
||||||
*/
|
*/
|
||||||
void postApply(GlobalQuotaSettings quotaPojo) throws IOException;
|
void postApply(GlobalQuotaSettingsImpl quotaPojo) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
|
|
|
@ -29,7 +29,7 @@ import org.junit.Test;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
@Category(SmallTests.class)
|
@Category(SmallTests.class)
|
||||||
public class TestGlobalQuotaSettings {
|
public class TestGlobalQuotaSettingsImpl {
|
||||||
|
|
||||||
QuotaProtos.TimedQuota REQUEST_THROTTLE = QuotaProtos.TimedQuota.newBuilder()
|
QuotaProtos.TimedQuota REQUEST_THROTTLE = QuotaProtos.TimedQuota.newBuilder()
|
||||||
.setScope(QuotaProtos.QuotaScope.MACHINE).setSoftLimit(100)
|
.setScope(QuotaProtos.QuotaScope.MACHINE).setSoftLimit(100)
|
||||||
|
@ -51,8 +51,8 @@ public class TestGlobalQuotaSettings {
|
||||||
QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder()
|
QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder()
|
||||||
.setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build();
|
.setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build();
|
||||||
|
|
||||||
GlobalQuotaSettings settings = new GlobalQuotaSettings("joe", null, null, quota);
|
GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl("joe", null, null, quota);
|
||||||
GlobalQuotaSettings merged = settings.merge(
|
GlobalQuotaSettingsImpl merged = settings.merge(
|
||||||
new ThrottleSettings("joe", null, null, writeThrottle));
|
new ThrottleSettings("joe", null, null, writeThrottle));
|
||||||
|
|
||||||
QuotaProtos.Throttle mergedThrottle = merged.getThrottleProto();
|
QuotaProtos.Throttle mergedThrottle = merged.getThrottleProto();
|
||||||
|
@ -73,9 +73,9 @@ public class TestGlobalQuotaSettings {
|
||||||
QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder()
|
QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder()
|
||||||
.setSpace(SPACE_QUOTA).build();
|
.setSpace(SPACE_QUOTA).build();
|
||||||
|
|
||||||
GlobalQuotaSettings settings = new GlobalQuotaSettings(null, tn, null, quota);
|
GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl(null, tn, null, quota);
|
||||||
// Switch the violation policy to DISABLE
|
// Switch the violation policy to DISABLE
|
||||||
GlobalQuotaSettings merged = settings.merge(
|
GlobalQuotaSettingsImpl merged = settings.merge(
|
||||||
new SpaceLimitSettings(tn, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.DISABLE));
|
new SpaceLimitSettings(tn, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.DISABLE));
|
||||||
|
|
||||||
QuotaProtos.SpaceQuota mergedSpaceQuota = merged.getSpaceProto();
|
QuotaProtos.SpaceQuota mergedSpaceQuota = merged.getSpaceProto();
|
||||||
|
@ -89,7 +89,7 @@ public class TestGlobalQuotaSettings {
|
||||||
final String ns = "org1";
|
final String ns = "org1";
|
||||||
QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder()
|
QuotaProtos.Quotas quota = QuotaProtos.Quotas.newBuilder()
|
||||||
.setThrottle(THROTTLE).setSpace(SPACE_QUOTA).build();
|
.setThrottle(THROTTLE).setSpace(SPACE_QUOTA).build();
|
||||||
GlobalQuotaSettings settings = new GlobalQuotaSettings(null, null, ns, quota);
|
GlobalQuotaSettingsImpl settings = new GlobalQuotaSettingsImpl(null, null, ns, quota);
|
||||||
|
|
||||||
QuotaProtos.TimedQuota writeQuota = REQUEST_THROTTLE.toBuilder()
|
QuotaProtos.TimedQuota writeQuota = REQUEST_THROTTLE.toBuilder()
|
||||||
.setSoftLimit(500).build();
|
.setSoftLimit(500).build();
|
||||||
|
@ -97,9 +97,9 @@ public class TestGlobalQuotaSettings {
|
||||||
QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder()
|
QuotaProtos.ThrottleRequest writeThrottle = QuotaProtos.ThrottleRequest.newBuilder()
|
||||||
.setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build();
|
.setTimedQuota(writeQuota).setType(QuotaProtos.ThrottleType.WRITE_NUMBER).build();
|
||||||
|
|
||||||
GlobalQuotaSettings merged = settings.merge(
|
GlobalQuotaSettingsImpl merged = settings.merge(
|
||||||
new ThrottleSettings(null, null, ns, writeThrottle));
|
new ThrottleSettings(null, null, ns, writeThrottle));
|
||||||
GlobalQuotaSettings finalQuota = merged.merge(new SpaceLimitSettings(
|
GlobalQuotaSettingsImpl finalQuota = merged.merge(new SpaceLimitSettings(
|
||||||
ns, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.NO_WRITES_COMPACTIONS));
|
ns, SPACE_QUOTA.getSoftLimit(), SpaceViolationPolicy.NO_WRITES_COMPACTIONS));
|
||||||
|
|
||||||
// Verify both throttle quotas
|
// Verify both throttle quotas
|
Loading…
Reference in New Issue