mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-24 02:09:05 +00:00
Apply system environment prefix to management context
Update `ManagementContextFactory` so that any system environment prefix set on the parent environment is applied to the child. Closes gh-45858
This commit is contained in:
+10
-2
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.ApplicationContextFactory;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor;
|
||||
import org.springframework.boot.web.server.WebServerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
@@ -60,8 +61,8 @@ public final class ManagementContextFactory {
|
||||
Environment parentEnvironment = parentContext.getEnvironment();
|
||||
ConfigurableEnvironment childEnvironment = ApplicationContextFactory.DEFAULT
|
||||
.createEnvironment(this.webApplicationType);
|
||||
if (parentEnvironment instanceof ConfigurableEnvironment configurableEnvironment) {
|
||||
childEnvironment.setConversionService((configurableEnvironment).getConversionService());
|
||||
if (parentEnvironment instanceof ConfigurableEnvironment configurableParentEnvironment) {
|
||||
postProcessChildEnvironment(childEnvironment, configurableParentEnvironment);
|
||||
}
|
||||
ConfigurableApplicationContext managementContext = ApplicationContextFactory.DEFAULT
|
||||
.create(this.webApplicationType);
|
||||
@@ -70,6 +71,13 @@ public final class ManagementContextFactory {
|
||||
return managementContext;
|
||||
}
|
||||
|
||||
private void postProcessChildEnvironment(ConfigurableEnvironment childEnvironment,
|
||||
ConfigurableEnvironment parentEnvironment) {
|
||||
childEnvironment.setConversionService((parentEnvironment).getConversionService());
|
||||
SystemEnvironmentPropertySourceEnvironmentPostProcessor.postProcessEnvironment(childEnvironment,
|
||||
parentEnvironment);
|
||||
}
|
||||
|
||||
public void registerWebServerFactoryBeans(ApplicationContext parentContext,
|
||||
ConfigurableApplicationContext managementContext, AnnotationConfigRegistry registry) {
|
||||
registry.register(this.autoConfigurationClasses);
|
||||
|
||||
+5
-1
@@ -121,7 +121,7 @@ class ChildManagementContextInitializer implements BeanRegistrationAotProcessor,
|
||||
@Override
|
||||
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
|
||||
Assert.isInstanceOf(ConfigurableApplicationContext.class, this.parentContext);
|
||||
BeanFactory parentBeanFactory = ((ConfigurableApplicationContext) this.parentContext).getBeanFactory();
|
||||
BeanFactory parentBeanFactory = this.parentContext.getBeanFactory();
|
||||
if (registeredBean.getBeanClass().equals(getClass())
|
||||
&& registeredBean.getBeanFactory().equals(parentBeanFactory)) {
|
||||
ConfigurableApplicationContext managementContext = createManagementContext();
|
||||
@@ -136,6 +136,10 @@ class ChildManagementContextInitializer implements BeanRegistrationAotProcessor,
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigurableApplicationContext getManagementContext() {
|
||||
return this.managementContext;
|
||||
}
|
||||
|
||||
private void registerBeans(ConfigurableApplicationContext managementContext) {
|
||||
if (this.applicationContextInitializer != null) {
|
||||
this.applicationContextInitializer.initialize(managementContext);
|
||||
|
||||
+36
@@ -16,21 +16,30 @@
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.web.server;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.origin.OriginLookup;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -95,6 +104,25 @@ class ManagementContextAutoConfigurationTests {
|
||||
.hasMessageStartingWith("Management-specific server address cannot be configured"));
|
||||
}
|
||||
|
||||
@Test // gh-45858
|
||||
void childEnvironmentShouldInheritPrefix() {
|
||||
SpringApplication application = new SpringApplication(ChildEnvironmentConfiguration.class);
|
||||
Map<String, Object> properties = new LinkedHashMap<>();
|
||||
properties.put("server.port", "0");
|
||||
properties.put("management.server.port", "0");
|
||||
application.setDefaultProperties(properties);
|
||||
application.setEnvironmentPrefix("my");
|
||||
try (ConfigurableApplicationContext parentContext = application.run()) {
|
||||
ChildManagementContextInitializer initializer = parentContext
|
||||
.getBean(ChildManagementContextInitializer.class);
|
||||
ConfigurableApplicationContext managementContext = initializer.getManagementContext();
|
||||
PropertySource<?> systemEnvironmentPropertySource = managementContext.getEnvironment()
|
||||
.getPropertySources()
|
||||
.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
|
||||
assertThat(((OriginLookup<?>) systemEnvironmentPropertySource).getPrefix()).isEqualTo("my");
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends CharSequence> Consumer<T> numberOfOccurrences(String substring, int expectedCount) {
|
||||
return (charSequence) -> {
|
||||
int count = StringUtils.countOccurrencesOf(charSequence.toString(), substring);
|
||||
@@ -102,4 +130,12 @@ class ManagementContextAutoConfigurationTests {
|
||||
};
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ImportAutoConfiguration({ ManagementContextAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
|
||||
ServletManagementContextAutoConfiguration.class, WebEndpointAutoConfiguration.class,
|
||||
EndpointAutoConfiguration.class, DispatcherServletAutoConfiguration.class })
|
||||
static class ChildEnvironmentConfiguration {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+23
-1
@@ -36,6 +36,7 @@ import org.springframework.util.StringUtils;
|
||||
* {@link SystemEnvironmentOrigin} for every system environment property.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class SystemEnvironmentPropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||
@@ -49,10 +50,14 @@ public class SystemEnvironmentPropertySourceEnvironmentPostProcessor implements
|
||||
|
||||
@Override
|
||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||
postProcessEnvironment(environment, application.getEnvironmentPrefix());
|
||||
}
|
||||
|
||||
private void postProcessEnvironment(ConfigurableEnvironment environment, String environmentPrefix) {
|
||||
String sourceName = StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME;
|
||||
PropertySource<?> propertySource = environment.getPropertySources().get(sourceName);
|
||||
if (propertySource != null) {
|
||||
replacePropertySource(environment, sourceName, propertySource, application.getEnvironmentPrefix());
|
||||
replacePropertySource(environment, sourceName, propertySource, environmentPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +79,23 @@ public class SystemEnvironmentPropertySourceEnvironmentPostProcessor implements
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process the given {@link ConfigurableEnvironment} by copying appropriate
|
||||
* settings from a parent {@link ConfigurableEnvironment}.
|
||||
* @param environment the environment to post-process
|
||||
* @param parentEnvironment the parent environment
|
||||
* @since 3.4.12
|
||||
*/
|
||||
public static void postProcessEnvironment(ConfigurableEnvironment environment,
|
||||
ConfigurableEnvironment parentEnvironment) {
|
||||
PropertySource<?> parentSystemEnvironmentPropertySource = parentEnvironment.getPropertySources()
|
||||
.get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
|
||||
if (parentSystemEnvironmentPropertySource instanceof OriginAwareSystemEnvironmentPropertySource parentOriginAwareSystemEnvironmentPropertySource) {
|
||||
new SystemEnvironmentPropertySourceEnvironmentPostProcessor().postProcessEnvironment(environment,
|
||||
parentOriginAwareSystemEnvironmentPropertySource.getPrefix());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link SystemEnvironmentPropertySource} that also tracks {@link Origin}.
|
||||
*/
|
||||
|
||||
+14
@@ -105,4 +105,18 @@ class SystemEnvironmentPropertySourceEnvironmentPostProcessorTests {
|
||||
assertThat(replaced.getPrefix()).isEqualTo("my");
|
||||
}
|
||||
|
||||
@Test
|
||||
void postProcessWithParentEnvironmentShouldApplyPrefix() {
|
||||
SpringApplication application = new SpringApplication();
|
||||
application.setEnvironmentPrefix("my");
|
||||
new SystemEnvironmentPropertySourceEnvironmentPostProcessor().postProcessEnvironment(this.environment,
|
||||
application);
|
||||
StandardEnvironment child = new StandardEnvironment();
|
||||
SystemEnvironmentPropertySourceEnvironmentPostProcessor.postProcessEnvironment(child, this.environment);
|
||||
OriginAwareSystemEnvironmentPropertySource replaced = (OriginAwareSystemEnvironmentPropertySource) child
|
||||
.getPropertySources()
|
||||
.get("systemEnvironment");
|
||||
assertThat(replaced.getPrefix()).isEqualTo("my");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user