com.azure.core.util.ConfigurationPropertyBuilder Maven / Gradle / Ivy
Show all versions of azure-core Show documentation
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.core.util;
import java.time.Duration;
import java.util.Objects;
import java.util.function.Function;
/**
* Builds configuration property.
*
* @param The property value type.
*/
public final class ConfigurationPropertyBuilder {
private static final String[] EMPTY_ARRAY = new String[0];
private static final Function PERMIT_VALUE_SANITIZER = (value) -> value;
private static final Function CONFIGURATION_PROPERTY_BOOLEAN_CONVERTER = Boolean::valueOf;
private static final Function CONFIGURATION_PROPERTY_DURATION_CONVERTER = (value) -> {
long timeoutMillis = Long.parseLong(value);
if (timeoutMillis < 0) {
throw new IllegalArgumentException("Duration can't be negative");
}
return Duration.ofMillis(timeoutMillis);
};
private static final Function CONFIGURATION_PROPERTY_INTEGER_CONVERTER = Integer::valueOf;
private static final Function CONFIGURATION_PROPERTY_STRING_CONVERTER = Function.identity();
private final String name;
private final Function converter;
private String[] aliases = EMPTY_ARRAY;
private String environmentVariableName;
private String systemPropertyName;
private T defaultValue;
private boolean shared;
private Function valueSanitizer;
private boolean required;
/**
* Creates default {@link ConfigurationPropertyBuilder}. String property values are redacted in logs by default. If
* property value does not contain sensitive information, use {@link ConfigurationPropertyBuilder#logValue} to
* enable logging.
*
*
*
* ConfigurationProperty<String> property = ConfigurationPropertyBuilder.ofString("http.proxy.hostname")
* .shared(true)
* .logValue(true)
* .systemPropertyName("http.proxyHost")
* .build();
*
* // attempts to get local `azure.sdk.<client-name>.http.proxy.host` property and falls back to
* // shared azure.sdk.http.proxy.port
* System.out.println(configuration.get(property));
*
*
*
* @param name property name.
* @return instance of {@link ConfigurationPropertyBuilder}.
*/
public static ConfigurationPropertyBuilder ofString(String name) {
return new ConfigurationPropertyBuilder<>(name, CONFIGURATION_PROPERTY_STRING_CONVERTER);
}
/**
* Creates {@link ConfigurationPropertyBuilder} configured to log property value and parse value using
* {@link Integer#valueOf(String)}, proxying {@link NumberFormatException} exception.
*
*
*
* ConfigurationProperty<Integer> integerProperty = ConfigurationPropertyBuilder.ofInteger("retry-count")
* .build();
* System.out.println(configuration.get(integerProperty));
*
*
*
* @param name property name.
* @return instance of {@link ConfigurationPropertyBuilder}.
*/
public static ConfigurationPropertyBuilder ofInteger(String name) {
return new ConfigurationPropertyBuilder<>(name, CONFIGURATION_PROPERTY_INTEGER_CONVERTER).logValue(true);
}
/**
* Creates {@link ConfigurationPropertyBuilder} configured to log property value and parses value as long number of
* milliseconds, proxying {@link NumberFormatException} exception.
*
*
*
* ConfigurationProperty<Duration> timeoutProperty = ConfigurationPropertyBuilder.ofDuration("timeout")
* .build();
* System.out.println(configuration.get(timeoutProperty));
*
*
*
* @param name property name.
* @return instance of {@link ConfigurationPropertyBuilder}.
*/
public static ConfigurationPropertyBuilder ofDuration(String name) {
return new ConfigurationPropertyBuilder<>(name, CONFIGURATION_PROPERTY_DURATION_CONVERTER).logValue(true);
}
/**
* Creates {@link ConfigurationPropertyBuilder} configured to log property value and parse value using
* {@link Boolean#parseBoolean(String)}.
*
*
*
* ConfigurationProperty<Boolean> booleanProperty = ConfigurationPropertyBuilder.ofBoolean("is-enabled")
* .build();
* System.out.println(configuration.get(booleanProperty));
*
*
*
* @param name property name.
* @return instance of {@link ConfigurationPropertyBuilder}.
*/
public static ConfigurationPropertyBuilder ofBoolean(String name) {
return new ConfigurationPropertyBuilder<>(name, CONFIGURATION_PROPERTY_BOOLEAN_CONVERTER).logValue(true);
}
/**
* Constructs {@code ConfigurationPropertyBuilder} instance.
*
*
*
* ConfigurationProperty<SampleEnumProperty> modeProperty =
* new ConfigurationPropertyBuilder<>("mode", SampleEnumProperty::fromString)
* .logValue(true)
* .defaultValue(SampleEnumProperty.MODE_1)
* .build();
* System.out.println(configuration.get(modeProperty));
*
*
*
* @param name name of the property.
* @param converter Converter used to map the configuration to {@code T}.
*/
public ConfigurationPropertyBuilder(String name, Function converter) {
this.name = Objects.requireNonNull(name, "'name' cannot be null");
this.converter = Objects.requireNonNull(converter, "'converter' cannot be null");
}
/**
* Sets default property value. {@code null} by default.
*
* @param defaultValue value to be returned by {@link Configuration#get(ConfigurationProperty)} if the property
* isn't found.
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder defaultValue(T defaultValue) {
this.defaultValue = defaultValue;
return this;
}
/**
* Sets flag indicating that property can be provided in the shared configuration section in addition to
* client-specific configuration section. Default is {@code false}, indicating that property can only be provided in
* local configuration.
*
* @param shared If set to {@code true}, {@link Configuration#get(ConfigurationProperty)} will attempt to retrieve
* property from local configuration and fall back to shared section, when local property is missing. Otherwise,
* only local configuration will be checked.
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder shared(boolean shared) {
this.shared = shared;
return this;
}
/**
* Sets flag indicating if property value can be logged. Default is {@code false}, indicating that property value
* should not be logged. When and if retrieving of corresponding configuration property is logged,
* {@link Configuration} will use "redacted" string instead of property value. If flag is set to {@code true}, value
* is populated on the logs as is.
*
* @param logValue If set to {@code true}, {@link Configuration#get(ConfigurationProperty)} will log property value,
* Otherwise, value is redacted.
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder logValue(boolean logValue) {
if (logValue) {
this.valueSanitizer = PERMIT_VALUE_SANITIZER;
}
return this;
}
/**
* Sets flag indicating if property is required. Default is {@code false}, indicating that property is optional.
*
* @param required If set to {@code true}, {@link Configuration#get(ConfigurationProperty)} will throw when property
* is not found.
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder required(boolean required) {
this.required = required;
return this;
}
/**
* Sets one or more alias for property. {@link Configuration#get(ConfigurationProperty)} attempts to retrieve
* property by name first and only then tries to retrieve properties by alias in the order aliases are provided.
*
* @param aliases one or more alias for the property name.
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder aliases(String... aliases) {
this.aliases = aliases;
return this;
}
/**
* Sets environment variable name that can represent this property if explicit configuration is not set.
*
*
* When property value is not found by {@code name} or {@code alias},
* {@link Configuration#get(ConfigurationProperty)} falls back to system properties and environment variables.
*
* When environment variable (or system property) is not set, {@link Configuration#get(ConfigurationProperty)} does
* not attempt to read environment configuration.
*
* @param environmentVariableName environment variable name.
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder environmentVariableName(String environmentVariableName) {
this.environmentVariableName = environmentVariableName;
return this;
}
/**
* Sets system property name that can represent this property if explicit configuration is not set.
*
*
* When property value is not found by {@code name} or {@code alias},
* {@link Configuration#get(ConfigurationProperty)} falls back to system properties and environment variables.
*
* When environment variable (or system property) is not set, {@link Configuration#get(ConfigurationProperty)} does
* not attempt to read environment configuration.
*
* @param systemPropertyName one or more environment variable (or system property).
* @return the updated ConfigurationPropertyBuilder object.
*/
public ConfigurationPropertyBuilder systemPropertyName(String systemPropertyName) {
this.systemPropertyName = systemPropertyName;
return this;
}
/**
* Builds configuration property instance.
*
* @return {@link ConfigurationProperty} instance.
*/
public ConfigurationProperty build() {
return new ConfigurationProperty<>(name, defaultValue, required, converter, shared, environmentVariableName,
systemPropertyName, aliases, valueSanitizer);
}
}