reference.conf vs application.conf files in Akka - scala

I am new in Akka and I am trying to understand the difference between the reference.conf and application.conf files?
What is the proper way to use them? What kind of variables should I have in each file?

reference.conf is a file for library developers. All properties required by the library should be mentioned there and filled with reasonable default values when possible.
application.conf is a file for application developers. A developer can set values for properties used by libraries in case they are not the same as defaults.
Also he/she can declare his own properties and refer them from the code.
When ConfigFactory.load is called all reference.conf and application.conf files are merged into one configuration and application.conf has higher precedence.

Related

Is there a way to set application.conf location in Scala?

If i'm using Java, I can set custom application.properties location with something like this:
#PropertySources({
#PropertySource(value = "file:${APP_CONF_DIR}/application.properties", ignoreResourceNotFound = true)
})
Is there any way to do the same thing in Scala without using "-Dbla.bla=app.config" on application start
The behavior of Lightbend Config around loading application.conf is mostly from ConfigFactory.load(), which will look for application.conf or the file/resource given by Java properties (the -Dconfig.file and friends in your question).
If not interested in setting the alternative to application.conf through Java properties, one can load a different resource from the classpath with ConfigFactory.load("foo") to load foo.conf. Alternatively if one is loading a file, one can use ConfigFactory.load(ConfigFactory.parseFile(file)), where file is a java.io.File.

Externalize configuration Akka

I am new in Akka and I faced the problem below.
I want to externalize the configuration in my App. More specifically, I have some variables that are different per each environment. So I think that I can have specific environment variables (secrets, etc) for each environment.
But what I can do with some variables (non-secrets) which are different per each environment?
What is the difference between, dev.properties, application.conf, deploy.json files?
What is the proper way to load variables from those files?
There's a few options:
Environment variables and using the support for substitution (there is also support for having default in the file and only use the environment vars if they are set). - https://github.com/lightbend/config#optional-system-or-env-variable-overrides
System properties, if you set a system property when you start the JVM, and that system property matches a path in the config file, it overrides the setting
You can point to an alternative application.conf file using a system property - https://github.com/lightbend/config#standard-behavior
If that is not enough you could also do completely custom logic around selecting logic by programmatically creating a Config instance and passing that to the ActorSystem when you create it.
The dev.properties and deploy.json is AFAIK not related to Akka, unless something specifically done in your application.

Setting Cassandra password in reference.conf using Scala

How can an attribute be set programmatically in a reference.conf file?
For example, I am using something like this in Spring to set the attributes of the keystore:
System.setProperty("server.ssl.keyStore", "keystore.jks")
System.setProperty("server.ssl.keyStorePassword", "password123")
Same way, you can override configuration from the reference conf file using system properties, they have the highest precedence order as described here:
https://github.com/lightbend/config#standard-behavior
Please be aware you need to do it before the config is loaded by the class that uses it (via ConfigFactory.load()) and if any other class has already used ConfigFactory, then a call to ConfigFactory.invalidateCaches() will also be required, otherwise the cached value will be used.

sbt-assembly: prefix extracted files from some jars

In JOGL, there are lots of native jars for different OS x arch combinations. JOGL has several of its own mechanisms to load the right ones if you aren't using java.library.path, and supports a kind of "fat jar" layout.
In a fat jar layout, any native libraries need to be in a subdirectory ./natives/os.and.arch/. However, since the native jars themselves don't have any internal layout, similarly named so/dylib/dll files collide the flat hierarchy in the final jar.
From what I can tell, I don't think I want to de-duplicate with any of the given MergeStrategy because it's only invoked if there is a collision. The layout is mandatory per JOGL's native library loaders - I want to invoke it every time. Is there a mechanism that can allow me to map certain jar -> prefix/with/path in sbt-assembly?
Example
jogl-all-2.1.3-natives-android-armv6.jar is pulled in through a dependency.
$ jar -tf jogl-all-2.1.3-natives-linux-amd64.jar
META-INF/MANIFEST.MF
libjogl_mobile.so
libnewt.so
I'd like this to go here in the final jar:
./natives/
./natives/linux.and.amd64/
./natives/linux.and.amd64/libnewt.so
./natives/linux.and.amd64/libjogl_mobile.so
From what I can tell, I don't think I want to de-duplicate with any of the given MergeStrategy because it's only invoked if there is a collision. The layout is mandatory per JOGL's native library loaders - I want to invoke it every time.
All merge strategies are invoked every time. MergeStrategy.deduplicate, which is the default strategy for most files, just happens to take effect only if there's a collision.
MergeStrategy.rename, applied for README and license files by default for example, will rename the file every time by appending the jar name.
Is there a mechanism that can allow me to map certain jar -> prefix/with/path in sbt-assembly?
There's no strategy out of the box that does exactly that, but you can define a custom strategy similar to MergeStrategy.rename.
Just follow this rule as Xerxes explained here. There is then no longer any risk of collision. The official JogAmp forum is a better place to ask questions about all JogAmp APIs. If you don't follow my advice, GlueGen will be unable to extract and load the correct native libraries. In your case, natives/linux-amd64 is correct whereas natives/linux.and.amd64 isn't.

How can I save a property using the Props object in scala Lift?

First of all, should I use Lift Props to store specific configurations of my App? Lift documentation explains that you can use this Props to configure the enviroment (production, testing, etc etc.) but never says if you can use them for other purposes.
If there's nothing wrong in using them, how can I store these properties (save them). All the functions that I can see in Props object are getters. E.g if I have a property myapp.myconf1
I would like to do something like:
Prop.save("myapp.myconf1","value1")
Is this possible using Props or should I use other libs like Typesafe config or java props?
Thanks in advance!
The Lift Props object isn't intended to be a read/write store. It's a repository for deployment specific config info (i.e. the settings that are different between your development/test/release environments). The file is stored within the classpath and if you are deploying as WAR file I don't believe there would be any way to change it even if an API existed.
If all you need is to store name value pairs then java props should work fine.