spring-cloud / spring-cloud-consul

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

Property keys from consul are not overriding the ones in the classpath #741

Closed danparisi closed 2 years ago

danparisi commented 2 years ago

I'm having this bug after upgrading:

Involved actors are:

  1. a common-library, containing default properties on resources/application.yml
  2. multiple services running on k8s having this common-library as dependency and additional properties on resources/config/application.yml
  3. A consul instance having additional property files in the config/ folder

I'm expecting my services to load the configuration in this order (higher on top in the following list):

  1. service-profile.yml from consul config/ directory
  2. servicename.yml from consul config/ directory
  3. resources/config/application.yml from the service classpath
  4. resources/application.yml from the common-library application.yml

In common-library/resources/application.yml I've:

spring:
  profiles:
    active: profile
  config:
    import: optional:consul:consul:8500/

It seems that property keys are always overridden only from the ones from service-profile.yml from consul and not from servicename.yml. Keys from servicename.yml are only able to override the ones from the application.yml from the common-library.

The idea is that consul properties should always have the higher precedence over the configuration files in the classpath.

danparisi commented 2 years ago

I fixed the behavior by adding the following EnvironmentPostProcessor:

public class ConsulConfigEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        var customProperties = new Properties(1);
        customProperties.setProperty("spring.config.import", "optional:consul:consul:8500/");
        var ps = new PropertiesPropertySource("custom-resource", customProperties);
        environment.getPropertySources().addLast(ps);
    }

    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }

}

P.S. Don't forget to register it in your spring.factories:

org.springframework.boot.env.EnvironmentPostProcessor=\
eu.dimoco.hub.gateway.ConsulConfigEnvironmentPostProcessor