Skip to content

Commit

Permalink
Improve documentation (#779)
Browse files Browse the repository at this point in the history
  • Loading branch information
radcortez authored Jul 7, 2022
1 parent 29c567a commit 7023248
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 34 deletions.
1 change: 1 addition & 0 deletions documentation/mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ nav:
- 'Secret Keys': config/secret-keys.md
- Config Sources:
- 'Custom': config-sources/custom.md
- 'Factories': config-sources/factories.md
- 'Locations': config-sources/locations.md
- 'YAML': config-sources/yaml.md
- 'FileSystem': config-sources/filesystem.md
Expand Down
82 changes: 82 additions & 0 deletions documentation/src/main/docs/config-sources/factories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Config Source Factory

Another way to create a `ConfigSource` is via the `ConfigSourceFactory`. The difference between the SmallRye Config
Factory and the standard way to make a `ConfigSource` as specified in MicroProfile Config is the Factory's ability to
provide a context with access to the available configuration. With the `ConfigSourceFactory` it is possible to
bootstrap a `ConfigSource` that configures itself with previously initialized `ConfigSource's`.

By implementing
[ConfigSourceFactory](https://github.com/smallrye/smallrye-config/blob/main/implementation/src/main/java/io/smallrye/config/ConfigSourceFactory.java),
a list of `ConfigSource's` may be provided via the `
Iterable<ConfigSource> getConfigSources(ConfigSourceContext context)` method. The `ConfigSourceFactory` may also
assign a priority by overriding the default method `OptionalInt getPriority()`. The priority only sorts the factories
during initialization. After initialization, the provided `ConfigSources` will use their own ordinal and sorted with
all `ConfigSources` available in the `Config` instance.

When the Factory initializes, the provided `ConfigSourceContext` may call the method
`ConfigValue getValue(String name)`. This method looks up configuration names in all `ConfigSource's` already
initialized by the `Config` instance, including sources with lower ordinals than the ones defined in the
`ConfigSourceFactory`. The `ConfigSourceFactory` does not consider `ConfigSources's` provided by other
`ConfigSourceFactory's` (the priority does not matter).

Registration of a `ConfigSourceFactory` is done via the `ServiceLoader` mechanism by providing the
implementation classes in a `META-INF/services/io.smallrye.config.ConfigSourceFactory` file. Alternatively, factories
may be registered via the Programmatic API in `SmallRyeConfigBuilder#withSources`.

A `ConfigSourceFactory` requires an implementation of `io.smallrye.config.ConfigSourceFactory`. Each implementation
requires registration via the `ServiceLoader` mechanism in the
`META-INF/services/io.smallrye.config.ConfigSourceFactory` file. Alternatively, interceptors may be registered via the
Programmatic API in `SmallRyeConfigBuilder#withSources`.

```java
package org.acme.config

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.List;

import org.eclipse.microprofile.config.spi.ConfigSource;

import io.smallrye.config.ConfigMessages;
import io.smallrye.config.PropertiesConfigSource;
import io.smallrye.config.ConfigSourceContext;
import io.smallrye.config.ConfigSourceFactory;
import io.smallrye.config.ConfigValue;

public class FileSystemConfigSourceFactory implements ConfigSourceFactory {
@Override
public Iterable<ConfigSource> getConfigSources(final ConfigSourceContext context) {
final ConfigValue value = context.getValue("org.acme.config.file.locations");
if (value == null || value.getValue() == null) {
return Collections.emptyList();
}

try {
return List.of(new PropertiesConfigSource(toURL(value.getValue()), 250));
} catch (IOException e) {
return Collections.emptyList();
}
}

private URL toURL(final String value) {
try {
return new URI(value).toURL();
} catch (URISyntaxException | MalformedURLException e) {
throw ConfigMessages.msg.uriSyntaxInvalid(e, value);
}
}
}
```

And registration in:
_META-INF/services/io.smallrye.config.ConfigSourceFactory_
```properties
org.acme.config.FileSystemConfigSourceFactory
```

The `FileSystemConfigSourceFactory` look ups the configuration value for `org.acme.config.file.locations`, and uses it
to set up an additional `ConfigSource`.
23 changes: 0 additions & 23 deletions documentation/src/main/docs/config-sources/factory.md

This file was deleted.

4 changes: 3 additions & 1 deletion documentation/src/main/docs/config/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ Expression expansion may be selectively disabled with `io.smallrye.config.Expres

```java
Config config = ConfigProvider.getConfig();
String url = Expressions.withoutExpansion(() -> config.getValue("callable.url", String.class));

String url = Expressions.withoutExpansion(() ->
config.getValue("callable.url", String.class));
```
24 changes: 16 additions & 8 deletions documentation/src/main/docs/config/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@

By default, SmallRye Config reads configuration properties from multiple configuration sources (by descending ordinal):

1. (400) System properties
2. (300) Environment variables
3. (100) MicroProfile Config configuration file `META-INF/microprofile-config.properties` in the classpath
1. (`400`) System properties
2. (`300`) Environment variables
3. (`100`) MicroProfile Config configuration file `META-INF/microprofile-config.properties` in the classpath

A configuration source is handled by a `ConfigSource`. A `ConfigSource` provides configuration values from a specific
place.

The final configuration is the aggregation of the properties defined by all these sources. A configuration property
lookup starts by the highest ordinal configuration source available and works it way down to other sources until a
match is found. This means that any configuration property may override a value just by setting a different value in a
higher ordinal config source. For example, a property configured using an environment property overrides the value
higher ordinal config source. For example, a property configured using an Environment Variable overrides the value
provided using the `microprofile-config.properties` file.

### System Properties

System properties can be handed to the application through the `-D` flag during startup. For instance,
`java -Dmy.prop -jar my.jar`.

### Env Properties
### Environment Variables

Environment variables are set directly in the host operating system. Environment variables names follow the conversion
rules specified by [MicroProfile Config](https://github.com/eclipse/microprofile-config/).
rules detailed by [Environment Variables](environment-variables.md).

### MicroProfile Config configuration file

Expand All @@ -46,7 +46,7 @@ SmallRye Config provides additional extensions which cover other configuration f
- [ZooKeeper](../config-sources/zookeeper.md)
- [HOCON](../config-sources/hocon.md)

It is also possible to create a Custom Config Source.
It is also possible to create a [Custom ConfigSource](../config-sources/custom.md).

## Retrieving the Configuration

Expand Down Expand Up @@ -93,13 +93,21 @@ String suffix;
@Inject
@ConfigProperty(name = "greeting.name")
Optional<String> name;

@Inject
SmallRyeConfig config;
```

- If a value if not provided for this `greeting.message`, the application startup fails with a
`javax.enterprise.inject.spi.DeploymentException: No config value of type [class java.lang.String] exists for: greeting.message`.
- The default value `!` is injected if the configuration does not provide a value for `greeting.suffix`.
- The property `greeting.name` is optional - an empty Optional is injected if the configuration does not provide a
value for it.
value for it.

## Override Config

It is possible to override `Config` default initialization `ConfigProvider.getConfig()`, by extending
`io.smallrye.config.SmallRyeConfigFactory` and registering the implementation with the `ServiceLoader` mechanism.

## Config vs SmallRyeConfig

Expand Down
2 changes: 1 addition & 1 deletion documentation/src/main/docs/config/mappings.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ mapping instance:

```java
SmallRyeConfig config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class);
Server server = config.getConfigMapping(Server.class);
Server server = config.getConfigMapping(Server.class);
```

!!! info
Expand Down
1 change: 0 additions & 1 deletion documentation/src/main/docs/converters/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ The following dependency is required in the classpath to use the JSON Converter:
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config-converter-json</artifactId>
<version>{{attributes['version']}}</version>
<scope>runtime</scope>
</dependency>
```

Expand Down
42 changes: 42 additions & 0 deletions documentation/src/main/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,45 @@ very flexible library.
It follows the [MicroProfile Config](https://github.com/eclipse/microprofile-config/) specification to provide
the initial config foundations and expands with it own concepts to cover a wide range of use cases observed in the
configuration space.

## Use SmallRye Config in a Java application

Add the _dependency_ to your project using your preferred build tool:

=== "Maven"

```xml
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
<version>{{attributes['version']}}</version>
</dependency>
```

=== "Gradle (Groovy)"

```groovy
implementation 'io.smallrye.config:smallrye-config:{{ attributes.versions }}'
```

=== "Gradle (Kotlin)"

```kotlin
implementation("io.smallrye.config:smallrye-config:{{ attributes.versions }}")
```

=== "JBang"

```java
//DEPS io.smallrye.config:smallrye-config:{{ attributes.versions }}
```

And retrieve a `SmallRyeConfig` instance with:

```java
SmallRyeConfig config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class);
```

!!! info

`SmallRyeConfig` is the entry point to all the config capabilities provided by SmallRye Config.

0 comments on commit 7023248

Please sign in to comment.