Объединение нескольких файлов 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);