public Map<String, ConfigValue> validateAll(Map<String, String> props) { Map<String, ConfigValue> configValues = new HashMap<>(); for (String name: configKeys.keySet()) { configValues.put(name, new ConfigValue(name)); } List<String> undefinedConfigKeys = undefinedDependentConfigs(); for (String undefinedConfigKey: undefinedConfigKeys) { ConfigValue undefinedConfigValue = new ConfigValue(undefinedConfigKey); undefinedConfigValue.addErrorMessage(undefinedConfigKey + " is referred in the dependents, but not defined."); undefinedConfigValue.visible(false); configValues.put(undefinedConfigKey, undefinedConfigValue); } Map<String, Object> parsed = parseForValidate(props, configValues); return validate(parsed, configValues); }
private void validate(String name, Map<String, Object> parsed, Map<String, ConfigValue> configs) { if (!configKeys.containsKey(name)) { return; } ConfigKey key = configKeys.get(name); ConfigValue value = configs.get(name); if (key.recommender != null) { try { List<Object> recommendedValues = key.recommender.validValues(name, parsed); List<Object> originalRecommendedValues = value.recommendedValues(); if (!originalRecommendedValues.isEmpty()) { Set<Object> originalRecommendedValueSet = new HashSet<>(originalRecommendedValues); recommendedValues.removeIf(o -> !originalRecommendedValueSet.contains(o)); } value.recommendedValues(recommendedValues); value.visible(key.recommender.visible(name, parsed)); } catch (ConfigException e) { value.addErrorMessage(e.getMessage()); } } configs.put(name, value); for (String dependent: key.dependents) { validate(dependent, parsed, configs); } }
@Test public void testValidateMissingConfigKey() { Map<String, ConfigValue> expected = new HashMap<>(); String errorMessageB = "Missing required configuration \"b\" which has no default value."; String errorMessageC = "Missing required configuration \"c\" which has no default value."; String errorMessageD = "d is referred in the dependents, but not defined."; ConfigValue configA = new ConfigValue("a", 1, Arrays.<Object>asList(1, 2, 3), Collections.<String>emptyList()); ConfigValue configB = new ConfigValue("b", null, Arrays.<Object>asList(4, 5), Arrays.asList(errorMessageB)); ConfigValue configC = new ConfigValue("c", null, Arrays.<Object>asList(4, 5), Arrays.asList(errorMessageC)); ConfigValue configD = new ConfigValue("d", null, Collections.emptyList(), Arrays.asList(errorMessageD)); configD.visible(false); expected.put("a", configA); expected.put("b", configB); expected.put("c", configC); expected.put("d", configD); ConfigDef def = new ConfigDef() .define("a", Type.INT, Importance.HIGH, "docs", "group", 1, Width.SHORT, "a", Arrays.asList("b", "c", "d"), new IntegerRecommender(false)) .define("b", Type.INT, Importance.HIGH, "docs", "group", 2, Width.SHORT, "b", new IntegerRecommender(true)) .define("c", Type.INT, Importance.HIGH, "docs", "group", 3, Width.SHORT, "c", new IntegerRecommender(true)); Map<String, String> props = new HashMap<>(); props.put("a", "1"); List<ConfigValue> configs = def.validate(props); for (ConfigValue config: configs) { String name = config.name(); ConfigValue expectedConfig = expected.get(name); assertEquals(expectedConfig, config); } }
/** * Validate the supplied fields in this configuration. Extra fields not described by the supplied {@code fields} parameter * are not validated. * * @param fields the fields * @return the {@link ConfigValue} for each of the fields; never null */ default Map<String, ConfigValue> validate(Field.Set fields) { // Create a map of configuration values for each field ... Map<String, ConfigValue> configValuesByFieldName = new HashMap<>(); fields.forEach(field -> { configValuesByFieldName.put(field.name(), new ConfigValue(field.name())); }); // If any dependents don't exist ... fields.forEachMissingDependent(missingDepedent -> { ConfigValue undefinedConfigValue = new ConfigValue(missingDepedent); undefinedConfigValue.addErrorMessage(missingDepedent + " is referred in the dependents, but not defined."); undefinedConfigValue.visible(false); configValuesByFieldName.put(missingDepedent, undefinedConfigValue); }); // Now validate each top-level field ... fields.forEachTopLevelField(field -> { field.validate(this, fields::fieldWithName, configValuesByFieldName); }); return configValuesByFieldName; }
try { value.visible(recommender.visible(this, config));
private static ConfigValueInfo convertConfigValue(ConfigValue configValue, Type type) { String value = ConfigDef.convertToString(configValue.value(), type); List<String> recommendedValues = new LinkedList<>(); if (type == Type.LIST) { for (Object object: configValue.recommendedValues()) { recommendedValues.add(ConfigDef.convertToString(object, Type.STRING)); } } else { for (Object object : configValue.recommendedValues()) { recommendedValues.add(ConfigDef.convertToString(object, type)); } } return new ConfigValueInfo(configValue.name(), value, recommendedValues, configValue.errorMessages(), configValue.visible()); }
/** * Validate the supplied fields in this configuration. Extra fields not described by the supplied {@code fields} parameter * are not validated. * * @param fields the fields * @return the {@link ConfigValue} for each of the fields; never null */ default Map<String, ConfigValue> validate(Field.Set fields) { // Create a map of configuration values for each field ... Map<String, ConfigValue> configValuesByFieldName = new HashMap<>(); fields.forEach(field -> { configValuesByFieldName.put(field.name(), new ConfigValue(field.name())); }); // If any dependents don't exist ... fields.forEachMissingDependent(missingDepedent -> { ConfigValue undefinedConfigValue = new ConfigValue(missingDepedent); undefinedConfigValue.addErrorMessage(missingDepedent + " is referred in the dependents, but not defined."); undefinedConfigValue.visible(false); configValuesByFieldName.put(missingDepedent, undefinedConfigValue); }); // Now validate each top-level field ... fields.forEachTopLevelField(field -> { field.validate(this, fields::fieldWithName, configValuesByFieldName); }); return configValuesByFieldName; }
try { value.visible(recommender.visible(this, config));