Объединение нескольких файлов TypeSafe Config и разрешение только после того, как все они объединены

Я пишу тестовый код для проверки службы RESTful. Я хочу иметь возможность указать его в любой из наших различных сред, просто изменив переменную среды перед выполнением тестов.

Я хочу иметь возможность объединить три разных файла конфигурации:

  • conf/env/default.conf - значения конфигурации по умолчанию для всех сред
  • conf/env/<env>.conf - специфические для окружающей среды ценности
  • application.conf - пользователь отменяет любой из вышеперечисленных

Идея состоит в том, что я не хочу, чтобы все было в одном файле конфигурации, и я рискую ошибочно редактировать, что приведет к потере элементов конфигурации. Поэтому вместо этого держите их отдельно и дайте пользователю возможность переопределять их.

Вот где это становится сложным: default.conf будет включать ${ссылки} на вещи, которые должны быть переопределены в <env>.confи может быть в дальнейшем переопределено в application.conf,

Мне нужно отложить решение, пока все три не будут объединены. Как я могу это сделать?

2 ответа

Решение

Ответ заключается в использовании ConfigFactory.parseResource() на месте ConfigFactory.load(),

Вот готовый результат

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 = userConfig
                          .withFallback(environmentConfig)
                          .withFallback(defaultConfig)
                          .resolve()

Я советую вам использоватьuserConfig.withFallback(ConfigFactory.load()).resolve(), нетConfigFactory.load().withFallback(userConfig).resolve().parseResourcesдля меня это не меняет, тот же результат (но в этом тесте я не использую референсы)

Вот мои тесты:

application1.conf

      app {
  option1 = 323
  common-option = 64
}

application2.conf

      app {
  option2 = 234
  common-option = 32
}
        val conf1 = ConfigFactory.load("application1.conf")
  val conf2 = ConfigFactory.load("application2.conf")

  // 1st variant: there is no option1
  println(conf1.withValue("app", conf2.getValue("app")).resolve().getConfig("app"))
  // {"common-option":32,"option2":234}

  // 2nd variant: common option from config1
  println(conf1.withFallback(conf2).resolve().getConfig("app"))
  // {"common-option":64,"option1":323,"option2":234}

  // 3nd variant: common option from config2
  println(conf2.withFallback(conf1).resolve().getConfig("app"))
  // {"common-option":32,"option1":323,"option2":234}

Документация: https://github.com/lightbend/config/blob/main/config/src/main/java/com/typesafe/config/ConfigMergeable.java#L66

           /** ... Again, for details see the spec.
     * 
     * @param other
     *            an object whose keys should be used as fallbacks, if the keys
     *            are not present in this one
     * @return a new object (or the original one, if the fallback doesn't get
     *         used)
     */
    ConfigMergeable withFallback(ConfigMergeable other);
Другие вопросы по тегам