Merge branch '1.3.x'
This commit is contained in:
		
						commit
						ae249f7568
					
				| 
						 | 
					@ -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
 | 
				
			||||||
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
 | 
				
			||||||
	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
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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
 | 
				
			||||||
				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'.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2012-2015 the original author or authors.
 | 
					 * Copyright 2012-2016 the original author or authors.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,7 @@ import org.springframework.messaging.MessageChannel;
 | 
				
			||||||
public class MetricsChannelAutoConfiguration {
 | 
					public class MetricsChannelAutoConfiguration {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Bean
 | 
						@Bean
 | 
				
			||||||
 | 
						@ExportMetricWriter
 | 
				
			||||||
	@ConditionalOnMissingBean
 | 
						@ConditionalOnMissingBean
 | 
				
			||||||
	public MessageChannelMetricWriter messageChannelMetricWriter(
 | 
						public MessageChannelMetricWriter messageChannelMetricWriter(
 | 
				
			||||||
			@Qualifier("metricsChannel") MessageChannel channel) {
 | 
								@Qualifier("metricsChannel") MessageChannel channel) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.util.EnvironmentTestUtils;
 | 
					import org.springframework.boot.test.util.EnvironmentTestUtils;
 | 
				
			||||||
import org.springframework.boot.testutil.Matched;
 | 
					import org.springframework.boot.testutil.Matched;
 | 
				
			||||||
| 
						 | 
					@ -176,6 +178,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");
 | 
				
			||||||
 | 
							assertThat(interceptors).hasSize(1);
 | 
				
			||||||
 | 
							EmbeddedServletContainerFactory parentContainerFactory = this.applicationContext
 | 
				
			||||||
 | 
									.getBean(EmbeddedServletContainerFactory.class);
 | 
				
			||||||
 | 
							EmbeddedServletContainerFactory managementContainerFactory = managementContext
 | 
				
			||||||
 | 
									.getBean(EmbeddedServletContainerFactory.class);
 | 
				
			||||||
 | 
							assertThat(parentContainerFactory)
 | 
				
			||||||
 | 
									.isInstanceOf(SpecificEmbeddedServletContainerFactory.class);
 | 
				
			||||||
 | 
							assertThat(managementContainerFactory)
 | 
				
			||||||
 | 
									.isInstanceOf(SpecificEmbeddedServletContainerFactory.class);
 | 
				
			||||||
 | 
							assertThat(managementContainerFactory).isNotSameAs(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,
 | 
				
			||||||
| 
						 | 
					@ -609,6 +640,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 {
 | 
				
			||||||
| 
						 | 
					@ -636,6 +677,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
 | 
				
			||||||
| 
						 | 
					@ -648,6 +690,7 @@ public class EndpointWebMvcAutoConfigurationTests {
 | 
				
			||||||
			public int getCount() {
 | 
								public int getCount() {
 | 
				
			||||||
				return this.count;
 | 
									return this.count;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -728,4 +771,9 @@ public class EndpointWebMvcAutoConfigurationTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class SpecificEmbeddedServletContainerFactory
 | 
				
			||||||
 | 
								extends TomcatEmbeddedServletContainerFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,6 +75,7 @@ public class MetricExportAutoConfigurationTests {
 | 
				
			||||||
				PropertyPlaceholderAutoConfiguration.class);
 | 
									PropertyPlaceholderAutoConfiguration.class);
 | 
				
			||||||
		MetricExporters exporter = this.context.getBean(MetricExporters.class);
 | 
							MetricExporters exporter = this.context.getBean(MetricExporters.class);
 | 
				
			||||||
		assertThat(exporter).isNotNull();
 | 
							assertThat(exporter).isNotNull();
 | 
				
			||||||
 | 
							assertThat(exporter.getExporters()).containsKey("messageChannelMetricWriter");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Test
 | 
						@Test
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -961,14 +961,30 @@ public class ServerProperties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void customizeUndertow(ServerProperties serverProperties,
 | 
							void customizeUndertow(ServerProperties serverProperties,
 | 
				
			||||||
				UndertowEmbeddedServletContainerFactory factory) {
 | 
									UndertowEmbeddedServletContainerFactory factory) {
 | 
				
			||||||
			factory.setBufferSize(this.bufferSize);
 | 
								if (this.bufferSize != null) {
 | 
				
			||||||
			factory.setBuffersPerRegion(this.buffersPerRegion);
 | 
									factory.setBufferSize(this.bufferSize);
 | 
				
			||||||
			factory.setIoThreads(this.ioThreads);
 | 
								}
 | 
				
			||||||
			factory.setWorkerThreads(this.workerThreads);
 | 
								if (this.buffersPerRegion != null) {
 | 
				
			||||||
			factory.setDirectBuffers(this.directBuffers);
 | 
									factory.setBuffersPerRegion(this.buffersPerRegion);
 | 
				
			||||||
			factory.setAccessLogDirectory(this.accesslog.dir);
 | 
								}
 | 
				
			||||||
			factory.setAccessLogPattern(this.accesslog.pattern);
 | 
								if (this.ioThreads != null) {
 | 
				
			||||||
			factory.setAccessLogEnabled(this.accesslog.enabled);
 | 
									factory.setIoThreads(this.ioThreads);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.workerThreads != null) {
 | 
				
			||||||
 | 
									factory.setWorkerThreads(this.workerThreads);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.directBuffers != null) {
 | 
				
			||||||
 | 
									factory.setDirectBuffers(this.directBuffers);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.accesslog.dir != null) {
 | 
				
			||||||
 | 
									factory.setAccessLogDirectory(this.accesslog.dir);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.accesslog.pattern != null) {
 | 
				
			||||||
 | 
									factory.setAccessLogPattern(this.accesslog.pattern);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this.accesslog.enabled != null) {
 | 
				
			||||||
 | 
									factory.setAccessLogEnabled(this.accesslog.enabled);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			factory.setUseForwardHeaders(serverProperties.getOrDeduceUseForwardHeaders());
 | 
								factory.setUseForwardHeaders(serverProperties.getOrDeduceUseForwardHeaders());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -977,7 +993,7 @@ public class ServerProperties
 | 
				
			||||||
			/**
 | 
								/**
 | 
				
			||||||
			 * Enable access log.
 | 
								 * Enable access log.
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			private boolean enabled = false;
 | 
								private Boolean enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/**
 | 
								/**
 | 
				
			||||||
			 * Format pattern for access logs.
 | 
								 * Format pattern for access logs.
 | 
				
			||||||
| 
						 | 
					@ -989,11 +1005,11 @@ public class ServerProperties
 | 
				
			||||||
			 */
 | 
								 */
 | 
				
			||||||
			private File dir = new File("logs");
 | 
								private File dir = new File("logs");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			public boolean isEnabled() {
 | 
								public Boolean getEnabled() {
 | 
				
			||||||
				return this.enabled;
 | 
									return this.enabled;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			public void setEnabled(boolean enabled) {
 | 
								public void setEnabled(Boolean enabled) {
 | 
				
			||||||
				this.enabled = enabled;
 | 
									this.enabled = enabled;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ import org.springframework.mock.env.MockEnvironment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
					import static org.assertj.core.api.Assertions.assertThat;
 | 
				
			||||||
import static org.mockito.BDDMockito.given;
 | 
					import static org.mockito.BDDMockito.given;
 | 
				
			||||||
 | 
					import static org.mockito.Matchers.anyBoolean;
 | 
				
			||||||
import static org.mockito.Mockito.atLeastOnce;
 | 
					import static org.mockito.Mockito.atLeastOnce;
 | 
				
			||||||
import static org.mockito.Mockito.mock;
 | 
					import static org.mockito.Mockito.mock;
 | 
				
			||||||
import static org.mockito.Mockito.never;
 | 
					import static org.mockito.Mockito.never;
 | 
				
			||||||
| 
						 | 
					@ -418,6 +419,14 @@ public class ServerPropertiesTests {
 | 
				
			||||||
		verify(container).setSessionStoreDir(new File("myfolder"));
 | 
							verify(container).setSessionStoreDir(new File("myfolder"));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test
 | 
				
			||||||
 | 
						public void skipNullElementsForUndertow() throws Exception {
 | 
				
			||||||
 | 
							UndertowEmbeddedServletContainerFactory container = mock(
 | 
				
			||||||
 | 
									UndertowEmbeddedServletContainerFactory.class);
 | 
				
			||||||
 | 
							this.properties.customize(container);
 | 
				
			||||||
 | 
							verify(container, never()).setAccessLogEnabled(anyBoolean());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void bindProperties(Map<String, String> map) {
 | 
						private void bindProperties(Map<String, String> map) {
 | 
				
			||||||
		new RelaxedDataBinder(this.properties, "server")
 | 
							new RelaxedDataBinder(this.properties, "server")
 | 
				
			||||||
				.bind(new MutablePropertyValues(map));
 | 
									.bind(new MutablePropertyValues(map));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,80 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-2016 the original author or authors.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package org.springframework.boot.context.embedded.jetty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.servlet.ServletContext;
 | 
				
			||||||
 | 
					import javax.servlet.http.HttpServletRequest;
 | 
				
			||||||
 | 
					import javax.servlet.http.HttpServletRequestWrapper;
 | 
				
			||||||
 | 
					import javax.servlet.http.HttpServletResponse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.eclipse.jetty.http.HttpMethod;
 | 
				
			||||||
 | 
					import org.eclipse.jetty.server.Request;
 | 
				
			||||||
 | 
					import org.eclipse.jetty.server.handler.ErrorHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Variation of Jetty's {@link ErrorHandler} that supports all {@link HttpMethod
 | 
				
			||||||
 | 
					 * HttpMethods} rather than just {@code GET}, {@code POST} and {@code HEAD}. Jetty
 | 
				
			||||||
 | 
					 * <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=446039">intentionally only
 | 
				
			||||||
 | 
					 * supports a limited set of HTTP methods</a> for error pages, however, Spring Boot
 | 
				
			||||||
 | 
					 * prefers Tomcat, Jetty and Undertow to all behave in the same way.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Phillip Webb
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class JettyEmbeddedErrorHandler extends ErrorHandler {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private final ErrorHandler delegate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						JettyEmbeddedErrorHandler(ErrorHandler delegate) {
 | 
				
			||||||
 | 
							this.delegate = delegate;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public void handle(String target, Request baseRequest, HttpServletRequest request,
 | 
				
			||||||
 | 
								HttpServletResponse response) throws IOException {
 | 
				
			||||||
 | 
							String method = request.getMethod();
 | 
				
			||||||
 | 
							if (!HttpMethod.GET.is(method) && !HttpMethod.POST.is(method)
 | 
				
			||||||
 | 
									&& !HttpMethod.HEAD.is(method)) {
 | 
				
			||||||
 | 
								request = new ErrorHttpServletRequest(request);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							this.delegate.handle(target, baseRequest, request, response);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static class ErrorHttpServletRequest extends HttpServletRequestWrapper {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private boolean simulateGetMethod = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ErrorHttpServletRequest(HttpServletRequest request) {
 | 
				
			||||||
 | 
								super(request);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public String getMethod() {
 | 
				
			||||||
 | 
								return (this.simulateGetMethod ? HttpMethod.GET.toString()
 | 
				
			||||||
 | 
										: super.getMethod());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Override
 | 
				
			||||||
 | 
							public ServletContext getServletContext() {
 | 
				
			||||||
 | 
								this.simulateGetMethod = false;
 | 
				
			||||||
 | 
								return super.getServletContext();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -410,11 +410,14 @@ public class JettyEmbeddedServletContainerFactory
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private Configuration getErrorPageConfiguration() {
 | 
						private Configuration getErrorPageConfiguration() {
 | 
				
			||||||
		return new AbstractConfiguration() {
 | 
							return new AbstractConfiguration() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			@Override
 | 
								@Override
 | 
				
			||||||
			public void configure(WebAppContext context) throws Exception {
 | 
								public void configure(WebAppContext context) throws Exception {
 | 
				
			||||||
				ErrorHandler errorHandler = context.getErrorHandler();
 | 
									ErrorHandler errorHandler = context.getErrorHandler();
 | 
				
			||||||
 | 
									context.setErrorHandler(new JettyEmbeddedErrorHandler(errorHandler));
 | 
				
			||||||
				addJettyErrorPages(errorHandler, getErrorPages());
 | 
									addJettyErrorPages(errorHandler, getErrorPages());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -424,6 +427,7 @@ public class JettyEmbeddedServletContainerFactory
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private Configuration getMimeTypeConfiguration() {
 | 
						private Configuration getMimeTypeConfiguration() {
 | 
				
			||||||
		return new AbstractConfiguration() {
 | 
							return new AbstractConfiguration() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			@Override
 | 
								@Override
 | 
				
			||||||
			public void configure(WebAppContext context) throws Exception {
 | 
								public void configure(WebAppContext context) throws Exception {
 | 
				
			||||||
				MimeTypes mimeTypes = context.getMimeTypes();
 | 
									MimeTypes mimeTypes = context.getMimeTypes();
 | 
				
			||||||
| 
						 | 
					@ -432,6 +436,7 @@ public class JettyEmbeddedServletContainerFactory
 | 
				
			||||||
							mapping.getMimeType());
 | 
												mapping.getMimeType());
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,6 +334,19 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
 | 
				
			||||||
		assertThat(getResponse(getLocalUrl("/bang"))).isEqualTo("Hello World");
 | 
							assertThat(getResponse(getLocalUrl("/bang"))).isEqualTo("Hello World");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test
 | 
				
			||||||
 | 
						public void errorPageFromPutRequest() throws Exception {
 | 
				
			||||||
 | 
							AbstractEmbeddedServletContainerFactory factory = getFactory();
 | 
				
			||||||
 | 
							factory.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/hello"));
 | 
				
			||||||
 | 
							this.container = factory.getEmbeddedServletContainer(exampleServletRegistration(),
 | 
				
			||||||
 | 
									errorServletRegistration());
 | 
				
			||||||
 | 
							this.container.start();
 | 
				
			||||||
 | 
							assertThat(getResponse(getLocalUrl("/hello"), HttpMethod.PUT),
 | 
				
			||||||
 | 
									equalTo("Hello World"));
 | 
				
			||||||
 | 
							assertThat(getResponse(getLocalUrl("/bang"), HttpMethod.PUT),
 | 
				
			||||||
 | 
									equalTo("Hello World"));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Test
 | 
						@Test
 | 
				
			||||||
	public void basicSslFromClassPath() throws Exception {
 | 
						public void basicSslFromClassPath() throws Exception {
 | 
				
			||||||
		testBasicSslWithKeyStore("classpath:test.jks");
 | 
							testBasicSslWithKeyStore("classpath:test.jks");
 | 
				
			||||||
| 
						 | 
					@ -869,7 +882,12 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected String getResponse(String url, String... headers)
 | 
						protected String getResponse(String url, String... headers)
 | 
				
			||||||
			throws IOException, URISyntaxException {
 | 
								throws IOException, URISyntaxException {
 | 
				
			||||||
		ClientHttpResponse response = getClientResponse(url, headers);
 | 
							return getResponse(url, HttpMethod.GET, headers);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected String getResponse(String url, HttpMethod method, String... headers)
 | 
				
			||||||
 | 
								throws IOException, URISyntaxException {
 | 
				
			||||||
 | 
							ClientHttpResponse response = getClientResponse(url, method, headers);
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			return StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"));
 | 
								return StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -881,7 +899,14 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
 | 
				
			||||||
	protected String getResponse(String url,
 | 
						protected String getResponse(String url,
 | 
				
			||||||
			HttpComponentsClientHttpRequestFactory requestFactory, String... headers)
 | 
								HttpComponentsClientHttpRequestFactory requestFactory, String... headers)
 | 
				
			||||||
					throws IOException, URISyntaxException {
 | 
										throws IOException, URISyntaxException {
 | 
				
			||||||
		ClientHttpResponse response = getClientResponse(url, requestFactory, headers);
 | 
							return getResponse(url, HttpMethod.GET, requestFactory, headers);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected String getResponse(String url, HttpMethod method,
 | 
				
			||||||
 | 
								HttpComponentsClientHttpRequestFactory requestFactory, String... headers)
 | 
				
			||||||
 | 
										throws IOException, URISyntaxException {
 | 
				
			||||||
 | 
							ClientHttpResponse response = getClientResponse(url, method, requestFactory,
 | 
				
			||||||
 | 
									headers);
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			return StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"));
 | 
								return StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -892,21 +917,27 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected ClientHttpResponse getClientResponse(String url, String... headers)
 | 
						protected ClientHttpResponse getClientResponse(String url, String... headers)
 | 
				
			||||||
			throws IOException, URISyntaxException {
 | 
								throws IOException, URISyntaxException {
 | 
				
			||||||
		return getClientResponse(url, new HttpComponentsClientHttpRequestFactory() {
 | 
							return getClientResponse(url, HttpMethod.GET, headers);
 | 
				
			||||||
 | 
					 | 
				
			||||||
			@Override
 | 
					 | 
				
			||||||
			protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
 | 
					 | 
				
			||||||
				return AbstractEmbeddedServletContainerFactoryTests.this.httpClientContext;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		}, headers);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected ClientHttpResponse getClientResponse(String url,
 | 
						protected ClientHttpResponse getClientResponse(String url, HttpMethod method,
 | 
				
			||||||
 | 
								String... headers) throws IOException, URISyntaxException {
 | 
				
			||||||
 | 
							return getClientResponse(url, method,
 | 
				
			||||||
 | 
									new HttpComponentsClientHttpRequestFactory() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										@Override
 | 
				
			||||||
 | 
										protected HttpContext createHttpContext(HttpMethod httpMethod,
 | 
				
			||||||
 | 
												URI uri) {
 | 
				
			||||||
 | 
											return AbstractEmbeddedServletContainerFactoryTests.this.httpClientContext;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									}, headers);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected ClientHttpResponse getClientResponse(String url, HttpMethod method,
 | 
				
			||||||
			HttpComponentsClientHttpRequestFactory requestFactory, String... headers)
 | 
								HttpComponentsClientHttpRequestFactory requestFactory, String... headers)
 | 
				
			||||||
					throws IOException, URISyntaxException {
 | 
										throws IOException, URISyntaxException {
 | 
				
			||||||
		ClientHttpRequest request = requestFactory.createRequest(new URI(url),
 | 
							ClientHttpRequest request = requestFactory.createRequest(new URI(url), method);
 | 
				
			||||||
				HttpMethod.GET);
 | 
					 | 
				
			||||||
		request.getHeaders().add("Cookie", "JSESSIONID=" + "123");
 | 
							request.getHeaders().add("Cookie", "JSESSIONID=" + "123");
 | 
				
			||||||
		for (String header : headers) {
 | 
							for (String header : headers) {
 | 
				
			||||||
			String[] parts = header.split(":");
 | 
								String[] parts = header.split(":");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue