Updating spring boot application configuration at runtime - java

I have implemented shutdown API in my spring-boot project by setting following values in application.properties:
management.endpoint.shutdown.enabled=true
management.endpoint.info.enabled=true
management.endpoints.web.exposure.include=*
Now I want to disable the shutdown API dynamically with help of database like I will have those above configurations as key, value pair that I can change anytime.
On its change, the application should get also updated with the new config values thereby shutdown API gets disabled.

You could use Netflix Archaius
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-archaius</artifactId>
</dependency>
You don't need to use #Value annotation here.
Usage
DynamicStringProperty dynamicProperty = DynamicPropertyFactory.getInstance().getStringProperty("management.endpoint.shutdown.enabled", "default value here");
String propertyCurrentValue = dynamicProperty.get();
If the data changes in property file at any point, Archaius will detect it at runtime and will start retrieving the new values.
Useful references
Archaius Girhub info
Archaius with Various Database Configurations
Archaius for Property Management - Basics

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.

Enable Debug Logs for Couchbase SDK with spring boot

I am using Couchbase SDK along with Spring boot 2.6.x version. I am using the spring spring-data-couchbase:jar:4.4.0 which in turn has com.couchbase.client:java-client:jar:3.3.0 dependency. The issue, is when trying to execute cluster.query() methods, I need to see what query is getting executed. I need to enable debug logs. However, I have tried configuring it under properties for logging.level for the package com.couchbase.client to DEBUG level, nothing is showing up. I tried the similar config in log4j.xml as well and no luck either. Does couchbase uses any wierd property or is it not reading the properties specified from either log4j or spring's properties?
You may ask if raw query is passed then why log specifically, but this is required if using parameterised queries and to debug it.
How does one enable logging for couchbase if using plain sdk methods under spring's context ?
Can you enable couchbase specific properties of spring-data and not package within the application?
logging:
level:
org.springframework.data.couchbase.repository.query: DEBUG
This should help ! It won't require any external dependency or logging solutions
For the cluster, add ServiceType.QUERY to captureTraffic...
env.ioConfig(it -> it.captureTraffic(ServiceType.QUERY))
and also set the log level for the com.couchbase category to TRACE

spring boot with aws secrets manager is not download the secrets

I have updated the Spring boot from 2.0.9.RELEASE to 2.4.3, and I am using the package to get the AWS Secrets version 2.2.5.RELEASE. When I deploy the code, it looks like it didn't find the credentials, and the database connection can't be closed.
bootstrap.properties
spring.application.name=myapp
aws.secretsmanager.region=eu-central-1
With Spring Boot 2.4.0 Bootstrap phase was deprecated, that is why nothing is happening.
Because of deprecation and giving users more control over specifying which secrets they want, a new way of loading secrets was introduced in 2.3.0.
More about the new way and prefered way of loading secrets with spring.config.import can be found on here.
However, if you would still like to use old way of loading secrets with bootstrap phase, please add following dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>{spring-cloud-version}</version>
</dependency>

Spring-boot property value used in another property key

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;

How to make Spring Boot fail fast when did not found database configuration

I'm running a Spring Boot application.
When there's no application.properties file in standard config paths it is not loaded and default configuration seems to be loaded.
application.properties:
spring.datasource.url=jdbc:sqlserver:...
Because of that, Spring Boot creates empty database with scheme without data which leads to empty program output.
How can one prevent Spring Boot from loading database default configuration?
you can use something as follows exclude in #EnableAutoConfiguration annotations to exclude Datasource default configuration. Reference
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
I don't know if there is any provision to make the app fail fast.
In order to stop Spring-Boot from autoconfiguring certain features for you, you need to explicitly exclude the corresponding class from the auto-configuration config:
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
Note: using this annotation you are taking back the responsibility from Spring to setup things for you, so you need to configure your DB properly from now on.

Categories