Close and reopen the socket if necessary when the properties change.

This commit is contained in:
akwizgran
2011-10-06 17:39:51 +01:00
parent f23e89c80e
commit bb9f03f1e8
2 changed files with 73 additions and 1 deletions

View File

@@ -130,6 +130,18 @@ abstract class SocketPlugin implements StreamTransportPlugin {
throws InvalidPropertiesException {
if(!started) throw new IllegalStateException();
localProperties = properties;
// Close and reopen the socket if its address has changed
if(socket != null) {
SocketAddress addr = socket.getLocalSocketAddress();
if(!getLocalSocketAddress().equals(addr)) {
try {
socket.close();
} catch(IOException e) {
// FIXME: Logging
}
executor.execute(createBinder());
}
}
}
public synchronized void setRemoteProperties(ContactId c,

View File

@@ -58,13 +58,15 @@ public class SimpleSocketPluginTest extends TestCase {
Socket s = new Socket();
assertEquals(0, callback.incomingConnections);
s.connect(addr, 100);
Thread.sleep(100);
Thread.sleep(10);
assertEquals(1, callback.incomingConnections);
s.close();
// Stop the plugin
plugin.stop();
Thread.sleep(10);
// The plugin should no longer be listening
try {
s = new Socket();
s.connect(addr, 100);
fail();
} catch(IOException expected) {}
@@ -110,6 +112,64 @@ public class SimpleSocketPluginTest extends TestCase {
plugin.stop();
}
@Test
public void testUpdatingPropertiesReopensSocket() throws Exception {
StubCallback callback = new StubCallback();
localProperties.put("host", "127.0.0.1");
localProperties.put("port", "0");
SimpleSocketPlugin plugin =
new SimpleSocketPlugin(new ImmediateExecutor(), 10);
plugin.start(localProperties, remoteProperties, config, callback);
// The plugin should have bound a socket and stored the port number
assertNotNull(callback.localProperties);
String host = callback.localProperties.get("host");
assertNotNull(host);
assertEquals("127.0.0.1", host);
String portString = callback.localProperties.get("port");
assertNotNull(portString);
int port = Integer.valueOf(portString);
assertTrue(port > 0 && port < 65536);
// The plugin should be listening on the port
InetSocketAddress addr = new InetSocketAddress(host, port);
Socket s = new Socket();
assertEquals(0, callback.incomingConnections);
s.connect(addr, 100);
Thread.sleep(10);
assertEquals(1, callback.incomingConnections);
s.close();
// Update the local properties with a new port number
localProperties.put("port", "0");
plugin.setLocalProperties(localProperties);
// The plugin should no longer be listening on the old port
try {
s = new Socket();
s.connect(addr, 100);
fail();
} catch(IOException expected) {}
// Find out what the new port is
portString = callback.localProperties.get("port");
assertNotNull(portString);
int newPort = Integer.valueOf(portString);
assertFalse(newPort == port);
// The plugin should be listening on the new port
addr = new InetSocketAddress(host, newPort);
assertEquals(1, callback.incomingConnections);
s = new Socket();
s.connect(addr, 100);
Thread.sleep(10);
assertEquals(2, callback.incomingConnections);
s.close();
// Stop the plugin
plugin.stop();
Thread.sleep(10);
// The plugin should no longer be listening
try {
s = new Socket();
s.connect(addr, 100);
fail();
} catch(IOException expected) {}
}
private static class ImmediateExecutor implements Executor {
public void execute(Runnable r) {