Commit a1284bce authored by Phillip Webb's avatar Phillip Webb

Configure ChildManagementContext container type

Ensure any ChildManagementContext created to start a management server
on a different port uses the same EmbeddedServletContainerFactory type.

Fixes gh-5474
parent d7e56abd
...@@ -30,11 +30,14 @@ import org.apache.commons.logging.LogFactory; ...@@ -30,11 +30,14 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext; import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
...@@ -55,6 +58,7 @@ import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfigurat ...@@ -55,6 +58,7 @@ import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfigurat
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
...@@ -104,6 +108,8 @@ public class EndpointWebMvcAutoConfiguration ...@@ -104,6 +108,8 @@ public class EndpointWebMvcAutoConfiguration
private static final Log logger = LogFactory private static final Log logger = LogFactory
.getLog(EndpointWebMvcAutoConfiguration.class); .getLog(EndpointWebMvcAutoConfiguration.class);
private static final ConfigurableListableBeanFactory BeanDefinitionRegistry = null;
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private BeanFactory beanFactory; private BeanFactory beanFactory;
...@@ -164,7 +170,7 @@ public class EndpointWebMvcAutoConfiguration ...@@ -164,7 +170,7 @@ public class EndpointWebMvcAutoConfiguration
} }
private void createChildManagementContext() { private void createChildManagementContext() {
final AnnotationConfigEmbeddedWebApplicationContext childContext = new AnnotationConfigEmbeddedWebApplicationContext(); AnnotationConfigEmbeddedWebApplicationContext childContext = new AnnotationConfigEmbeddedWebApplicationContext();
childContext.setParent(this.applicationContext); childContext.setParent(this.applicationContext);
childContext.setNamespace("management"); childContext.setNamespace("management");
childContext.setId(this.applicationContext.getId() + ":management"); childContext.setId(this.applicationContext.getId() + ":management");
...@@ -172,12 +178,30 @@ public class EndpointWebMvcAutoConfiguration ...@@ -172,12 +178,30 @@ public class EndpointWebMvcAutoConfiguration
PropertyPlaceholderAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
EmbeddedServletContainerAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class,
DispatcherServletAutoConfiguration.class); DispatcherServletAutoConfiguration.class);
registerEmbeddedServletContainerFactory(childContext);
CloseEventPropagationListener.addIfPossible(this.applicationContext, CloseEventPropagationListener.addIfPossible(this.applicationContext,
childContext); childContext);
childContext.refresh(); childContext.refresh();
managementContextResolver().setApplicationContext(childContext); managementContextResolver().setApplicationContext(childContext);
} }
private void registerEmbeddedServletContainerFactory(
AnnotationConfigEmbeddedWebApplicationContext childContext) {
try {
EmbeddedServletContainerFactory servletContainerFactory = this.applicationContext
.getBean(EmbeddedServletContainerFactory.class);
ConfigurableListableBeanFactory beanFactory = childContext.getBeanFactory();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
registry.registerBeanDefinition("embeddedServletContainerFactory",
new RootBeanDefinition(servletContainerFactory.getClass()));
}
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore and assume auto-configuration
}
}
/** /**
* Add an alias for 'local.management.port' that actually resolves using * Add an alias for 'local.management.port' that actually resolves using
* 'local.server.port'. * 'local.server.port'.
......
...@@ -58,7 +58,9 @@ import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebAppl ...@@ -58,7 +58,9 @@ import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebAppl
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainer; import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerException; import org.springframework.boot.context.embedded.EmbeddedServletContainerException;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent; import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer; import org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
...@@ -85,6 +87,7 @@ import static org.hamcrest.Matchers.instanceOf; ...@@ -85,6 +87,7 @@ import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.Matchers.startsWith; import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
...@@ -177,6 +180,35 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -177,6 +180,35 @@ public class EndpointWebMvcAutoConfigurationTests {
assertAllClosed(); assertAllClosed();
} }
@Test
public void onDifferentPortWithSpecificContainer() throws Exception {
this.applicationContext.register(SpecificContainerConfig.class, RootConfig.class,
DifferentPortConfig.class, EndpointConfig.class, BaseConfiguration.class,
EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class);
this.applicationContext.refresh();
assertContent("/controller", ports.get().server, "controlleroutput");
assertContent("/endpoint", ports.get().server, null);
assertContent("/controller", ports.get().management, null);
assertContent("/endpoint", ports.get().management, "endpointoutput");
assertContent("/error", ports.get().management, startsWith("{"));
ApplicationContext managementContext = this.applicationContext
.getBean(ManagementContextResolver.class).getApplicationContext();
List<?> interceptors = (List<?>) ReflectionTestUtils.getField(
managementContext.getBean(EndpointHandlerMapping.class), "interceptors");
assertEquals(1, interceptors.size());
EmbeddedServletContainerFactory parentContainerFactory = this.applicationContext
.getBean(EmbeddedServletContainerFactory.class);
EmbeddedServletContainerFactory managementContainerFactory = managementContext
.getBean(EmbeddedServletContainerFactory.class);
assertThat(parentContainerFactory,
instanceOf(SpecificEmbeddedServletContainerFactory.class));
assertThat(managementContainerFactory,
instanceOf(SpecificEmbeddedServletContainerFactory.class));
assertThat(managementContainerFactory, not(sameInstance(parentContainerFactory)));
this.applicationContext.close();
assertAllClosed();
}
@Test @Test
public void onDifferentPortAndContext() throws Exception { public void onDifferentPortAndContext() throws Exception {
this.applicationContext.register(RootConfig.class, EndpointConfig.class, this.applicationContext.register(RootConfig.class, EndpointConfig.class,
...@@ -611,6 +643,16 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -611,6 +643,16 @@ public class EndpointWebMvcAutoConfigurationTests {
} }
@Configuration
public static class SpecificContainerConfig {
@Bean
public SpecificEmbeddedServletContainerFactory embeddedServletContainerFactory() {
return new SpecificEmbeddedServletContainerFactory();
}
}
@Configuration @Configuration
@Import(ServerPortConfig.class) @Import(ServerPortConfig.class)
public static class DifferentPortConfig { public static class DifferentPortConfig {
...@@ -638,6 +680,7 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -638,6 +680,7 @@ public class EndpointWebMvcAutoConfigurationTests {
} }
protected static class TestInterceptor extends HandlerInterceptorAdapter { protected static class TestInterceptor extends HandlerInterceptorAdapter {
private int count = 0; private int count = 0;
@Override @Override
...@@ -650,6 +693,7 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -650,6 +693,7 @@ public class EndpointWebMvcAutoConfigurationTests {
public int getCount() { public int getCount() {
return this.count; return this.count;
} }
} }
} }
...@@ -730,4 +774,9 @@ public class EndpointWebMvcAutoConfigurationTests { ...@@ -730,4 +774,9 @@ public class EndpointWebMvcAutoConfigurationTests {
} }
private static class SpecificEmbeddedServletContainerFactory
extends TomcatEmbeddedServletContainerFactory {
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment