Another post about Lightweight Config, a library I’ve recently built from the ground up, after creating various versions of it in previous projects.
Where previously, I’d tried to be clever and prepare the library for lots of possibilities, I took the opposite approach this time. I created a simple monolithic library to solve the core problem, and then in a later version added some new ideas that the simple idea opened up for me.
The Basic Challenge
In a service that has no specific injection framework, like Spring or DropWizard, and especially in a test, what’s the nicest way to load some configuration into an object.
E.g.
username: user
password: foo
urls:
- http://foo.com
- http://bar.com
We’d like to load this into an object:
public class Config {
private String user;
private String password;
private List<String> urls;
// getters and setters
}
This is easily achieved in one line with ConfigLoader.loadYmlConfigFromResource("config.yml", Config.class)
This assumes config.yml is in the appropriate resources.
Placeholders
What if we wanted to interpolate runtime values from environment variables or system properties? Well, that’s really the point of this framework. It’s intended to externalise the setting of values:
username: ${USERNAME}
password: ${PASSWORD}
urls:
- http://foo.com
- http://bar.com
Imports
If we have some common snippets of configuration to share between various configuration objects, then an import syntax would be nice. Even better if we can drive the import by a placeholder:
# config.yml
#import ${PROFILE}-config.yml
And then:
# dev-config.yml
username: username
password: foo
urls:
- http://www.dev.com
And so on. Now we can load the config.yml but set PROFILE to determine which child config is also loaded. We can even put some common properties in the parent and it’ll all mash together into the load operation.Plugins
What if we’re using a password/secret manager to load certain values dynamically? Let’s say we want to express that a certain value may be loaded from a secret:
username: !secret ${SECRET_ID}.user
password: !secret ${SECRET_ID}.password
We can add our custom tag – secret – to the loader:
Config myConfig = new ConfigLoader()
.withTag("secret", secretPath -> secretsManager.load(secretPath))
.loadAs("config.yml", Config.class);
Source: codingcraftsman.wordpress.com
0 comments:
Post a Comment