Spring Boot properties that depend on profile-specific properties - java

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...)

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.

How to merge application.properties with application-default.properties and include in other test profiles with Spring Boot >2.4

We would like to merge src/main/resources/application.properties with additional default properties when running tests which in turn should be included by other (test) properties files activated via specific profiles in our Spring Boot application.
Up until Spring Boot 2.4 this worked quite well by having all common test properties in src/test/resources/application-default.properties to keep things DRY. Those were then automatically merged with the ones from src/main/resources/application.properties by Spring [1]. This allowed us to have our own set of default properties without requiring tests to specify an #ActiveProfiles("default").
Other (test) profiles could then have their own application-<profile>.properties with spring.profiles.include=default and then further extend the defaults.
With Spring Boot 2.4 I'm struggling with the new "rules":
I can no longer load application-default.properties from application-<profile>.properties since spring.profiles.include is no longer allowed in non profile-specific documents [2].
I don't want to introduce a src/test/resources/application.properties since I don't want to repeat everything from src/main/resources/application.properties. Also I don't want to load any activate any test-related profiles in the app's properties.
It looks like one solution could be to explicitly add spring.profiles.include=default to src/main/resources/application.properties to force the application to include the properties file with default properties which will work as before when it comes to running the actual application but consider src/test/resources/application-default.properties when running the tests.
Is this the way to go or are there smarter solutions to tackle this problem and still keep the properties free of redundancies?
spring.profiles.active=dev
add this config in application.properties file

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.

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.

Separate properties file for multiple environments

I am trying to have separate property files for prod and dev environment.
I have two property files application-prod.properties, application-dev.properties placed in classpath:/config
I added VM option -Dspring.profiles.active=dev
According to what I understand from the documentation and many other references on the web, on accessing Spring Environment as environment.getProperty("") the property in "application-dev.properties" should be loaded. However, I am getting null and as it seems the property files are not read by Spring.
I also tried defining both the files in #PropertySource. Doing this, the file defined second is picked up and the corresponding property is returned. Spring is not choosing the file based on the active profile.
Am I missing something?
I also came across a issue raised through some SO questions, but I am not sure if it refers to the same problem.
Right, so documentation you are pointing to is from Spring Boot project. That is not the same as Spring Framework. If you are not using Spring Boot, -Dspring.profiles.active=dev wouldn't work.
You have two options:
Introduce Spring Boot to your project ans turn on auto-configuration (#SpringBootApplication or #EnableAutoConfiguration).
Use plain Spring Framework features like PropertyPlaceholderConfigurer, but it doesn't give you same flexibility as Spring Boot features and you will need to create some boilerplate code to handle various envs.

Categories