Add NettyServerCustomizer beans to the auto-configured factory
Closes gh-17556
This commit is contained in:
parent
ea1139755d
commit
dad7fb4f6d
@ -28,6 +28,7 @@ import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory
|
|||||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||||
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
|
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
|
||||||
|
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
||||||
@ -66,10 +67,11 @@ abstract class ReactiveWebServerFactoryConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory,
|
NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory,
|
||||||
ObjectProvider<NettyRouteProvider> routes) {
|
ObjectProvider<NettyRouteProvider> routes, ObjectProvider<NettyServerCustomizer> serverCustomizers) {
|
||||||
NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory();
|
NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory();
|
||||||
serverFactory.setResourceFactory(resourceFactory);
|
serverFactory.setResourceFactory(resourceFactory);
|
||||||
routes.orderedStream().forEach((route) -> serverFactory.addRouteProviders(route));
|
routes.orderedStream().forEach((route) -> serverFactory.addRouteProviders(route));
|
||||||
|
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().collect(Collectors.toList()));
|
||||||
return serverFactory;
|
return serverFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.boot.autoconfigure.web.reactive;
|
package org.springframework.boot.autoconfigure.web.reactive;
|
||||||
|
|
||||||
|
import io.undertow.Undertow;
|
||||||
import io.undertow.Undertow.Builder;
|
import io.undertow.Undertow.Builder;
|
||||||
import org.apache.catalina.Context;
|
import org.apache.catalina.Context;
|
||||||
import org.apache.catalina.connector.Connector;
|
import org.apache.catalina.connector.Connector;
|
||||||
@ -25,10 +26,14 @@ import org.junit.jupiter.api.Test;
|
|||||||
import reactor.netty.http.server.HttpServer;
|
import reactor.netty.http.server.HttpServer;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
|
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
|
||||||
|
import org.springframework.boot.logging.LogLevel;
|
||||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||||
|
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||||
|
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
||||||
@ -49,6 +54,7 @@ import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@ -279,6 +285,33 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nettyServerCustomizerBeanIsAddedToFactory() {
|
||||||
|
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new)
|
||||||
|
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||||
|
.withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class, Undertow.class))
|
||||||
|
.withUserConfiguration(NettyServerCustomizerConfiguration.class, HttpHandlerConfiguration.class)
|
||||||
|
.withInitializer(new ConditionEvaluationReportLoggingListener(LogLevel.INFO)).run((context) -> {
|
||||||
|
NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class);
|
||||||
|
assertThat(factory.getServerCustomizers()).hasSize(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||||
|
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||||
|
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||||
|
.withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class, Undertow.class))
|
||||||
|
.withUserConfiguration(DoubleRegistrationNettyServerCustomizerConfiguration.class,
|
||||||
|
HttpHandlerConfiguration.class)
|
||||||
|
.withPropertyValues("server.port: 0").run((context) -> {
|
||||||
|
NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class);
|
||||||
|
NettyServerCustomizer customizer = context.getBean("serverCustomizer", NettyServerCustomizer.class);
|
||||||
|
assertThat(factory.getServerCustomizers()).contains(customizer);
|
||||||
|
verify(customizer, times(1)).apply(any(HttpServer.class));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void forwardedHeaderTransformerShouldBeConfigured() {
|
void forwardedHeaderTransformerShouldBeConfigured() {
|
||||||
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||||
@ -489,6 +522,37 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class NettyServerCustomizerConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
NettyServerCustomizer serverCustomizer() {
|
||||||
|
return (server) -> server;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
static class DoubleRegistrationNettyServerCustomizerConfiguration {
|
||||||
|
|
||||||
|
private final NettyServerCustomizer customizer = mock(NettyServerCustomizer.class);
|
||||||
|
|
||||||
|
DoubleRegistrationNettyServerCustomizerConfiguration() {
|
||||||
|
given(this.customizer.apply(any(HttpServer.class))).willAnswer((invocation) -> invocation.getArgument(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
NettyServerCustomizer serverCustomizer() {
|
||||||
|
return this.customizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
WebServerFactoryCustomizer<NettyReactiveWebServerFactory> nettyCustomizer() {
|
||||||
|
return (netty) -> netty.addServerCustomizers(this.customizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class ForwardedHeaderTransformerConfiguration {
|
static class ForwardedHeaderTransformerConfiguration {
|
||||||
|
|
||||||
|
@ -21,7 +21,9 @@ import java.time.Duration;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import reactor.netty.http.HttpProtocol;
|
import reactor.netty.http.HttpProtocol;
|
||||||
import reactor.netty.http.server.HttpServer;
|
import reactor.netty.http.server.HttpServer;
|
||||||
@ -43,7 +45,7 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFactory {
|
public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFactory {
|
||||||
|
|
||||||
private List<NettyServerCustomizer> serverCustomizers = new ArrayList<>();
|
private Set<NettyServerCustomizer> serverCustomizers = new LinkedHashSet<>();
|
||||||
|
|
||||||
private List<NettyRouteProvider> routeProviders = new ArrayList<>();
|
private List<NettyRouteProvider> routeProviders = new ArrayList<>();
|
||||||
|
|
||||||
@ -85,7 +87,7 @@ public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
|
|||||||
*/
|
*/
|
||||||
public void setServerCustomizers(Collection<? extends NettyServerCustomizer> serverCustomizers) {
|
public void setServerCustomizers(Collection<? extends NettyServerCustomizer> serverCustomizers) {
|
||||||
Assert.notNull(serverCustomizers, "ServerCustomizers must not be null");
|
Assert.notNull(serverCustomizers, "ServerCustomizers must not be null");
|
||||||
this.serverCustomizers = new ArrayList<>(serverCustomizers);
|
this.serverCustomizers = new LinkedHashSet<>(serverCustomizers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user