Multi-layered properties and secrets management library, for JAVA.
This project aims to provide a library which manages properties and secrets coming from multiple sources (startup properties, environment, property files, etc.)
While props is currently implemented in JAVA, additional languages are planned in the future.
props uses the Bazel build system which comes with
ErrorProne enabled by default.Add props as a dependency in your project.
<dependency>
  <groupId>com.mihaibojin.props</groupId>
  <artifactId>props-core</artifactId>
  <version>0.0.4</version>
</dependency>
Initialize a registry object which resolves values from the system properties and the environment.
Props props = Props.factory()
                   .withResolver(new SystemPropertyResolver())
                   .withResolver(new EnvResolver())
                   .build();
Create and bind a String property which retrieves the value of file.encoding 
from the system properties.
Prop<String> aProp = props.prop("file.encoding").build();
String encoding = aProp.value(); // will return an encoding such as UTF-8
Read more to see other features.
To use the library, you first need to initialize a Props registry.
Props props = Props.factory()
                   .withResolver(...)
                   .build();
Once configured, the Props object can:
Prop) objectsAll the examples below assume you have initialized a Props registry.
Props has a number of predefined resolvers.
Support for the following sources is provided out of the box:
Additionally, you may define custom resolvers by implementing the Resolver interface.
The following examples assume you have already configured a Props registry.
Props supports multiple types out of the box.
For example, you can load an integer property’s value, without registering a prop with the registry:
Integer maybeValue = props.valueOf("prop.key", Cast.asInteger());
Or if you need to retrieve its value more than once, you can bind it to the registry as follows:
Prop<Integer> aProp = props.prop("prop.key", Cast.asInteger()).build();
Integer maybeValue = aProp.value(); // will return the current value, at calling time
If more than one resolver has a value for prop.key, the last one to define it 
will decide the property’s value.
Props props =
    Props.factory()
        .withResolver(new PropertyFileResolver(...)) // prop.key="one"
        .withResolver(new PropertyFileResolver(...)) // prop.key="two"
        .build();
String maybeValue = props.valueOf("prop.key"); // will return "two"
Sometimes you may require to configure the resolver layers differently, depending on the environment in which the app is running.
For example, you may choose to define the resolvers in a configuration file, and specify the configuration file as an argument:
# /tmp/production.config
system
env
classpath=layer1.properties
file=/tmp/layer2.properties
# Start the app with
javac Main.java && java -DresolverConfig=production.config Main
// Main.java
String confFile = System.getProperty("resolverConfig")
Props props =
    Props.factory()
        .withResolvers(readResolverConfig(Files.newInputStream(Path.of(confFile)))
        .build();
// props will be initialized with the resolvers defined in the config file
Properties can be registered with a single resolver. In that case, the registry will disregard all but the configured resolver.
Props props =
    Props.factory()
        .withResolver("MY-ID", new PropertyFileResolver(...)) // prop.key="one"
        .withResolver(new PropertyFileResolver(...)) // prop.key="two"
        .build();
// retrieve a value without binding a Prop to the registry
String maybeValue = props.prop("prop.key").resolver("MY-ID").value(); // will return "one"
If no value can be found for the specified property, Prop.value() will return null.
String maybeValue = props.valueOf("unknown.prop"); // will return null
Further examples are included as part of the examples test suite.
These examples include code samples for the following features:
You can find a copy of the latest Javadocs, here.
Please see the contributor guide.
Copyright 2020 Mihai Bojin
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.