Как управлять application.conf в нескольких средах с помощью play 2.0?

В Play 1.2 я могу ставить перед ключами конфигурации идентификатор фреймворка или режим приложения следующим образом:

# Production configuration
%prod.http.port=80
%prod.application.log=INFO
%prod.application.mode=prod

Но с 2.0 не работает.

Есть ли способ заставить его работать?


person tototoshi    schedule 15.03.2012    source источник
comment
вот ссылка SO на решение с использованием Play2.4.6 Java   -  person beerstorm    schedule 10.02.2016


Ответы (6)


Play 2 не принуждает вас использовать какой-либо конкретный метод управления средами. Но он предоставляет вам мощные и гибкие инструменты для самостоятельной реализации в соответствии с потребностями вашего проекта.

Например, распространенным шаблоном является сохранение общих настроек среды в одном файле и наличие переопределений для конкретной среды в других файлах. Для этого вам понадобится настраиваемый глобальный объект (вы можете поместить его прямо в ./app/Global.scala). Следующий код действителен для Play 2.1.1 (Scala 2.10):

import java.io.File
import play.api._
import com.typesafe.config.ConfigFactory

object Global extends GlobalSettings {
  override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
    val modeSpecificConfig = config ++ Configuration(ConfigFactory.load(s"application.${mode.toString.toLowerCase}.conf"))
    super.onLoadConfig(modeSpecificConfig, path, classloader, mode)
  }
}

Теперь вы можете поместить application.dev.conf, application.test.conf и application.prod.conf в свой ./conf с переопределениями для конкретной среды (при сохранении общих настроек в application.conf).

В этом примере мы полагаемся на собственный mode Play, который обычно имеет смысл, но вы можете быть настолько детализированы, насколько хотите, и использовать переменные среды или что угодно.

См. также: Конфигурация Typesafe

person coffeesnake    schedule 10.04.2013
comment
Фантастический! Спасибо. - person Kevin Mansel; 14.08.2013
comment
Кажется, это не работает для меня. Когда я использую этот код, кажется, что все, что не установлено в файле переопределения режима, устанавливается в Play по умолчанию, а не в application.conf. Я использую play 2.2.1 built with Scala 2.10.2 (running Java 1.7.0_45). Может ли кто-нибудь еще подтвердить это поведение? Я думаю, это связано с ConfigFactory.load. - person mushroom; 13.01.2014
comment
Глядя на документацию для ConfigFactory, я вижу это для ConfigFactory.load(String): Loads an application's configuration from the given classpath resource or classpath resource basename, sandwiches it between default reference config and default overrides, and then resolves it. - person mushroom; 13.01.2014
comment
Когда я переключился на ConfigFactory.parseFile, он начал работать, как и ожидалось. Не знаю, лучшее ли это решение. Могут быть параметры, которые вы можете указать для ConfigFactory.load, чтобы он не объединял ваши переопределения со значениями по умолчанию. - person mushroom; 13.01.2014
comment
@mushroom Как я уже упоминал в своем ответе, этот простой пример был написан для Play 2.1.1. Мое намерение состояло в том, чтобы просто проиллюстрировать подход. Если вы ищете готовое к копированию/вставке решение, вам, вероятно, придется немного поработать самостоятельно и удовлетворить потребности вашего проекта. - person coffeesnake; 13.01.2014
comment
Да, это то, что я сделал. Пожалуйста, прочитайте мои другие комментарии. Я сказал, как я заставил его работать с моей версией. - person mushroom; 13.01.2014
comment
@coffeesnake Этот метод работает для меня для запуска / запуска / тестирования Play, но не для dist. Кто-нибудь видел это? - person Jack Chi; 28.01.2014
comment
Это не помешает мне передать аргумент командной строки конфигурации, не так ли? -Dconfig.file=.... - person Blankman; 31.12.2014
comment
Согласно документам, сейчас это кажется устаревшим: этот метод ничего не делает. Вместо этого укажите конфигурацию в файле конфигурации или создайте собственный ApplicationLoader (см. GuiceApplicationBuilder.loadConfig) - person redwulf; 18.01.2016
comment
[вот ссылка SO] [1] на решение с использованием Play2.4.6 Java [1]: stackoverflow.com/a/35324046/ 492918 - person beerstorm; 10.02.2016

У меня тоже был этот вопрос в течение длительного времени, и ниже приведен лучший подход, который я изучил до сих пор, я получил подсказку, задавая аналогичный вопрос в группе Google Play 2.

