Support registering Filters in WebSocket test servers
This commit is contained in:
@@ -17,12 +17,17 @@
|
||||
package org.springframework.web.socket;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.FilterHolder;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.springframework.util.SocketUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Jetty based {@link WebSocketTestServer}.
|
||||
*
|
||||
@@ -46,13 +51,20 @@ public class JettyWebSocketTestServer implements WebSocketTestServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deployConfig(WebApplicationContext cxt) {
|
||||
public void deployConfig(WebApplicationContext cxt, Filter... filters) {
|
||||
ServletContextHandler contextHandler = new ServletContextHandler();
|
||||
ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(cxt));
|
||||
contextHandler.addServlet(servletHolder, "/");
|
||||
for (Filter filter : filters) {
|
||||
contextHandler.addFilter(new FilterHolder(filter), "/*", getDispatcherTypes());
|
||||
}
|
||||
this.jettyServer.setHandler(contextHandler);
|
||||
}
|
||||
|
||||
private EnumSet<DispatcherType> getDispatcherTypes() {
|
||||
return EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undeployConfig() {
|
||||
// Stopping jetty will undeploy the servlet
|
||||
|
||||
@@ -18,17 +18,23 @@ package org.springframework.web.socket;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.coyote.http11.Http11NioProtocol;
|
||||
import org.apache.tomcat.util.descriptor.web.ApplicationListener;
|
||||
import org.apache.tomcat.util.descriptor.web.FilterDef;
|
||||
import org.apache.tomcat.util.descriptor.web.FilterMap;
|
||||
import org.apache.tomcat.websocket.server.WsContextListener;
|
||||
import org.springframework.util.SocketUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
|
||||
/**
|
||||
* Tomcat based {@link WebSocketTestServer}.
|
||||
*
|
||||
@@ -82,11 +88,27 @@ public class TomcatWebSocketTestServer implements WebSocketTestServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deployConfig(WebApplicationContext wac) {
|
||||
public void deployConfig(WebApplicationContext wac, Filter... filters) {
|
||||
this.context = this.tomcatServer.addContext("", System.getProperty("java.io.tmpdir"));
|
||||
this.context.addApplicationListener(WS_APPLICATION_LISTENER);
|
||||
Tomcat.addServlet(context, "dispatcherServlet", new DispatcherServlet(wac));
|
||||
Tomcat.addServlet(this.context, "dispatcherServlet", new DispatcherServlet(wac)).setAsyncSupported(true);
|
||||
this.context.addServletMapping("/", "dispatcherServlet");
|
||||
for (Filter filter : filters) {
|
||||
FilterDef filterDef = new FilterDef();
|
||||
filterDef.setFilterName(filter.getClass().getName());
|
||||
filterDef.setFilter(filter);
|
||||
filterDef.setAsyncSupported("true");
|
||||
this.context.addFilterDef(filterDef);
|
||||
FilterMap filterMap = new FilterMap();
|
||||
filterMap.setFilterName(filter.getClass().getName());
|
||||
filterMap.addURLPattern("/*");
|
||||
filterMap.setDispatcher("REQUEST,FORWARD,INCLUDE,ASYNC");
|
||||
this.context.addFilterMap(filterMap);
|
||||
}
|
||||
}
|
||||
|
||||
private EnumSet<DispatcherType> getDispatcherTypes() {
|
||||
return EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package org.springframework.web.socket;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.servlet.api.DeploymentManager;
|
||||
import io.undertow.servlet.api.FilterInfo;
|
||||
import io.undertow.servlet.api.InstanceFactory;
|
||||
import io.undertow.servlet.api.InstanceHandle;
|
||||
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
||||
@@ -56,7 +59,7 @@ public class UndertowTestServer implements WebSocketTestServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deployConfig(WebApplicationContext cxt) {
|
||||
public void deployConfig(WebApplicationContext cxt, Filter... filters) {
|
||||
DispatcherServletInstanceFactory servletFactory = new DispatcherServletInstanceFactory(cxt);
|
||||
|
||||
DeploymentInfo servletBuilder = deployment()
|
||||
@@ -66,6 +69,13 @@ public class UndertowTestServer implements WebSocketTestServer {
|
||||
.addServlet(servlet("DispatcherServlet", DispatcherServlet.class, servletFactory).addMapping("/"))
|
||||
.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, new WebSocketDeploymentInfo());
|
||||
|
||||
for (final Filter filter : filters) {
|
||||
String filterName = filter.getClass().getName();
|
||||
servletBuilder.addFilter(new FilterInfo(filterName, filter.getClass(), new FilterInstanceFactory(filter)));
|
||||
for (DispatcherType type : DispatcherType.values()) {
|
||||
servletBuilder.addFilterUrlMapping(filterName, "/*", type);
|
||||
}
|
||||
}
|
||||
this.manager = defaultContainer().addDeployment(servletBuilder);
|
||||
this.manager.deploy();
|
||||
|
||||
@@ -117,4 +127,25 @@ public class UndertowTestServer implements WebSocketTestServer {
|
||||
}
|
||||
}
|
||||
|
||||
private static class FilterInstanceFactory implements InstanceFactory<Filter> {
|
||||
|
||||
private final Filter filter;
|
||||
|
||||
private FilterInstanceFactory(Filter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceHandle<Filter> createInstance() throws InstantiationException {
|
||||
return new InstanceHandle<Filter>() {
|
||||
@Override
|
||||
public Filter getInstance() {
|
||||
return filter;
|
||||
}
|
||||
@Override
|
||||
public void release() {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,24 +58,22 @@ public class WebSocketIntegrationTests extends AbstractWebSocketIntegrationTest
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedConfigClasses() {
|
||||
return new Class<?>[] {TestWebSocketConfigurer.class};
|
||||
return new Class<?>[] { TestConfig.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subProtocolNegotiation() throws Exception {
|
||||
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
|
||||
headers.setSecWebSocketProtocol("foo");
|
||||
|
||||
WebSocketSession session = this.webSocketClient.doHandshake(
|
||||
new AbstractWebSocketHandler() {}, headers, new URI(getWsBaseUrl() + "/ws")).get();
|
||||
|
||||
URI url = new URI(getWsBaseUrl() + "/ws");
|
||||
WebSocketSession session = this.webSocketClient.doHandshake(new TextWebSocketHandler(), headers, url).get();
|
||||
assertEquals("foo", session.getAcceptedProtocol());
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
static class TestWebSocketConfigurer implements WebSocketConfigurer {
|
||||
static class TestConfig implements WebSocketConfigurer {
|
||||
|
||||
@Autowired
|
||||
private DefaultHandshakeHandler handshakeHandler; // can't rely on classpath for server detection
|
||||
@@ -83,17 +81,13 @@ public class WebSocketIntegrationTests extends AbstractWebSocketIntegrationTest
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
this.handshakeHandler.setSupportedProtocols("foo", "bar", "baz");
|
||||
registry.addHandler(serverHandler(), "/ws").setHandshakeHandler(this.handshakeHandler);
|
||||
registry.addHandler(handler(), "/ws").setHandshakeHandler(this.handshakeHandler);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestServerWebSocketHandler serverHandler() {
|
||||
return new TestServerWebSocketHandler();
|
||||
public TextWebSocketHandler handler() {
|
||||
return new TextWebSocketHandler();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestServerWebSocketHandler extends TextWebSocketHandler {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.web.socket;
|
||||
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
|
||||
/**
|
||||
* Contract for a test server to use for WebSocket integration tests.
|
||||
*
|
||||
@@ -27,7 +29,7 @@ public interface WebSocketTestServer {
|
||||
|
||||
int getPort();
|
||||
|
||||
void deployConfig(WebApplicationContext cxt);
|
||||
void deployConfig(WebApplicationContext cxt, Filter... filters);
|
||||
|
||||
void undeployConfig();
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ public class WebSocketConfigurationTests extends AbstractWebSocketIntegrationTes
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedConfigClasses() {
|
||||
return new Class<?>[] {TestWebSocketConfigurer.class};
|
||||
return new Class<?>[] { TestConfig.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -65,7 +65,7 @@ public class WebSocketConfigurationTests extends AbstractWebSocketIntegrationTes
|
||||
WebSocketSession session = this.webSocketClient.doHandshake(
|
||||
new AbstractWebSocketHandler() {}, getWsBaseUrl() + "/ws").get();
|
||||
|
||||
TestWebSocketHandler serverHandler = this.wac.getBean(TestWebSocketHandler.class);
|
||||
TestHandler serverHandler = this.wac.getBean(TestHandler.class);
|
||||
assertTrue(serverHandler.connectLatch.await(2, TimeUnit.SECONDS));
|
||||
|
||||
session.close();
|
||||
@@ -76,7 +76,7 @@ public class WebSocketConfigurationTests extends AbstractWebSocketIntegrationTes
|
||||
WebSocketSession session = this.webSocketClient.doHandshake(
|
||||
new AbstractWebSocketHandler() {}, getWsBaseUrl() + "/sockjs/websocket").get();
|
||||
|
||||
TestWebSocketHandler serverHandler = this.wac.getBean(TestWebSocketHandler.class);
|
||||
TestHandler serverHandler = this.wac.getBean(TestHandler.class);
|
||||
assertTrue(serverHandler.connectLatch.await(2, TimeUnit.SECONDS));
|
||||
|
||||
session.close();
|
||||
@@ -85,7 +85,7 @@ public class WebSocketConfigurationTests extends AbstractWebSocketIntegrationTes
|
||||
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
static class TestWebSocketConfigurer implements WebSocketConfigurer {
|
||||
static class TestConfig implements WebSocketConfigurer {
|
||||
|
||||
@Autowired
|
||||
private HandshakeHandler handshakeHandler; // can't rely on classpath for server detection
|
||||
@@ -99,12 +99,12 @@ public class WebSocketConfigurationTests extends AbstractWebSocketIntegrationTes
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestWebSocketHandler serverHandler() {
|
||||
return new TestWebSocketHandler();
|
||||
public TestHandler serverHandler() {
|
||||
return new TestHandler();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestWebSocketHandler extends AbstractWebSocketHandler {
|
||||
private static class TestHandler extends AbstractWebSocketHandler {
|
||||
|
||||
private CountDownLatch connectLatch = new CountDownLatch(1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user