Конкретная конфигурация среды в Scala
Что такое хороший способ настроить проект в Scala, который использует различную конфигурацию в зависимости от окружения.
Мне нужно специально иметь разные базы данных для разработки, test и production (аналогично тому, как это делается в Rails)
Ответы
Ответ 1
Используйте typafe Config. Создайте объект Config следующим образом:
import com.typesafe.config._
object Config {
val env = if (System.getenv("SCALA_ENV") == null) "development" else System.getenv("SCALA_ENV")
val conf = ConfigFactory.load()
def apply() = conf.getConfig(env)
}
Затем создайте файл application.conf
в папке src/main/resources
:
development {
your_app {
databaseUrl = "jdbc:mysql://localhost:3306/dev_db"
databaseUser = "xxxx"
databasePassword = "xxxx"
}
}
test {
your_app {
databaseUrl = "jdbc:mysql://localhost:3306/test_db"
databaseUser = "xxxxx"
databasePassword = "xxxx"
}
}
Теперь из любого места приложения вы можете получить доступ к конфигурации:
Config(). GetString ( "your_app.databaseUrl" )
Если вы создали свою среду (например, export SCALA_ENV=test
) при запуске приложения, она рассмотрит правильный раздел конфигурации. По умолчанию используется
Ответ 2
Другая стратегия, которую я использую, состоит в использовании includes.
Обычно я храню настройки DEV в файле default application.conf
, тогда я создаю новый файл conf для других сред и включаю по умолчанию.
Скажем, мой DEV conf application.conf
выглядит следующим образом:
myapp {
server-address = "localhost"
server-port = 9000
some-other-setting = "cool !"
}
Тогда для PROD мог бы быть другой файл с именем prod.conf
:
include "application"
# override default (DEV) settings
myapp {
server-address = ${PROD_SERVER_HOSTNAME}
server-port = ${PROD_SERVER_PORT}
}
Обратите внимание, что я переопределяю только параметры, которые изменяются в среде PROD (some-other-setting
, таким же образом, как в DEV).
Код начальной загрузки конфигурации не проверяет ничего
...
val conf = ConfigFactory.load()
...
Чтобы переключиться с DEV на PROD conf, просто передайте системное свойство с именем загружаемого файла конфигурации:
java -Dconfig.resource=prod.conf ...
В DEV нет необходимости передавать его, так как application.conf
будет загружаться по умолчанию.
Итак, для этого мы используем механизм загрузки по умолчанию Configafe Config.
Я создал простой проект, чтобы продемонстрировать эту технику. Не стесняйтесь клонировать и экспериментировать.
Ответ 3
Я был недоволен тем, как решение Дэниела Кукьера не разрешало дефолты и переопределения, поэтому я изменил его, чтобы в полной мере использовать их.
Единственная конфигурация, которую вы должны сделать, это установить переменную ENVIRONMENT в системе (по умолчанию "dev", если ни один не установлен)
(Java-решение, совместимое с Scala):
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
public class MyCompanyConfig {
public final static Config base = ConfigFactory.load().getConfig("mycompany");
public final static String environment = System.getenv("ENVIRONMENT") == null ? "dev" : System.getenv("ENVIRONMENT");
/**
* Returns a subtree of the base configuration with environment settings applied.
*
* @param setting The subtree to return config for.
* @return A config with base in given setting, with environment modifications applied.
*/
public static Config load(String setting) {
Config config = base.getConfig(setting);
if (config.hasPath(environment)) {
return config.getConfig(environment).withFallback(config);
}
return config;
}
}
Это позволяет использовать один файл reference.conf в следующей библиотеке:
mycompany.module1 {
setting1 : "adefaultvalue"
url : "localhost"
test {
// will be used where ENVIRONMENT="test"
url : "test.mycompany.com"
}
prod {
// will be used where ENVIRONMENT="prod"
setting1 : "changethedefault"
url : "www.mycompany.com"
}
}
Использование:
Config conf = MyCompanyConfig.load("module1")