Конфигурация в зависимости от режима запуска

Игра может быть запущена в режиме разработки (через run), в рабочем режиме (через start) или в тестовом режиме. Есть ли способ предоставить другой файл конфигурации (conf/application.conf) в зависимости от того, в каком режиме он запущен?


person Reactormonk    schedule 11.06.2015    source источник
comment
Какую Playframework версию вы используете?   -  person Mon Calamari    schedule 12.06.2015
comment
@MonCalamari 2.4 атм, когда-нибудь обновится до 3.0.   -  person Reactormonk    schedule 12.06.2015


Ответы (3)


Обычно у меня есть базовая конфигурация (application.conf) и три дополнительных конфигурации для каждой среды. В Play Framework 2.4 это можно сделать, расширив GuiceApplicationLoader и объединив базовую конфигурацию с конфигурацией, специфичной для вашей среды. Вы можете сделать еще один шаг вперед и предоставить разные модули guice для каждой среды.

Скала версия:

class CustomApplicationLoader extends GuiceApplicationLoader {

    override protected def builder(context: Context): GuiceApplicationBuilder = {
        val builder = initialBuilder.in(context.environment).overrides(overrides(context): _*)
        context.environment.mode match {
            case Prod =>
                // start mode
                val prodConf = Configuration(ConfigFactory.load("prod.conf"))
                builder.loadConfig(prodConf ++ context.initialConfiguration).bindings(new ProdModule());
            case Dev =>
                // run mode
                val devConf = Configuration(ConfigFactory.load("dev.conf"))
                builder.loadConfig(devConf ++ context.initialConfiguration).bindings(new DevModule());
            case Test =>
                // test mode
                val testConf = Configuration(ConfigFactory.load("test.conf"))
                builder.loadConfig(testConf ++ context.initialConfiguration).bindings(new TestModule());
        }
    }
}

Java-версия:

public class CustomApplicationLoader extends GuiceApplicationLoader {

    @Override
    public GuiceApplicationBuilder builder(ApplicationLoader.Context context) {
        final Environment environment = context.environment();
        GuiceApplicationBuilder builder = initialBuilder.in(environment);
        Configuration config = context.initialConfiguration();
        if (environment.isTest()) {
            config = merge("test.conf", config);
            builder = builder.bindings(new TestModule());
        } else if (environment.isDev()) {
            config = merge("dev.conf", config);
            builder = builder.bindings(new DevModule());
        } else if (environment.isProd()) {
            config = merge("prod.conf", config);
            builder = builder.bindings(new DevModule());
        } else {
            throw new IllegalStateException("No such mode.");
        }
        return builder.in(environment).loadConfig(config);
    }

    private Configuration merge(String configName, Configuration currentConfig) {
        return new Configuration(currentConfig.getWrappedConfiguration().$plus$plus(new play.api.Configuration(ConfigFactory.load(configName))));
    }
}

Не забудьте включить play.application.loader = "modules.CustomApplicationLoader" в свой application.conf.

В более ранних версиях Play чего-то подобного можно добиться, используя класс GlobalSettings и переопределяя onLoadConfig. Разум GlobalSettings в Play 2.4 устарел.

Если вам не нравится включать test.conf и test mocks из TestModule в производственную сборку, вы можете filter файлы с помощью sbt.

person Mon Calamari    schedule 12.06.2015
comment
И добавить play.application.loader = "modules.CustomApplicationLoader" в application.conf? - person Reactormonk; 12.06.2015
comment
Ага. Перейдите по ссылке в ответе для более подробной информации. - person Mon Calamari; 12.06.2015
comment
Я думаю, что политика stackoverflow заключается в том, чтобы копировать/вставлять вещи, потому что ссылки могут стать мертвыми. - person Reactormonk; 12.06.2015
comment
Да, правда, однако ответ не выглядит аккуратно с вставленной ссылкой. :-) - person Mon Calamari; 12.06.2015
comment
Когда я следую описанному выше подходу в Scala, я получаю ConfigurationException: Guice configuration errors: 1) No implementation for play.api.Application was bound.. Я что-то упускаю? - person Michael A.; 30.06.2015
comment
У меня не работает в тестовом режиме. groups.google.com/forum/#!topic/play-framework/ JnxK4MiQf74 - person HEX; 14.12.2015

Вы можете установить другой файл конфигурации, используя один из 3 способов, которые предлагает вам игра:

1 - Использование -Dconfig.resource

Он будет искать альтернативный файл конфигурации в пути к классам приложения (вы обычно предоставляете эти альтернативные файлы конфигурации в каталоге conf/ вашего приложения перед упаковкой). Play заглянет в conf/, поэтому вам не нужно добавлять conf/.

$ /path/to/bin/ -Dconfig.resource=prod.conf

2 - Использование -Dconfig.file

Вы также можете указать другой локальный файл конфигурации, не упакованный в артефакты приложения:

$ /path/to/bin/ -Dconfig.file=/opt/conf/prod.conf

3 - Использование -Dconfig.url

Вы также можете указать файл конфигурации для загрузки с любого URL-адреса:

$ /path/to/bin/ -Dconfig.url=http://conf.mycompany.com/conf/prod.conf

Оформить заказ:

https://www.playframework.com/documentation/2.3.x/ProductionConfiguration

person Thiago Pereira    schedule 11.06.2015
comment
Да, я знаю, как указать конфиги, но я специально ищу, как указать параметры конфигурации в зависимости от run/start/test, например. javaOptions in Run - person Reactormonk; 12.06.2015

Это можно сделать, загрузив файлы конфигурации на основе среды, которая может быть предоставлена ​​​​через -Dmode=staging/dev/prod, и для загрузки файлов я переопределяю onLoadConfig GlobalSettings в Global.java.

Фрагмент Java-

 @Override
 public Configuration onLoadConfig(Configuration config, File file,ClassLoader classLoader) {
 Configuration updatedConfig = config;
 String mode = config.getString("mode");
 if (StringUtils.isNotEmpty(mode)) {
   try {
     File modeFolder = FileUtils.getFile(file, "conf/" + mode);
     if (modeFolder.exists()) {
       play.api.Configuration modeConfig = config.getWrappedConfiguration();
       IOFileFilter fileFilter = new WildcardFileFilter("*.conf");
       Collection<File> fileList = FileUtils.listFiles(modeFolder, fileFilter, null);
       for (File confFile : fileList) {
         modeConfig = modeConfig
            .$plus$plus(new play.api.Configuration(ConfigFactory.parseFile(confFile)));

      }
       updatedConfig = new Configuration(modeConfig);
     }
   } catch (Exception e) {
     Logger.error("Exception while loading configuration for mode : " + mode, e);
   }
 } else {
   Logger.error("Please provide mode in which play application has to start (Ex. play -Dmode=<mode>) ");
 }

Для каждого режима создайте папку (имя такое же, как у среды) и сохраните конфигурацию среды в этой папке.

person xitter    schedule 18.11.2015