- Microprofile Config Sources
A Config Source provides configuration values from different sources such as property files and user classes that are registered by the application.
Helidon configuration sources can use different formats for the configuration data. You can specify the format on a per-source bases, mixing and matching formats as required.
The following configuration sources can be used to retrieve the configuration:
Source Description System properties A mutable source that uses System.getProperties()to obtain configuration values.Environment variables An immutable source that uses System.env()to obtain configuration values and resolves aliases as defined by the MicroProfile Config specification.META-INF/microprofile-config.propertiesThe properties config source as defined by MicroProfile Config specification. File Creates the source from a properties file on the file system with MpConfigSources.create(Path).URL Creates the source from properties from an URL with MpConfigSources.create(URL).Map<String, String>Creates the source from a Map with MpConfigSources.create(Map).PropertiesCreates the source directly from Properties with MpConfigSources.create(Properties).File on classpath Creates the source from a properties file on classpath with MpConfigSources.classpath(String).YAML Creates the source from YAML using YamlMpConfigSource.create(Path)orYamlMpConfigSource.create(URL).
Understanding the Ordering of Default Config Sources
The default MicroProfile Config Sources are:
System properties (ordinal=400)
Environment variables (ordinal=300)
/META-INF/microprofile-config.properties (ordinal=100)
Each Config Source has an ordinal that determines the priority of the Config Source. A Config Source with higher ordinal has higher priority as compared to the Config Source with lower ordinal. The values taken from the high-priority Config Source overrides the values from low-priority Config Source.
This helps to customize the configuration of Config Sources using external Config Source if an external Config Source has higher ordinal values than the built-in Config Sources of the application.
Creating Custom Config Sources
Custom Config Sources are loaded using the Java Service Loader pattern, by implementing either org.eclipse.microprofile.config.spi.ConfigSource, or org.eclipse.microprofile.config.spi.ConfigSourceProvider SPI and registering it as a service (Using META-INF/services/${class-name} file when using classpath, or using the provides statement in module-info.java when using module path).
The interface org.eclipse.microprofile.config.spi.ConfigSource requires implementation of the following methods:
String getName()Map<String, String> getProperties()String getValue(String key)getOrdinal()
Example of a Custom Config Source
public class CustomConfigSource implements ConfigSource {
private static final String NAME = "MyConfigSource";
private static final int ORDINAL = 200; // Default for MP is 100
private static final Map<String, String> PROPERTIES = mapOf("app.greeting", "Hi");
@Override
public String getName() {
return NAME;
}
@Override
public Map<String, String> getProperties() {
return PROPERTIES;
}
@Override
public String getValue(String key) {
return PROPERTIES.get(key);
}
@Override
public int getOrdinal() {
return ORDINAL;
}
}- Returns the name of the Config Source to use for logging or analysis of configured values.
- Returns the properties in this Config Source as a map.
- Returns the value of the requested key, or
nullif the key is not available - Returns the ordinal of this Config Source.
Creating MicroProfile Config Sources for Manual Setup of Config
You can use the following methods to create MicroProfile Config Sources to manually set up the Config from org.eclipse.microprofile.config.spi.ConfigProviderResolver#getBuilder() on io.helidon.config.mp.MpConfigSources class:
| Method | Description |
|---|---|
systemProperties() | System properties config source. |
environmentVariables() | Environment variables config source. |
create(java.nio.file.Path) | Loads a properties file from file system. To load the properties file from file system with custom name, use create(String, java.nio.file.Path). |
create(java.util.Map) | Creates an in-memory source from map. To create an in-memory source from map with custom name, use create(String, java.util.Map). |
create(java.util.Properties) | Creates an in-memory source from properties. To create an in-memory source from properties with custom name, use create(String, java.util.Properties). |
Create Custom Map MicroProfile Config Source
You can create Microprofile Config Source from a map.
ConfigProviderResolver resolver = ConfigProviderResolver.instance();
org.eclipse.microprofile.config.Config config = resolver.getBuilder()
.withSources(MpConfigSources.environmentVariables())
.withSources(MpConfigSources.create(Map.of("key","value")))
.build();
resolver.registerConfig(config, null); - Creates MicroProfile Config Source builder.
- Adds environment variables.
- Adds a custom map.
- Builds the MicroProfile Config Source.
- Registers the config, so it can be used by other components
Create Yaml MicroProfile Config Source
You can create Yaml Microprofile Config Source from a path or a URL. When you create a MicroProfile instance from the builder, the YamlMpConfigSource allows you to create a custom Config Source and register it with the builder.
ConfigProviderResolver.instance().newBuilder()
.withSources(YamlMpConfigSource.create(path))
.build();Creating MicroProfile Config Sources from meta-config
Instead of directly specifying the configuration sources in your code, you can use meta-configuration in a file that declares the configuration sources, and their attributes as mentioned in Microprofile Config
When used, the Microprofile Config uses configuration sources and flags configured in the meta configuration file.
If a file named mp-meta-config.yaml, or mp-meta-config.properties is in the current directory or on the classpath, and there is no explicit setup of configuration in the code, the configuration will be loaded from the meta-config file. The location of the file can be overridden using system property io.helidon.config.mp.meta-config, or environment variable HELIDON_MP_META_CONFIG
add-discovered-sources: true
add-discovered-converters: false
add-default-sources: false
sources:
- type: "environment-variables"
- type: "system-properties"
- type: "properties"
path: "/conf/prod.properties"
ordinal: 50
optional: true
- type: "yaml"
classpath: "META-INF/database.yaml"
- type: "hocon"
classpath: "custom-application.conf"
- type: "json"
path: "path: conf/custom-application.json" - If configured to
true, config sources discovered through service loader will be added - If configured to
true, converters discovered through service loader will be added - If configured to
true, default config sources (system properties, environment variables, and `META-INF/microprofile-config.properties) will be added - Loads the environment variables config source.
- Loads the system properties config source.
- Loads a properties file
- Location of the file:
/conf/prod.propertieson the file system - Custom ordinal, if not defined, the value defined in the file, or default value is used. The source precedence order is the order of appearance in the file.
- The file is optional (if not optional and no file is found, the bootstrap fails)
- Loads a YAML file
- Location of the file:
META-INF/database.yamlon the classpath - Loads a HOCON file
- Location of the file:
custom-application.confon the classpath - Loads a JSON file
- Location of the file:
conf/custom-application.jsonrelative to the directory of where the app was executed on the file system.
Important Note: To enable support for HOCON and JSON types, add the following dependency to your project’s pom.xml.
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config-hocon-mp</artifactId>
</dependency>Extending meta-config to create a custom config source type
Helidon meta-config by default supports the following types: environment-variables, system-properties, properties, yaml, hocon and json. Users can also extend meta-config to create a custom config source type by loading it using the Java Service Loader pattern. This is achieved by implementing io.helidon.config.mp.spi.MpMetaConfigProvider SPI and registering it as a service (Using META-INF/services/${class-name} file when using classpath, or using the provides statement in module-info.java when using module path).
The interface io.helidon.config.mp.spi.MpMetaConfigProvider requires implementation of the following methods:
Set<String> supportedTypes()List<? extends ConfigSource> create(String type, Config metaConfig, String profile);
Example of a Meta-Config Custom Type
public class CustomMpMetaConfigProvider implements MpMetaConfigProvider {
@Override
public Set<String> supportedTypes() {
return Set.of("custom");
}
@Override
public List<? extends ConfigSource> create(String type, Config metaConfig, String profile) {
ConfigValue<Path> pathConfig = metaConfig.get("path").as(Path.class);
if (pathConfig.isPresent()) {
Path path = pathConfig.get();
List<ConfigSource> sources = sourceFromPath(path, profile);
if (sources != null && !sources.isEmpty()) {
return result;
}
location = "path " + path.toAbsolutePath();
} else {
ConfigValue<String> classpathConfig = metaConfig.get("classpath").as(String.class);
if (classpathConfig.isPresent()) {
String classpath = classpathConfig.get();
List<ConfigSource> sources = sourceFromClasspath(classpath, profile);
if (sources != null && !sources.isEmpty()) {
return sources;
}
location = "classpath " + classpath;
} else {
ConfigValue<URL> urlConfig = metaConfig.get("url").as(URL.class);
if (urlConfig.isPresent()) {
URL url = urlConfig.get();
List<ConfigSource> sources = sourceFromUrlMeta(url, profile);
if (sources != null && !sources.isEmpty()) {
return sources;
}
location = "url " + url;
} else {
throw new ConfigException("No config source location for " + config.key());
}
}
}
}
if (metaConfig.get("optional").asBoolean().orElse(false);) {
return List.of();
}
throw new ConfigException("Meta configuration could not find non-optional config source on " + location);
}- Returns the names of the types that will be supported in this meta-config.
- Processes config source from file system if
pathis provided. - Method to parse config source from a specified
path - Processes config source from classpath location if
classpathis provided. - Method to parse config source from a specified
classpath - Processes config source from url location if
locationis provided. - Method to parse config source from a specified
url - Returns an empty result if set to
optionaland config source is not found. - Throws a ConfigException if not set to
optionaland config source is not found.
Creating MicroProfile Config Source from Helidon SE Config Source
To use the Helidon SE features in Helidon MP, create MicroProfile Config Source from Helidon SE Config Source. The Config Source is immutable regardless of configured polling strategy or change watchers.
Config config = ConfigProviderResolver.instance()
.getBuilder()
.withSources(MpConfigSources.create(helidonConfigSource)
.build();- Creates a MicroProfile config instance using Helidon Config Source.
Creating MicroProfile Config Source from Helidon SE Config Instance
To use advanced Helidon SE features in Helidon MP, create MicroProfile Config Source from Helidon SE Config. The Config Source is mutable if the config uses either polling strategy and change watchers, or polling strategy or change watchers. The latest config version is queried each time org.eclipse.microprofile.config.spi.ConfigSource#getValue(String) is called.
io.helidon.config.Config helidonConfig = io.helidon.config.Config.builder()
.addSource(ConfigSources.create(Map.of("key", "value")))
.build();
ConfigProviderResolver.instance();
Config config = ConfigProviderResolver.instance()
.getBuilder()
.withSources(MpConfigSources.create(helidonConfig))
.build();- Creates a config source from Helidon Config.
- Creates a MicroProfile config instance using Helidon Config.