How to add application.conf files for akka multi-jvm applications - scala

I have created a set of applications in akka in the multi-jvm. Following all the conventions on the docs http://doc.akka.io/docs/akka/snapshot/dev/multi-jvm-testing.html I can run them using multi-jvm:run {application name}.
This behaves perfectly but the applications now require remote akka features. To do this I need to change settings in application.conf as mentioned here: http://doc.akka.io/docs/akka/snapshot/scala/remoting.html
My problem is that I do not now how to give each of these multi-jvm test applications an application.conf file of their own. I'm not sure if their is a file-system based convention, or it has to be done in code. Either solution would solve the problem in theory.

I suggest that you define the configuration in code in the test using ConfigFactory.parseString and use that in MultiNodeConfig.commonConfig.
Note that you can use define specific config per node with MultiNodeConfig.nodeConfig.

The application.conf's are loaded from the class path, but you can override them with system properties as described here: https://github.com/typesafehub/config#standard-behavior
So for each JVM, you can specify the necessary System properties(which is kind of ugly), or you can drop an application.conf in the classpath of each JVM that overrides the reference.conf's in the libraries.

Related

how to disclude development.conf from docker image creation of play framework application artifact

Using scala playframework 2.5,
I build the app into a jar using sbt plugin PlayScala,
And then build and pushes a docker image out of it using sbt plugin DockerPlugin
Residing in the source code repository conf/development.conf (same where application.conf is).
The last line in application.conf says include development which means that in case development.conf exists, the entries inside of it will override some of the entries in application.conf in such way that provides all default values necessary for making the application runnable locally right out of the box after the source was cloned from source control with zero extra configuration. This technique allows every new developer to slip right in a working application without wasting time on configuration.
The only missing piece to make that architectural design complete is finding a way to exclude development.conf from the final runtime of the app - otherwise this overrides leak into production runtime and obviously the application fails to run.
That can be achieved in various different ways.
One way could be to some how inject logic into the build task (provided as part of the sbt pluging PlayScala I assume) to exclude the file from the jar artifact.
Other way could be injecting logic into the docker image creation process. this logic could manually delete development.conf from the existing jar prior to executing it (assuming that's possible)
If you ever implemented one of the ideas offered,
or maybe some different architectural approach that gives the same "works out of the box" feature, please be kind enough to share :)
I usually have the inverse logic:
I use the application.conf file (that Play uses by default) with all the things needed to run locally. I then have a production.conf file that starts by including the application.conf, and then overrides the necessary stuff.
for deploying to production (or staging) I specify the production/staging.conf file to be used
This is how I solved it eventually.
conf/application.conf is production ready configuration, it contains placeholders for environment variables whom values will be injected in runtime by k8s given the service's deployment.yaml file.
right next to it, conf/development.conf - its first line is include application.conf and the rest of it are overrides which will make the application run out of the box right after git clone by a simple sbt run
What makes the above work, is the addition of the following to build.sbt :
PlayKeys.devSettings := Seq(
"config.resource" -> "development.conf"
)
Works like a charm :)
This can be done via the mappings config key of sbt-native-packager:
mappings in Universal ~= (_.filterNot(_._1.name == "development.conf"))
See here.

SpringXD/Spring Integration: Using different versions of spring-integration-kafka for producer and consumer

I have the following configuration:
Spring-integration-kafka 1.3.1.RELEASE
I have a custom kafka-sink and a custom kafka-source
The configuration I want to have:
I'd like to still using Spring-integration-kafka 1.3.1.RELEASE with my custom kafka-sink.
I'm changing my kafka-source logic to use Spring-integration-kafka-2.1.0.RELEASE. I noticed the way to implement a consumer/producer is way different to prior versions of Spring-integration-kafka.
My question is: could I face some compatibily issues?
I'm using Rabbit.
You should be ok then; it would probably work with the newer kafka jars in the source's /lib directory since each module is loaded in its own classloader so there should be no clashes with the xd/lib jars.
However, you might have to remove the old kafka jars from the xd/lib directory (which is why I asked about the message bus).

How to change configuration in play dynamically via JMX

