config

External configuration for JVM apps

About

External configuration for JVM applications.

Getting started

1. Add dependency
<dependency>
  <groupId>io.avaje</groupId>
  <artifactId>config</artifactId>
  <version>1.0</version>
</dependency>

Add the dependency to your project.

2. For Test configuration

For configuration used when running local tests add into src/test/resources either:

  • application-test.yaml or application-test.properties
3. For Main configuration
3a. Resources

Optionally provide "default" configuration by adding to src/main/resources either:

  • application.yaml or application.properties

Configuration specified by these files will be overridden by other configuration sources (load.properties, command line args or plugins).

3b. load.properties

Optionally specify a load.properties property to define locations to load external configuration from. For example:

## in application.yaml
load.properties: /etc/config/myapp.properties /etc/other.yaml

After default configuration files are loaded the load.properties property is read to see if it specifies other properties/yaml configuration files to load.

3c. Command line arguments

Command line arguments proceeded by -P are considered potential configuration files. For example:

java -jar myapp.jar -P/etc/config/myapp.yaml -P/etc/other.yaml

Using Config

We use Config to access the global configuration. Config can be used anywhere in application code - static initialisers, constructors etc. There is no limitation on where we can use Config.

Example reading properties
// get a String property
String value = Config.get("myapp.foo");

// with a default value
String value = Config.get("myapp.foo", "withDefaultValue");

// also int, long and boolean with and without default values
int intVal = Config.getInt("bar");
long longVal = Config.getLong("bar", 42);
// get a String property
val value: String = Config.get("myapp.foo");

// with a default value
val value = Config.get("myapp.foo", "withDefaultValue");

// also int, long and boolean with and without default values
val intVal = Config.getInt("bar");
val longVal = Config.getLong("bar", 42);
Optional properties

If a property is not defined then Config will fail fast and throw an IllegalStateException unless a default value is supplied or getOptional() is used.

// if myapp.foo is not defined
// ... throws IllegalStateException
String value = Config.get("myapp.foo");

// specify a default
String value = Config.get("myapp.foo", "someDefault");

// or use optional
Optional<String> value = Config.getOptional("myapp.foo");
// if myapp.foo is not defined
// ... throws IllegalStateException
val value = Config.get("myapp.foo");

// specify a default
val value = Config.get("myapp.foo", "someDefault");

// or use optional
val value = Config.getOptional("myapp.foo");

Config will load configuration and provides API to read, change and listen to changes to configuration.

Local development

Sometimes we want configuration for when we run our application locally (via main). For example, we want to provide configuration that points our application to a local database.

To do this we need to:

1. Specify app.name property

Specify app.name as a configuration property (in application.yaml or similarly loaded configuration).

2. Add ~/.localdev/${app.name}.yaml

Add a file into ~/.localdev called either ${app.name}.yaml or ${app.name}.properties

For example, if the app.name was myapp then we have either:

  • ~/.localdev/myapp.yaml or ~/.localdev/myapp.properties

Note that the local development configuration is not loaded if the test configuration is loaded.

Kubernetes Env variables

Config will use the following environment variables if they are set.

  • POD_NAME - to set app.name & app.instanceId
  • POD_ENVIRONMENT - to set app.environment

Config will check if those environment variables are set and if so translate them into app.name and app.environment if those properties have not already been set.

Plugins

TODO: Plugins to load extra configuration (like URL)