Spring Config Server delivering config file but not activating profiles - java

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.

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.

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

How to configure multiple spring cloud config servers in spring boot

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

Load application.properties when the config server is not resolved

My project has a bootstrap.yaml and a config server that deliver its appropriate profile. Everything is working great but I have to accomplish some others task like CI and CD.
My problem comes because the Jenkins machine is not allowed to resolved external domains and try to compile and run the Spring boot app without an a profile.
So my question is:
Is there a way to load application.properties when the config server
is not resolved?
Yes, there is a natural way based on the order in which Spring Boot loads PropertySources.
You can include properties you want to be applied in application.properties.
In case config server is not available - properties from application.properties will be used. If config server is available - you'll receive properties from there.
You might also want to disable config server connectivity for your CI using environment variable SPRING_CLOUD_CONFIG_ENABLED=false.

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.

Categories