Overview
Getting started
Usage
The library is designed to provide a simple easy-to-use swift-setup .property-file based configuration management functionality suitable to use with any JVM-based language.
It supports:
- File-based environment properties, by specifying property
env=environment_name
. - Properties override in such a chain: default properties ← file properties ← environment variables
← system properties.
That means:- User provides default properties through code
- Which are overrided by file-based environment properties
- Which are overrided by the same named environment variables
- Which are overrided by JVM system properties
- Placeholder resolve functionality in a Spring-framework fashion, like:
my.property.value=${MY_VALUE:default value}
. Including recursive placeholders. - Default property values.
Add a repository into your basic build.gradle file:
repositories {
...
maven { url 'https://jitpack.io' }
}
Or if you are using sub-projects:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
Add dependency:
dependencies {
implementation 'com.github.HardNorth:config-simple:$LATEST_VERSION'
}
Specify a repository:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Add a dependency:
<dependency>
<groupId>com.github.HardNorth</groupId>
<artifactId>config-simple</artifactId>
<version>$LATEST_VERSION</version>
</dependency>
Add it in your build.sbt at the end of resolvers:
resolvers += "jitpack" at "https://jitpack.io"
Add a dependency:
libraryDependencies += "com.github.HardNorth" % "config-simple" % "$LATEST_VERSION"
By standard behavior (if there is no specified env
parameter somewhere in environment and system properties)
the library seeks for default.properties
file in classpath and reads it. So let's place such file,
for example into src/main/resources
.
test.string.value=my string value 1
Then let's implement a class which will read the file:
import com.github.hardnorth.common.config.ConfigLoader;
import com.github.hardnorth.common.config.ConfigProvider;
public class Config {
private static final ConfigProvider PROVIDER = new ConfigLoader().get();
public static final String STRING_VALUE = PROVIDER.getProperty("test.string.value", String.class);
// just for testing and examples, remove from real code
public static void main(String[] args) {
// Will output "my string value 1"
System.out.println(STRING_VALUE);
}
}
Now we can use our property anywhere in an application referring it as a constant:
LOGGER.info(Config.STRING_VALUE); // Will log "my string value 1"
The library also supports more complex type conversion:
test.url.value=https://www.example.com
Such value will be set correctly:
public static final URL URL_VALUE = PROVIDER.getProperty("test.url.value", URL.class);
You can bypass default values to ConfigLoader
constructor:
import com.github.hardnorth.common.config.ConfigLoader;
import com.github.hardnorth.common.config.ConfigProvider;
import java.util.Properties;
public class Config {
private static final Properties DEFAULT_PROPERTIES;
static {
DEFAULT_PROPERTIES = new Properties();
DEFAULT_PROPERTIES.put("test.default.value", "my default value");
}
private static final ConfigProvider PROVIDER = new ConfigLoader(DEFAULT_PROPERTIES).get();
public static final String VALUE = PROVIDER.getProperty("test.default.value", String.class);
// just for testing and examples, remove from real code
public static void main(String[] args) {
// Will output "my default value"
System.out.println(VALUE);
}
}
There is also possible to set a default value on the fly:
// Will be "my default value"
public static final String NOT_EXISTING_VALUE = PROVIDER.getProperty("test.not.existing.value", String.class, "my default value");
The library provides environment switch. To switch on different property file use env
parameter specified
somewhere in environment or system properties, or bypassed as a default property to ConfigLoader
constructor.
To demonstrate the feature let's update default.properties
with additional value:
test.url.value=https://www.example.com
And add another property file, let's say dev.properties
with:
test.url.value=http://localhost
Our new Config class:
import com.github.hardnorth.common.config.ConfigLoader;
import com.github.hardnorth.common.config.ConfigProvider;
import java.net.URL;
public class Config {
private static final ConfigProvider PROVIDER = new ConfigLoader().get();
public static final URL URL_VALUE = PROVIDER.getProperty("test.url.value", URL.class);
// just for testing and examples, remove from real code
public static void main(String[] args) {
// Will output an URL
System.out.println(URL_VALUE);
}
}
Now we can run our class like this:
#!/bin/bash
export env=dev
java -cp config-simple-1.0.1-SNAPSHOT-all.jar:. Config
This code outputs: http://localhost
.
It also possible to bypass env
param through System properties:
java -cp config-simple-1.0.1-SNAPSHOT-all.jar:. -Denv=dev Config
Will output: http://localhost
.
But:
#!/bin/bash
export env=dev
java -cp config-simple-1.0.1-SNAPSHOT-all.jar:. -Denv=default Config
Will output: https://www.example.com
, since System properties have greater weight in the library than
Environment variables. As was specified the inheritance/override chain looks like this (from lower weight to greater weight):
default properties <- file properties <- environment variables <- system properties
The library supports placeholders in a format ${placeholder.reference:placeholder.default.value}
.
Let's update our default.properties
file to test it:
test.string.value=my string value 1
test.placeholder.value=${test.string.value}
If we set new test.placeholder.value
to a variable it will be resolved to "my string value 1".
// Will be "my string value 1"
public static final String PLACEHOLDER_VALUE = PROVIDER.getProperty("test.placeholder.value", String.class);
Placeholders can be a part of a value:
STRING_VALUE=my string property
# Will be resolved into 'this is my string property' on get
com.github.hardnorth.common.config.test.placeholder.part.value.string=this is ${STRING_VALUE}
In case if placeholder reference value does not exist you can specify default value inside a placeholder, after a
character :
.
# Will return 'my default string property' on get
test.placeholder.default.value=${THERE_IS_NO_SUCH_PLACEHOLDER:my default string property}
Default values can be also converted in different types:
placeholder.default.int=${THERE_IS_NO_SUCH_PLACEHOLDER:10003}
// Integer 10003
public static final Integer INTEGER_VALUE = PROVIDER.getProperty("placeholder.default.int", Integer.class);
For complex property value generation it is possible to place placeholders recursively:
FIRST_PLACEHOLDER=SECOND
SECOND_PLACEHOLDER=2
# Will be resolved into '2' on get
placeholder.recursive.resolve=${${FIRST_PLACEHOLDER}_PLACEHOLDER}
There is no special limits for recursion depth, but the library detects infinite recursion.