Quarkus #ConfigMapping: when no prefix defined, skip/ignore system and environment variables, only scan properties with defined keys - quarkus

Some properties defined in my app are used by other applications in the same organization, so I cannot add a dedicated namespace before them to differentiate. While moving to Quarkus #ConfigMapping, I found Quarkus by default scans all system and environment variables as well as application scoped properties, and non-mapped properties will stop app from launching, showing a lot of "cannot find any root to map" error.

Quarkus YAML config is based on Smallrye config, which has:
smallrye.config.mapping.validate-unknown=false
to stop this behaviour.
https://smallrye.io/smallrye-config/2.11.1/config/mappings/#retrieval
For a Config Mapping to be valid, it needs to match every configuration property name contained in the Config under the specified prefix set in #ConfigMapping. This prevents unknown configuration properties in the Config. This behaviour can be disabled with the configuration smallrye.config.mapping.validate-unknown=false.

Related

How to set logging.file.name through command line arguments in spring boot?

I am setting the logging.file.name in application.properties file which I want to pass as command line argument. Is it possible?
The reason is I am trying to run multiple jar files from a single application and I want to display logs of each application run at a single location.
Spring Boot provides several options to externalize configuration.
Spring Boot uses a very particular PropertySource order that is
designed to allow sensible overriding of values. Properties are
considered in the following order (with values from lower items
overriding earlier ones):
Default properties (specified by setting SpringApplication.setDefaultProperties).
#PropertySource annotations on your #Configuration classes. Please note that such property sources are not added to the
Environment until the application context is being refreshed. This is
too late to configure certain properties such as logging.* and
spring.main.* which are read before refresh begins.
Config data (such as application.properties files).
A RandomValuePropertySource that has properties only in random.*.
OS environment variables.
Java System properties (System.getProperties()).
JNDI attributes from java:comp/env.
ServletContext init parameters.
ServletConfig init parameters.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
Command line arguments.
properties attribute on your tests. Available on #SpringBootTest and the test annotations for testing a particular
slice of your application.
#TestPropertySource annotations on your tests.
Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.
So you should be possible to override the values defined in your application.properties by setting environment variables, Java system properties, or command line arguments:
Environmant variables: export LOGGING_FILE_NAME=yourfile.txt
Java system property: -Dlogging.file.name=yourfile.txt
Command line argument: --logging.file.name=yourfile.txt

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 YAML default and environment variable override like HOCON files

Is there a way in spring-boot YAML file to do the same as in HOCON files where you can have a default and be able to override it with an environment variable like this:
basedir = "/whatever/whatever"
basedir = ${?FORCED_BASEDIR}
In this case in HOCON if you don't define a environment variable named FORCED_BASEDIR then basedir will be "/whatever/whatever" but if you do then the value of basedir will be whatever is defined in the environment variable.
Thanks
So based on webdizz answer below I looked up a little bit and I found a pretty good description in book "Spring Boot in Action". Here is the hierarchy:
There are, in fact, several ways to set properties for a Spring Boot application. Spring
Boot will draw properties from several property sources, including the following:
Command-line arguments
JNDI attributes from java:comp/env
JVM system properties
Operating system environment variables
Randomly generated values for properties prefixed with random.* (referenced
when setting other properties, such as `${random.long})
An application.properties or application.yml file outside of the application
Licensed to Thomas Snead 58 CHAPTER 3 Customizing configuration
An application.properties or application.yml file packaged inside of the
application
Property sources specified by #PropertySource
Default properties
Spring Boot provides means to define variables at many levels and your case is supported, you just need to define variable in following way:
in application.yml:
basedir: "/whatever/whatever"
and in environment:
export BASEDIR = "/another/whatever"
Then in runtime application will use value from environment.
For more details check this out enter link description here.

Spring boot - expose common application properties with different names

I have a requirement where I need my custom application properties to act as aliases to various common application properties that spring provides for different packages.
Example:
Whenever I set a value to the application property foo.host, it should set the value for spring.rabbit.host property.
Similarly setting the value for foo.port should set the value for spring.rabbitmq.port.
Can this be achieved?
It can, you can add these to your application.properties:
spring.rabbit.host=${foo.host}
spring.rabbit.port=${foo.port}
However, if you still provide spring.rabbit.host via system properties, as an environment variable or as direct argument then it will take precedence over foo config.

Spring boot, use profiles to load files

I have used spring-boot profiles to change property values for different environments, now I want to use the same approach to load different resource files, ie example I have dev_queries and prod_queries.xml with sql queries.
How can I make spring-boot load dev_queries.xml if active profile is dev and prod_queries.xml otherwise. I know that I can check the active profile but my idea is to do not add specific logic for handle this situation.
Would it help to externalize the filename as a custom property (docs, especially 24.4)? So that in your properties you would use:
# application-dev.properties
myapp.query-source=dev_queries.xml
# application-production.properties
myapp.query-source=prod_queries.xml
In your application beans this setting can be accessed by using the #Value annotation:
#Value("${myapp.query-source}")
private String querySource; // will be dev_queries.xml or prod_queries.xml
That way in the code where you are loading the xml file you don't have to conditionally check for the currently active profiles but can externalize that setting to the properties.

Resources