From 3ff772957ba176093072caf16bcccbe3fcae07e8 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 1 Feb 2018 14:47:06 -0800 Subject: [PATCH] Add WebServerApplicationContext abstraction Add a new `WebServerApplicationContext` interface that provides a common abstraction for all application contexts that create and manage the lifecycle of an embedded `WebServer`. Allows server namespaces to become a first-class concept (rather subverting `ConfigurableWebApplicationContext.getNamespace()`) and allow us to drop `getServerId()` from `WebServerInitializedEvent`. Also helps to improve `ManagementContextAutoConfiguration` and `ManagementContextFactory`. Fixes gh-11881 --- .../web/ManagementContextFactory.java | 8 +-- .../ReactiveManagementContextFactory.java | 6 +- .../ManagementContextAutoConfiguration.java | 22 ++---- .../ServletManagementContextFactory.java | 6 +- .../boot/system/ApplicationPidFileWriter.java | 3 +- .../system/EmbeddedServerPortFileWriter.java | 24 +++---- ...nfigurableWebServerApplicationContext.java | 39 +++++++++++ ...PortInfoApplicationContextInitializer.java | 16 +++-- .../context/WebServerApplicationContext.java | 47 +++++++++++++ .../context/WebServerInitializedEvent.java | 16 ++--- ...onConfigReactiveWebApplicationContext.java | 14 +--- ...igurableReactiveWebApplicationContext.java | 8 +-- .../GenericReactiveWebApplicationContext.java | 14 +--- .../ReactiveWebApplicationContext.java | 8 +-- .../ReactiveWebServerApplicationContext.java | 20 +++++- .../ReactiveWebServerInitializedEvent.java | 11 +-- .../ServletWebServerApplicationContext.java | 17 +++-- .../ServletWebServerInitializedEvent.java | 16 +---- .../boot/ApplicationPidTests.java | 3 +- .../EmbeddedServerPortFileWriterTests.java | 67 ++++--------------- .../com/example/DevToolsTestApplication.java | 4 +- .../example/ResourceHandlingApplication.java | 4 +- 22 files changed, 185 insertions(+), 188 deletions(-) create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java create mode 100644 spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java index ec17a98724..416530709c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/ManagementContextFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -16,8 +16,8 @@ package org.springframework.boot.actuate.autoconfigure.web; +import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; /** * Factory for creating a separate management context when the management web server is @@ -35,7 +35,7 @@ public interface ManagementContextFactory { * @param configurationClasses the configuration classes * @return a configured application context */ - ConfigurableApplicationContext createManagementContext(ApplicationContext parent, - Class... configurationClasses); + ConfigurableWebServerApplicationContext createManagementContext( + ApplicationContext parent, Class... configurationClasses); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextFactory.java index 2fa7986003..9725880992 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextFactory.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/reactive/ReactiveManagementContextFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -25,10 +25,10 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerAutoConfiguration; +import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; import org.springframework.util.ObjectUtils; /** @@ -39,7 +39,7 @@ import org.springframework.util.ObjectUtils; class ReactiveManagementContextFactory implements ManagementContextFactory { @Override - public ConfigurableApplicationContext createManagementContext( + public ConfigurableWebServerApplicationContext createManagementContext( ApplicationContext parent, Class... configClasses) { AnnotationConfigReactiveWebServerApplicationContext child = new AnnotationConfigReactiveWebServerApplicationContext(); child.setParent(parent); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java index b08af79f2f..9599c42c64 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/server/ManagementContextAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -25,21 +25,19 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.context.event.ApplicationFailedEvent; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.reactive.context.ConfigurableReactiveWebApplicationContext; +import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.support.AbstractApplicationContext; import org.springframework.core.Ordered; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.util.Assert; -import org.springframework.web.context.ConfigurableWebApplicationContext; /** * {@link EnableAutoConfiguration Auto-configuration} for the management context. If the @@ -131,11 +129,11 @@ public class ManagementContextAutoConfiguration { @Override public void afterSingletonsInstantiated() { - ConfigurableApplicationContext managementContext = this.managementContextFactory + ConfigurableWebServerApplicationContext managementContext = this.managementContextFactory .createManagementContext(this.applicationContext, EnableChildManagementContextConfiguration.class, PropertyPlaceholderAutoConfiguration.class); - setNamespaceIfPossible(managementContext); + managementContext.setServerNamespace("management"); managementContext.setId(this.applicationContext.getId() + ":management"); setClassLoaderIfPossible(managementContext); CloseManagementContextListener.addIfPossible(this.applicationContext, @@ -145,21 +143,11 @@ public class ManagementContextAutoConfiguration { private void setClassLoaderIfPossible(ConfigurableApplicationContext child) { if (child instanceof DefaultResourceLoader) { - ((AbstractApplicationContext) child) + ((DefaultResourceLoader) child) .setClassLoader(this.applicationContext.getClassLoader()); } } - private void setNamespaceIfPossible(ConfigurableApplicationContext child) { - if (child instanceof ConfigurableReactiveWebApplicationContext) { - ((ConfigurableReactiveWebApplicationContext) child) - .setNamespace("management"); - } - else if (child instanceof ConfigurableWebApplicationContext) { - ((ConfigurableWebApplicationContext) child).setNamespace("management"); - } - } - } /** diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextFactory.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextFactory.java index ba79dfa41b..ef237ea21e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextFactory.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/ServletManagementContextFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -28,10 +28,10 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextFactory; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; /** * A {@link ManagementContextFactory} for servlet-based web applications. @@ -41,7 +41,7 @@ import org.springframework.context.ConfigurableApplicationContext; class ServletManagementContextFactory implements ManagementContextFactory { @Override - public ConfigurableApplicationContext createManagementContext( + public ConfigurableWebServerApplicationContext createManagementContext( ApplicationContext parent, Class... configClasses) { AnnotationConfigServletWebServerApplicationContext child = new AnnotationConfigServletWebServerApplicationContext(); child.setParent(parent); diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationPidFileWriter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationPidFileWriter.java index 726a32a06e..667fa15470 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationPidFileWriter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/ApplicationPidFileWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -31,6 +31,7 @@ import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEven import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.SpringApplicationEvent; +import org.springframework.boot.system.SystemProperties; import org.springframework.context.ApplicationListener; import org.springframework.core.Ordered; import org.springframework.core.env.Environment; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/EmbeddedServerPortFileWriter.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/EmbeddedServerPortFileWriter.java index 386e88776e..bd3468d1c1 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/EmbeddedServerPortFileWriter.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/system/EmbeddedServerPortFileWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -21,14 +21,13 @@ import java.io.File; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; import org.springframework.util.StringUtils; -import org.springframework.web.context.ConfigurableWebApplicationContext; /** * An {@link ApplicationListener} that saves embedded server port and management port into @@ -107,18 +106,18 @@ public class EmbeddedServerPortFileWriter * @return the file that should be written */ protected File getPortFile(ApplicationContext applicationContext) { - String contextName = getContextName(applicationContext); - if (StringUtils.isEmpty(contextName)) { + String namespace = getServerNamespace(applicationContext); + if (StringUtils.isEmpty(namespace)) { return this.file; } String name = this.file.getName(); String extension = StringUtils.getFilenameExtension(this.file.getName()); name = name.substring(0, name.length() - extension.length() - 1); if (isUpperCase(name)) { - name = name + "-" + contextName.toUpperCase(); + name = name + "-" + namespace.toUpperCase(); } else { - name = name + "-" + contextName.toLowerCase(); + name = name + "-" + namespace.toLowerCase(); } if (StringUtils.hasLength(extension)) { name = name + "." + extension; @@ -126,13 +125,10 @@ public class EmbeddedServerPortFileWriter return new File(this.file.getParentFile(), name); } - private String getContextName(ApplicationContext applicationContext) { - if (applicationContext instanceof ConfigurableWebApplicationContext) { - return ((ConfigurableWebApplicationContext) applicationContext) - .getNamespace(); - } - if (applicationContext instanceof ReactiveWebApplicationContext) { - return ((ReactiveWebApplicationContext) applicationContext).getNamespace(); + private String getServerNamespace(ApplicationContext applicationContext) { + if (applicationContext instanceof WebServerApplicationContext) { + return ((WebServerApplicationContext) applicationContext) + .getServerNamespace(); } return null; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java new file mode 100644 index 0000000000..3e36850502 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ConfigurableWebServerApplicationContext.java @@ -0,0 +1,39 @@ +/* + * Copyright 2012-2018 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.web.context; + +import org.springframework.context.ConfigurableApplicationContext; + +/** + * SPI interface to be implemented by most if not all {@link WebServerApplicationContext + * web server application contexts}. Provides facilities to configure the context, in + * addition to the methods in the {WebServerApplicationContext} interface. + * + * @author Phillip Webb + * @since 2.0.0 + */ +public interface ConfigurableWebServerApplicationContext + extends ConfigurableApplicationContext, WebServerApplicationContext { + + /** + * Set the server namespace of the context. + * @param serverNamespace the server namespance + * @see #getServerNamespace() + */ + void setServerNamespace(String serverNamespace); + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java index 017af4138b..d139f9feb6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/ServerPortInfoApplicationContextInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -30,6 +30,7 @@ import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; +import org.springframework.util.StringUtils; /** * {@link ApplicationContextInitializer} that sets {@link Environment} properties for the @@ -38,9 +39,9 @@ import org.springframework.core.env.PropertySource; * {@link Value @Value} or obtained via the {@link Environment}. *

* If the {@link WebServerInitializedEvent} has a - * {@link WebServerInitializedEvent#getServerId() server ID}, it will be used to construct - * the property name. For example, the "management" actuator context will have the - * property name {@literal "local.management.port"}. + * {@link WebServerApplicationContext#getServerNamespace() server namespace} , it will be + * used to construct the property name. For example, the "management" actuator context + * will have the property name {@literal "local.management.port"}. *

* Properties are automatically propagated up to any parent context. * @@ -59,11 +60,16 @@ public class ServerPortInfoApplicationContextInitializer @Override public void onApplicationEvent(WebServerInitializedEvent event) { - String propertyName = "local." + event.getServerId() + ".port"; + String propertyName = "local." + getName(event.getApplicationContext()) + ".port"; setPortProperty(event.getApplicationContext(), propertyName, event.getWebServer().getPort()); } + private String getName(WebServerApplicationContext context) { + String name = context.getServerNamespace(); + return (StringUtils.hasText(name) ? name : "server"); + } + private void setPortProperty(ApplicationContext context, String propertyName, int port) { if (context instanceof ConfigurableApplicationContext) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java new file mode 100644 index 0000000000..f72067cbf3 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerApplicationContext.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2018 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.web.context; + +import org.springframework.boot.web.server.WebServer; +import org.springframework.context.ApplicationContext; + +/** + * Interface to be implemented by {@link ApplicationContext application contexts} that + * create and manage the lifecyle of an embedded {@link WebServer}. + * + * @author Phillip Webb + * @since 2.0.0 + */ +public interface WebServerApplicationContext extends ApplicationContext { + + /** + * Returns the {@link WebServer} that was created by the context or {@code null} if + * the server has not yet been created. + * @return the web server + */ + WebServer getWebServer(); + + /** + * Returns the namespace of the web server application context or {@code null} if no + * namepace has been set. Used for disambiguation when multiple web servers are + * running in the same application (for example a management context running on a + * different port). + * @return the server namespace + */ + String getServerNamespace(); + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java index 45fcfd6b5d..8b7fde79a4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/context/WebServerInitializedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -17,7 +17,6 @@ package org.springframework.boot.web.context; import org.springframework.boot.web.server.WebServer; -import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEvent; /** @@ -31,8 +30,8 @@ import org.springframework.context.ApplicationEvent; @SuppressWarnings("serial") public abstract class WebServerInitializedEvent extends ApplicationEvent { - protected WebServerInitializedEvent(WebServer source) { - super(source); + protected WebServerInitializedEvent(WebServer webServer) { + super(webServer); } /** @@ -49,7 +48,7 @@ public abstract class WebServerInitializedEvent extends ApplicationEvent { * context) before acting on the server itself. * @return the applicationContext that the server was created from */ - public abstract ApplicationContext getApplicationContext(); + public abstract WebServerApplicationContext getApplicationContext(); /** * Access the source of the event (an {@link WebServer}). @@ -60,11 +59,4 @@ public abstract class WebServerInitializedEvent extends ApplicationEvent { return (WebServer) super.getSource(); } - /** - * Access the {@link WebServer} Id used internally to differentiate application / - * management servers. - * @return the server internal Id - */ - public abstract String getServerId(); - } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java index 09f37b8aa6..e0c2927ebf 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/AnnotationConfigReactiveWebApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -65,8 +65,6 @@ public class AnnotationConfigReactiveWebApplicationContext private final Set basePackages = new LinkedHashSet<>(); - private String namespace; - @Override protected ConfigurableEnvironment createEnvironment() { return new StandardReactiveWebEnvironment(); @@ -326,14 +324,4 @@ public class AnnotationConfigReactiveWebApplicationContext return new FilteredReactiveWebContextResource(path); } - @Override - public void setNamespace(String namespace) { - this.namespace = namespace; - } - - @Override - public String getNamespace() { - return this.namespace; - } - } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java index 09ee1f1f9e..d811068caf 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ConfigurableReactiveWebApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -27,10 +27,4 @@ import org.springframework.context.ConfigurableApplicationContext; public interface ConfigurableReactiveWebApplicationContext extends ConfigurableApplicationContext, ReactiveWebApplicationContext { - /** - * Set the namespace for this reactive web application context. - * @param namespace the namespace for the context - */ - void setNamespace(String namespace); - } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java index 4a8ece8e6b..ce01343ade 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/GenericReactiveWebApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -31,8 +31,6 @@ import org.springframework.core.io.Resource; public class GenericReactiveWebApplicationContext extends GenericApplicationContext implements ConfigurableReactiveWebApplicationContext { - private String namespace; - /** * Create a new {@link GenericReactiveWebApplicationContext}. * @see #registerBeanDefinition @@ -57,16 +55,6 @@ public class GenericReactiveWebApplicationContext extends GenericApplicationCont return new StandardReactiveWebEnvironment(); } - @Override - public void setNamespace(String namespace) { - this.namespace = namespace; - } - - @Override - public String getNamespace() { - return this.namespace; - } - @Override protected Resource getResourceByPath(String path) { // We must be careful not to expose classpath resources diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java index 703bc469cb..04b793b06f 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -26,10 +26,4 @@ import org.springframework.context.ApplicationContext; */ public interface ReactiveWebApplicationContext extends ApplicationContext { - /** - * Return the namespace for this reactive web application context, if any. - * @return the namespace or {@code null} - */ - String getNamespace(); - } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java index 390390f117..6b026fcdc0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -18,6 +18,7 @@ package org.springframework.boot.web.reactive.context; import org.springframework.beans.BeansException; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; import org.springframework.boot.web.server.WebServer; import org.springframework.context.ApplicationContextException; @@ -32,10 +33,13 @@ import org.springframework.util.StringUtils; * @since 2.0.0 */ public class ReactiveWebServerApplicationContext - extends GenericReactiveWebApplicationContext { + extends GenericReactiveWebApplicationContext + implements ConfigurableWebServerApplicationContext { private volatile WebServer webServer; + private String serverNamespace; + /** * Create a new {@link ReactiveWebServerApplicationContext}. */ @@ -102,6 +106,7 @@ public class ReactiveWebServerApplicationContext * the server has not yet been created. * @return the web server */ + @Override public WebServer getWebServer() { return this.webServer; } @@ -170,4 +175,15 @@ public class ReactiveWebServerApplicationContext } } } + + @Override + public String getServerNamespace() { + return this.serverNamespace; + } + + @Override + public void setServerNamespace(String serverNamespace) { + this.serverNamespace = serverNamespace; + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java index c126e28fbc..22ee86a781 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/context/ReactiveWebServerInitializedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -32,9 +32,9 @@ public class ReactiveWebServerInitializedEvent extends WebServerInitializedEvent private final ReactiveWebServerApplicationContext applicationContext; - public ReactiveWebServerInitializedEvent(WebServer source, + public ReactiveWebServerInitializedEvent(WebServer webServer, ReactiveWebServerApplicationContext applicationContext) { - super(source); + super(webServer); this.applicationContext = applicationContext; } @@ -43,9 +43,4 @@ public class ReactiveWebServerInitializedEvent extends WebServerInitializedEvent return this.applicationContext; } - @Override - public String getServerId() { - return "server"; - } - } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java index d5724f8931..4284ab47b5 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -37,6 +37,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.Scope; import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; import org.springframework.boot.web.server.WebServer; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletContextInitializer; @@ -87,7 +88,8 @@ import org.springframework.web.context.support.WebApplicationContextUtils; * @see XmlServletWebServerApplicationContext * @see ServletWebServerFactory */ -public class ServletWebServerApplicationContext extends GenericWebApplicationContext { +public class ServletWebServerApplicationContext extends GenericWebApplicationContext + implements ConfigurableWebServerApplicationContext { private static final Log logger = LogFactory .getLog(ServletWebServerApplicationContext.class); @@ -104,7 +106,7 @@ public class ServletWebServerApplicationContext extends GenericWebApplicationCon private ServletConfig servletConfig; - private String namespace; + private String serverNamespace; /** * Create a new {@link ServletWebServerApplicationContext}. @@ -322,13 +324,13 @@ public class ServletWebServerApplicationContext extends GenericWebApplicationCon } @Override - public void setNamespace(String namespace) { - this.namespace = namespace; + public String getServerNamespace() { + return this.serverNamespace; } @Override - public String getNamespace() { - return this.namespace; + public void setServerNamespace(String serverNamespace) { + this.serverNamespace = serverNamespace; } @Override @@ -346,6 +348,7 @@ public class ServletWebServerApplicationContext extends GenericWebApplicationCon * the server has not yet been created. * @return the embedded web server */ + @Override public WebServer getWebServer() { return this.webServer; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java index f7cb4a88e2..0c5f65b1d4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/context/ServletWebServerInitializedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -18,7 +18,6 @@ package org.springframework.boot.web.servlet.context; import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.boot.web.server.WebServer; -import org.springframework.util.StringUtils; /** * Event to be published after the {@link ServletWebServerApplicationContext} is refreshed @@ -36,9 +35,9 @@ public class ServletWebServerInitializedEvent extends WebServerInitializedEvent private final ServletWebServerApplicationContext applicationContext; - public ServletWebServerInitializedEvent(WebServer source, + public ServletWebServerInitializedEvent(WebServer webServer, ServletWebServerApplicationContext applicationContext) { - super(source); + super(webServer); this.applicationContext = applicationContext; } @@ -53,13 +52,4 @@ public class ServletWebServerInitializedEvent extends WebServerInitializedEvent return this.applicationContext; } - @Override - public String getServerId() { - String name = this.applicationContext.getNamespace(); - if (StringUtils.isEmpty(name)) { - name = "server"; - } - return name; - } - } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ApplicationPidTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ApplicationPidTests.java index a428d363df..f8243935a1 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ApplicationPidTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/ApplicationPidTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -24,6 +24,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; +import org.springframework.boot.ApplicationPid; import org.springframework.util.FileCopyUtils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/system/EmbeddedServerPortFileWriterTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/system/EmbeddedServerPortFileWriterTests.java index d9b818ee52..f25eda2571 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/system/EmbeddedServerPortFileWriterTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/system/EmbeddedServerPortFileWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -19,26 +19,17 @@ package org.springframework.boot.system; import java.io.File; import java.io.FileReader; import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Set; -import java.util.function.BiFunction; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; +import org.springframework.boot.web.context.WebServerApplicationContext; import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext; -import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent; import org.springframework.boot.web.server.WebServer; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent; import org.springframework.util.FileCopyUtils; import org.springframework.util.StringUtils; @@ -53,52 +44,11 @@ import static org.mockito.Mockito.mock; * @author Phillip Webb * @author Andy Wilkinson */ -@RunWith(Parameterized.class) public class EmbeddedServerPortFileWriterTests { @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); - @Parameters(name = "{0}") - public static Object[] parameters() { - Map> parameters = new LinkedHashMap<>(); - parameters.put("Servlet", - EmbeddedServerPortFileWriterTests::servletEventParameter); - parameters.put("Reactive", - EmbeddedServerPortFileWriterTests::reactiveEventParameter); - return parameters.entrySet().stream() - .map((e) -> new Object[] { e.getKey(), e.getValue() }).toArray(); - } - - private static WebServerInitializedEvent servletEventParameter(String name, - Integer port) { - ServletWebServerApplicationContext applicationContext = mock( - ServletWebServerApplicationContext.class); - given(applicationContext.getNamespace()).willReturn(name); - WebServer source = mock(WebServer.class); - given(source.getPort()).willReturn(port); - ServletWebServerInitializedEvent event = new ServletWebServerInitializedEvent( - source, applicationContext); - return event; - } - - private static WebServerInitializedEvent reactiveEventParameter(String name, - Integer port) { - ReactiveWebServerApplicationContext applicationContext = mock( - ReactiveWebServerApplicationContext.class); - given(applicationContext.getNamespace()).willReturn(name); - WebServer source = mock(WebServer.class); - given(source.getPort()).willReturn(port); - return new ReactiveWebServerInitializedEvent(source, applicationContext); - } - - private final BiFunction eventFactory; - - public EmbeddedServerPortFileWriterTests(String name, - BiFunction eventFactory) { - this.eventFactory = eventFactory; - } - @Before @After public void reset() { @@ -167,8 +117,17 @@ public class EmbeddedServerPortFileWriterTests { assertThat(collectFileNames(file.getParentFile())).contains(managementFile); } - private WebServerInitializedEvent mockEvent(String name, int port) { - return this.eventFactory.apply(name, port); + private WebServerInitializedEvent mockEvent(String namespace, int port) { + WebServer webServer = mock(WebServer.class); + given(webServer.getPort()).willReturn(port); + WebServerApplicationContext applicationContext = mock( + WebServerApplicationContext.class); + given(applicationContext.getServerNamespace()).willReturn(namespace); + given(applicationContext.getWebServer()).willReturn(webServer); + WebServerInitializedEvent event = mock(WebServerInitializedEvent.class); + given(event.getApplicationContext()).willReturn(applicationContext); + given(event.getWebServer()).willReturn(webServer); + return event; } private Set collectFileNames(File directory) { diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/com/example/DevToolsTestApplication.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/com/example/DevToolsTestApplication.java index 812b7cb8fa..dc29f1f9b3 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/com/example/DevToolsTestApplication.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/com/example/DevToolsTestApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -18,7 +18,7 @@ package com.example; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.system.EmbeddedServerPortFileWriter; +import org.springframework.boot.web.context.EmbeddedServerPortFileWriter; @SpringBootApplication public class DevToolsTestApplication { diff --git a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/com/example/ResourceHandlingApplication.java b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/com/example/ResourceHandlingApplication.java index 7ee6783e6e..31b64317e2 100644 --- a/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/com/example/ResourceHandlingApplication.java +++ b/spring-boot-tests/spring-boot-integration-tests/spring-boot-server-tests/src/test/java/com/example/ResourceHandlingApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.system.EmbeddedServerPortFileWriter; +import org.springframework.boot.web.context.EmbeddedServerPortFileWriter; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean;