use of io.airlift.configuration.ConfigurationMetadata.AttributeMetadata in project airlift by airlift.
the class ConfigurationMetadataTest method verifyMetaData.
private void verifyMetaData(ConfigurationMetadata<?> metadata, Class<?> configClass, String description, boolean securitySensitive, Map<String, Set<String>> attributeProperties) throws Exception {
assertEquals(metadata.getConfigClass(), configClass);
if (metadata.getConstructor() != null) {
assertEquals(metadata.getConstructor(), configClass.getDeclaredConstructor());
} else {
try {
configClass.getDeclaredConstructor();
fail(String.format("Expected configClass [%s] not to have a constructor", configClass.getName()));
} catch (NoSuchMethodException expected) {
}
}
assertEquals(metadata.getAttributes().size(), attributeProperties.keySet().size());
for (String name : attributeProperties.keySet()) {
AttributeMetadata attribute = metadata.getAttributes().get(name);
assertEquals(attribute.getConfigClass(), configClass);
Set<String> namesToTest = new HashSet<>();
namesToTest.add(attribute.getInjectionPoint().getProperty());
for (ConfigurationMetadata.InjectionPointMetaData legacyInjectionPoint : attribute.getLegacyInjectionPoints()) {
namesToTest.add(legacyInjectionPoint.getProperty());
}
assertEquals(namesToTest, attributeProperties.get(name));
assertEquals(attribute.getDescription(), description);
assertEquals(attribute.isSecuritySensitive(), securitySensitive);
}
}
use of io.airlift.configuration.ConfigurationMetadata.AttributeMetadata in project airlift by airlift.
the class ConfigAssertions method assertPropertiesSupported.
private static void assertPropertiesSupported(ConfigurationMetadata<?> metadata, Set<String> propertyNames, boolean allowDeprecatedProperties) {
Set<String> supportedProperties = new TreeSet<>();
Set<String> nonDeprecatedProperties = new TreeSet<>();
for (AttributeMetadata attribute : metadata.getAttributes().values()) {
if (attribute.getInjectionPoint().getProperty() != null) {
nonDeprecatedProperties.add(attribute.getInjectionPoint().getProperty());
supportedProperties.add(attribute.getInjectionPoint().getProperty());
}
for (ConfigurationMetadata.InjectionPointMetaData deprecated : attribute.getLegacyInjectionPoints()) {
supportedProperties.add(deprecated.getProperty());
}
}
if (!supportedProperties.containsAll(propertyNames)) {
Set<String> unsupportedProperties = new TreeSet<>(propertyNames);
unsupportedProperties.removeAll(supportedProperties);
throw new AssertionError("Unsupported properties: " + unsupportedProperties);
}
// check for usage of deprecated properties
if (!allowDeprecatedProperties && !nonDeprecatedProperties.containsAll(propertyNames)) {
Set<String> deprecatedProperties = new TreeSet<>(propertyNames);
deprecatedProperties.removeAll(nonDeprecatedProperties);
throw new AssertionError("Deprecated properties: " + deprecatedProperties);
}
}
use of io.airlift.configuration.ConfigurationMetadata.AttributeMetadata in project airlift by airlift.
the class ConfigAssertions method assertDefaults.
public static <T> void assertDefaults(Map<String, Object> expectedAttributeValues, Class<T> configClass) {
ConfigurationMetadata<?> metadata = ConfigurationMetadata.getValidConfigurationMetadata(configClass);
// verify all supplied attributes are supported
if (!metadata.getAttributes().keySet().containsAll(expectedAttributeValues.keySet())) {
Set<String> unsupportedAttributes = new TreeSet<>(expectedAttributeValues.keySet());
unsupportedAttributes.removeAll(metadata.getAttributes().keySet());
throw new AssertionError("Unsupported attributes: " + unsupportedAttributes);
}
// verify all supplied attributes are supported not deprecated
Set<String> nonDeprecatedAttributes = new TreeSet<>();
for (AttributeMetadata attribute : metadata.getAttributes().values()) {
if (attribute.getInjectionPoint().getProperty() != null) {
nonDeprecatedAttributes.add(attribute.getName());
}
}
if (!nonDeprecatedAttributes.containsAll(expectedAttributeValues.keySet())) {
Set<String> unsupportedAttributes = new TreeSet<>(expectedAttributeValues.keySet());
unsupportedAttributes.removeAll(nonDeprecatedAttributes);
throw new AssertionError("Deprecated attributes: " + unsupportedAttributes);
}
// verify all attributes are tested
if (!expectedAttributeValues.keySet().containsAll(nonDeprecatedAttributes)) {
Set<String> untestedAttributes = new TreeSet<>(nonDeprecatedAttributes);
untestedAttributes.removeAll(expectedAttributeValues.keySet());
throw new AssertionError("Untested attributes: " + untestedAttributes);
}
// create an uninitialized default instance
T actual = newDefaultInstance(configClass);
// verify each attribute is either the supplied default value
for (AttributeMetadata attribute : metadata.getAttributes().values()) {
Method getter = attribute.getGetter();
if (getter == null) {
continue;
}
Object actualAttributeValue = invoke(actual, getter);
Object expectedAttributeValue = expectedAttributeValues.get(attribute.getName());
if (!Objects.deepEquals(actualAttributeValue, expectedAttributeValue)) {
throw new AssertionError(notEquals(attribute.getName(), actualAttributeValue, expectedAttributeValue));
}
}
}
use of io.airlift.configuration.ConfigurationMetadata.AttributeMetadata in project airlift by airlift.
the class ConfigAssertions method assertRecordedDefaults.
public static <T> void assertRecordedDefaults(T recordedConfig) {
$$RecordedConfigData<T> recordedConfigData = getRecordedConfig(recordedConfig);
Set<Method> invokedMethods = recordedConfigData.getInvokedMethods();
T config = recordedConfigData.getInstance();
Class<T> configClass = getClass(config);
ConfigurationMetadata<?> metadata = ConfigurationMetadata.getValidConfigurationMetadata(configClass);
// collect information about the attributes that have been set
Map<String, Object> attributeValues = new TreeMap<>();
Set<String> setDeprecatedAttributes = new TreeSet<>();
Set<Method> validSetterMethods = new HashSet<>();
for (AttributeMetadata attribute : metadata.getAttributes().values()) {
if (attribute.getInjectionPoint().getProperty() != null) {
validSetterMethods.add(attribute.getInjectionPoint().getSetter());
}
if (invokedMethods.contains(attribute.getInjectionPoint().getSetter())) {
if (attribute.getInjectionPoint().getProperty() != null) {
Object value = invoke(config, attribute.getGetter());
attributeValues.put(attribute.getName(), value);
} else {
setDeprecatedAttributes.add(attribute.getName());
}
}
}
// verify no deprecated attribute setters have been called
if (!setDeprecatedAttributes.isEmpty()) {
throw new AssertionError("Invoked deprecated attribute setter methods: " + setDeprecatedAttributes);
}
// verify no other methods have been set
if (!validSetterMethods.containsAll(invokedMethods)) {
Set<Method> invalidInvocations = new HashSet<>(invokedMethods);
invalidInvocations.removeAll(validSetterMethods);
throw new AssertionError("Invoked non-attribute setter methods: " + invalidInvocations);
}
assertDefaults(attributeValues, configClass);
}
use of io.airlift.configuration.ConfigurationMetadata.AttributeMetadata in project airlift by airlift.
the class ConfigurationFactory method build.
private <T> ConfigurationHolder<T> build(Class<T> configClass, Optional<String> configPrefix, ConfigDefaults<T> configDefaults) {
if (configClass == null) {
throw new NullPointerException("configClass is null");
}
String prefix = configPrefix.map(value -> value + ".").orElse("");
ConfigurationMetadata<T> configurationMetadata = getMetadata(configClass);
configurationMetadata.getProblems().throwIfHasErrors();
T instance = newInstance(configurationMetadata);
configDefaults.setDefaults(instance);
Problems problems = new Problems(monitor);
for (AttributeMetadata attribute : configurationMetadata.getAttributes().values()) {
Problems attributeProblems = new Problems(monitor);
try {
setConfigProperty(instance, attribute, prefix, attributeProblems);
} catch (InvalidConfigurationException e) {
attributeProblems.addError(e.getCause(), e.getMessage());
}
problems.record(attributeProblems);
}
// Check that none of the defunct properties are still in use
if (configClass.isAnnotationPresent(DefunctConfig.class)) {
for (String value : configClass.getAnnotation(DefunctConfig.class).value()) {
String name = prefix + value;
if (!value.isEmpty() && properties.get(name) != null) {
problems.addError("Defunct property '%s' (class [%s]) cannot be configured.", name, configClass.toString());
}
}
}
// if there already problems, don't run the bean validation as it typically reports duplicate errors
problems.throwIfHasErrors();
for (ConstraintViolation<?> violation : validate(instance)) {
String propertyFieldName = violation.getPropertyPath().toString();
// upper case first character to match config attribute name
String attributeName = LOWER_CAMEL.to(UPPER_CAMEL, propertyFieldName);
AttributeMetadata attribute = configurationMetadata.getAttributes().get(attributeName);
if (attribute != null && attribute.getInjectionPoint() != null) {
String propertyName = attribute.getInjectionPoint().getProperty();
if (!prefix.isEmpty()) {
propertyName = prefix + propertyName;
}
problems.addError("Invalid configuration property %s: %s (for class %s.%s)", propertyName, violation.getMessage(), configClass.getName(), violation.getPropertyPath());
} else {
problems.addError("Invalid configuration property with prefix '%s': %s (for class %s.%s)", prefix, violation.getMessage(), configClass.getName(), violation.getPropertyPath());
}
}
problems.throwIfHasErrors();
return new ConfigurationHolder<>(instance, problems);
}
Aggregations