Skip to content

Latest commit

 

History

History
179 lines (133 loc) · 8.11 KB

configsources.asciidoc

File metadata and controls

179 lines (133 loc) · 8.11 KB

ConfigSources

A ConfigSource is exactly what its name says: a source for configured values. The Config uses all configured implementations of ConfigSource to look up the property in question. Dynamically added config sources after the Config object has been built would be ignored, which means Config.getConfigSources always returns the same collection of ConfigSources. The same rule applies to ConfigSourceProvider.getConfigSources.

ConfigSource Ordering

Each ConfigSource has a specified ordinal, which is used to determine the importance of the values taken from the associated ConfigSource. A higher ordinal means that the values taken from this ConfigSource will override values from lower priority ConfigSources. This allows a configuration to be customized from outside a binary, assuming that external ConfigSource s have higher ordinal values than the ones whose values originate within the release binaries.

It can also be used to implement a drop-in configuration approach. Simply create a jar containing a ConfigSource with a higher ordinal and override configuration values in it. Specifying an empty string as the value effectively erases the property. If the jar is present on the classpath then it will override configuration values from ConfigSources with lower ordinal values.

Manually defining the Ordinal of a built-in ConfigSource

Note that a special property config_ordinal can be set within any built-in ConfigSource implementation. The default implementation of getOrdinal() will attempt to read this value. If found and a valid integer, the value will be used. Otherwise the respective default value will be used.

config_ordinal = 120
com.acme.myproject.someserver.url = http://more_important.server/some/endpoint

Default ConfigSources

A MicroProfile Config implementation must provide ConfigSources for the following data out of the box:

  • System properties (default ordinal=400).

  • Environment variables (default ordinal=300).

  • A ConfigSource for each property file META-INF/microprofile-config.properties found on the classpath. (default ordinal = 100).

Environment Variables Mapping Rules

Some operating systems allow only alphabetic characters or an underscore, _, in environment variables. Other characters such as ., /, etc may be disallowed. In order to set a value for a config property that has a name containing such disallowed characters from an environment variable, the following rules are used.

The ConfigSource for the environment variables searches three environment variables for a given property name (e.g. com.ACME.size):

  1. Exact match (i.e. com.ACME.size)

  2. Replace each character that is neither alphanumeric nor _ with _ (i.e. com_ACME_size)

  3. Replace each character that is neither alphanumeric nor _ with _; then convert the name to upper case (i.e. COM_ACME_SIZE)

The first environment variable that is found is returned by this ConfigSource.

Custom ConfigSources

ConfigSources are discovered using the java.util.ServiceLoader mechanism.

To add a custom ConfigSource, implement the interface org.eclipse.microprofile.config.spi.ConfigSource.

public class CustomDbConfigSource implements ConfigSource {

    @Override
    public int getOrdinal() {
        return 112;
    }

    @Override
    public Set<String> getPropertyNames() {
        return readPropertyNames();
    }

    @Override
    public Map<String, String> getProperties() {
        return readPropertiesFromDb();
    }

    @Override
    public String getValue(String key) {
        return readPropertyFromDb(key);
    }

    @Override
    public String getName() {
        return "customDbConfig";
    }

}

Then register your implementation in a resource file /META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource by including the fully qualified class name of the custom implementation in the file.

Custom ConfigSources via ConfigSourceProvider

If you need dynamic ConfigSources you can also register a ConfigSourceProvider in a similar manner. This is useful if you need to dynamically pick up multiple ConfigSources of the same kind; for example, to pick up all myproject.properties resources from all the JARs in your classpath.

A custom ConfigSourceProvider must implement the interface org.eclipse.microprofile.config.spi.ConfigSourceProvider. Register your implementation in a resource file /META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider by including the fully qualified class name of the custom implementation/s in the file.

An example which registers all YAML files with the name exampleconfig.yaml:

public class ExampleYamlConfigSourceProvider
        implements org.eclipse.microprofile.config.spi.ConfigSourceProvider {
    @Override
    public List<ConfigSource> getConfigSources(ClassLoader forClassLoader) {
        List<ConfigSource> configSources = new ArrayList<>();

        Enumeration<URL> yamlFiles
            = forClassLoader.getResources("sampleconfig.yaml");
        while (yamlFiles.hasMoreElements()) {
            configSources.add(new SampleYamlConfigSource(yamlFiles.nextElement()));
        }
        return configSources;
    }
}

Please note that a single ConfigSource should be either registered directly or via a ConfigSourceProvider, but never both ways.

Dynamic ConfigSource

As a ConfigSource is a view of configuration data, its data may be changing, or unchanging. If the data is changing, and a ConfigSource can represent its changes, we call that ConfigSource a dynamic ConfigSource, since at any two moments two operations on it may reflect two different sets of underlying configuration data. If instead the data is unchanging, we call the ConfigSource a static ConfigSource, since at any two moments two operations on it will reflect only one set of underlying (unchanging) configuration data. A caller cannot know whether a ConfigSource is dynamic or static.

For the property lookup, the method config.getValue() or config.getOptionalValue() retrieves the up-to-date value. Alternatively, for the injection style, the following lookup should be used to retrieve the up-to-date value.

    @Inject
    @ConfigProperty(name="myprj.some.dynamic.timeout", defaultValue="100")
    private jakarta.inject.Provider<Long> timeout;

Whether a ConfigSource supports this dynamic behavior or not depends on how it’s implemented. For instance, the default ConfigSource microprofile-config.properties and Environment Variables are not dynamic while System Properties are dynamic by nature. MicroProfile Config Implementation can decide whether a ConfigSource can be dynamic or not.

Cleaning up a ConfigSource

If a ConfigSource implements the java.lang.AutoCloseable interface then the close() method will be called when the underlying Config is being released.

ConfigSource and Mutable Data

A Config instance provides no caching but iterates over all ConfigSources for each getValue(String) operation. A ConfigSource is allowed to cache the underlying values itself.