I was suggested to use 2 or more config files for different modes:
play -Dconfig.file=/conf/dev_application.conf run
Well, how can I deal with some common settings that are the same for different modes? Copy-pasting those is not what I'd use.
I'd use one common config file if it was possible:
play -Dconfig.file=/conf/dev_application.conf /conf/common_application.conf run
As far as I'm concerned, it's not possible. Any idea?
You can import settings in another configuration file via use of an include statement:
# Note that the name of the file being included must be quoted
include "common_application.conf"
This will import all configuration entries from your common configuration. You can then also override the values of any these common keys lower down in your mode-specific config file:
common_application.conf
foo=0
dev_application.conf
# Import common configuration
include "common_application.conf"
# Override common configuration
foo=1
# Dev configuration
bar=0
Good question, look what I found:
GlobalSettings has an onLoadConfig method, so you should be able to do something like this:
import com.typesafe.config.ConfigFactory
override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode): Configuration = {
val richConfig = config ++ Configuration(ConfigFactory.load(s"${mode.toString.toLowerCase}_application.conf"))
super.onLoadConfig(richConfig, path, classloader, mode)
}
This way you can keep your common settings in application.conf and environment-specific settings in prod_application.conf or dev_application.conf (but I did not recheck the values of mode parameter so the names may differ)
EDIT
Yes, I just rechecked the Mode values. Here they are:
val Dev: Value
val Prod: Value
val Test: Value
So using this approach you can name your conf files as dev_application.conf, prod_application.conf and test_application.conf
Related
I'm having a SBT Multi Module project where in some of the sub modules, I'm actually having a place holder to resolve certain configurations. The project structure looks like this:
core
src
main
resources
application.conf
mod1
src
main
resources
application.conf
mod2
src
main
resources
application.conf
In the module2, in my application.conf, I have the following:
# The environment representation of the configurations
# ~~~~~
app {
environment = "test"
name = ${NAME}-split # TODO: Get the default name from application.conf which should also be located here
}
As it can be seen that the NAME is a place holder that I would like to inherit from either the default application.conf that I include or pass it in via a command line argument. As expected, I get to see compiler error like this:
[error] at java.base/java.lang.Thread.run(Thread.java:829)
[error] Caused by: com.typesafe.config.ConfigException$UnresolvedSubstitution: application.test.conf # file:/home/runner/work/housing-price-prediction-data-preparation/housing-price-prediction-data-preparation/split/target/scala-2.12/test-classes/application.test.conf: 7: Could not resolve substitution to a value: ${NAME}
[error] at com.typesafe.config.impl.ConfigReference.resolveSubstitutions(ConfigReference.java:108)
Normally you would put a reference.conf per module and an application.conf at the top application level.
Also note the module level configs are resolved first (in order, first th lower modules than the ones that depend on those). Then the application.conf and finally overrides from the command line.
The order is important, you can't depend on things not yet set, or if they are set to an intem value and then overriden. the dependent config will be based on the one effective when it is resolved.
I'm trying to merge 2 config file (or create a config file based on a single reference file) using
lazy val finalConfig:
Option(System.getProperty("user.resource"))
.map(ConfigFactory.load)
.map(_.withFallback(ConfigFactory.load(System.getProperty("config.resource"))).resolve())
.getOrElse(ConfigFactory.load(System.getProperty("config.resource")))
I'm defining my java variable inside spark using spark-submit ....... --conf spark.driver.extraJavaOptions=-Dconfig.resource=./reference.conf,-Duser.resource=./user.conf ...
My goal is to be able to point a file that is not inside my jar to be used by System.getProperty("..") in my code. I changed the folder for testing (cd ..) and keep getting the same error so I guess spark doesn't care about my java arguments..?
Is there a way to point to a file (or even 2 files in my case) so that they can be merged?
I also tried to include the reference.conf file but not the user.conf file: it recognizes the reference.conf but not the user.conf that i gave with --conf spark.driver.extraJavaOptions=-Duser.resource=./user.conf .
Is there a way to do that? Thanks if you can help
I don't see you doing ConfigFactory.parseFile to loaded a file containing properties.
Typesafe automatically read any .properties file in the class path, all -D parameters passed in to the JVM and then merges them.
I am reading an external property file which is not part of the jar as following. The file "application.conf" is placed on the same directory where the jar is kept.
val applicationRootPath = System.getProperty("user.dir")
val config = Try {
ConfigFactory.parseFile(new File(applicationRootPath + "/" + "application.conf"))
}.getOrElse(ConfigFactory.empty())
appConfig = config.withFallback(ConfigFactory.load()).resolve
ConfigFactory.load() already contains all the properties present on the properties files in the class path and -d parameters. I am giving priority to my external "application.conf" and falling back on default values. For matching keys "application.conf" take precedence over other sources.
I read that SBT has functionality to generate source code and resource files.
In my case I want to add/modify a field in an application.conf file during compilation/packaging of the project (leaving the others in place)
For instance my application.conf file has something like:
A {
B = "Some Value"
C = "Some value to be modified"
}
I would like in the SBT to read an external file and change or add the value of A.B or A.C
So if it is possible to do something along the lines of:
build.sbt
lazy val myProject = project.in(file('myproject')
// pseudo code - How do I do this?
.sourceGenerators in Compile += "Read file /path/to/external/file and add or replace the value of application.conf A.B = some external value"
You can replace the values with environment variable values provided while compiling / building your project. For that you'd have to
A {
B = "Some Value"
B = ${?B_ENV}
C = "Some value to be modified"
C = ${?C_ENV}
}
Where B_ENV and C_ENV are the environment variables you set in your terminal either before build or within the build command (before it)
$ B_ENV=1 C_ENV=2 sbt run
Source: https://www.playframework.com/documentation/2.6.x/ProductionConfiguration#using-environment-variables
In this case you can do without sbt and this approach would also work with maven or cradle.
The *.conf support orignates from typesafe config (https://github.com/lightbend/config).
There is a feature to get environment variables to be used in the configuration which should be a good fit to solve the problem.
There are two approaches I would suggest to use
1.) Fail on missing configuration
If configuration of this vallue is important and to prevent the deplyment of misconfigurated application the startup should fail on missing environment variables.
in application.conf
key=${TEST} // expects "TEST" to be set, fails otherwise
2.) Hardcoded value with override
If there is a sensible default behaviour that only in some circumstances should be changed.
in application.conf
key="test" // hardcoded key
key=${?TEST} // override "key" with 3nv "$TEST" value, when it is given
Play 2.6.x Scala
I have a default application.conf within the folder {project}/conf/ but I'd like to override some values depending on the environment by passing in the respective file as command-line arguments (as detailed in the docs):
sbt run -Dconfig.file=/conf/qa.conf or sbt run -Dconfig.resource=qa.conf
But I'm not able to get play to pick up the overrides. Here's my file directory:
application
|- playApp1
|- playApp2
|-- conf
|-- application.conf
|-- qa.conf
My build.sbt makes playApp2 the default project on load. And I have confirmed that the defulat application.conf is working -- just the override is not.
Thanks for any ideas!
--
Update
Here are the HOCON files play uses. application.conf
platform {
scheme = "http"
host = "localhost:8080"
}
and the overrides as provided in qa.conf
include "application.conf"
platform {
scheme = "https"
host = "ea311.34.com"
}
Your question is about HOCON, in case you did not realize it.
Without seeing your application.conf I can only provide a generic answer. Here is an example of providing a default value for akka.log-config-on-start, which will be overridden by a Java system property or an environment variable called CONFIG_DUMP, if defined:
akka {
log-config-on-start = false
log-config-on-start = ${?CONFIG_DUMP}
}
This feature of HOCON is documented here.
This works if you provide the command line argument first
sbt -Dconfig.resource=qa.conf run
Currently, I have a resources/application.conf file which has the following keys:
development {
server = www.myapp.com
aws_key = my_aws_key
aws_secret = my_aws_secret
}
I would like to remove my aws_key and aws_secret from the file.
I was thinking of creating another file called resources/credentials.conf and storing my personal authentications there.
credentials {
aws_key = my_aws_key
aws_secret = my_aws_secret
}
and then include it some way in my application.conf or merge that config to the Config object in addition to application.conf.
credentials.conf would be git ignored. A sample file would be checked in credentials-sample.conf which each developer would change according to his own credentials and rename the sample file to credentials.conf
I tried different variation of include like
include "credentials"
include "credentials.conf"
include "./credentials.conf"
include file("./credentials.conf")
and so on.
I know I can pass it via system variables but I would like to try it like mentioned above. If you know of a better way, please let me know.
Typesafe Config provide the way to fallback from one configuration to another. You can try the ConfigFactory.Load() to load different config and use withFallback to line them up in your designated order. Such as:
ConfigFactory.Load("credentials.conf") withFallback ConfigFactory.Load("application.conf")
Inside your conf file, add
include "another_file.conf"
ie: https://github.com/cicco94/scala-akka-slick-demo/blob/master/src/main/resources/application.conf