Search code examples
mergetypesafe-config

Merging multiple TypeSafe Config files and resolving only after they are all merged


I am writing test code to validate a RESTful service. I want to be able to point it at any of our different environments by simply changing an environment variable before executing the tests.

I want to be able to merge three different config files:

  • conf/env/default.conf - the default configuration values for all environments
  • conf/env/<env>.conf - the environment-specific values
  • application.conf - the user's overrides of any of the above

The idea is that I don't want everything in a single config file, and run the risk of a bad edit causing configuration items to get lost. So instead, keep them separate and give the user the ability to override them.

Here's where it gets tricky: default.conf will include ${references} to things that are meant to be overridden in <env>.conf, and may be further overridden in application.conf.

I need to postpone resolving until all three are merged. How do I do that?


Solution

  • The answer is to use ConfigFactory.parseResource() in place of ConfigFactory.load().

    Here is the finished result

    private lazy val defaultConfig     = ConfigFactory.parseResources("conf/env/default.conf")
    private lazy val environmentConfig = ConfigFactory.parseResources("conf/env/" + env + ".conf" )
    private lazy val userConfig        = ConfigFactory.parseResources("application.conf")
    private lazy val config = ConfigFactory.load()
                              .withFallback(userConfig)
                              .withFallback(environmentConfig)
                              .withFallback(defaultConfig)
                              .resolve()