Add reactive websocket auto-configuration for Tomcat
This commit adds a `TomcatWebSocketReactiveWebServerCustomizer` that customizes the Tomcat context to accept WebSockets connections. Since reactive servers don't use the JSR 356 for that support, only Tomcat customization is required for now. This commit also reorders the server auto-configuration so that undertow has a chance to be auto-configured before reactor-netty, which should be a popular dependency thanks to its HTTP client library. The existing WebSocket infrastructure for Serlvet based containers has been moved to a dedicated package and renamed accordingly. Fixes gh-9113
This commit is contained in:
parent
1835dd7b94
commit
89c284cb13
|
@ -50,8 +50,8 @@ import org.springframework.util.ObjectUtils;
|
|||
@Import({ ReactiveWebServerAutoConfiguration.BeanPostProcessorsRegistrar.class,
|
||||
ReactiveWebServerConfiguration.TomcatAutoConfiguration.class,
|
||||
ReactiveWebServerConfiguration.JettyAutoConfiguration.class,
|
||||
ReactiveWebServerConfiguration.ReactorNettyAutoConfiguration.class,
|
||||
ReactiveWebServerConfiguration.UndertowAutoConfiguration.class })
|
||||
ReactiveWebServerConfiguration.UndertowAutoConfiguration.class,
|
||||
ReactiveWebServerConfiguration.ReactorNettyAutoConfiguration.class})
|
||||
public class ReactiveWebServerAutoConfiguration {
|
||||
|
||||
@ConditionalOnMissingBean
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2012-2017 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.autoconfigure.websocket.reactive;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.tomcat.websocket.server.WsContextListener;
|
||||
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* WebSocket customizer for {@link TomcatReactiveWebServerFactory}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TomcatWebSocketReactiveWebServerCustomizer
|
||||
implements WebServerFactoryCustomizer<TomcatReactiveWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
||||
public void customize(TomcatReactiveWebServerFactory factory) {
|
||||
factory.addContextCustomizers(new TomcatContextCustomizer() {
|
||||
|
||||
@Override
|
||||
public void customize(Context context) {
|
||||
context.addApplicationListener(WsContextListener.class.getName());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2012-2017 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.autoconfigure.websocket.reactive;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
import javax.websocket.server.ServerContainer;
|
||||
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto configuration for WebSocket reactive server in Tomcat, Jetty or Undertow.
|
||||
* Requires the appropriate WebSocket modules to be on the classpath.
|
||||
* <p>
|
||||
* If Tomcat's WebSocket support is detected on the classpath we add a customizer that
|
||||
* installs the Tomcat WebSocket initializer.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Servlet.class, ServerContainer.class })
|
||||
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
||||
@AutoConfigureBefore(ReactiveWebServerAutoConfiguration.class)
|
||||
public class WebSocketReactiveAutoConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = "org.apache.tomcat.websocket.server.WsSci", value = Tomcat.class)
|
||||
static class TomcatWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer")
|
||||
public TomcatWebSocketReactiveWebServerCustomizer websocketContainerCustomizer() {
|
||||
return new TomcatWebSocketReactiveWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for WebSocket support in reactive web servers.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.websocket.reactive;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import org.eclipse.jetty.util.thread.ShutdownThread;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
|
@ -32,9 +32,9 @@ import org.springframework.core.Ordered;
|
|||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.0
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JettyWebSocketContainerCustomizer
|
||||
public class JettyWebSocketServletWebServerCustomizer
|
||||
implements WebServerFactoryCustomizer<JettyServletWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
|
@ -14,9 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.tomcat.websocket.server.WsContextListener;
|
||||
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||
|
@ -30,21 +29,15 @@ import org.springframework.core.Ordered;
|
|||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.0
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TomcatWebSocketContainerCustomizer
|
||||
public class TomcatWebSocketServletWebServerCustomizer
|
||||
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
||||
public void customize(TomcatServletWebServerFactory factory) {
|
||||
factory.addContextCustomizers(new TomcatContextCustomizer() {
|
||||
|
||||
@Override
|
||||
public void customize(Context context) {
|
||||
context.addApplicationListener(WsContextListener.class.getName());
|
||||
}
|
||||
|
||||
});
|
||||
factory.addContextCustomizers((TomcatContextCustomizer) context ->
|
||||
context.addApplicationListener(WsContextListener.class.getName()));
|
||||
}
|
||||
|
||||
@Override
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
||||
|
@ -28,9 +28,9 @@ import org.springframework.core.Ordered;
|
|||
* WebSocket customizer for {@link UndertowServletWebServerFactory}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.2.0
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class UndertowWebSocketContainerCustomizer
|
||||
public class UndertowWebSocketServletWebServerCustomizer
|
||||
implements WebServerFactoryCustomizer<UndertowServletWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import javax.servlet.Servlet;
|
||||
import javax.websocket.server.ServerContainer;
|
||||
|
@ -32,11 +32,11 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto configuration for websocket server in embedded Tomcat, Jetty or Undertow. Requires
|
||||
* the appropriate WebSocket modules to be on the classpath.
|
||||
* Auto configuration for WebSocket servlet server in embedded Tomcat, Jetty or Undertow.
|
||||
* Requires the appropriate WebSocket modules to be on the classpath.
|
||||
* <p>
|
||||
* If Tomcat's WebSocket support is detected on the classpath we add a customizer that
|
||||
* installs the Tomcat Websocket initializer. In a non-embedded server it should already
|
||||
* installs the Tomcat WebSocket initializer. In a non-embedded server it should already
|
||||
* be there.
|
||||
* <p>
|
||||
* If Jetty's WebSocket support is detected on the classpath we add a configuration that
|
||||
|
@ -44,7 +44,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
* already be there.
|
||||
* <p>
|
||||
* If Undertow's WebSocket support is detected on the classpath we add a customizer that
|
||||
* installs the Undertow Websocket DeploymentInfo Customizer. In a non-embedded server it
|
||||
* installs the Undertow WebSocket DeploymentInfo Customizer. In a non-embedded server it
|
||||
* should already be there.
|
||||
*
|
||||
* @author Dave Syer
|
||||
|
@ -55,16 +55,16 @@ import org.springframework.context.annotation.Configuration;
|
|||
@ConditionalOnClass({ Servlet.class, ServerContainer.class })
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@AutoConfigureBefore(ServletWebServerFactoryAutoConfiguration.class)
|
||||
public class WebSocketAutoConfiguration {
|
||||
public class WebSocketServletAutoConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(name = "org.apache.tomcat.websocket.server.WsSci", value = Tomcat.class)
|
||||
static class TomcatWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketContainerCustomizer")
|
||||
public TomcatWebSocketContainerCustomizer websocketContainerCustomizer() {
|
||||
return new TomcatWebSocketContainerCustomizer();
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
public TomcatWebSocketServletWebServerCustomizer websocketContainerCustomizer() {
|
||||
return new TomcatWebSocketServletWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ public class WebSocketAutoConfiguration {
|
|||
static class JettyWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketContainerCustomizer")
|
||||
public JettyWebSocketContainerCustomizer websocketContainerCustomizer() {
|
||||
return new JettyWebSocketContainerCustomizer();
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
public JettyWebSocketServletWebServerCustomizer websocketContainerCustomizer() {
|
||||
return new JettyWebSocketServletWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -86,9 +86,9 @@ public class WebSocketAutoConfiguration {
|
|||
static class UndertowWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketContainerCustomizer")
|
||||
public UndertowWebSocketContainerCustomizer websocketContainerCustomizer() {
|
||||
return new UndertowWebSocketContainerCustomizer();
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
public UndertowWebSocketServletWebServerCustomizer websocketContainerCustomizer() {
|
||||
return new UndertowWebSocketServletWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2017 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.
|
||||
|
@ -15,6 +15,6 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Spring WebSocket.
|
||||
* Auto-configuration for WebSocket support in servlet web servers.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
|
@ -118,8 +118,9 @@ org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfigurati
|
|||
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
|
||||
|
||||
# Failure analyzers
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
|
@ -207,10 +207,10 @@ public class WebSocketMessagingAutoConfigurationTests {
|
|||
@EnableWebSocket
|
||||
@EnableConfigurationProperties
|
||||
@EnableWebSocketMessageBroker
|
||||
@ImportAutoConfiguration({ JacksonAutoConfiguration.class,
|
||||
@ImportAutoConfiguration({JacksonAutoConfiguration.class,
|
||||
ServletWebServerFactoryAutoConfiguration.class,
|
||||
WebSocketMessagingAutoConfiguration.class,
|
||||
DispatcherServletAutoConfiguration.class })
|
||||
DispatcherServletAutoConfiguration.class})
|
||||
static class WebSocketMessagingConfiguration
|
||||
extends AbstractWebSocketMessageBrokerConfigurer {
|
||||
|
||||
|
@ -235,8 +235,8 @@ public class WebSocketMessagingAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public TomcatWebSocketContainerCustomizer tomcatCustomizer() {
|
||||
return new TomcatWebSocketContainerCustomizer();
|
||||
public TomcatWebSocketServletWebServerCustomizer tomcatCustomizer() {
|
||||
return new TomcatWebSocketServletWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket;
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import javax.websocket.server.ServerContainer;
|
||||
|
||||
|
@ -33,11 +33,11 @@ import org.springframework.context.annotation.Configuration;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link WebSocketAutoConfiguration}
|
||||
* Tests for {@link WebSocketServletAutoConfiguration}
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class WebSocketAutoConfigurationTests {
|
||||
public class WebSocketServletAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigServletWebServerApplicationContext context;
|
||||
|
||||
|
@ -56,13 +56,13 @@ public class WebSocketAutoConfigurationTests {
|
|||
@Test
|
||||
public void tomcatServerContainerIsAvailableFromTheServletContext() {
|
||||
serverContainerIsAvailableFromTheServletContext(TomcatConfiguration.class,
|
||||
WebSocketAutoConfiguration.TomcatWebSocketConfiguration.class);
|
||||
WebSocketServletAutoConfiguration.TomcatWebSocketConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jettyServerContainerIsAvailableFromTheServletContext() {
|
||||
serverContainerIsAvailableFromTheServletContext(JettyConfiguration.class,
|
||||
WebSocketAutoConfiguration.JettyWebSocketConfiguration.class);
|
||||
WebSocketServletAutoConfiguration.JettyWebSocketConfiguration.class);
|
||||
}
|
||||
|
||||
private void serverContainerIsAvailableFromTheServletContext(
|
|
@ -17,7 +17,12 @@
|
|||
package org.springframework.boot.web.embedded.tomcat;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.Host;
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.apache.catalina.loader.WebappLoader;
|
||||
|
@ -48,6 +53,8 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
|
|||
|
||||
private String protocol = DEFAULT_PROTOCOL;
|
||||
|
||||
private List<TomcatContextCustomizer> tomcatContextCustomizers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create a new {@link TomcatServletWebServerFactory} instance.
|
||||
*/
|
||||
|
@ -97,9 +104,20 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
|
|||
context.setLoader(loader);
|
||||
Tomcat.addServlet(context, "httpHandlerServlet", servlet);
|
||||
context.addServletMappingDecoded("/", "httpHandlerServlet");
|
||||
configureContext(context);
|
||||
host.addChild(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the Tomcat {@link Context}.
|
||||
* @param context the Tomcat context
|
||||
*/
|
||||
protected void configureContext(Context context) {
|
||||
for (TomcatContextCustomizer customizer : this.tomcatContextCustomizers) {
|
||||
customizer.customize(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Needs to be protected so it can be used by subclasses
|
||||
protected void customizeConnector(Connector connector) {
|
||||
int port = (getPort() >= 0 ? getPort() : 0);
|
||||
|
@ -122,6 +140,39 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@link TomcatContextCustomizer}s that should be applied to the Tomcat
|
||||
* {@link Context} . Calling this method will replace any existing customizers.
|
||||
* @param tomcatContextCustomizers the customizers to set
|
||||
*/
|
||||
public void setTomcatContextCustomizers(
|
||||
Collection<? extends TomcatContextCustomizer> tomcatContextCustomizers) {
|
||||
Assert.notNull(tomcatContextCustomizers,
|
||||
"TomcatContextCustomizers must not be null");
|
||||
this.tomcatContextCustomizers = new ArrayList<>(tomcatContextCustomizers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mutable collection of the {@link TomcatContextCustomizer}s that will be
|
||||
* applied to the Tomcat {@link Context} .
|
||||
* @return the listeners that will be applied
|
||||
*/
|
||||
public Collection<TomcatContextCustomizer> getTomcatContextCustomizers() {
|
||||
return this.tomcatContextCustomizers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link TomcatContextCustomizer}s that should be added to the Tomcat
|
||||
* {@link Context}.
|
||||
* @param tomcatContextCustomizers the customizers to add
|
||||
*/
|
||||
public void addContextCustomizers(
|
||||
TomcatContextCustomizer... tomcatContextCustomizers) {
|
||||
Assert.notNull(tomcatContextCustomizers,
|
||||
"TomcatContextCustomizers must not be null");
|
||||
this.tomcatContextCustomizers.addAll(Arrays.asList(tomcatContextCustomizers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method called to create the {@link TomcatWebServer}. Subclasses can
|
||||
* override this method to return a different {@link TomcatWebServer} or apply
|
||||
|
|
|
@ -88,4 +88,19 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF
|
|||
return getAddress().getHostAddress();
|
||||
}
|
||||
|
||||
public void setBufferSize(Integer bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public void setIoThreads(Integer ioThreads) {
|
||||
this.ioThreads = ioThreads;
|
||||
}
|
||||
|
||||
public void setWorkerThreads(Integer workerThreads) {
|
||||
this.workerThreads = workerThreads;
|
||||
}
|
||||
|
||||
public void setDirectBuffers(Boolean directBuffers) {
|
||||
this.directBuffers = directBuffers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,18 @@
|
|||
|
||||
package org.springframework.boot.web.embedded.tomcat;
|
||||
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link TomcatReactiveWebServerFactory}.
|
||||
|
@ -28,8 +38,23 @@ public class TomcatReactiveWebServerFactoryTests
|
|||
extends AbstractReactiveWebServerFactoryTests {
|
||||
|
||||
@Override
|
||||
protected AbstractReactiveWebServerFactory getFactory() {
|
||||
protected TomcatReactiveWebServerFactory getFactory() {
|
||||
return new TomcatReactiveWebServerFactory(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tomcatCustomizers() throws Exception {
|
||||
TomcatReactiveWebServerFactory factory = getFactory();
|
||||
TomcatContextCustomizer[] listeners = new TomcatContextCustomizer[4];
|
||||
for (int i = 0; i < listeners.length; i++) {
|
||||
listeners[i] = mock(TomcatContextCustomizer.class);
|
||||
}
|
||||
factory.setTomcatContextCustomizers(Arrays.asList(listeners[0], listeners[1]));
|
||||
factory.addContextCustomizers(listeners[2], listeners[3]);
|
||||
this.webServer = factory.getWebServer(mock(HttpHandler.class));
|
||||
InOrder ordered = inOrder((Object[]) listeners);
|
||||
for (TomcatContextCustomizer listener : listeners) {
|
||||
ordered.verify(listener).customize(any(Context.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.boot.web.embedded.undertow;
|
||||
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests;
|
||||
|
||||
/**
|
||||
|
@ -28,7 +27,7 @@ public class UndertowReactiveWebServerFactoryTests
|
|||
extends AbstractReactiveWebServerFactoryTests {
|
||||
|
||||
@Override
|
||||
protected AbstractReactiveWebServerFactory getFactory() {
|
||||
protected UndertowReactiveWebServerFactory getFactory() {
|
||||
return new UndertowReactiveWebServerFactory(0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue