14

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

мне нужно конкретно иметь различные базы данных для развития, тест и производства окружающей среды (по аналогии с тем, что делается в Rails)

ответ

16

Использование типизированного 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), когда вы запускаете вас r, он рассмотрит правильный раздел конфигурации. По умолчанию - разработка

+0

Мне понадобилось некоторое время, чтобы найти этот шаблон, который поддерживает первичность свойств системы: ConfigFactory.defaultOverrides(). WithFallback (config2.getConfig (среда)). WithFallback (config2); https://github.com/typesafehub/config/blob/master/examples/java/complex-app/src/main/java/ComplexApp.java –

28

Другая стратегия, которую я использую, состоит из использования includes. Обычно я храню настройки DEV в файле defaultapplication.conf, затем создаю новый файл conf для других сред и включаю по умолчанию.

Скажем, мой DEV конф 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 конф не тест, просто передать системное свойство с именем конфигурационного файла для загрузки:

java -Dconfig.resource=prod.conf ... 

В DEV, нет необходимости передавать его с application.conf будет загружен default.

Таким образом, для этого мы используем механизм загрузки по умолчанию .

Я создал простой project, чтобы продемонстрировать эту технику. Не стесняйтесь клонировать и экспериментировать.

+0

Для полноты, я считаю, что bootstrap конфигурации будет: val conf = ConfigFactory. load() def apply() = conf.getConfig ("myapp") – mmeyer

+0

@ozeebee по какой-то причине это не работает. Обратите внимание, что я добавил: 'fork в run: = true' и' java -Dconfig.resource = stg.conf' в build.sbt. Файл stg.conf находится под ресурсами, но моя конфигурация все еще поступает из application.conf. Заметьте также, что когда я использую: 'val conf = ConfigFactory.load (" stg.conf ")', тогда мои конфигурации загружаются на stg.conf. Есть идеи? – has981

+0

@ has981 не знаю. Я продемонстрировал этот метод простым [проектом] (https://github.com/ozeebee/test-scala-config). Не стесняйтесь клонировать и экспериментировать. – ozeebee

1

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

Единственная конфигурация, которую вы должны сделать, это установить переменные окружения на системе (по умолчанию «разработчику», если ни один не установлен)

(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") 
Смежные вопросы