use of org.apache.kafka.server.common.ApiMessageAndVersion in project kafka by apache.
the class ClientQuotaControlManager method alterClientQuotaEntity.
private void alterClientQuotaEntity(ClientQuotaEntity entity, Map<String, Double> newQuotaConfigs, List<ApiMessageAndVersion> outputRecords, Map<ClientQuotaEntity, ApiError> outputResults) {
// Check entity types and sanitize the names
Map<String, String> validatedEntityMap = new HashMap<>(3);
ApiError error = validateEntity(entity, validatedEntityMap);
if (error.isFailure()) {
outputResults.put(entity, error);
return;
}
// Check the combination of entity types and get the config keys
Map<String, ConfigDef.ConfigKey> configKeys = new HashMap<>(4);
error = configKeysForEntityType(validatedEntityMap, configKeys);
if (error.isFailure()) {
outputResults.put(entity, error);
return;
}
// Don't share objects between different records
Supplier<List<EntityData>> recordEntitySupplier = () -> validatedEntityMap.entrySet().stream().map(mapEntry -> new EntityData().setEntityType(mapEntry.getKey()).setEntityName(mapEntry.getValue())).collect(Collectors.toList());
List<ApiMessageAndVersion> newRecords = new ArrayList<>(newQuotaConfigs.size());
Map<String, Double> currentQuotas = clientQuotaData.containsKey(entity) ? clientQuotaData.get(entity) : Collections.emptyMap();
for (Map.Entry<String, Double> entry : newQuotaConfigs.entrySet()) {
String key = entry.getKey();
Double newValue = entry.getValue();
if (newValue == null) {
if (currentQuotas.containsKey(key)) {
// Null value indicates removal
newRecords.add(new ApiMessageAndVersion(new ClientQuotaRecord().setEntity(recordEntitySupplier.get()).setKey(key).setRemove(true), CLIENT_QUOTA_RECORD.highestSupportedVersion()));
}
} else {
ApiError validationError = validateQuotaKeyValue(configKeys, key, newValue);
if (validationError.isFailure()) {
outputResults.put(entity, validationError);
return;
} else {
final Double currentValue = currentQuotas.get(key);
if (!Objects.equals(currentValue, newValue)) {
// Only record the new value if it has changed
newRecords.add(new ApiMessageAndVersion(new ClientQuotaRecord().setEntity(recordEntitySupplier.get()).setKey(key).setValue(newValue), CLIENT_QUOTA_RECORD.highestSupportedVersion()));
}
}
}
}
outputRecords.addAll(newRecords);
outputResults.put(entity, ApiError.NONE);
}
use of org.apache.kafka.server.common.ApiMessageAndVersion in project kafka by apache.
the class ConfigurationControlManager method incrementalAlterConfigResource.
private void incrementalAlterConfigResource(ConfigResource configResource, Map<String, Entry<OpType, String>> keysToOps, Consumer<ConfigResource> existenceChecker, List<ApiMessageAndVersion> outputRecords, Map<ConfigResource, ApiError> outputResults) {
List<ApiMessageAndVersion> newRecords = new ArrayList<>();
for (Entry<String, Entry<OpType, String>> keysToOpsEntry : keysToOps.entrySet()) {
String key = keysToOpsEntry.getKey();
String currentValue = null;
TimelineHashMap<String, String> currentConfigs = configData.get(configResource);
if (currentConfigs != null) {
currentValue = currentConfigs.get(key);
}
String newValue = currentValue;
Entry<OpType, String> opTypeAndNewValue = keysToOpsEntry.getValue();
OpType opType = opTypeAndNewValue.getKey();
String opValue = opTypeAndNewValue.getValue();
switch(opType) {
case SET:
newValue = opValue;
break;
case DELETE:
newValue = null;
break;
case APPEND:
case SUBTRACT:
if (!isSplittable(configResource.type(), key)) {
outputResults.put(configResource, new ApiError(INVALID_CONFIG, "Can't " + opType + " to " + "key " + key + " because its type is not LIST."));
return;
}
List<String> newValueParts = getParts(newValue, key, configResource);
if (opType == APPEND) {
if (!newValueParts.contains(opValue)) {
newValueParts.add(opValue);
}
newValue = String.join(",", newValueParts);
} else if (newValueParts.remove(opValue)) {
newValue = String.join(",", newValueParts);
}
break;
}
if (!Objects.equals(currentValue, newValue)) {
newRecords.add(new ApiMessageAndVersion(new ConfigRecord().setResourceType(configResource.type().id()).setResourceName(configResource.name()).setName(key).setValue(newValue), CONFIG_RECORD.highestSupportedVersion()));
}
}
ApiError error = validateAlterConfig(configResource, newRecords, existenceChecker);
if (error.isFailure()) {
outputResults.put(configResource, error);
return;
}
outputRecords.addAll(newRecords);
outputResults.put(configResource, ApiError.NONE);
}
use of org.apache.kafka.server.common.ApiMessageAndVersion in project kafka by apache.
the class ConfigurationControlManager method validateAlterConfig.
private ApiError validateAlterConfig(ConfigResource configResource, List<ApiMessageAndVersion> newRecords, Consumer<ConfigResource> existenceChecker) {
Map<String, String> newConfigs = new HashMap<>();
TimelineHashMap<String, String> existingConfigs = configData.get(configResource);
if (existingConfigs != null)
newConfigs.putAll(existingConfigs);
for (ApiMessageAndVersion newRecord : newRecords) {
ConfigRecord configRecord = (ConfigRecord) newRecord.message();
if (configRecord.value() == null) {
newConfigs.remove(configRecord.name());
} else {
newConfigs.put(configRecord.name(), configRecord.value());
}
}
try {
validator.validate(configResource, newConfigs);
existenceChecker.accept(configResource);
if (alterConfigPolicy.isPresent()) {
alterConfigPolicy.get().validate(new RequestMetadata(configResource, newConfigs));
}
} catch (ConfigException e) {
return new ApiError(INVALID_CONFIG, e.getMessage());
} catch (Throwable e) {
return ApiError.fromThrowable(e);
}
return ApiError.NONE;
}
use of org.apache.kafka.server.common.ApiMessageAndVersion in project kafka by apache.
the class ReplicationControlManager method deleteTopic.
void deleteTopic(Uuid id, List<ApiMessageAndVersion> records) {
TopicControlInfo topic = topics.get(id);
if (topic == null) {
throw new UnknownTopicIdException(UNKNOWN_TOPIC_ID.message());
}
records.add(new ApiMessageAndVersion(new RemoveTopicRecord().setTopicId(id), REMOVE_TOPIC_RECORD.highestSupportedVersion()));
}
use of org.apache.kafka.server.common.ApiMessageAndVersion in project kafka by apache.
the class ReplicationControlManager method alterPartitionReassignment.
void alterPartitionReassignment(String topicName, ReassignablePartition target, List<ApiMessageAndVersion> records) {
Uuid topicId = topicsByName.get(topicName);
if (topicId == null) {
throw new UnknownTopicOrPartitionException("Unable to find a topic " + "named " + topicName + ".");
}
TopicControlInfo topicInfo = topics.get(topicId);
if (topicInfo == null) {
throw new UnknownTopicOrPartitionException("Unable to find a topic " + "with ID " + topicId + ".");
}
TopicIdPartition tp = new TopicIdPartition(topicId, target.partitionIndex());
PartitionRegistration part = topicInfo.parts.get(target.partitionIndex());
if (part == null) {
throw new UnknownTopicOrPartitionException("Unable to find partition " + topicName + ":" + target.partitionIndex() + ".");
}
Optional<ApiMessageAndVersion> record;
if (target.replicas() == null) {
record = cancelPartitionReassignment(topicName, tp, part);
} else {
record = changePartitionReassignment(tp, part, target);
}
record.ifPresent(records::add);
}
Aggregations