spring-cloud / spring-cloud-consul

Spring Cloud Consul
http://cloud.spring.io/spring-cloud-consul/
Apache License 2.0
813 stars 541 forks source link

Spring Cloud Config does not respect application.yml as default configuration #762

Closed PokimonZerg closed 2 years ago

PokimonZerg commented 2 years ago

Describe the bug I want to do one simple thing. It was possible earlier. On the cloud (kubernetes), I want to read config from the consul and merge it with application.yml On my laptop, I want to read the config only from application.yml

Sample Here is my configuration for the kubernetes

config:
    import: "consul:"
  cloud:
    consul:
      config:
        enabled: true
        watch:
          enabled: false
        format: yaml
        fail-fast: true
        prefixes: epsr
      host: http://consul.dev.epsr
      port: 80

Here is my configuration for my laptop

config:
    import: ""
  cloud:
    consul:
      config:
        enabled: false
        watch:
          enabled: false
        format: yaml
        fail-fast: true
        prefixes: epsr
      host: http://consul.dev.epsr
      port: 80

Why should I specify empty string for import? It is totaly undocumented. I want to simply set spring.cloud.consul.config.enable=false to complete disable the consul and read properties from the application.yml If I do this and set spring.config.import: "consul:", I will get a error

java.lang.IllegalStateException: Unable to load config data from 'consul:'
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:141)
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:126)
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:119)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.lambda$resolve$1(ConfigDataLocationResolvers.java:115)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:126)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:115)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:107)
    at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:105)
    at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:97)
    at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:85)
    at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:121)
    at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:240)
    at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:227)
    at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
    at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
    at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
    at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
    at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:338)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)
    at ru.stdev.smev3.SmevAdapterApplication$Companion.main(SmevAdapterApplication.kt:20)
    at ru.stdev.smev3.SmevAdapterApplication.main(SmevAdapterApplication.kt)
Caused by: java.lang.IllegalStateException: File extension is not known to any PropertySourceLoader. If the location is meant to reference a directory, it must end in '/' or File.separator
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferencesForFile(StandardConfigDataLocationResolver.java:229)
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:138)
    ... 32 common frames omitted

I don't want to have multiple profiles or multiple application.yml I want to set consul state by ENV variables (true/false)

ryanjbaxter commented 2 years ago

This doesn't seem to have to do with spring cloud config, instead it should be in spring cloud consul.

ryanjbaxter commented 2 years ago

Why not use optional? https://docs.spring.io/spring-cloud-consul/docs/current/reference/html/#config-data-import

PokimonZerg commented 2 years ago

Thx for your answer.

With optional:consul: and spring.cloud.consul.config.enabled=true works as expected. Config was loaded from Consul.

With optional:consul: and spring.cloud.consul.config.enabled=false I have got a error

java.lang.IllegalStateException: Unable to load config data from 'optional:consul:'
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:141)
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:126)
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.resolve(StandardConfigDataLocationResolver.java:119)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.lambda$resolve$1(ConfigDataLocationResolvers.java:115)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:126)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:115)
    at org.springframework.boot.context.config.ConfigDataLocationResolvers.resolve(ConfigDataLocationResolvers.java:107)
    at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:105)
    at org.springframework.boot.context.config.ConfigDataImporter.resolve(ConfigDataImporter.java:97)
    at org.springframework.boot.context.config.ConfigDataImporter.resolveAndLoad(ConfigDataImporter.java:85)
    at org.springframework.boot.context.config.ConfigDataEnvironmentContributors.withProcessedImports(ConfigDataEnvironmentContributors.java:121)
    at org.springframework.boot.context.config.ConfigDataEnvironment.processInitial(ConfigDataEnvironment.java:240)
    at org.springframework.boot.context.config.ConfigDataEnvironment.processAndApply(ConfigDataEnvironment.java:227)
    at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:102)
    at org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor.postProcessEnvironment(ConfigDataEnvironmentPostProcessor.java:94)
    at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent(EnvironmentPostProcessorApplicationListener.java:102)
    at org.springframework.boot.env.EnvironmentPostProcessorApplicationListener.onApplicationEvent(EnvironmentPostProcessorApplicationListener.java:87)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85)
    at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:338)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)
    at ru.stdev.smev3.SmevAdapterApplication$Companion.main(SmevAdapterApplication.kt:18)
    at ru.stdev.smev3.SmevAdapterApplication.main(SmevAdapterApplication.kt)
Caused by: java.lang.IllegalStateException: File extension is not known to any PropertySourceLoader. If the location is meant to reference a directory, it must end in '/' or File.separator
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferencesForFile(StandardConfigDataLocationResolver.java:229)
    at org.springframework.boot.context.config.StandardConfigDataLocationResolver.getReferences(StandardConfigDataLocationResolver.java:138)
    ... 32 common frames omitted

I expect that Spring Cloud Config will read config from my application.yml without errors like this

ryanjbaxter commented 2 years ago

How are you separating these configurations? What version of Spring Boot and Spring Cloud are you using?

kobynet commented 2 years ago

I can confirm it happens to us as well in spring boot 2.5.9 (latest 2.5 for the moment of speaking). When having spring boot test, for example, and we want to omit the consul part and use only application.yml file, having optional:consul: with spring.cloud.consul.config.enabled=false will throw an error as if import has precedence over spring.cloud.consul.config.enabled so we must put import part in default profile so in tests it won't appear at all (by activating test profile instead of default)

ryanjbaxter commented 2 years ago

Can you provide a complete, minimal, verifiable sample that reproduces the problem? It should be available as a GitHub (or similar) project or attached to this issue as a zip file.

spring-cloud-issues commented 2 years ago

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-cloud-issues commented 2 years ago

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.