We upgraded from 2022.0.2 to 2022.0.3 and our Spring Cloud Config clients no longer seem to work.
2022.0.2
2023-05-31T15:57:45.777-07:00 INFO 22800 --- [ restartedMain] org.example.ConfigTestApplication : The following 1 profile is active: "dev"
2023-05-31T15:57:45.823-07:00 INFO 22800 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://XXXX
2023-05-31T15:57:45.823-07:00 INFO 22800 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=notification-service, profiles=[dev], label=null, version=baa976431f5c111b2bed9a8b7643212c5f302f9e, state=null
2023-05-31T15:57:45.824-07:00 DEBUG 22800 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Environment notification-service has 1 property sources with 18 properties.
2022.0.3
2023-05-31T15:55:45.211-07:00 INFO 32892 --- [ restartedMain] org.example.ConfigTestApplication : The following 1 profile is active: "dev"
2023-05-31T15:55:45.249-07:00 INFO 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://XXXX
2023-05-31T15:55:45.250-07:00 INFO 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=application, profiles=[default], label=null, version=baa976431f5c111b2bed9a8b7643212c5f302f9e, state=null
2023-05-31T15:55:45.250-07:00 DEBUG 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Environment application has 0 property sources with 0 properties.
2023-05-31T15:55:45.250-07:00 INFO 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://XXXX
2023-05-31T15:55:45.250-07:00 INFO 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=application, profiles=[dev], label=null, version=baa976431f5c111b2bed9a8b7643212c5f302f9e, state=null
2023-05-31T15:55:45.250-07:00 DEBUG 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Environment application has 0 property sources with 0 properties.
2023-05-31T15:55:45.250-07:00 INFO 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://XXXX
2023-05-31T15:55:45.250-07:00 INFO 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=application, profiles=[default], label=null, version=baa976431f5c111b2bed9a8b7643212c5f302f9e, state=null
2023-05-31T15:55:45.250-07:00 DEBUG 32892 --- [ restartedMain] o.s.c.c.c.ConfigServerConfigDataLoader : Environment application has 0 property sources with 0 properties.
I didn't drill down too deeply in the code, but I do see that it is definitely passing in "application" to the restTemplate in ConfigServerConfigDataLoader instead of the value from spring.application.name ("notification-service").
This was tested against Spring Boot 3.0.7.
The profile and server uri are being passed through env variables
SPRING_PROFILES_ACTIVE=dev spring.config.import=configserver:http://u:p@XXXX
We have no additional config. I created a dummy project to reproduce this, but unless I am missing something, this seems to be fundamentally broken. I didn't see any required config changes in the release notes.
Comment From: ryanjbaxter
Can you provide the sample that reproduces the problem?
Comment From: ryanjbaxter
How are you setting spring.application.name
? Can you try setting it via an environment variable? Or placing spring.config.import
in your application configuration file as opposed to an environment variable.
Comment From: westmc
All of our code has spring.application.name in the application.yml with SPRING_PROFILES_ACTIVE and spring.config.import being passed into the docker container as env variables at runtime.
I did some more testing. If I put spring.application.name, spring.config.import, and spring.profiles.active in the application.yml then it works with the odd behavior that it makes 3 calls out to to the config server. Once without a profile, then with the profile, and then again without. In 2022.0.2 (and all previous versions that we have used), it correctly only made 1 call with the profile.
If I add spring.config.import and SPRING_PROFILES_ACTIVE as env variables (with all 3 values still in the application.yml) then it fails and also makes 6 calls. All with "application" instead of the application name and with the pattern of no profile/no profile/profile/no profile/profile/no profile. It works if I also add spring.application.name as an env variable, but again it makes 6 calls.
Doing just env variables works (as long as I have all 3) but again it is making 3 calls instead of 1.
I had assumed initially that this had something to do with the code that was added to ConfigServerConfigDataLoader to handle application names with a "-" so I tested using a name without dashes but that didn't fix it.
Here is a dummy client and server implementation to demonstrate this.
I didn't test to see what those extra calls are doing if I had a default config. Not sure if it would try merging it or what, which would definitely be different behavior than previous versions.
Comment From: martinvisser
This sounds similar to what I posted in Gitter: https://matrix.to/#/!ZDFMLMDSttmhtcDdOk:gitter.im/$Pviy47HRPd1ltjPVna94VZ59v745LHvCL6O4bPgkNQA?via=gitter.im&via=matrix.org&via=matrix.freyachat.eu
We tried to upgrade to Spring Cloud 2022.0.3 and right after our application fails to start. It runs on Cloud Foundry with a config server. Before we had no issues reading configuration properties, but after the upgrade the property ${service.server}
fails to resolve which makes the bean fail to load. This is the piece of code which attempts to read the property:
@FeignClient(
name="${service.name:SomeClient}",
url="${service.server}/api/1",
configuration = SomeFeignClientConfiguration.class
)
@Component
public interface SomeApiClient extends SomeApi {
}
The exception is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'com.example.SomeApiClient' defined in null: Could not resolve placeholder 'service.server' in value "http://${service.server}/api/1"
.
Tried with both Spring Boot 3.1.0 and 3.0.7. With a locally running Spring Boot app annotated with @EnableConfigServer
I cannot reproduce it, so creating an example app would be difficult. I'm trying to get one working - well, failing ;) -, but haven't found a way yet.
It seems that downgrading (overriding the version from 2022.0.3) back to spring-cloud-config-client:4.0.2 resolves the issue btw.
Comment From: eazybytes
I faced same issue. If I mention all the below environment properties inside docker compose file, it is working fine. If I remove SPRING_APPLICATION_NAME, the config clients are not starting.
SPRING_APPLICATION_NAME: accounts
SPRING_PROFILES_ACTIVE: default
SPRING_CONFIG_IMPORT: configserver:http://configserver:8071/
Comment From: ryanjbaxter
@martinvisser is the application name also not correct in the request to the config server, so its failing to load the right configuration containing the service.name
property?
Comment From: fseneque
Hi Everyone. I have also experienced the same issue with the ConfigServerConfigDataLoader resolving to "application" instead of the spring.application.name value that I have provided :
o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://configserver:8080
o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=application, profiles=[default], label=null, version=null, state=null
Working with 2022.0.2 :
# No need to specify env variable for SPRING_APPLICATION_NAME as the one included in the application.properties is taken into account
SPRING_CONFIG_IMPORT: 'configserver:http://configserver:8080'
SPRING_PROFILES_ACTIVE: dev
Not working with 2022.0.3 :
SPRING_CONFIG_IMPORT: 'configserver:http://configserver:8080'
SPRING_PROFILES_ACTIVE: dev
But if we add the env variable SPRING_APPLICATION_NAME with the valye, it works again.
Another test I did also is to remove the SPRING_CONFIG_IMPORT env variable (and set it directly in the application.properties) makes it work again.
After digging in the code, my gut feeling goes towards this commit : https://github.com/spring-cloud/spring-cloud-config/commit/6ec9c432cb2c02840b85fdd8bcd0859eabc0ba46
Here is a sample project with a config server and a client ( spring cloud 2022.0.3, java 17). You can run it with docker compose. There is an additionnal step to build the docker image of the client with jib plugin, it's explain in the readme.md
demo-issue-cloud-config.tar.gz
Comment From: ryanjbaxter
Yes this change introduced the problem https://github.com/spring-cloud/spring-cloud-config/commit/6ec9c432cb2c02840b85fdd8bcd0859eabc0ba46
The workaround for now is to
1. Set spring.application.name
and spring.config.import
as environment variables (or as command line arguments)
2. Set spring.application.name
and spring.config.import
in the same configuration properties file
There is always going to be a slight caveat here with how we load configuration data from the config server and how spring.config.import
is set. When spring.config.import
is set via an environment variable or as a command line argument configuration will be fetched BEFORE any application configuration properties files have been loaded.
The reason why there is a different behavior as of 2022.0.3 is because with https://github.com/spring-cloud/spring-cloud-config/commit/6ec9c432cb2c02840b85fdd8bcd0859eabc0ba46 now the config client fetches config data in two separate phases. The first phase is gathers any profiles that may be activated in configuration from the config server. The second phase will fetch the configuration again with all the activated profiles. This is why you see multiple requests now.
However as a side effect of this if you set spring.config.import=optional:configsever
in an environment variable the config client will try to fetch configuration for activated profiles before any other configuration properties are loaded and will not have a value for spring.application.name
. This behavior is dictate by Spring Boot and is out of our control. However the subsequent request with all the activate profiles will have a value for spring.application.name
. The problem is that we created ConfigClientProperties in the first request and never update it.
PR #2275 addresses this and will now update ConfigClientProperties with the value of spring.application.name
allowing the second request to succeed.
I know that might be hard to follow, but essentially after PR #2275 is merged it will still be possible that the first request fails, however the second request will succeed and that should yield the same behavior as 2022.02.
Comment From: fseneque
Hi! Thank you for your reactivity and explanations on this one. I'm going to apply the first workaround with the two env variables until 2022.0.4 is released.
Comment From: ryanjbaxter
If anyone wants to try the fix it should now be available in 2022.0.4-SNAPSHOT
Comment From: westmc
If anyone wants to try the fix it should now be available in
2022.0.4-SNAPSHOT
I see it following the behavior you mentioned where it makes the incorrect call followed by a correct one, but I see it still making that extra call without a profile. Is that going to cause issues? 2022.0.2 does not make any calls without the profile. If I put spring.config.import in both application.yml and env, then it goes up to 6 calls.
2023-06-02T10:27:00.843-07:00 INFO 24236 --- [ main] org.example.ConfigTestApplication : The following 1 profile is active: "dev"
2023-06-02T10:27:00.888-07:00 INFO 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://localhost:8888
2023-06-02T10:27:00.888-07:00 INFO 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=application, profiles=[default], label=null, version=null, state=null
2023-06-02T10:27:00.889-07:00 DEBUG 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Environment application has 0 property sources with 0 properties.
2023-06-02T10:27:00.889-07:00 INFO 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://localhost:8888
2023-06-02T10:27:00.889-07:00 INFO 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=config-client-test, profiles=[dev], label=null, version=null, state=null
2023-06-02T10:27:00.889-07:00 DEBUG 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Environment config-client-test has 2 property sources with 2 properties.
2023-06-02T10:27:00.889-07:00 INFO 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://localhost:8888
2023-06-02T10:27:00.889-07:00 INFO 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Located environment: name=config-client-test, profiles=[default], label=null, version=null, state=null
2023-06-02T10:27:00.889-07:00 DEBUG 24236 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Environment config-client-test has 1 property sources with 1 properties.
Comment From: ryanjbaxter
but I see it still making that extra call without a profile. Yes I checked with the Spring Boot team as to why this is and they didn't have a good answer. It is Spring Boot causing this and there is nothing from a Spring Cloud perspective we can do. It should not cause any issues (other than the extra request to the config server). The call without profiles allows us to now include any profiles activated via configuration coming from the config server.
If I put spring.config.import in both application.yml and env, then it goes up to 6 calls.
Are you expecting the spring.config.import
environment variable to override the one in application.yml
? If so, that is not how spring.config.import
works. Spring Boot goes through each config data source gathering ALL spring,config.import
statements in order to import configuration from all sources. So in this case Boot will resolve the configuration from the environment variable first and then the one in your application.yaml
.
Comment From: westmc
Are you expecting the
spring.config.import
environment variable to override the one inapplication.yml
?
No. Just an observation that it suddenly starts making another 3 calls. With both places set, 2022.0.2 still only made 1 call.
Comment From: ryanjbaxter
With both places set, 2022.0.2 still only made 1 call.
That is not what I see, I see 2 calls being made when set in both places
2023-06-02T14:27:55.851-04:00 INFO 53821 --- [ main] com.example.demo.Demo1Application : Starting Demo1Application using Java 17.0.4.1 with PID 53821 (/Users/ryanjbaxter/temp/issues/2274/demo1/target/classes started by ryanjbaxter in /Users/ryanjbaxter/temp/issues/2274/demo1)
2023-06-02T14:27:55.852-04:00 INFO 53821 --- [ main] com.example.demo.Demo1Application : No active profile set, falling back to 1 default profile: "default"
2023-06-02T14:27:55.864-04:00 INFO 53821 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://localhost:8888
2023-06-02T14:27:55.864-04:00 INFO 53821 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Exception on Url - http://localhost:8888:org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8888/testapp/default": Connection refused. Will be trying the next url if available
2023-06-02T14:27:55.864-04:00 WARN 53821 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Could not locate PropertySource ([ConfigServerConfigDataResource@419a20a6 uris = array<String>['http://localhost:8888'], optional = true, profiles = list['default']]): I/O error on GET request for "http://localhost:8888/testapp/default": Connection refused
2023-06-02T14:27:55.864-04:00 INFO 53821 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Fetching config from server at : http://localhost:8888
2023-06-02T14:27:55.865-04:00 INFO 53821 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Exception on Url - http://localhost:8888:org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8888/testapp/default": Connection refused. Will be trying the next url if available
2023-06-02T14:27:55.865-04:00 WARN 53821 --- [ main] o.s.c.c.c.ConfigServerConfigDataLoader : Could not locate PropertySource ([ConfigServerConfigDataResource@62e70ea3 uris = array<String>['http://localhost:8888'], optional = true, profiles = list['default']]): I/O error on GET request for "http://localhost:8888/testapp/default": Connection refused
2023-06-02T14:27:56.025-04:00 INFO 53821 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=c1d60177-05a1-370d-9f44-ce3e49de8cf2
2023-06-02T14:27:56.134-04:00 INFO 53821 --- [ main] com.example.demo.Demo1Application : Started Demo1Application in 0.592 seconds (process running for 0.901)
Comment From: westmc
That is not what I see, I see 2 calls being made when set in both places
Sorry, looks like you are right. I didn't have the env variable set correctly for the 2022.0.2 test.
Comment From: roma2341
If you have any issues when the client doesn't see server configuration just check "spring.application.name" in client service. I renamed the service name from my-service to my_service and forgot to rename "spring.application.name" param.