Using variables from different properties file in spring application properties - spring

I have multiple application-[profile]properties files for different profiles but all of them use the same DB.
I don't want to have the username and password hardcoded in each file, instead I want to have them as variables in some sort of global variables file.
Is is possible to do something like that without using system environment variables?

As Karthikeyan suggested, you can put your username and password only in the application.properties file. The file application.properties will always be loaded even if you use an environment-specific property file like application-dev.properties. However, if there is a property collision, the environment-specific property file takes precedence.

Related

Override Spring Boot yaml property via environment variable

Using Spring Boot 2.6.1, If I have an application.properties file that looks like:
spring.datasource.url="jdbc://blahblah"
I can override that value at runtime with an environment variable named spring.datasource.url and my application will connect to the database specified in the env var.
However, if I have an equivalent application.yaml file, specifying the environment variable that way appears to have no effect.
spring:
datasource:
url: "jdbc://localhost..."
However, if I rename my environment variable to SPRING_DATASOURCE_URL, the override works again. This appears to be consistent across other properties as well (not just the datasource url).
Looking through the docs it wasn't obvious why this should be the case, except that yaml configuration seems like it's generally treated a little different than "normal" properties files.
Is this behaviour expected?
As described in the documentation, you should use the environment variable SPRING_DATASOURCE_URL to set the spring.datasource.url property. I am surprised that spring.datasource.url worked at all when configured as an environment variable and I would not rely on it continuing to do so.

Profile-specific spring.config.additional-location?

I have specified an external properties file to a Spring Boot app by setting spring.config.additional-location in the SpringApplicationBuilder.
new SpringApplicationBuilder(MyApplication)
.properties(['spring.config.additional-location': myExternalProperties])
.run(myArgs)
This works insofar as it allows me to override properties in the application.properties file using myExternalProperties.
However, myExternalProperties are in turn overridden by any profile-specific properties, e.g. application-myProfile.properties.
I understand this to be consistent with Spring's prioritization of Externalized Configuration, but I want myExternalProperties to override even profile-specific properties.
How can I achieve that order of priority?
I do not control the file name or location of myExternalProperties. This variable is a System property that is preset in the environment.
I have been looking at Profile-specific Properties and in particular this quote.
If you have specified any files in spring.config.location, profile-specific variants of those files are not considered. Use directories in spring.config.location if you want to also use profile-specific properties.
I assume this note applies equally to spring.config.additional-location, but without control over the property file name or location I don't think that helps me.
I'm afraid it cannot be achieved in a non-hacky way.
The docs state:
Profile-specific files always overriding the non-specific ones.
Also:
If several profiles are specified, a last-wins strategy applies. For example, profiles specified by the spring.profiles.active property are added after those configured through the SpringApplication API and therefore take precedence.
Could you consider using profile based configuration for myExternalProperties?
You can even use env vars as placeholders.
Hope this helps: Env vars in Spring boot properties

Spring boot external config override isnt working

I have an application.yml and application-qa.yml in my resources folder.
I have an external application-qa.yml.
I want the properties in the external application-qa.yml to override the matching ones from the default application.yml and from the internal application-qa.yml, I dont want to override the entire file.
Im adding this VM option (In Intellij): -Dspring.config.additional-location=file:{absolute/path/to/external/ending/with/application-qa.yml}
I also have in env variables (also in Intellij): spring.profiles.active=qa
And for some reason the override doesnt work, I get the value from the internal application-qa.yml instead of the external one.
Tried naming the external file as application.yml, didnt work.
UPDATE:
It does work if I remove application-qa.yml from the end of the path and just give a path to the folder where the file is, but I want to specify a file, I dont want him to take everything thats in the dir.
This is a change in behavior from 1.x to 2.x. The spring.config.location overrides the default instead of adding to it. We need to use spring.config.additional-location to keep the defaults. So if you want to override try spring.config.location instead.

parent properties for application-{profile}.properties with Spring-Boot app

There are common properties which are shared among different profiles for e.g. path location for temp files and path remains same among different env(tst,prd).
Is there a way to have a parent application-{parent}.properties from which all the profile specific properties files can inherit the properties.
That will help in avoiding writing same properties in all application-{profile}.properties
In addition, each application-{profile}.properties have something like :
profileLocation=xxx
abc=${profileLocation}/tempPath
Here can I move abc to a common location? I cannot in application.properties as it gets loaded before application-{profile}.properties
Actually, that is not entirely true that application.properties are loaded before any others. They are processed together. To set common properties that are used by all profiles, you should use the ordinary application.properties file. Two main thing you should know are described below.
Case 1. The keys that are placed inside the application.properties file can be overridden by profile specific configuration.
common.path.for.all.envs=/some/path
default.path=/another/path
Than in your e.g. application-dev.properties you can override some values.
default.path=/dev/path
At runtime with dev profile your application will have access to two keys. The value of common.path.for.all.envs will be set to /some/path as declared only in the main file and default.path will be set to /dev/path because you override the property in the profile configuration.
Case 2. The values defines in the application.properties file can use placeholders for the values included in profile configurations. For instance, in your application.properties define the following variable:
abc=${profileLocation}/tempPath
Next, in the application-dev.properties declare the missing variable:
profileLocation=xxx
Then running with the dev profile the value of abc will be set to xxx/tempPath. As you see, the variable declared in the profile configuration can be used in the main application.properties file as well.

How do I access Spring properties in a logback configuration

Is there a way to access Spring properties within a logback.xml file?
I know one can import a properties file if you know its location, but I'm using Spring profiles to control where the properties file should be loaded or not.
Is there done kind of connector that asked me to feed Spring data into logback? This would only be at startup; I don't need to be able to do this on the fly.
I'm guessing you do have to import a property file (common property file, non-environment specific one) that will contain the name of the property that you are going to use in the logback.xml, and that you want to optionally override the value of the property for some environment (you need at least one property file containing the name of the property, because you will be using that property in the logback.xml, and you need it to be available to be able to use it).
For the optional environment-override, how about including an additional property file? For example, we use both application.properties and application-${spring.profiles.active}.properties files. Then if we don't need to override the property for some environment, we simply don't include it in the environment specific property file (application-dev.properties, etc.)

Resources