Describe the bug
Spring Cloud Consul: 3.0.4
Spring Boot: 2.5.14
Java: 11
Given the following application context hierarchy:
final SpringApplicationBuilder parentBuilder = new SpringApplicationBuilder()
.profiles("A")
.web(WebApplicationType.NONE);
parentBuilder.run(args);
parentBuilder.child(BootstrapApplication.class)
.web(WebApplicationType.NONE)
.profiles("A", "B")
.run(args)
.close();
parentBuilder.child(ApplicationConfiguration.class)
.profiles("A")
.web(WebApplicationType.SERVLET)
.run(args);
And given that ConsulPropertySourceLocator is a singleton in the bootstrap context, when the empty parent context (parentBuilder) is loaded it's Environment contains the following ConsulPropertySource's:
The problem is that the ConsulPropertySourceLocator is caching Consul context's from the previous ApplicationContext and just appending them together. And properties from the "B" profile that override properties from the "default" profile are not being picked up.
The current workaround I have, which is very much a hack is a @BoostrapConfiguration class that registers a BeanPostProcessor to wrap the ConsulPropertySourceLocator and clear() the context's before the next invocation of locate() is called.
@BootstrapConfiguration
public class FixConsulPropertySourceLocatorBootstrapConfiguration {
@Bean
public BeanPostProcessor fixConsulPropertySourceLocatorBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
if (bean instanceof ConsulPropertySourceLocator) {
return new FixedConsulPropertySourceLocator((ConsulPropertySourceLocator) bean);
} else {
return bean;
}
}
};
}
static class FixedConsulPropertySourceLocator implements PropertySourceLocator, ConsulConfigIndexes {
private final ConsulPropertySourceLocator delegate;
public FixedConsulPropertySourceLocator(final ConsulPropertySourceLocator delegate) {
this.delegate = delegate;
}
@Override
public PropertySource<?> locate(final Environment environment) {
delegate.getContexts().clear();
return delegate.locate(environment);
}
@Override
public LinkedHashMap<String, Long> getIndexes() {
return delegate.getIndexes();
}
}
}
It would be nice if this was fixed upstream and in a better manor than I have attempted here.
This then makes the ConsulPropertySource's for that Environment appear as expected:
Describe the bug Spring Cloud Consul: 3.0.4 Spring Boot: 2.5.14 Java: 11
Given the following application context hierarchy:
And given that
ConsulPropertySourceLocator
is a singleton in thebootstrap
context, when the empty parent context (parentBuilder
) is loaded it'sEnvironment
contains the followingConsulPropertySource
's:This is all good and normal, but when the second context is loaded, it's
Environment
contains the followingConsulPropertySource
's:The problem is that the
ConsulPropertySourceLocator
is caching Consul context's from the previousApplicationContext
and just appending them together. And properties from the "B" profile that override properties from the "default" profile are not being picked up.The current workaround I have, which is very much a hack is a
@BoostrapConfiguration
class that registers aBeanPostProcessor
to wrap theConsulPropertySourceLocator
andclear()
the context's before the next invocation oflocate()
is called.It would be nice if this was fixed upstream and in a better manor than I have attempted here.
This then makes the
ConsulPropertySource
's for thatEnvironment
appear as expected: