Describe the bug Libraries: - Spring Boot: 3.1.2 - Spring Cloud: 2022.0.4 - Spring Cloud GCP: 4.7.2
I have a Spring Boot application that runs inside a K8s cluster. The deployment.yaml
configures the environment like:
env:
- name: SPRING_PROFILES_ACTIVE
value: development
The application correctly picks up the environment name when booting up and runs with 2 profiles: kubernetes
and development
everything is great!
Except when I add Spring Cloud Configuration. I see the application making 2 calls, one for a default
profile and one for the correct development/kubernetes
one
Correctly finds this profile:
Fetching config from server at : http://configuration-service:8080
Located environment: name=dog-service, profiles=[kubernetes,development], label=null, version=null, state=null
Then fails with:
Application run failed
org.springframework.cloud.config.client.ConfigClientFailFastException: Could not locate PropertySource and the resource is not optional, failing: None of labels [] found
Back in the configuration service I can see 2 calls made:
dog-service/development/application.yaml
<-- Correctly found
dog-service/default/application.yaml
<-- will fail as there is no such configuration on the repo
Random guess: does the app fire a request to the configuration server before getting its active profile set by the environment?
Comment From: ryanjbaxter
I am not entirely clear on exactly how everything is cofigured...
but your assumption is right.
Spring Boot has always loaded configuration without and active profiles to discover potentially activated profiles first, and then goes back and loads configuration with all the activated profiles. Prior to Spring Cloud 2022.0.4 Spring Cloud Config only ever loaded configuration after all active profiles were discovered, the problem was you couldn't activate profiles from configuration from the config server. Now there will be a request to the config server with no active profiles first, and then a second one with all the active profiles.
I'm a little unclear how your app is configured so this first request is failing, but the second request succeeded...
Comment From: Alos
Well, the problem is that my custom configuration server throws an exception as it can't find anything for the "default" profile (It was only expecting "development" or "production").
Maybe my custom Configuration Server needs to not throw an exception when it receives a call for a file it doesn't have. I guess I could return an empty org.springframework.cloud.config.environment.Environment
? Is that normal behaviour?
Would this cause Spring to use the "default" profile and not the "development" one? Or does it prefer the activated profile if there is one?
Comment From: ryanjbaxter
OK this makes more sense.
If you look at how the config server responds when a file does not exist it does not throw an exception it returns a response, but with no property sources
{
"name": "application",
"profiles": [
"default"
],
"label": null,
"version": "22542bc51277718c381187b5b8dca549f170819f",
"state": null,
"propertySources": []
}
Comment From: Alos
Makes sense, I hope Spring prefers the active profile properties and not the default empty ones 👍 Thanks for the help!