В вашем application.config используйте следующий синтаксис для переопределения значения конфигурации, когда присутствует системный параметр:

# Local machine fallback URI
mongodb.uri="mongodb://192.168.56.101:27017/application"
# Env variable override
mongodb.uri=${?MONGOLAB_URI}

Знак вопроса означает, что вы не переопределяете переменную env, если она не установлена. Если вы просто используете ${MONGOLAB_URI}, вы ожидаете, что переменная будет установлена, и, я полагаю, вы получите какое-то исключение, если она не установлена.

Для полноты, вот пример того, как вы читаете значение:

lazy val mongoUri = current.configuration.getString("mongodb.uri").getOrElse("mongodb:///")

При таком подходе есть одно предостережение: убедитесь, что вы сохраняете конфигурацию системных параметров в каком-либо SCM.

person Magnus    schedule 18.05.2012
comment
Привет, Магнус, как мне создать новую переменную окружения в application.conf, которая равна mongodb.uri, но с добавлением к ней /a.xml? - person Kevin Meredith; 31.10.2013
comment
@KevinMeredith: я знаю, что это очень старый комментарий, но... вы можете использовать что-то вроде my_new_cfg = ${mongodb.uri}"/a.xml". Это, конечно, при условии, что вы используете формат HOCON для безопасной конфигурации. - person Sanjay T. Sharma; 30.08.2017

Вы должны определить другой файл конфигурации с соответствующими свойствами

http://www.playframework.org/documentation/2.0/Configuration

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

person Seb Cesbron    schedule 15.03.2012
comment
Я пытался это сделать, единственная проблема, с которой я столкнулся, заключается в том, что когда у меня есть db.default.driver, db.default.url, db.default.user, etc как в application.conf, так и в prod.conf, по какой-то причине с prod.conf он никогда не подключается. Но когда я УДАЛИВАЮ настройки базы данных из application.conf и запускаю prod.conf, все работает. Для этого есть причина? - person KVISH; 07.06.2012
comment
Кстати, у меня prod.conf включая application.conf - person KVISH; 07.06.2012
comment
Да, кажется, Play 2 не позволяет вам переопределять параметры базы данных по умолчанию. - person cdmckay; 24.08.2013

Если вы хотите быть независимым от ограниченных режимов запуска scala, вы можете использовать свойства JVM. Поместите измененный пример @coffesnake в ./app/Global.scala :

import java.io.File

import play.api._
import com.typesafe.config.ConfigFactory

object Global extends GlobalSettings {
  override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
    val environment = System.getProperty("environment")
    val environmentSpecificConfig = config ++ Configuration(ConfigFactory.load(s"application.${environment}.conf"))
    super.onLoadConfig(environmentSpecificConfig, path, classloader, mode)
  }
}

Следующий запуск воспроизведения play

и запустите приложение с параметром среды run -Denvironment=prod-server1

Не присоединяйтесь к обеим командам, тогда это не работает

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

./conf/application.prod-server1.conf

РЕДАКТИРОВАТЬ:

С точки зрения времени я видел, что этот обходной путь не нужен. Лучше использовать встроенный в Play механизм загрузки конфига -Dconfig.file=/etc/play-application/foo-production.conf

person mgosk    schedule 05.02.2014

Я использую это решение:

в application.conf я определил конфигурации по умолчанию, в myUsername.conf я включил конфигурацию по умолчанию и переопределил пользовательскую конфигурацию:

include "application.conf"
logger.application=DEBUG

затем в Global.java я загрузил конфигурацию пользователя (если она существует):

public Configuration onLoadConfig(Configuration config, File path,
        ClassLoader classloader) {

    String username = System.getProperty("user.name");
    File confFile = new File(new File(path, "conf"), username + ".conf");

    if (confFile.exists()) {
        Logger.info("configuration file {} found", confFile.getName());
        return new Configuration(ConfigFactory.load(confFile.getName()));
    } else {
        Logger.info(
                "configuration file {} not found, using default application.conf",
                confFile.getAbsolutePath());
        return null;
    }

}
person Antonio Salvati    schedule 20.01.2014

У нас просто есть несколько файлов application.conf, во время разработки используется файл по умолчанию, и у нас есть файл prod-applicaton.conf, который мы просто копируем на место при развертывании.

person nylund    schedule 12.11.2012
comment
это работает нормально, но для этого требуется, чтобы команда синхронизировала оба этих файла друг с другом. - person Jack Chi; 28.01.2014