Ensure that customizers registered multiple times are only called once

Closes gh-17264
pull/17563/head
Andy Wilkinson 5 years ago
parent 62233a0750
commit ea1139755d

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.web.reactive;
import io.undertow.Undertow.Builder;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
@ -222,6 +223,21 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
});
}
@Test
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class))
.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class,
HttpHandlerConfiguration.class)
.withPropertyValues("server.port=0").run((context) -> {
JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class);
JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class);
assertThat(factory.getServerCustomizers()).contains(customizer);
verify(customizer, times(1)).customize(any(Server.class));
});
}
@Test
void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() {
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new)
@ -247,6 +263,22 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
});
}
@Test
void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class))
.withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class,
HttpHandlerConfiguration.class)
.withPropertyValues("server.port: 0").run((context) -> {
UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class);
UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer",
UndertowBuilderCustomizer.class);
assertThat(factory.getBuilderCustomizers()).contains(customizer);
verify(customizer, times(1)).customize(any(Builder.class));
});
}
@Test
void forwardedHeaderTransformerShouldBeConfigured() {
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
@ -401,6 +433,23 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class DoubleRegistrationJettyServerCustomizerConfiguration {
private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class);
@Bean
JettyServerCustomizer serverCustomizer() {
return this.customizer;
}
@Bean
WebServerFactoryCustomizer<JettyReactiveWebServerFactory> jettyCustomizer() {
return (jetty) -> jetty.addServerCustomizers(this.customizer);
}
}
@Configuration(proxyBeanMethods = false)
static class UndertowBuilderCustomizerConfiguration {
@ -412,6 +461,23 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class DoubleRegistrationUndertowBuilderCustomizerConfiguration {
private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class);
@Bean
UndertowBuilderCustomizer builderCustomizer() {
return this.customizer;
}
@Bean
WebServerFactoryCustomizer<UndertowReactiveWebServerFactory> undertowCustomizer() {
return (undertow) -> undertow.addBuilderCustomizers(this.customizer);
}
}
@Configuration(proxyBeanMethods = false)
static class UndertowDeploymentInfoCustomizerConfiguration {

@ -22,6 +22,8 @@ import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import io.undertow.Undertow.Builder;
import io.undertow.servlet.api.DeploymentInfo;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
@ -163,6 +165,22 @@ class ServletWebServerFactoryAutoConfigurationTests {
});
}
@Test
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
WebApplicationContextRunner runner = new WebApplicationContextRunner(
AnnotationConfigServletWebServerApplicationContext::new)
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class))
.withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class)
.withPropertyValues("server.port: 0");
runner.run((context) -> {
JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class);
JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class);
assertThat(factory.getServerCustomizers()).contains(customizer);
verify(customizer, times(1)).customize(any(Server.class));
});
}
@Test
void undertowDeploymentInfoCustomizerBeanIsAddedToFactory() {
WebApplicationContextRunner runner = new WebApplicationContextRunner(
@ -177,6 +195,40 @@ class ServletWebServerFactoryAutoConfigurationTests {
});
}
@Test
void undertowDeploymentInfoCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
WebApplicationContextRunner runner = new WebApplicationContextRunner(
AnnotationConfigServletWebServerApplicationContext::new)
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class))
.withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration.class)
.withPropertyValues("server.port: 0");
runner.run((context) -> {
UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class);
UndertowDeploymentInfoCustomizer customizer = context.getBean("deploymentInfoCustomizer",
UndertowDeploymentInfoCustomizer.class);
assertThat(factory.getDeploymentInfoCustomizers()).contains(customizer);
verify(customizer, times(1)).customize(any(DeploymentInfo.class));
});
}
@Test
void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
WebApplicationContextRunner runner = new WebApplicationContextRunner(
AnnotationConfigServletWebServerApplicationContext::new)
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class))
.withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class))
.withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class)
.withPropertyValues("server.port: 0");
runner.run((context) -> {
UndertowServletWebServerFactory factory = context.getBean(UndertowServletWebServerFactory.class);
UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer",
UndertowBuilderCustomizer.class);
assertThat(factory.getBuilderCustomizers()).contains(customizer);
verify(customizer, times(1)).customize(any(Builder.class));
});
}
@Test
void undertowBuilderCustomizerBeanIsAddedToFactory() {
WebApplicationContextRunner runner = new WebApplicationContextRunner(
@ -510,6 +562,23 @@ class ServletWebServerFactoryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class DoubleRegistrationJettyServerCustomizerConfiguration {
private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class);
@Bean
JettyServerCustomizer serverCustomizer() {
return this.customizer;
}
@Bean
WebServerFactoryCustomizer<JettyServletWebServerFactory> jettyCustomizer() {
return (jetty) -> jetty.addServerCustomizers(this.customizer);
}
}
@Configuration(proxyBeanMethods = false)
static class UndertowBuilderCustomizerConfiguration {
@ -521,6 +590,23 @@ class ServletWebServerFactoryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class DoubleRegistrationUndertowBuilderCustomizerConfiguration {
private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class);
@Bean
UndertowBuilderCustomizer builderCustomizer() {
return this.customizer;
}
@Bean
WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowCustomizer() {
return (undertow) -> undertow.addBuilderCustomizers(this.customizer);
}
}
@Configuration(proxyBeanMethods = false)
static class UndertowDeploymentInfoCustomizerConfiguration {
@ -532,6 +618,23 @@ class ServletWebServerFactoryAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class DoubleRegistrationUndertowDeploymentInfoCustomizerConfiguration {
private final UndertowDeploymentInfoCustomizer customizer = mock(UndertowDeploymentInfoCustomizer.class);
@Bean
UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() {
return this.customizer;
}
@Bean
WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowCustomizer() {
return (undertow) -> undertow.addDeploymentInfoCustomizers(this.customizer);
}
}
@Configuration(proxyBeanMethods = false)
static class ForwardedHeaderFilterConfiguration {

@ -17,10 +17,10 @@
package org.springframework.boot.web.embedded.jetty;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -68,7 +68,7 @@ public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
private boolean useForwardHeaders;
private List<JettyServerCustomizer> jettyServerCustomizers = new ArrayList<>();
private Set<JettyServerCustomizer> jettyServerCustomizers = new LinkedHashSet<>();
private JettyResourceFactory resourceFactory;
@ -119,7 +119,7 @@ public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
*/
public void setServerCustomizers(Collection<? extends JettyServerCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null");
this.jettyServerCustomizers = new ArrayList<>(customizers);
this.jettyServerCustomizers = new LinkedHashSet<>(customizers);
}
/**

@ -27,7 +27,9 @@ import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.AbstractConnector;
@ -101,7 +103,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
*/
private int selectors = -1;
private List<JettyServerCustomizer> jettyServerCustomizers = new ArrayList<>();
private Set<JettyServerCustomizer> jettyServerCustomizers = new LinkedHashSet<>();
private ResourceLoader resourceLoader;
@ -425,7 +427,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
*/
public void setServerCustomizers(Collection<? extends JettyServerCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null");
this.jettyServerCustomizers = new ArrayList<>(customizers);
this.jettyServerCustomizers = new LinkedHashSet<>(customizers);
}
/**

@ -24,6 +24,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.catalina.Context;
import org.apache.catalina.Engine;
@ -72,11 +73,11 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
private List<LifecycleListener> contextLifecycleListeners = getDefaultLifecycleListeners();
private Collection<TomcatContextCustomizer> tomcatContextCustomizers = new LinkedHashSet<>();
private Set<TomcatContextCustomizer> tomcatContextCustomizers = new LinkedHashSet<>();
private Collection<TomcatConnectorCustomizer> tomcatConnectorCustomizers = new LinkedHashSet<>();
private Set<TomcatConnectorCustomizer> tomcatConnectorCustomizers = new LinkedHashSet<>();
private Collection<TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>();
private Set<TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>();
private final List<Connector> additionalTomcatConnectors = new ArrayList<>();
@ -234,7 +235,7 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
*/
public void setTomcatContextCustomizers(Collection<? extends TomcatContextCustomizer> tomcatContextCustomizers) {
Assert.notNull(tomcatContextCustomizers, "TomcatContextCustomizers must not be null");
this.tomcatContextCustomizers = new ArrayList<>(tomcatContextCustomizers);
this.tomcatContextCustomizers = new LinkedHashSet<>(tomcatContextCustomizers);
}
/**
@ -265,7 +266,7 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
public void setTomcatConnectorCustomizers(
Collection<? extends TomcatConnectorCustomizer> tomcatConnectorCustomizers) {
Assert.notNull(tomcatConnectorCustomizers, "TomcatConnectorCustomizers must not be null");
this.tomcatConnectorCustomizers = new ArrayList<>(tomcatConnectorCustomizers);
this.tomcatConnectorCustomizers = new LinkedHashSet<>(tomcatConnectorCustomizers);
}
/**
@ -297,7 +298,7 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
public void setTomcatProtocolHandlerCustomizers(
Collection<? extends TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers) {
Assert.notNull(tomcatProtocolHandlerCustomizers, "TomcatProtocolHandlerCustomizers must not be null");
this.tomcatProtocolHandlerCustomizers = new ArrayList<>(tomcatProtocolHandlerCustomizers);
this.tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(tomcatProtocolHandlerCustomizers);
}
/**

@ -116,11 +116,11 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
private List<LifecycleListener> contextLifecycleListeners = getDefaultLifecycleListeners();
private Collection<TomcatContextCustomizer> tomcatContextCustomizers = new LinkedHashSet<>();
private Set<TomcatContextCustomizer> tomcatContextCustomizers = new LinkedHashSet<>();
private Collection<TomcatConnectorCustomizer> tomcatConnectorCustomizers = new LinkedHashSet<>();
private Set<TomcatConnectorCustomizer> tomcatConnectorCustomizers = new LinkedHashSet<>();
private Collection<TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>();
private Set<TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers = new LinkedHashSet<>();
private final List<Connector> additionalTomcatConnectors = new ArrayList<>();
@ -569,7 +569,7 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
*/
public void setTomcatContextCustomizers(Collection<? extends TomcatContextCustomizer> tomcatContextCustomizers) {
Assert.notNull(tomcatContextCustomizers, "TomcatContextCustomizers must not be null");
this.tomcatContextCustomizers = new ArrayList<>(tomcatContextCustomizers);
this.tomcatContextCustomizers = new LinkedHashSet<>(tomcatContextCustomizers);
}
/**
@ -595,7 +595,7 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
public void setTomcatConnectorCustomizers(
Collection<? extends TomcatConnectorCustomizer> tomcatConnectorCustomizers) {
Assert.notNull(tomcatConnectorCustomizers, "TomcatConnectorCustomizers must not be null");
this.tomcatConnectorCustomizers = new ArrayList<>(tomcatConnectorCustomizers);
this.tomcatConnectorCustomizers = new LinkedHashSet<>(tomcatConnectorCustomizers);
}
@Override
@ -622,7 +622,7 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
public void setTomcatProtocolHandlerCustomizers(
Collection<? extends TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizer) {
Assert.notNull(tomcatProtocolHandlerCustomizer, "TomcatProtocolHandlerCustomizers must not be null");
this.tomcatProtocolHandlerCustomizers = new ArrayList<>(tomcatProtocolHandlerCustomizer);
this.tomcatProtocolHandlerCustomizers = new LinkedHashSet<>(tomcatProtocolHandlerCustomizer);
}
/**

@ -22,7 +22,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import io.undertow.Handlers;
@ -52,7 +54,7 @@ import org.springframework.util.Assert;
public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerFactory
implements ConfigurableUndertowWebServerFactory {
private List<UndertowBuilderCustomizer> builderCustomizers = new ArrayList<>();
private Set<UndertowBuilderCustomizer> builderCustomizers = new LinkedHashSet<>();
private List<UndertowDeploymentInfoCustomizer> deploymentInfoCustomizers = new ArrayList<>();
@ -295,7 +297,7 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF
*/
public void setBuilderCustomizers(Collection<? extends UndertowBuilderCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null");
this.builderCustomizers = new ArrayList<>(customizers);
this.builderCustomizers = new LinkedHashSet<>(customizers);
}
/**

@ -26,6 +26,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EventListener;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -92,9 +93,9 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
private static final Set<Class<?>> NO_CLASSES = Collections.emptySet();
private List<UndertowBuilderCustomizer> builderCustomizers = new ArrayList<>();
private Set<UndertowBuilderCustomizer> builderCustomizers = new LinkedHashSet<>();
private List<UndertowDeploymentInfoCustomizer> deploymentInfoCustomizers = new ArrayList<>();
private Set<UndertowDeploymentInfoCustomizer> deploymentInfoCustomizers = new LinkedHashSet<>();
private ResourceLoader resourceLoader;
@ -157,7 +158,7 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
*/
public void setBuilderCustomizers(Collection<? extends UndertowBuilderCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null");
this.builderCustomizers = new ArrayList<>(customizers);
this.builderCustomizers = new LinkedHashSet<>(customizers);
}
/**
@ -183,7 +184,7 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
*/
public void setDeploymentInfoCustomizers(Collection<? extends UndertowDeploymentInfoCustomizer> customizers) {
Assert.notNull(customizers, "Customizers must not be null");
this.deploymentInfoCustomizers = new ArrayList<>(customizers);
this.deploymentInfoCustomizers = new LinkedHashSet<>(customizers);
}
/**

Loading…
Cancel
Save