From c15fa538135cf601f2f184b453b13949b100fda4 Mon Sep 17 00:00:00 2001 From: Arjav Desai Date: Fri, 16 Jul 2021 12:20:47 -0500 Subject: [PATCH] Helidon config documentation updates (#3187) --- docs/mp/config/01_introduction.adoc | 116 +------ docs/mp/config/02_MP_config_sources.adoc | 119 +++++-- docs/mp/guides/03_config.adoc | 396 +--------------------- docs/se/config/01_introduction.adoc | 82 ----- docs/se/config/05_mutability-support.adoc | 2 +- 5 files changed, 117 insertions(+), 598 deletions(-) diff --git a/docs/mp/config/01_introduction.adoc b/docs/mp/config/01_introduction.adoc index 06668a4bfdd..dc0606e8bfb 100644 --- a/docs/mp/config/01_introduction.adoc +++ b/docs/mp/config/01_introduction.adoc @@ -44,10 +44,8 @@ include::{common-deps-page-prefix-inc}[tag=maven-dependency] == About {spec-name} Helidon MicroProfile Config is an implementation of https://github.com/eclipse/microprofile-config/[Eclipse MicroProfile Config]. -You can configure your applications using MicroProfile's config configuration sources and APIs. - -You can also extend the configuration using MicroProfile SPI to add custom `ConfigSource` and `Converter` by implementing the -`org.eclipse.microprofile.config.spi.ConfigSource` and `org.eclipse.microprofile.config.spi.Converter` interfaces respectively. +You can configure your applications using MicroProfile's config configuration sources and APIs. You can also extend the +configuration using MicroProfile SPI to add custom `ConfigSource` and `Converter`. === {spec-name} Features @@ -61,8 +59,6 @@ instance programmatically. {spec-name} provides typed access to configuration values, using built-in converters, and `Converter` implementations located by Java Service Loader. -{spec-name} supports a concept of configuration profiles. You can define a profile using the configuration property `mp.config.profile` (when using default configuration, this can be defined as a system property, environment variable or as a property in `microprofile-config.properties`). When a profile is defined, additional config source is loaded (`microprofile-config-profile.properties) and properties from profile have precedence over default properties. Profile properties can be defined using `%profile` prefix, such as `%dev.server.port`. - ==== Using {spec-name} API You can use MicroProfile Config API to get configuration properties by using `ConfigProvider.getConfig()` @@ -98,6 +94,13 @@ server.port=8080 server.host=0.0.0.0 ---- +==== {spec-name} Profiles + +{spec-name} supports a concept of configuration profiles. You can define a profile using the configuration property `mp.config.profile` +(when using default configuration, this can be defined as a system property, environment variable or as a property in `microprofile-config.properties`). +When a profile is defined, additional config source is loaded (`microprofile-config-profile.properties`) and properties from profile have precedence over +default properties. Profile properties can be defined using `%profile` prefix, such as `%dev.server.port`. + === Helidon {spec-name} Features Helidon MicroProfile Config offers the following features on top of the specification: @@ -118,7 +121,7 @@ service-2: "${uri}/service2" * *Encryption* + You can encrypt secrets using a master password and store them in a configuration file. The config encryption filter in MicroProfile Config is enabled by default. -For more information, see <>. +For more information, see <>. [source,properties] .Example of encrypted secrets @@ -133,52 +136,12 @@ client_secret=${CLEAR=known_password} ---- * *Meta Configuration* + -You can configure the Config using Helidon MP Config meta configuration feature. -This is a Helidon specific feature available since version 2.3.0. - -When used, the {spec-name} uses configuration sources and flags configured in the meta configuration file. +You can configure the Config using Helidon MP Config meta configuration feature. The meta-config allows configuration of config sources and other +configuration options, including addition of discovered sources and converters. -The meta-config allows configuration of config sources and other configuration options, -including addition of discovered sources and converters. +This is a Helidon specific feature available since version 2.3.0. See <> for detailed information. -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` - -[source,yaml] -.Example of a YAML meta configuration file: ----- -add-discovered-sources: true <1> -add-discovered-converters: false <2> -add-default-sources: false <3> - -sources: - - type: "environment-variables" <4> - - type: "system-properties" <5> - - type: "properties" <6> - path: "/conf/prod.properties" <7> - ordinal: 50 <8> - optional: true <9> - - type: "yaml" <10> - classpath: "META-INF/database.yaml" <11> - ----- - -<1> If configured to `true`, config sources discovered through service loader will be added -<2> If configured to `true`, converters discovered through service loader will be added -<3> If configured to `true`, default config sources (system properties, environment variables, and `META-INF/microprofile-config.properties) will be added -<4> Loads the environment variables config source. -<5> Loads the system properties config source. -<6> Loads a properties file -<7> Location of the file: `/conf/prod.properties` on the file system -<8> Custom ordinal, if not defined, the value defined in the file, or default value is used -<9> The file is optional (if not optional and no file is found, the bootstrap fails) -<10> Loads a YAML file -<11> Location of the file: `META-INF/database.yaml` on the classpath - -For backward compatibility, we will support usage of Helidon SE meta-configuration until version 3.0.0. Using this approach causes behavior that is not compatible with {spec-name} specification. +NOTE: For backward compatibility, we will support usage of Helidon SE meta-configuration until version 3.0.0. Using this approach causes behavior that is not compatible with {spec-name} specification. == Guides @@ -192,57 +155,6 @@ Step-by-step guide about using {spec-name} in your Helidon MP application. -- ==== -== Using MicroProfile Config Sources - -The following configuration sources can be used to retrieve the configuration: - -[cols="3,5"] -|=== -|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.properties` |The properties config source as defined by MicroProfile Config specification. - -|`application.yaml` |The Helidon default configuration source. - -|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` |Creates the source from a Map with `MpConfigSources.create(Map)`. - -|`Properties` |Creates 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)` or `YamlMpConfigSource.create(URL)`. - -|=== - -== Using Helidon Config APIs - -You can use `MpConfigSources.create(helidonConfig)` to create a config source from Helidon config and then use it to create a MicroProfile instance. - -[source,java] ----- -io.helidon.config.Config helidonConfig = io.helidon.config.Config.builder() - .addSource(ConfigSources.create(Map.of("key", "value"))) <1> - .build(); - -Config config = ConfigProviderResolver.instance() - .getBuilder() - .withSources(MpConfigSources.create(helidonConfig)) <2> - .build(); ----- - -<1> Creates a config source from Helidon Config. -<2> Creates a MicroProfile Config instance. - -For more information on using Helidon Config APIs, see the Helidon SE Configuration documentation. - == Additional Information - link:{javadoc-base-url-api}spi/package-summary.html[Helidon Config SPI] diff --git a/docs/mp/config/02_MP_config_sources.adoc b/docs/mp/config/02_MP_config_sources.adoc index e27047d864d..764b144c7eb 100644 --- a/docs/mp/config/02_MP_config_sources.adoc +++ b/docs/mp/config/02_MP_config_sources.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2020 Oracle and/or its affiliates. + Copyright (c) 2020, 2021 Oracle and/or its affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,6 +25,34 @@ 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: + +[cols="3,5"] +|=== +|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.properties` |The 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` |Creates the source from a Map with `MpConfigSources.create(Map)`. + +|`Properties` |Creates 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)` or `YamlMpConfigSource.create(URL)`. + +|=== + == Understanding the Ordering of Default Config Sources The default MicroProfile Config Sources are: @@ -41,7 +69,6 @@ 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 @@ -118,14 +145,15 @@ To create an in-memory source from properties with custom name, use `create(Stri |=== -=== Example +=== Create Custom Map MicroProfile Config Source +You can create Microprofile Config Source from a map. [source,java] .Create MicroProfile Config Source based on Environment Variables and Custom Map ---- ConfigProviderResolver resolver = ConfigProviderResolver.instance(); -org.eclipse.microprofile.config.Config Config config = resolver.getBuilder().getBuilder() <1> +org.eclipse.microprofile.config.Config config = resolver.getBuilder().getBuilder() <1> .withSources(MpConfigSources.environmentVariables()) <2> .withSources(MpConfigSources.create(Map.of("key","value"))) <3> .build(); <4> @@ -138,6 +166,63 @@ resolver.registerConfig(config, null); <5> <4> Builds the MicroProfile Config Source. <5> 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. + +[source,java] +.Create YamlMPConfigSource from a path +---- +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 <> + +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` + +[source,yaml] +.Example of a YAML meta configuration file: +---- +add-discovered-sources: true <1> +add-discovered-converters: false <2> +add-default-sources: false <3> + +sources: + - type: "environment-variables" <4> + - type: "system-properties" <5> + - type: "properties" <6> + path: "/conf/prod.properties" <7> + ordinal: 50 <8> + optional: true <9> + - type: "yaml" <10> + classpath: "META-INF/database.yaml" <11> + +---- + +<1> If configured to `true`, config sources discovered through service loader will be added +<2> If configured to `true`, converters discovered through service loader will be added +<3> If configured to `true`, default config sources (system properties, environment variables, and `META-INF/microprofile-config.properties) will be added +<4> Loads the environment variables config source. +<5> Loads the system properties config source. +<6> Loads a properties file +<7> Location of the file: `/conf/prod.properties` on the file system +<8> 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. +<9> The file is optional (if not optional and no file is found, the bootstrap fails) +<10> Loads a YAML file +<11> Location of the file: `META-INF/database.yaml` on the classpath == Creating MicroProfile Config Source from Helidon SE Config Source @@ -157,30 +242,16 @@ To use advanced Helidon SE features in Helidon MP, create MicroProfile Config So 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"))) <1> + .build(); ConfigProviderResolver.instance(); Config config = ConfigProviderResolver.instance() .getBuilder() - .withSources(MpConfigSources.create(helidonConfig)) <1> + .withSources(MpConfigSources.create(helidonConfig)) <2> .build(); ---- -<1> Creates a MicroProfile config instance using Helidon Config. - - -== Create Yaml MicroProfile Config Source Programatically - -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. - - -=== Example - -[source,java] -.Create YamlMPConfigSource from a path ----- -ConfigProviderResolver.instance().newBuilder() - .withSources(YamlMpConfigSource.create(path)) - .build() ----- +<1> Creates a config source from Helidon Config. +<2> Creates a MicroProfile config instance using Helidon Config. diff --git a/docs/mp/guides/03_config.adoc b/docs/mp/guides/03_config.adoc index f988d89f62f..c33912b46d5 100644 --- a/docs/mp/guides/03_config.adoc +++ b/docs/mp/guides/03_config.adoc @@ -29,7 +29,7 @@ that can be used to run some basic examples using both default and custom config [width=50%,role="flex, sm7"] |=== -|About 30 minutes +|About 20 minutes |<> |=== @@ -63,19 +63,6 @@ mvn -U archetype:generate -DinteractiveMode=false \ cd helidon-quickstart-mp ---- -=== Configuration Formats - -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. Here are the supported formats, -each with the extension name you should use. By default, Helidon will determine the media type based on the extension name. - -* Java Property (.properties) -* JSON (.json) -* YAML (.yaml) -* HOCON (.conf) - -The remainder of this document will use these formats in examples and show you how to configure Helidon to parse them. - === Default configuration Helidon has an internal configuration, so you are not required to provide any configuration data for your application, @@ -237,360 +224,6 @@ curl http://localhost:8080/greet ---- <1> The system property took precedence over both the environment variable and `META-INF/microprofile-config.properties`. -== Custom configuration sources - -To use custom configuration sources, your application needs to use a `Config` object when -creating a `Server` object. When you use a `Config` object, you are in full control of -all configuration sources and precedence. By default, the environment variable and system property -sources are enabled, but you can disable them using the `disableEnvironmentVariablesSource` and `disableSystemPropertiesSource` -methods. - -This section will show you how to use a custom configuration with various sources, formats, and precedence rules. - -=== Full list of configuration sources - -Here is the full list of external config sources that you can use programmatically. - -1. Java system properties - the property is a name/value pair. -2. Environment variables - the property is a name/value pair. -3. Resources in the classpath - the contents of the resource is parsed according to its inferred format. -4. File - the contents of the file is parsed according to its inferred format. -5. Directory - each non-directory file in the directory becomes a config entry: the file name is the key. -and the contents of that file are used as the corresponding config String value. -6. A URL resource - contents is parsed according to its inferred format. - -You can also define custom sources, such as Git, and use them in your Helidon application. -See <> for more information. - -=== Classpath sources - -The first custom resource example demonstrates how to add a second internal configuration resource that is discovered in the `classpath`. -The code needs to build a `Config` object, which in turn is used to build the `Server` object. The `Config` object is built using a `Config.Builder`, -which lets you inject any number of sources into the builder. Furthermore, you can set precedence for the sources. -The first source has highest precedence, then the next has second highest, and so forth. - -[source,text] -.Add a resource file, named `config.properties` to the `resources` directory with the following contents: ----- -app.greeting=HelloFrom-config.properties ----- - -[source,java] -.Update the `Main` class; 1) Add new imports, 2) Replace the `startServer` method, and 3) Add `buildConfig` method: ----- -import io.helidon.config.Config; //<1> -import static io.helidon.config.ConfigSources.classpath; -... - - static Server startServer() { - return Server.builder() - .config(buildConfig()) // <2> - .build() - .start(); - } - - private static Config buildConfig() { - return Config.builder() - .disableEnvironmentVariablesSource() // <3> - .sources( - classpath("config.properties"), // <4> - classpath("META-INF/microprofile-config.properties")) // <5> - .build(); - } ----- -<1> Import config classes. -<2> Pass the custom `Config` object to the `Server.Builder`. -<3> Disable the environment variables as a source. -<4> Specify the new config.properties resource that is in the `classpath`. -<5> You must specify the existing `META-INF/microprofile-config.properties` or Helidon will not use it as a configuration source -even though it is considered a default source. - -[source,bash] -.Build and run the application (without the system property). Invoke the endpoint and check the response: ----- -curl http://localhost:8080/greet -... -{ - "message": "HelloFrom-config.properties World!" # <1> -} ----- -<1> The greeting was picked up from `config.properties`, overriding the value in `META-INF/microprofile-config.properties`. - -NOTE: It is important to remember that configuration from all sources is merged internally. If you have the same -configuration property in multiple sources, then only the one with highest precedence will be used at runtime. -This is true even the same property comes from sources with different formats. - -Swap the source order and run the test again. - -[source,java] -.Update the `Main` class and replace the `buildConfig` method: ----- - private static Config buildConfig() { - return Config.builder() - .disableEnvironmentVariablesSource() - .sources( - classpath("META-INF/microprofile-config.properties"), // <1> - classpath("config.properties")) - .build(); - } ----- -<1> Swap the source order, putting `META-INF/microprofile-config.properties` first. - -[source,bash] -.Build and run the application, then invoke the endpoint and check the response: ----- -curl http://localhost:8080/greet -... -{ - "message": "HelloFromMPConfig World!" // <1> -} ----- -<1> The file `META-INF/microprofile-config.properties` was used to get the greeting since it now has precedence over `config.properties`. - -=== External file sources - -You can move all or part of your configuration to external files, making them optional or mandatory. The obvious advantage to this -approach is that you do not need to rebuild your application to change configuration. In the following -example, the `app.greeting` configuration property will be added to `config-file.properties`. - -[source,bash] -.Unset the environment variable so that `disableEnvironmentVariablesSource` doesn't need to be called: ----- -unset APP_GREETING ----- - -[source,bash] -.Create a file named `config-file.properties` in the `helidon-quickstart-mp` directory with the following contents: ----- -app.greeting=HelloFromConfigFile ----- - -[source,java] -.Update the `Main` class; 1) Add new import and 2) Replace the `buildConfig` method: ----- -import static io.helidon.config.ConfigSources.file; -... - - private static Config buildConfig() { - return Config.builder() - .sources( - file("config-file.properties"), // <1> - classpath("META-INF/microprofile-config.properties")) - .build(); - } ----- -<1> Add a mandatory configuration file. - -[source,bash] -.Build and run the application, then invoke the endpoint and check the response: ----- -curl http://localhost:8080/greet -... -{ - "message": "HelloFromConfigFile World!" # <1> -} ----- -<1> The configuration property from the file `config-file.properties` takes precedence. - -NOTE: If you want the configuration file to be optional, you must use the `optional` method with `sources`, -otherwise Helidon will generate an error during startup as shown below. This is true for both `file` and -`classpath` sources. By default, these sources are mandatory. - -[source,java] -.Update the `Main` class and replace the `buildConfig` method: ----- - private static Config buildConfig() { - return Config.builder() - .sources( - file("missing-file"), // <1> - classpath("META-INF/microprofile-config.properties")) - .build(); - } ----- -<1> Specify a file that doesn't exist. - -[source,bash] -.Build then start the application and you will see the following output: ----- -Exception in thread "main" io.helidon.config.ConfigException: Cannot load data from mandatory source FileConfig[missing-file]. File `missing-file` not found. ----- - -To fix this, use the `optional` method as shown below, then rerun the test. - ----- -... - file("missing-file").optional(), // <1> - ----- -<1> The `missing-file` configuration file is now optional. - -=== Directory source - -A directory source treats every file in the directory as a key, and the file contents as the value. The -following example includes a directory source as highest precedence. - -[source,bash] -.Create a new directory `helidon-quickstart-mp/conf` then create a file named `app.greeting` in that directory with the following contents: ----- -HelloFromFileInDirectoryConf ----- - -[source,java] -.Update the `Main` class; 1) Add new import and 2) Replace the `buildConfig` method: ----- -import static io.helidon.config.ConfigSources.directory; -... - - private static Config buildConfig() { - return Config.builder() - .sources( - directory("conf"), // <1> - classpath("config.properties").optional(), - classpath("META-INF/microprofile-config.properties")) - .build(); - } ----- -<1> Add a mandatory configuration directory. - -[source,bash] -.Build and run the application, then invoke the endpoint and check the response: ----- -curl http://localhost:8080/greet -... -{ - "message": "HelloFromFileInDirectoryConf World!" # <1> -} ----- -<1> The greeting was fetched from the file named `app.greeting`. - -==== Exceeding three sources - -If you have more than three sources, you need to use a `ConfigSources` class to create a -custom source list as shown below. - -[source,java] -.Update the `Main` class; 1) Add new import and 2) Replace the `buildConfig` method: ----- -import io.helidon.config.ConfigSources; -... - - private static Config buildConfig() { - return Config.builder() - .sources(ConfigSources.create( // <1> - directory("conf"), - file("config-file.properties"), - classpath("config.properties").optional(), - classpath("META-INF/microprofile-config.properties"))) - .build(); - } ----- -<1> Create a list of four sources using `ConfigSources.create` method. - -[source,bash] -.Build and run the application, then invoke the endpoint and check the response: ----- -curl http://localhost:8080/greet -... - -{ - "message": "HelloFromFileInDirectoryConf World!" -} ----- - -=== Meta-configuration - -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. This requires using the `Config.loadSourcesFrom` method rather than a `Config.Buider` -object. The contents of the meta-configuration file needs to be in JSON, YAML, or HOCON format. YAML is used in the following example. - -[source,bash] -.Create a file named `meta-config.yaml` in the `helidon-quickstart-mp` directory with the following contents: ----- -sources: - - type: "classpath" // <1> - properties: - resource: "META-INF/microprofile-config.properties" // <2> ----- -<1> The source type. -<2> The name of the mandatory configuration resource. - - -[source,java] -.Update the `Main` class and replace the `buildConfig` method: ----- - private static Config buildConfig() { - return Config.loadSourcesFrom( file("meta-config.yaml")); // <1> - } ----- -<1> Specify the meta-configuration file, which contains a single configuration source. - -[source,bash] -.Build and run the application, then invoke the endpoint and check the response: ----- -curl http://localhost:8080/greet -... -{ - "message": "HelloFromMPConfig World!" // <1> -} ----- -<1> The `META-INF/microprofile-config.properties` resource file was used to get the greeting. - -The source precedence order in a meta-configuration file is the order of appearance in the file. -This is demonstrated below where the `config-file.properties` has highest precedence. - -[source,bash] -.Replace the contents of the `meta-config.yaml` file: ----- -sources: - - type: "file" // <1> - properties: - path: "./config-file.properties" // <2> - - type: "classpath" - properties: - resource: "META-INF/microprofile-config.properties" - - type: "file" - properties: - path: "optional-config-file" - optional: true // <3> ----- -<1> The source type specifies a file. -<2> The name of the mandatory configuration file. -<3> Specify that the `optional-config-file` file is optional. - -[source,bash] -.Restart the application, then invoke the endpoint below and check the response: ----- -curl http://localhost:8080/greet -... -{ - "message": "HelloFromConfigFile World!" // <1> -} ----- -<1> The `config-file.properties` source now takes precedence. - -When using a meta-config file, you need to explicitly include both environment variables and system properties as -a source if you want to use them. - -[source,bash] -.Replace the contents of the `meta-config.yaml` file: ----- -sources: - - type: "environment-variables" // <1> - - type: "system-properties" // <2> - - type: "classpath" - properties: - resource: "META-INF/microprofile-config.properties" - - type: "file" - properties: - path: "./config-file.properties" ----- -<1> Environment variables are now used as a source. -<2> System properties are now used as a source. - - -You can re-run the previous tests that exercised environment variables and system properties. Swap the two types to see -the precedence change. Be sure to unset APP_GREETING after you finish testing. - == Accessing Config within an application You have used Helidon to customize configuration behavior from your code using the `Config` and @@ -678,9 +311,6 @@ curl http://localhost:8080/greet === Injecting the Config object You can inject the `Config` object into the class and access it directly as shown below. -This object is not initialized when the `GreetingProvider` constructor is called, so you need to provide -a method (`onStartup`) that observes `@Initialized`. This method will be called when `GreetingProvider` is ready for -use. [source,java] .Update the `GreetingProvider.java` file; 1) Add new imports and 2) Replace the `GreetingProvider` class: @@ -695,11 +325,10 @@ import javax.enterprise.event.Observes; public class GreetingProvider { private final AtomicReference message = new AtomicReference<>(); - @Inject - Config config; // <2> - - public void onStartUp(@Observes @Initialized(ApplicationScoped.class) Object init) { - message.set(config.get("app.greeting").asString().get()); // <3> + @Inject // <2> + public GreetingProvider(Config config) { + String message = config.get("app.greeting").asString().get(); // <3> + this.message.set(message); } String getMessage() { @@ -968,20 +597,9 @@ kubectl delete configmap helidon-configmap == Summary This guide has demonstrated how to use basic Helidon configuration features. The full configuration documentation, starting with the -introduction section at <> has much more information including -the following: - -- Architecture -- Parsers -- Extensions -- Filters -- Hierarchical Access -- Property Mapping -- Mutability Support -- and more... - +introduction section at <> has much more information. -Refer to the following references for additional information: +Please refer to the following references for additional information: - MicroProfile Config specification at https://github.com/eclipse/microprofile-config/releases/tag/1.3 - MicroProfile Config Javadoc at https://javadoc.io/doc/org.eclipse.microprofile.config/microprofile-config-api/1.3 diff --git a/docs/se/config/01_introduction.adoc b/docs/se/config/01_introduction.adoc index aa497d72588..ec423ea3f16 100644 --- a/docs/se/config/01_introduction.adoc +++ b/docs/se/config/01_introduction.adoc @@ -106,88 +106,6 @@ For this first example we can see the basic features of `Config`: - You can immediately provide a default value for the cases the configuration option is not defined in any source -=== Your First Config Application -An easy way to start with the link:{javadoc-base-url-api}/Config.html[Config] API -is to follow these four steps: - -1. <> -2. <> -3. <> -4. <> - -==== Add Maven Dependency on Config [[add-maven-coords]] - -Add <> to your `pom.xml. - -==== Update `module-info.java` [[update-module-info]] -If you are using Java 11 then create or update the `module-info.java` file for your application: -[source,java] -.Config Dependency in `module-info.java` ----- -module myModule { - requires io.helidon.config; -} ----- - -==== Create simple Config Properties File [[create-simple-config-props]] -[source] -.Example `src/main/resources/application.properties` config file ----- -greeting = Hello - -web.debug = true -web.page-size = 20 -web.ratio = 1.3 - -bl.initial-id = 10000000000 - -origin = props -java.home=homeFromProps # will be ignored ----- - -==== Write Code using the Default Config [[Config-Basics-DefaultConfig]] - -[source,java] -.Create and Use Default `Config` from Java ----- -import io.helidon.config.Config; // <1> -... -Config config = Config.create(); // <2> -System.out.println(String.format( - "greeting is %s\n" - + "web.debug is %b\n" - + "web.page-size is %d\n" - + "web.ratio is %f\n" - + "bl.initial-id is %d\n" - + "origin is %s\n" - + "java.home is %s", - config.get("greeting").asString().orElse("Default greeting"), // <3> - config.get("web.debug").asBoolean().orElse(false), - config.get("web.page-size").asInt().orElse(50), - config.get("web.ratio").asDouble().orElse(2.0), - config.get("bl.initial-id").asLong().orElse(1L), - config.get("origin").asString().orElse("defaults"), - config.get("java.home").asString().get())); // <4> ----- -<1> Import `Config`. -<2> Create the root of the `Config` tree from the default sources. -<3> Retrieve various values by their dotted names and decode them as the appropriate -Java types, providing default values if the property is missing. -<4> Retrieve the value (and fail with a runtime exception if missing) - -When you build and run your project, the output will look like this: -[source] ----- -greeting is Hello -web.debug is true -web.page-size is 20 -web.ratio is 1.300000 -bl.initial-id is 10000000000 -origin is props -java.home is /Library/Java/JavaVirtualMachines/jdk-10.0.1.jdk/Contents/Home ----- - - === Overriding Values The `Config` system treats config sources as a hierarchy, where the first source that diff --git a/docs/se/config/05_mutability-support.adoc b/docs/se/config/05_mutability-support.adoc index 7c8c8a4952e..9554fd7529a 100644 --- a/docs/se/config/05_mutability-support.adoc +++ b/docs/se/config/05_mutability-support.adoc @@ -123,7 +123,7 @@ Config config = Config.create( .pollingStrategy(PollingStrategies.regular(Duration.ofSeconds(2))) // <1> .optional(), ConfigSources.file("conf/config.properties") - .pollingStrategy(PollingStrategies::watch) // <2> + .changeWatcher(FileSystemWatcher.create()) // <2> .optional(), ConfigSources.classpath("application.properties") .pollingStrategy(PollingStrategies::nop)); // <3>