Refactor random port in spring-websocket

Remove the use of SocketUtils#findAvailableTcpPort in favor of letting
servers pick a dynamic port by specifying port 0.
This commit is contained in:
Rossen Stoyanchev 2017-01-31 16:49:57 -05:00
parent c79092f0f9
commit 949bb55ef5
4 changed files with 30 additions and 31 deletions

View File

@ -41,7 +41,7 @@ public class JettyWebSocketTestServer implements WebSocketTestServer {
private Server jettyServer; private Server jettyServer;
private int port = -1; private int port;
private ServletContextHandler contextHandler; private ServletContextHandler contextHandler;

View File

@ -22,8 +22,6 @@ import javax.servlet.Filter;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import org.apache.catalina.Context; import org.apache.catalina.Context;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.connector.Connector; import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -34,7 +32,6 @@ import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.apache.tomcat.websocket.server.WsContextListener; import org.apache.tomcat.websocket.server.WsContextListener;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.SocketUtils;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.DispatcherServlet;
@ -50,24 +47,22 @@ public class TomcatWebSocketTestServer implements WebSocketTestServer {
private Tomcat tomcatServer; private Tomcat tomcatServer;
private int port = -1; private int port;
private Context context; private Context context;
@Override @Override
public void setup() { public void setup() {
this.port = SocketUtils.findAvailableTcpPort();
Connector connector = new Connector(Http11NioProtocol.class.getName()); Connector connector = new Connector(Http11NioProtocol.class.getName());
connector.setPort(this.port); connector.setPort(0);
File baseDir = createTempDir("tomcat"); File baseDir = createTempDir("tomcat");
String baseDirPath = baseDir.getAbsolutePath(); String baseDirPath = baseDir.getAbsolutePath();
this.tomcatServer = new Tomcat(); this.tomcatServer = new Tomcat();
this.tomcatServer.setBaseDir(baseDirPath); this.tomcatServer.setBaseDir(baseDirPath);
this.tomcatServer.setPort(this.port); this.tomcatServer.setPort(0);
this.tomcatServer.getService().addConnector(connector); this.tomcatServer.getService().addConnector(connector);
this.tomcatServer.setConnector(connector); this.tomcatServer.setConnector(connector);
} }
@ -117,12 +112,10 @@ public class TomcatWebSocketTestServer implements WebSocketTestServer {
@Override @Override
public void start() throws Exception { public void start() throws Exception {
this.tomcatServer.start(); this.tomcatServer.start();
this.context.addLifecycleListener(new LifecycleListener() { this.port = this.tomcatServer.getConnector().getLocalPort();
@Override this.context.addLifecycleListener(event -> {
public void lifecycleEvent(LifecycleEvent event) { if (logger.isDebugEnabled()) {
if (logger.isDebugEnabled()) { logger.debug("Event: " + event.getType());
logger.debug("Event: " + event.getType());
}
} }
}); });
} }
@ -130,6 +123,7 @@ public class TomcatWebSocketTestServer implements WebSocketTestServer {
@Override @Override
public void stop() throws Exception { public void stop() throws Exception {
this.tomcatServer.stop(); this.tomcatServer.stop();
this.port = 0;
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2016 the original author or authors. * Copyright 2002-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.web.socket; package org.springframework.web.socket;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.Servlet; import javax.servlet.Servlet;
@ -34,12 +35,12 @@ import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.xnio.OptionMap; import org.xnio.OptionMap;
import org.xnio.Xnio; import org.xnio.Xnio;
import org.springframework.util.Assert;
import org.springframework.util.SocketUtils;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.DispatcherServlet;
import static io.undertow.servlet.Servlets.*; import static io.undertow.servlet.Servlets.defaultContainer;
import static io.undertow.servlet.Servlets.deployment;
import static io.undertow.servlet.Servlets.servlet;
/** /**
* Undertow-based {@link WebSocketTestServer}. * Undertow-based {@link WebSocketTestServer}.
@ -49,7 +50,7 @@ import static io.undertow.servlet.Servlets.*;
*/ */
public class UndertowTestServer implements WebSocketTestServer { public class UndertowTestServer implements WebSocketTestServer {
private int port = -1; private int port;
private Undertow server; private Undertow server;
@ -58,13 +59,11 @@ public class UndertowTestServer implements WebSocketTestServer {
@Override @Override
public void setup() { public void setup() {
this.port = SocketUtils.findAvailableTcpPort();
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void deployConfig(WebApplicationContext wac, Filter... filters) { public void deployConfig(WebApplicationContext wac, Filter... filters) {
Assert.state(this.port != -1, "setup() was never called");
DispatcherServletInstanceFactory servletFactory = new DispatcherServletInstanceFactory(wac); DispatcherServletInstanceFactory servletFactory = new DispatcherServletInstanceFactory(wac);
// manually building WebSocketDeploymentInfo in order to avoid class cast exceptions // manually building WebSocketDeploymentInfo in order to avoid class cast exceptions
// with tomcat's implementation when using undertow 1.1.0+ // with tomcat's implementation when using undertow 1.1.0+
@ -85,7 +84,9 @@ public class UndertowTestServer implements WebSocketTestServer {
.addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, info); .addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, info);
for (final Filter filter : filters) { for (final Filter filter : filters) {
String filterName = filter.getClass().getName(); String filterName = filter.getClass().getName();
servletBuilder.addFilter(new FilterInfo(filterName, filter.getClass(), new FilterInstanceFactory(filter)).setAsyncSupported(true)); FilterInstanceFactory filterFactory = new FilterInstanceFactory(filter);
FilterInfo filterInfo = new FilterInfo(filterName, filter.getClass(), filterFactory);
servletBuilder.addFilter(filterInfo.setAsyncSupported(true));
for (DispatcherType type : DispatcherType.values()) { for (DispatcherType type : DispatcherType.values()) {
servletBuilder.addFilterUrlMapping(filterName, "/*", type); servletBuilder.addFilterUrlMapping(filterName, "/*", type);
} }
@ -94,7 +95,7 @@ public class UndertowTestServer implements WebSocketTestServer {
this.manager = defaultContainer().addDeployment(servletBuilder); this.manager = defaultContainer().addDeployment(servletBuilder);
this.manager.deploy(); this.manager.deploy();
HttpHandler httpHandler = this.manager.start(); HttpHandler httpHandler = this.manager.start();
this.server = Undertow.builder().addHttpListener(this.port, "localhost").setHandler(httpHandler).build(); this.server = Undertow.builder().addHttpListener(0, "localhost").setHandler(httpHandler).build();
} }
catch (ServletException ex) { catch (ServletException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
@ -109,11 +110,14 @@ public class UndertowTestServer implements WebSocketTestServer {
@Override @Override
public void start() throws Exception { public void start() throws Exception {
this.server.start(); this.server.start();
Undertow.ListenerInfo info = this.server.getListenerInfo().get(0);
this.port = ((InetSocketAddress) info.getAddress()).getPort();
} }
@Override @Override
public void stop() throws Exception { public void stop() throws Exception {
this.server.stop(); this.server.stop();
this.port = 0;
} }
@Override @Override

View File

@ -31,7 +31,6 @@ import org.junit.Test;
import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.SocketUtils;
import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketHttpHeaders; import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
@ -59,15 +58,13 @@ public class JettyWebSocketClientTests {
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
int port = SocketUtils.findAvailableTcpPort(); this.server = new TestJettyWebSocketServer(new TextWebSocketHandler());
this.server = new TestJettyWebSocketServer(port, new TextWebSocketHandler());
this.server.start(); this.server.start();
this.client = new JettyWebSocketClient(); this.client = new JettyWebSocketClient();
this.client.start(); this.client.start();
this.wsUrl = "ws://localhost:" + port + "/test"; this.wsUrl = "ws://localhost:" + this.server.getPort() + "/test";
} }
@After @After
@ -109,11 +106,11 @@ public class JettyWebSocketClientTests {
private final Server server; private final Server server;
public TestJettyWebSocketServer(int port, final WebSocketHandler webSocketHandler) { public TestJettyWebSocketServer(final WebSocketHandler webSocketHandler) {
this.server = new Server(); this.server = new Server();
ServerConnector connector = new ServerConnector(this.server); ServerConnector connector = new ServerConnector(this.server);
connector.setPort(port); connector.setPort(0);
this.server.addConnector(connector); this.server.addConnector(connector);
this.server.setHandler(new org.eclipse.jetty.websocket.server.WebSocketHandler() { this.server.setHandler(new org.eclipse.jetty.websocket.server.WebSocketHandler() {
@ -140,6 +137,10 @@ public class JettyWebSocketClientTests {
public void stop() throws Exception { public void stop() throws Exception {
this.server.stop(); this.server.stop();
} }
public int getPort() {
return ((ServerConnector) this.server.getConnectors()[0]).getLocalPort();
}
} }
} }