...
Quota management via Admin Client has gone through a couple drafts of proposals (KIP-248, KIP-422). While improvements have been made to the Admin interface for configuration handling, fitting quotas into the API would be restrictive because they don't fit the natural key-value pairing. Therefore, it'd be beneficial to have a quota-native API for administrating quotas, which would offer a more direct an intuitive and less error-prone interface, convey additional useful information beyond what a the configuration APIs could provide, and provide for future extensibility as quotas types are added or evolveevolved.
Background
Quotas are defined in terms of a user and and client ID, where the user acts as a specific opaque principal, and the client ID as a more generic group identifier.
...
Public Interfaces
Code Block |
---|
/** * Represents the Describesdefault howname tofor filteran quota entities. */ entity, i.e. the entity that's matched public* classwhen QuotaFilteran { exact match isn't found. // Matches the default entity's name.*/ public final static String public static final String DEFAULT;QUOTA_ENTITY_DEFAULT = // implementation defined /** // Matches* onlyDescribes entitiesan with the name omittedentity type. */ public static final String NULL; enum QuotaEntity { USER, // MatchesThe everyuser entity nameprincipal. public static final String ANY;CLIENT_ID, // The client ID. /** / Note others may be added in the future. * @param non-null user the user to match, or a sentinel filter value } public class QuotaFilter { public enum Rule { * @param non-null clientId the client ID to matchEXACT, or a sentinel filter// value exact name match */ NOT, public QuotaFilter(String user, String clientId);// matches all non-matching names public String user(); PREFIX, // matches all names with the public String clientId();given prefix } public class// ListQuotasOptionsNote { others may be added in the future. // Default. } public class ListQuotasResult {/** /** * A filtering rule to be applied. * @return the collection* of entities that matched the filter * @param entity the entity the rule applies */to Collection<QuotaEntity> entities(); } * @param rule the rule to apply public interface Admin extends AutoCloseable* { @param match the non-null string that's applied by the /**rule */ * Lists entities matching the provided filterpublic that have quotas defined.QuotaFilter(QuotaEntity entity, Rule rule, String match); public QuotaEntity *entity(); public Rule *rule(); For example, to determine the quota forpublic users that belongs to a particular client, set String match(); } public class DescribeQuotasOptions { * filter.user() to QuotaFilter.ANY and// filterDefault.clientId() to the client ID.} public class DescribeQuotasResult { /** * Alternatively,@return tothe determinecollection whichof usersentities havethat specificmatched quotathe values, set filter.user() filter */ * to the user nameKafkaFuture<Collection<Map<QuotaEntity, andString>>> filter.clientIdentities(); to QuotaFilter.NULL. } public interface Admin extends AutoCloseable */{ ListQuotasResult listQuotas(QuotaFilter filter); /** } |
Code Block |
/** * The quota types. * Describes all entities matching all provided filters (logical AND) that have at least one */ public* enumquota QuotaTypevalue {defined. CONSUMER_BYTE_RATE, */ PRODUCER_BYTE_RATE, REQUEST_PERCENTAGE,DescribeQuotasResult describeQuotas(Collection<QuotaFilter> filters, DescribeQuotasOptions options); } |
Code Block |
---|
/** * The quota configuration for a specific user and client IDtypes. */ public classenum QuotaConfigQuotaType { /**CONSUMER_BYTE_RATE, * How the quota is applied to the quota entity.PRODUCER_BYTE_RATE, REQUEST_PERCENTAGE, *// Note others may be added in public enum Entity {the future. } public class DescribeEffectiveQuotasOptions USER,{ // Whether Theto useromit principal. any inherited values in the result. CLIENT_IDIf true, then undefined // The client ID.values for // the entity's config // Others may will be addedexcluded infrom the futureresults. } // /** / Default: false. * HowDescribeQuotasOptions the quota is applied to the quota entity. */ public enum Behavior {setOmitInheritedValues(boolean omitInheritedValues); // Whether to include the list of overridden values for every quota type in the result. // SET, // Sets the value, overwriting and lower precedence SET values. Default: false. DescribeQuotasOptions setOmitOverriddenValues(boolean omitOverriddenValues); } public RESTRICT,class DescribeEffectiveQuotasResult { // Adds a limit (upper bound) to higher precedence values. /** * Information about //a Othersspecific mayquota be added in the futureconfiguration value. } /** */ public *class TheValue units{ for the quota. /**/ public enum Units { * @param source the entity source for the value BPS, * @param //value Bytesthe per second, on a global scale.non-null value BPS_PER_BROKER, // Bytes per second, on a per-broker level. */ public Value(Map<QuotaEntity, String> source, Double value); SHARE, public Map<QuotaEntity, String> source(); // The shares, used for determiningpublic proportional quota.Double value(); } /** * Information about the value for a specific quota configuration valuetype. */ public class ValueEntry { /** * @param sourcevalue the entity source for theactive quota value * @param behavior the behavior for applying the quota overriddenValues all values that are overridden due to being lower in specificity */ @param units the units to apply to the value public Entry(Value value, List<Value> overriddenValues); * @param value the non-null public Value value(); */public List<Value> overriddenValues(); } public Value(Map<Entity, String> source, Behavior behavior, Units units, Double value); /** * Maps a quota type to its configuration publicentry. Map<Entity, String> source(); * public Behavior behavior(); * Note that if `options.omitInheritedValues` is true, then this config may publicnot Units units();map every * quota type publicto Double value(); } /** * Information about the value for a quota type. */ public class Entry { /** * @param value the active quota value * @param overriddenValues list of all values lower that are ignored due to being lower in the hierarchy */ public Entry(Value value, List<Value> overriddenValues); public Value value(); public List<Value> overriddenValues(); } /** * Maps quota type to its configuration entry. * * Note that, depending upon the settings in the request's options, this config may not map every * quota type to an entry. If a key is not contained in the map, then that quota type's value * is not specified. */ public Map<QuotaType, Entry> config(); } /** * Identifies a quota entity. If a entity key type has a value, then it's a specified name, * if the value is the empty string, then the default name is used, otherwise if the key is * omitted or the value is null, then the name is omitted entirely. * * For example: * * {user="kafka-user", clientId="kafka-client-id"} corresponds to quota source `USER_CLIENT` with * specified user "kafka-user" and client ID "kafka-client-id". * * {user="kafka-user", clientId=Optional.empty()} corresponds to quota source `USER_DEFAULT_CLIENT` * with specified user "kafka-user" and default client ID. * * {user=null, clientId="kafka-client-id"} corresponds to quota source `CLIENT` for client with * ID "kafka-client-id". */ public class QuotaEntity { public QuotaEntity(Map<Entity, String> entity); public Optional<String> user(); public Optional<String> clientId(); } public class DescribeQuotasOptions { // Whether to include the inherited values in the result. If false, then undefined values for // the config entries will be ommitted in the results. // an entry. If a key is not contained in the map, then that quota type's value * is not specified. *// Default: true. public KafkaFuture<Map<QuotaType, DescribeQuotasOptionsEntry>> setWantInheritedValuesconfig(boolean wantInheritedValues); } //public Whetherinterface toAdmin includeextends theAutoCloseable overridden{ values for every quota type in the result./** // * Describes the effective quotas for the // Default: trueprovided entities. DescribeQuotasOptions setWantOverriddenValues(boolean wantOverriddenValues); } */ public class DescribeQuotasResult { DescribeEffectiveQuotasResult describeEffectiveQuotas(Collection<QuotaEntity> quotaEntities, Map<QuotaEntity, QuotaConfig> configs; } public interface Admin extends AutoCloseable { /** * Describes the quotas for the provided entities. */ DescribeQuotasResult describeQuotas(Collection<QuotaEntity>DescribeEffectiveQuotasOptions quotaEntitiesoptions); } |
Code Block |
---|
public class AlterQuotasOp { /** * @param type the quota type to alter * @param the new value for the quota, otherwise if null, then the existing value is cleared */ public QuotaAlteration(QuotaType type, Double value); public QuotaType type(); public Double value(); } public class AlterQuotasOptions { // Default. } public class AlterQuotasResult { /** * @return map of a quota entity update to its future */ public Map<QuotaEntity, KafkaFuture<Void>> futures(); } public interface Admin extends AutoCloseable { /** * Alters the quotas as specified for the provided quota entities. * * @param alterations the alterations to perform * @return the result of the alterations */ AlterQuotasResult alterQuotas(Map<QuotaEntity, AlterQuotasOp> alterations); } |
...