How to configure multiple spring cloud config servers in spring boot - java

I am using spring boot 2.4 and application related properties are stored in spring cloud config server. It works fine and I am able to read all properties in the application. Below properties have been configured in application.properties for this purpose.
spring.application.name=app-prop-config
spring.cloud.config.label=61465
spring.cloud.config.enable=true
spring.config.import=configserver:https://vmcloud-configsvc.farm-dev.ab.com
The above properties translates to: https://vmcloud-configsvc.farm-dev.ab.com/61465/app-prop-config-dev.properties
Per my requirement, I need to read few more properties as well and these properties are already available in another spring cloud config server which can be accessed using:
spring.application.name=common-prop-config
spring.cloud.config.label=61468
spring.cloud.config.enable=true
spring.config.import=configserver:https://vmcloud-common-configsvc.farm.ab.com
The above properties translates to: https://vmcloud-common-configsvc.farm.ab.com/61468/common-prop-config-dev.properties
The above config server(https://vmcloud-common-configsvc.farm.ab.com) properties have been used by multiple applications and duplicating properties into my config server(https://vmcloud-configsvc.farm-dev.ab.com) would cause maintenance issue in future as any change in properties have to get updated in 2 servers.
Is it possible to use above 2 spring cloud config servers in spring boot app so that I don't have to copy required properties into my existing config server?

Hi it's working for me when i use bootstrap first config. You can put multiple config name that you want to load. For example if you want to retreive user-service.properties et data-rest.properties in the same app your bootstrap.properties should be like:
spring.cloud.config.uri= http://config-server-host
spring.cloud.config.name= user-service, data-rest

Related

How to change database dynamically in Spring Boot?

How can we change database credentials and sources in Spring Boot project on run time or you can say dynamically? Let suppose if we are deploying to test server, database connection in API project point to test database, and if deploy to production server, database automatically point to production server. Do some research what kind of config we need to set these settings in our spring boot project. Technically our project will switch to more than one database connections dynamically.
How all this process will happen in Spring boot?
Let suppose if we are deploying to test server, database connection in
API project point to test database, and if deploy to production
server, database automatically point to production server.
There're couple of ways. The first you can provide the properties values as part of env variables. Ex:
-Ddb_url=jdbc:mysql://<server>:<port>/<databasename> -Ddb_username=root -Ddb_password=mysql
spring.datasource.url=${db_url}
spring.datasource.username=${db_username}
spring.datasource.password=${db_password}
or
You can use different properties files in accordance with different envs.
application.properties
application-test.properties
application-prod.properties
In these properties file you can pre-configured the addresses as per the profile. To activate the profile for particular env, you've to provide the following prop to springboot application. Ex:
-Dspring.profiles.active=prod
In this case, application.properties file will be used first to configured the properties and then the properties from application-prod.properties will be configured. In case of matching properties in both the files, the later file's properties will override the properties in the default property file i.e application.properties.

Using Spring Cloud config in application.yml files of clients?

I have some java services which use environment variables for config values.
I'd like to migrate them to use Spring Cloud config instead of environment variables.
Currently, my config is all in application.yml files, as the following:
someKey: ${SOME_KEY_ENV_VAR}
If I were to migrate to using Spring Cloud Config, how would I modify the above line to load its value from the cloud config server, instead of environment variables? (Assuming I've separately setup the maven dependencies & other configuration, to hook them up)
All examples of cloud config clients only show java code, e.g:
#Value("${someKey}")
private String someKey
Is that enough, or will I also need to make any changes to the yaml?
What about things like datasource URLs which don't have a corresponding #Value but are only defined in yaml?

Spring Config Server delivering config file but not activating profiles

I have a config server.
I'm migrating from 2.2 to 2.6 and I've seen that properties file are changed.
I have a situation that I don't think is covered (or maybe I misunderstood).
My situation is that I've a Config server that deliver:
application.properties --> containing properties shared by every microservices
application-dev.properties --> containing properties specific for dev profile
application-test.properties --> containing properties specific for test profile
application-production.properties --> containing properties specific for production profile
microservicesName.properties --> containing specific properties
microservicesName-mysql.properties --> if I use mysql profile
microservicesName-h2.properties --> if I use h2 profile
Before 2.4 I used to put in microservices application.properties path to fetch configuration from config server and in application.properties delivered by config server:
spring.profiles.include=dev,mysql
if for example I would like to activate for all microservices dev and mysql.
Now, I've converted include to groups. E.G.:
spring.profiles.groups.myConf=dev,mysql
(tried also with array notation --> spring.profiles.groups.myConf[0]=dev and [1]=mysql)
and adding to every microservices
spring.profiles.active=myConf
Watching for the config server logs, it deliver the configuration properly. My problem is that I have some Bean annotated with profile E.g.:
#Profile('h2')
or
#Profile('dev')
but these beans are not activated and application not start (also, in startup-logs profiles=[myConf])
The only solution that I found is to insert in every microservice application.properties
spring.profile.active=dev,mysql
but this don't look very comfortable because I've a lot of microservices.
Which is the proper way?
P.s.: I tried also to not touch anything and use simply
spring.config.use-legacy-processing=true
in all .properties but no luck.
After some month, with Spring Boot 2.6.6, and Spring Framework 5.3.18, this bug is solved.

External URL configuration in microservice

I have multiple microservices which communicates with each other through REST calls.
I have used spring boot and spring rest and have configured the URLS of the rest end points in application.properties file.
Now the problems is if the URL for one end point changes then I to have to manually modify all the property files of the services which are calling that particular end point which has got changed.
Is there a workaround for this so that the URLS can be somehow placed in a centralized location so that any modification does not impacts the other services which are using it.
You can use spring-cloud to achieve this. Usual way used in spring-cloud is by configuring the required properties in a git repo. And then those properties can be accessed by any micro-service you want with minimal configurations. You can refer projects in this repo
limits-services acts as a client that needs certain properties those are configured in spring-cloud-config-server. Hope this helps.
In case with microservices you can use Spring Cloud Config (Spring Cloud Config, Spring Cloud Config Server). It's very usefull and you can update your configuration at runtime.
Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications, but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate.
As others have mentioned you can use Spring Cloud Config Server to remotly load your application configuration. All you need is git repository containing your configuration.
Spring cloud configuration supporst Git, database as your store for configuration.
Idea is to create an spring-boot app that can provide configuration to other applications.
#SpringBootApplication
#EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
You can configurae port and provide your git repository using key spring.cloud.config.server
server.port: 8888
spring.cloud.config.server.git.uri: file://${user.home}/config-repo
At client side, if you have spring-config in your classpath, application will try to connect to an application runnign at port 8888 to retrieve configuration.
More information can be found here.
may put configuration inside a database.
after that need have one centralize cache service that used by other services, can be .jar service,
then the values can be load inside a cache class in this service,
then in the front end side need have update button for updating the cache after modify the URL value in the database, so then all impacted services can use new value.
and also to be easier may have stand alone UI for update those configuration rather than updating database directly.
You can use Microconfig.IO to manage your service configuration and it's placeholders functionality to reference configuration values of certain services from others. So in your case you configure your deploy url in your server and put placeholders on it in your clients. This allows you to edit value only in one place and then everyone who depend on it will get it automatically.

what is the mechanism of configuring Spring Cloud Config in a bootstrap.properties file?

According to the docs, to connect to the config server, spring.application.name and spring.cloud.config.uri should be set in a bootstrap.properties file for the config client, such that the parameters fetched from the config server can be prior to those set locally. I am just wondering how this works, since:
I searched the source code of Spring Cloud Config Client, but cannot find what it does with the bootstrap.properties
It still works if I set spring.application.name in application.properties
Is it a feature of SpringBoot?
This feature is not located in spring-cloud-config. Instead, it is in spring-cloud-context which is a dependency of spring-cloud-config.
Basically, it creates a parent context for the actual context of the application and initializes it with the parameters of the bootstrap.
You can find more information in https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html
It is a feature of spring cloud. The spring.cloud.config.uri needs to be set in bootstratp.properties. This comes from the spring-cloud-commons project. My guess is you might be running the config server in the default location of localhost:8888.

Categories