Spring-boot property value used in another property key - java

In my spring boot project, I want to use a property value in another property key:
server.mode=mock
server.protocol.mock=http
server.host.mock=my.host-mock.org
...
server.protocol.prod=https
server.host.prod=my.host-prod.org
...
I want to depending on "server.mode" value use the related property key server.protocol.{value}
How could I do this?
Thanks for help

You can use spring profiles, where you can setup different property configurations for different deployment environments.
Using property files, you can create a property file per profile and then have spring boot use the right property configuration depending on the active profile.
application-dev.properties
server.scheme=http
server.host=my.host-mock.org
application-prod.properties
server.scheme=http
server.host=my.host-mock.org
You would then have to tell spring boot which profile to use by setting it in the spring.profiles.active property. When deploying to the cloud with application manifests (like Cloud Foundry or Kubernetes), then it is convenient to set this via an environment variable SPRING_PROFILES_ACTIVE.
See the official spring-boot documentation for more information about profiles.

This can be achieved using the following format while fetching the value in code (or the correpsonding xml) where you are using it:
#Value("${server.protocol.${server.mode}}")
private String mode;

Related

Spring Boot: how to disable (or remove) property in application.properties using externalized configuration

I'm working on a Spring Boot project (v2.3.x) connected to a MongoDB instance.
The connection is configured using the property spring.data.mongodb.uri.
Now, for local development I'd like to configure the connection using host/port, i.e. using these properties (I'm configuring these via ENV VARs):
spring.data.mongodb.host
spring.data.mongodb.port
Adding these properties, while leaving spring.data.mongodb.uri, obviously results in an error on application run:
java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified
So I'm wondering if there is a way to disable the spring.data.mongodb.uri configuration using properties override (externalized configuraion) provided by Spring Boot.
Is this possible? I tried setting spring.data.mongodb.uri=null but the startup error remains.
How can I achieve this without directly modifying the application.properties file?
NOTE: I also considered using profiles, but also using this feature I cannot find a way to override the "main" configuration.
You could use "application-default.properties" file and put spring.data.mongodb.uri in there. The "default" Spring profile will be active when no other profiles are selected. So you can start locally with any profile ("dev" or whatever) and "application-default.properties" file will not be loaded.
Of course, keep in mind that adding any profile in production would also disable spring.data.mongodb.uri in this case.

Override configuration properties in micronaut

I have a micronaut application in which I want to override the default configuration properties based on a profile I pass through an environment variable.
Tha application has a default application.yml
I am currently passing:
MICRONAUT_CONFIG_FILES=classpath:application.yml,/path/to/application-prod.yml
MICRONAUT_ENVIRONMENTS=prod
However just application-prod.yml is taken into account (unlike for Spring Boot where it updates the defaults).
What is the best way to achieve the update? The only solution so far is to replicate all the settings in application-prod.yml but it seems pretty anti-DRY.

Spring config #RefreshScope

Can I use #RefreshScope (along with #Value on a property) only in Cloud config server or can I use without config server as well? I'm trying to use it without config server. I am trying to fetch #Value property by changing value in a .property file and trying to request again, will I get updated value? Is that possible?
No, you should use it along with Config server otherwise you won't be able to read the update properties on fly. Follow this article and have a look into this if you face any issue loading updated properties dynamically.
In theory, you could refresh the application context, but I wouldn't
recommend this. Spring Cloud has provided an annotation to mark a bean
as refreshable. By adding spring actuator, we can refresh those beans
on the fly.

Access properties dynamically with Spring

I have a Spring application with xml configuration (v4.0.8) where I need to access properties dynamically rather than using #Value annotation. I tried using tho methods for this, one of them is using #ConfigurationProperties with a Map which gives me all properties in a map, and the other way is using Environment.getProperty.
Both methods are getting the properties from the propertySources of the Environment. Unfortunately that contains 5 property sources including system properties, etc, but not my properties files. Therefore I cannot access my properties.
I'm adding my properties using EncryptablePropertySourcesPlaceholderConfigurer from jasypt which is a simple implementation of PropertySourcesPlaceholderConfigurer that decrypts encrypted property values. PropertySourcesPlaceholderConfigurer does not add properties to Environment.propertySources and I couldn't figure out how can I extend it myself rather than using jasypt implementation and add them to property sources manually.
Two notes:
#Value annotation works fine, because it's not using Environment but goes through configurers during bean creation. There's not problem with that.
I have a spring boot application where I cold achieve my goal appending to Environment.propertySources by listening to ApplicationEnvironmentPreparedEvent of spring boot and adding my properties to Environment rather than implementing PropertySourcesPlaceholderConfigurer. But this is only applicable to spring boot applications and my legacy application is not a spring boot app.

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