Properties inheritance? - java

Is there anyway to do inheritance of properties?
This would be good in different regions specific property environment .
Like
Common.properties
Abc=myvalue
Developer specific environment
Local.properties
FileLocation=xyz1
Dev cloud environment
Dev.properties
FileLocation=xyz2
QA cloud environment
QA.properties
FileLocation=xyz2
Prod cloud environment
prod.properties
FileLocation=xyz3
Like above in common.properties will have all common properties others will region specific
I know in spring we can do using profile base but still..we have to include both properties in each region.
If there is such tool or configuration in spring, really it would be good know n use it.

A pattern I've used (and see other's use it too) for a long time while using spring is the following.
Have a PropertyPlaceholderConfigurer that loads files in the following order
common.properties
${env}.properties
The ${env}.properties will override any properties with the same key in common.properties.
when you launch your application, you'll need to tell it which on which environment you're running, and then spring will inject whatever properties you need in your beans.
I hope I'm answering your question, as this is a very common pattern (and has nothing to do with profiles).

Related

Spring Web App Deployment:: how do you hide data in application.properties?

everyone!
this is going to be my first time pushing a newly developed Spring Boot App and I was wondering if there is a way to protect passwords and other sensitive information written in the application.properties file.
Assuming we have the following lines:
# PostgreSQL connection settings
spring.datasource.jdbc-url=jdbc:postgresql://localhost:5432/bdreminder
spring.datasource.username=username
spring.datasource.password=password
The source code is to be first stored on GitHub and having the credentials stored in plain text does not seem to be a good idea.
So, I could probably add the file to the .gitignore one; I could set some environment variables on the host but how would it populate the .properties file afterward? Also, this seems quite cumbersome in terms of the scaling later on.
So, basically, I am trying to see how it is done in a real-life :)
Please, help :)
Simplest option is to create a profile specific application.properties file and activate that profile. So for example create application-private.properties and activate profile private. Of course you have to watch out to not commit this file.
Alternatively, and probably a safer option, is to define a file outside your project and import it in your application.properties with following line:
spring.config.import=file:../path/to/your/external.properties
Spring Boot has extensive support for external configuration. The usual approach is to use one of environment variables, configuration provided by a platform such as Kubernetes, or a specialized configuration system through Spring Cloud Config; these all keep secrets (or just environment-specific information) entirely outside of the code. They also have the advantages of providing a common style of configuration for other applications that do not use Spring Boot.

Spring Boot properties that depend on profile-specific properties

I have a Spring Boot application which should connect to different servers in dev and prod, with many services running on those servers. To this point, I have created the configuration like this:
application.properties:
server.url.srv1=${server.url.base}/srv1
server.url.srv2=${server.url.base}/srv2
server.url.srv3=${server.url.base}/srv3
application-dev.properties:
server.url.base=http://192.168.86.17
application-prod.properties:
server.url.base=https://10.11.12.3
Yet when I initialize a bean argument with #Value("${server.url.srv1}"), I get a string of "${server.url.base}/srv1" and not "http://192.168.86.17/srv1" or "https://10.11.12.3/srv1" as expected.
Is this doable at all? It should be if the "${}" references are only resolved once all the config files are loaded, but this doesn't seem to be the case.
I have searched for an answer on both the Spring site, on Google (which pointed me to an otherwise useful Baeldung site), and here, but found nothing relevant to my particular question.
Placeholders in the application.properties should work. Please refer sample project I have added with your use case and it work as expected: https://github.com/itsprav/spring-profile-properties-using-placeholder
When you run your application you must have to set the specific spring-profile to be set in order to get the specific properties defined previously.
There is many ways to set these profiles.
Setting Profiles in different ways (JVM, Programmatically, Environment Variable...)

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?

Spring use one application.properties for production and another for debug

I have a Spring application and I would like to be able to switch between configurations depending if I'm debugging the server or if the server is running in production. (the difference in configurations being things like database location.)
Ideally, I'd like to pass in a command line argument to my Spring application on boot-up and set the application configuration.
I have two separate application.properties files, one with the production values, and another with the debug values. How can I switch between the two of them?
You can have 3 properties files, application-dev.properties, application-prod.properties and application.properties. And you can specify all the development properties in your dev properties file and production cionfiguration properties in your prod file
and specify the profile in your application.properties files as below
spring.profiles.active=dev
or you can select/override the profile using -Dprofile= argument in command line.
Spring profiles seem the way to go. You can start your application with something like -Dprofile=. Have a look at this example.
EDIT: after re-reading your question, I came to the conclusion that you might actually want something more basic: put your database properties externally. Depending on your application you could use #Value of a property configurator. Have a look at the spring docs.

Spring Best approach for multiple environments

I have the following:
System A - Authorization (REST API)
System B - Needs to check for auth
System C - Needs to check for auth
System D - Needs to check for auth
And I have many environment:
Development
Homolog
Production
Each one will have different URLs for System A. So I want to create a project that will integrate those systems. Since All Systems use Jersey and Spring, I can create one filter (jersey) that will abort the request in case the user is not authorized.
So the idea is to create Integration System that will be a JAR with Jerseys filters and uses the parents configuration (Active profile from Spring) to get the correct URL. I might even use this JAR to make System B communicate with System D also, if I can make this work.
The trick is, making this JAR get the correct .properties file based on the Enviroment (set on the parent-project). To be honest, I dont know where to begin.
Reading the DOCs for Spring Environment I found:
Do not use profiles if a simpler approach can get the job done. If the only thing changing between profiles is the value of properties, Spring's existing PropertyPlaceholderConfigurer / may be all you need.
I could have 3 different properties files (development, homolog or production) or I could have one properties file with different keys:
system.a.url.develpment=http://localhost:8080/systemA/authorize
system.a.url.homolog=http://localhost:8081/systemA/authorize
system.a.url.production=http://api.systemA.com/authorize
What is the best approach? What would you do?
In such "simple" case I would only use property file for configuration of urls and have different config files for different environments (dev, prod,..) with one (same named property), e.g.
system.a.url=http://localhost:8081/systemA/authorize
You can manage your property files manually (e.g. outside your jar/war) or you can use maven profiles to make jar/war file specific for your environment. But I don't see the need for spring profiles.
EDIT: Alternatively you can use environment variables to "configure" settings specific to an environment (what a coincidence in the names :)). Note that you can have different environments also inside one machine. For more details check e.g. this.
export AUTH_URL="http://localhost:8081/systemA/authorize"

Categories