use of io.strimzi.kafka.config.model.ConfigModel in project strimzi by strimzi.
the class ConfigModelTest method testLongValidation.
@Test
public void testLongValidation() {
ConfigModel cm = new ConfigModel();
cm.setType(Type.LONG);
assertThat(cm.validate("test", "1"), is(emptyList()));
assertThat(cm.validate("test", Long.valueOf(Long.MAX_VALUE).toString()), is(emptyList()));
assertThat(cm.validate("test", Long.valueOf(Long.MIN_VALUE).toString()), is(emptyList()));
assertThat(cm.validate("test", "9223372036854775808"), is(singletonList("test has value '9223372036854775808' which is not a long")));
assertThat(cm.validate("test", "-9223372036854775809"), is(singletonList("test has value '-9223372036854775809' which is not a long")));
cm.setMinimum(0);
assertThat(cm.validate("test", "-1"), is(singletonList("test has value -1 which less than the minimum value 0")));
cm.setMaximum(1);
assertThat(cm.validate("test", "2"), is(singletonList("test has value 2 which greater than the maximum value 1")));
}
use of io.strimzi.kafka.config.model.ConfigModel in project strimzi by strimzi.
the class ConfigModelTest method testStringValidation.
@Test
public void testStringValidation() {
ConfigModel cm = new ConfigModel();
cm.setType(Type.STRING);
assertThat(cm.validate("test", "dog"), is(emptyList()));
cm.setValues(asList("foo", "bar"));
assertThat(cm.validate("test", "foo"), is(emptyList()));
assertThat(cm.validate("test", "bar"), is(emptyList()));
assertThat(cm.validate("test", "baz"), is(singletonList("test has value 'baz' which is not one of the allowed values: [foo, bar]")));
cm.setValues(null);
cm.setPattern("foo|bar");
assertThat(cm.validate("test", "foo"), is(emptyList()));
assertThat(cm.validate("test", "bar"), is(emptyList()));
assertThat(cm.validate("test", "baz"), is(singletonList("test has value 'baz' which does not match the required pattern: foo|bar")));
}
use of io.strimzi.kafka.config.model.ConfigModel in project strimzi by strimzi.
the class DynamicConfSharedST method generateTestCases.
/**
* Method, which dynamically generate test cases based on Kafka version
* @param kafkaVersion specific kafka version
* @return String generated test cases
*/
@SuppressWarnings({ "checkstyle:CyclomaticComplexity" })
private static Map<String, Object> generateTestCases(String kafkaVersion) {
Map<String, ConfigModel> dynamicProperties = KafkaUtils.getDynamicConfigurationProperties(kafkaVersion);
Map<String, Object> testCases = new HashMap<>();
dynamicProperties.forEach((key, value) -> {
Type type = value.getType();
Object stochasticChosenValue;
switch(type) {
case STRING:
switch(key) {
case "compression.type":
List<String> compressionTypes = Arrays.asList("snappy", "gzip", "lz4", "zstd");
stochasticChosenValue = compressionTypes.get(ThreadLocalRandom.current().nextInt(0, compressionTypes.size() - 1));
break;
case "log.message.timestamp.type":
stochasticChosenValue = "LogAppendTime";
break;
case "ssl.protocol":
stochasticChosenValue = "TLSv1.1";
break;
default:
stochasticChosenValue = " ";
}
testCases.put(key, stochasticChosenValue);
break;
case INT:
case LONG:
switch(key) {
case "num.recovery.threads.per.data.dir":
case "log.cleaner.threads":
case "num.network.threads":
case "min.insync.replicas":
case "num.replica.fetchers":
case "num.partitions":
stochasticChosenValue = ThreadLocalRandom.current().nextInt(2, 3);
break;
case "log.cleaner.io.buffer.load.factor":
case "log.retention.ms":
case "max.connections":
case "max.connections.per.ip":
case "background.threads":
stochasticChosenValue = ThreadLocalRandom.current().nextInt(4, 20);
break;
default:
stochasticChosenValue = ThreadLocalRandom.current().nextInt(100, 50_000);
}
testCases.put(key, stochasticChosenValue);
break;
case DOUBLE:
switch(key) {
case "log.cleaner.min.cleanable.dirty.ratio":
case "log.cleaner.min.cleanable.ratio":
stochasticChosenValue = ThreadLocalRandom.current().nextDouble(0, 1);
break;
default:
stochasticChosenValue = ThreadLocalRandom.current().nextDouble(1, 20);
}
testCases.put(key, stochasticChosenValue);
break;
case BOOLEAN:
switch(key) {
case "unclean.leader.election.enable":
case "log.preallocate":
stochasticChosenValue = true;
break;
case "log.message.downconversion.enable":
stochasticChosenValue = false;
break;
default:
stochasticChosenValue = ThreadLocalRandom.current().nextInt(2) == 0;
}
testCases.put(key, stochasticChosenValue);
break;
case LIST:
// log.cleanup.policy = [delete, compact] -> default delete
switch(key) {
case "log.cleanup.policy":
stochasticChosenValue = "compact";
break;
case "ssl.enabled.protocols":
stochasticChosenValue = "TLSv1.1";
break;
default:
stochasticChosenValue = " ";
}
testCases.put(key, stochasticChosenValue);
}
// skipping these configuration, which doesn't work appear in the kafka pod (TODO: investigate why!)
testCases.remove("num.recovery.threads.per.data.dir");
testCases.remove("num.io.threads");
testCases.remove("log.cleaner.dedupe.buffer.size");
testCases.remove("num.partitions");
// skipping these configuration exceptions
testCases.remove("ssl.cipher.suites");
testCases.remove("zookeeper.connection.timeout.ms");
testCases.remove("zookeeper.connect");
});
return testCases;
}
use of io.strimzi.kafka.config.model.ConfigModel in project strimzi-kafka-operator by strimzi.
the class KafkaConfiguration method validate.
/**
* Validate the configs in this KafkaConfiguration returning a list of errors.
* @param kafkaVersion The broker version.
* @return A list of error messages.
*/
public List<String> validate(KafkaVersion kafkaVersion) {
List<String> errors = new ArrayList<>();
Map<String, ConfigModel> models = readConfigModel(kafkaVersion);
for (Map.Entry<String, String> entry : asOrderedProperties().asMap().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
ConfigModel config = models.get(key);
if (config != null) {
// It's not an error if config _is_ null because extra configs
// might be intended for plugins
errors.addAll(config.validate(key, value));
}
}
return errors;
}
use of io.strimzi.kafka.config.model.ConfigModel in project strimzi-kafka-operator by strimzi.
the class KafkaConfigModelGenerator method configs.
private static Map<String, ConfigModel> configs() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
ConfigDef def = brokerConfigs();
Map<String, String> dynamicUpdates = brokerDynamicUpdates();
Method getConfigValueMethod = def.getClass().getDeclaredMethod("getConfigValue", ConfigDef.ConfigKey.class, String.class);
getConfigValueMethod.setAccessible(true);
Method sortedConfigs = ConfigDef.class.getDeclaredMethod("sortedConfigs");
sortedConfigs.setAccessible(true);
List<ConfigDef.ConfigKey> keys = (List) sortedConfigs.invoke(def);
Map<String, ConfigModel> result = new TreeMap<>();
for (ConfigDef.ConfigKey key : keys) {
String configName = String.valueOf(getConfigValueMethod.invoke(def, key, "Name"));
Type type = parseType(String.valueOf(getConfigValueMethod.invoke(def, key, "Type")));
Scope scope = parseScope(dynamicUpdates.getOrDefault(key.name, "read-only"));
ConfigModel descriptor = new ConfigModel();
descriptor.setType(type);
descriptor.setScope(scope);
if (key.validator instanceof ConfigDef.Range) {
descriptor = range(key, descriptor);
} else if (key.validator instanceof ConfigDef.ValidString) {
descriptor.setValues(enumer(key.validator));
} else if (key.validator instanceof ConfigDef.ValidList) {
descriptor.setItems(validList(key));
} else if (key.validator instanceof ApiVersionValidator$) {
Iterator<ApiVersion> iterator = ApiVersion$.MODULE$.allVersions().iterator();
LinkedHashSet<String> versions = new LinkedHashSet<>();
while (iterator.hasNext()) {
ApiVersion next = iterator.next();
ApiVersion$.MODULE$.apply(next.shortVersion());
versions.add(Pattern.quote(next.shortVersion()) + "(\\.[0-9]+)*");
ApiVersion$.MODULE$.apply(next.version());
versions.add(Pattern.quote(next.version()));
}
descriptor.setPattern(String.join("|", versions));
} else if (key.validator instanceof ConfigDef.NonEmptyString) {
descriptor.setPattern(".+");
} else if (key.validator instanceof RaftConfig.ControllerQuorumVotersValidator) {
continue;
} else if (key.validator != null) {
throw new IllegalStateException("Invalid validator class " + key.validator.getClass() + " for option " + configName);
}
result.put(configName, descriptor);
}
return result;
}
Aggregations