mosquito87
mosquito87

Reputation: 4440

(Too) complex configuration management (Java properties)

I'm working at a company having a (too) complex configuration management process:

Those files are only needed if a property value depends on the environments (is different for development, testing, live).

This process is not only complex but also error prone. How could it be simplified/improved?

The approach should be compatbiel with Spring DI.

Upvotes: 1

Views: 413

Answers (3)

Alexey Melezhik
Alexey Melezhik

Reputation: 971

If not to take into consideration all the redesign methods mentioned in the previous comments, you can wrap all the complexity into Tomtit task manager which is good with these types if tasks.

Just create properties files templates and populate them using environments

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533530

I would start with a master configuration file and generate the properties files to start with.

Ultimately you could have a set of proprties files which can be deployed in all environments e.g.

database.host = localhost
database.host.prod = proddb1
database.host.uat = uatdb1

i.e. use the environment/host/region/service at the end as a search path. This has the advantage that you can see the variations between environments.

You can implement this collect like this

public class SearchProperties extends Properties {
    private final List<String> searchList;

    public SearchProperties(List<String> searchList) {
        this.searchList = searchList;
    }

    @Override
    public String getProperty(String key) {
        for (String s : searchList) {
            String property = super.getProperty(key + "." + s);
            if (property != null)
                return property;
        }
        return super.getProperty(key);
    }

You might construct this like

Properties prop = new SearchProperties(Arrays.asList(serverName, environment));

This way, if there is a match for that server, it will override, the environment which will overidden the default.

In Java 8 you can do

public String getProperty(String key) {
    return searchList.stream()
            .map(s -> key + "." + s)
            .map(super::getProperty)
            .filter(s -> s != null)
            .findFirst()
            .orElseGet(()-> super.getProperty(key));
}

Upvotes: 4

Adnan Isajbegovic
Adnan Isajbegovic

Reputation: 2307

There should be only one file, even if it has a lot of properties. Also, there should be only one property for each functionality, like database.host, not database.host and database_host, or anything similar.

You need to create hierarchy for such and for every property in order to know which one will be user. For example, if there is some head global value for database.host, it should be used for that property. If not, check next level in hierarchy, like specific environments (like production value). If such does not exist, check next level, like local or test level. And for bottom level, have a default value. In such way, you have two dimension of consuming properties and as such, decreases chances for error dramatically.

In one company I used to work, we had automated deployer which would handle such level setup, we would just set variable on its web site for level we wanted and it would go from top to bottom and set them. We never had problems with such setup and we would have more then 50 variables in app.properties file.

Upvotes: 0

Related Questions