Spring .properties files purpose - java

I read #yorkw answer at this topic. He said:
The purpose of .properties file is to provide the capability of
configuring database connections at application runtime (for web
application, usually require restarting application container/server
after .properties file changes).
The question is if we can change properties on the fly without restarting container/server? Provide me an example please (I ask because in my demo it doesn't work, means value isn't changed).
I mean if we have some kind of admin tool than we can move all our configured settings to .properties files and change them via that admin tool.

Spring property files are designed to change the Spring Config of an application. The spring config is read when the spring container is initialised - this will form part of the application startup.
If a change is made to one of the spring config files (includes the *.properties files) the spring container would need to be reloaded to pick up the change.
Properties put into spring properties files should typically be properties that are tied to the life cycle of the application - i.e. the kind of properties that when changed require an application/spring container re-initialised - things like the database url/config etc.
So values that you want to change at runtime without requiring a restart of the application are not good candidates for placement in a spring properties file.

Related

Dynamically set all properties files at runtime:

I am trying to dynamically set all properties at run-time in a java spring application. I am successfully doing that with program arguments/System Properties (a different SO post explaining this in detail here), but I haven't figured out a way to dynamically read all properties in .properties files and edit their values. The property sources stored under the spring application context do not contain properties in the previously mentioned files.
Is it possible to load up a spring app and before creating any beans, step in and edit the values across all properties files being loaded in the project?
The properties added to the properties file are read when the app starts. Once it is up and running, changes to the properties file wouldn't reflect unless you restart the app. There is no way to dynamically update the properties file to reflect in the app.
The only way to dynamically update properties of an app would be to use something like a configuration server. Read about it here.
https://spring.io/guides/gs/centralized-configuration/

How to consume properties from configmaps in Java Spring boot application deployed through Helm

I have simple Spring boot application which I need to deploy on development and prod different namespaces on a Kubernetes cluster using Helm.
I was thinking about keeping multiple application.properties (application-dev.properties, application-prod.properties) files for each environment and then create configmaps from them through values.yaml files which also will be different for each environment and specified when I execute Helm upgrade.
Now the question is how do I consume values from config.maps as I understand I can either mount the properties file inside container for example /deployment/application.properties
Or expose each property as an environment variable inside container.
But how do I consume them from Java application?
Also at the moment when I create container image it has current application .properties inside /resources/ files embedded and this is what application is using from default so I need to overwrite this behaviour when application is running inside container as opposite to then when its just build and run manually on developer desktop.
Springboot can automatically infer variables from environment variables. In your application.properties or application.yaml, just use ${MY_ENVIRONMENT_VARIABLE:my-defaultvalue}.
Use helm to populate your configmap.
Use configmap as environment variables into your deployment manifest.
This way you do not need to have multiple application.properties for dev, int ,prod inside your image. Keeping it intact across deployment.
And then in your helm chart, you can have multiple values.yaml example values-dev.yaml or values-int.yaml. you can also dynamically set helm values from command line, overriding the yaml file.
I have a demo app in github https://github.com/balchua/demo, which uses this pattern.
You could certainly use environment variables as Bal Chua suggests. If you do that you can override particular values at install time using --set or if you've a lot of config you can use the '-- values' flag and pass in a custom values.yaml file.
Another approach is to load a whole file using .Files.Glob (example in github) and load the file as part of the chart. You can then mount the file to /config to consume it in your spring boot application. Then your config file would be in the same form as a Spring boot config file, rather than a helm values.yaml. Though in many cases there needn't be much difference.
There's a discussion of how you could do similar for secrets (presumably you'll want to put your passwords in secrets) and use it for CI/CD in https://dzone.com/articles/hunting-treasure-with-kubernetes-configmaps-and-se (which is the article accompanying the github example). Basically you would use .Files.Glob with .AsSecrets instead of .AsConfig so as to encode the content. Many helm charts have the option to generate a random password if not specified but I'd guess you probably don't need that.
I'd recommend mounting the files (application.properties or application.yml) inside the ConfigMap onto somewhere on the file system that Spring Boot can automatically detect - then your app stays nice and simple

Multi-file config for Spring Boot app

So, I have a Spring Boot application that is based on a plugin architecture, with its config properties, as you would expect, in an application.yml. Due to the fact that plugins may or may not be enabled however, I am keeping the config for each plugin in a separate file.
What's more, I would like to differentiate between these files (e.g. by naming them differently - preferably after the name of the plugin itself) and not have them all as application.yml.
I know that I can use spring.config.name to add the names of all the property files, depending on what plugin is enabled, but I would like a more dynamic approach.
For example, a config directory, with an application.yml and sub-folders named after each plugin - with a separate application.yml in each one...
Ideally, I would then just set spring.config.location to the path of the config folder and Spring would pick up all these files, by looking up in the sub-folders recursively.
So, my question to you, dear Spring experts, is: what magic dust do I have to sprinkle on my config to make this happen?
Is there any other approach you would recommend I take?

Neo4j-ogm: How to use different configuration (ogm.properties/java configuration) depending on environment?

I've been using an embedded neo4j server in my project so far.
Now I want to try out the new bolt protocol with a standalone server, however only for my deployed application. For convenience, I still want to use an embedded database when running from IDE (permanent) or when running tests (impermanent).
In order to support this, I've migrated from the java based configuration to the use of a ogm.properties file. Depending on the environment I run in, I want to use the file which configures the respective driver/database location.
I have placed a default configuration in the root of my resources folder. However I am not able to "override" this in other environment.
In order to do that I placed a different ogm.properties in the root folder of the deployed application. This doesn't seem to work. This the mechanism that I previously already used in order to have different application.properties and logback.xml configurations.
Is this not supported by neo4j-ogm? If not, how can one achieve this? It also isn't (trivially) possible with the java based configuration.
I am a bit confused, since this doesn't sound like such an unlikely requirement...
You can use Spring Profile for this to configure different properties for different environments and you can look here.
You can use application.properties (spring.profiles.active) to load a different profile or by using a runtime argument if you are using Spring boot with CommandLineRunner.

off-the-shelf web application working directory

I've just started working with Spring/java web. I'm wondering how to accomplish following scenario:
Let's say that I'm creating an application which supports file upload, uses a database connection and maybe a web service. This is an off-the-shelf system, so all the settings are customer specific and should be configured by customer's IT people on the deployment time.
More general in the web.xml file I would like to point the application working directory containing uploaded files, license key file, configuration files, other customer specific resources and maybe even fragments of spring context.
<context-param>
<param-name>workdir</param-name>
<param-value>/var/r2/</param-value>
</context-param>
In my application I would like use the workdir value in order to include configuration files ...
<import resource="wordir_param_value/settings.properties" />
context config fragments
<import resource="wordir_param_value/security.xml"/>
And how may I later use these values in the java code? What is "the best" approach in case like this anyway (off-the-shelf application config)?
Best Regards,
Alek
You can use Spring's property support for that. This allowed two different approaches:
Having a property file outside the application (at a fixed location), the admin can edit it, and the application loads it
In a Tomcat you can write properties in the application specific context.XML file
In the code use #value annotation to inject the properties in a variable.
In the spring XML file you use it with ${name}
Of course you need to configure the proprtyPlaceholderConfigurer

Categories