I have my configuration for my Scala Play application in my application.conf file.
For now, everytime I want to change the configuration I have to make a deployment.
Can anybody help me finding out, how to expose the Configuration as a MBean?
I would like to change the configuration without deployment.
Didn't find any documentation on this.
Redeploy just for a configuration change is really boring and I understand you want to avoid that.
Changing configuration while the application is running is a risky operation and I would not recommend going in that direction.
But there are a few techniques that the framework provides that would only require a restart of the application.
Play allows you to point to an external file with your configuration
$ your-app -Dconfig.file=/full/path/to/conf/application-prod.conf
Besides that in your conf file you can use environment variables, so you can configure different servers differently using the same application.conf
my.key = defaultvalue
my.key = ${?MY_KEY_ENV}
And run your app using
$ your-app -DMY_KEY_ENV=bar
Reference:
https://www.playframework.com/documentation/2.4.x/Production
https://www.playframework.com/documentation/2.4.x/ProductionConfiguration

How to keep separate dev, test, and prod databases in Play! 2 Framework?

In particular, for test-cases, I want to keep the test database separate so that the test cases don't interfere with development or production databases.
What are some good practices for separating development, test and production environments?
EDIT1: Some context
In Ruby On Rails, there are different configuration files by convention for different environments. So does Play! 2 also support that ?
Or, do I have to cook the configuration files, and then write some glue code that selects the appropriate configuration files ?
At the moment if I run sbt test it uses development database ( configured as "default" in conf/application.conf ). However I would like Play!2 to use a different test database.
EDIT2: On commands that play provides
For Play! 2 framework, I observed this.
$ help play
Welcome to Play 2.2.2!
These commands are available:
-----------------------------
...OUTPUT SKIPPED...
run <port> Run the current application in DEV mode.
test Run Junit tests and/or Specs from the command line
start <port> Start the current application in another JVM in PROD mode.
...OUTPUT SKIPPED...
There are three well defined commands for "test", "development" and "production" instances which are:
test: This runs the test cases. So it should automatically select test configuration.
run <port>: this runs the development instance on the specified port. So this command should automatically select development configuration.
start <port>: this runs the production instance on the specified port. So this should automatically select production configuration.
However, all these commands select the values that are provided in conf/application.conf. I feel there is some gap to be filled here.
Please do correct me if I am wrong.
EDIT3: Best approach is using Global.scala
Described here: How to manage application.conf in several environments with play 2.0?
Good practice is keeping separate instances of the application in separate folders and synching them i.e. via git repo.
When you want to keep single instance you can use alternative configuration file for each environment.
In your application.conf file there is an entry (or entries) for your database, e.g. db.default.url=jdbc:mysql://127.0.0.1:3306/devdb
The conf file can read environment variables using ${?ENV_VAR_NAME} syntax, so change that to something like db.default.url=${?DB_URL} and use environment variables.
A simpler way to get this done and manage your configuration easier is via GlobalSettings. There is a method you can override and that its name is "onLoadConfig". Try check its api at API_LINK
Basically on your conf/ project folder, you'll setup similar to below:
conf/application.conf --> configurations common for all environment
conf/dev/application.conf --> configurations for development environment
conf/test/application.conf --> configurations for testing environment
conf/prod/application.conf --> configurations for production environment
So with this, your application knows which configuration to run for your specific environment mode. For a code snippet of my implementation on onLoadConfig try check my article at my blog post
I hope this is helpful.

Playframework settings depending on environment

I'm using playframework 2.1-RC2. First of all I've seen all the similar questions, so I followed the common instruction of separating application.conf file per environment. So I have application.test.conf and I run tests this way:
play -Dconfig.file=./conf/application.test.conf "test"
I tried different combinations, like
play -Dconfig.file=./conf/application.test.conf ~test
or
play -Dconfig.file=conf/application.test.conf ~test
Still no luck, it just does not get picked, default one (application.conf) is instead.
From the other side, if I do
play -Dconfig.file=./conf/application.dev.conf "run"
then application picks the right config.
So how can I specify the test configuration file?
I found the most robust way to specifiy this in a cross-platform compatible manner is to include it directly in the Build.scala:
val main = play.Project(appName, appVersion, appDependencies).settings(
javaOptions in Test += "-Dconfig.file=conf/test.conf",
...
)
Bonus: configure once and forget ;-)
Another approach is to override method on GlobalSettings / Global named onLoadConfig and that enables you to have control where your app will look for your configuration.
So in one of our application I have this setup below for my conf/ folder.
conf/application.conf --> configurations common for all environment
conf/dev/application.conf --> configurations for development environment
conf/test/application.conf --> configurations for testing environment
conf/prod/application.conf --> configurations for production environment
With that, you are able to implement inheritance like setup for configuration, you have common and 3 others for specific environment mode.
The code inside your onLoadConfig method should just load main configuration and set correct fallback configuration specific to your environment then return the configuration instance like below:
**return new Configuration(baseConfig.withFallback(envConfig));**
Try check this blog post for complete snippet of the code.
I hope this helps.