Monday, May 31, 2021

Go (Con)Figure

Core Java, Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Preparation

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

Core Java, Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Preparation
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

Related Posts

0 comments:

Post a Comment