GH-3299: Fix client connectionId for TCP/NIO

Resolves https://github.com/spring-projects/spring-integration/issues/3299

Connect before creating the `TcpNioConnection` object and publishing the
`TcpConnectionOpenEvent`.

This was a regression caused by supporting connect timout; which moved
the connect to after the object was created and event published, causing
the `connectionId` to start with `unknown`.

**cherry-pick to 5.3.x, 5.2.x**
This commit is contained in:
Gary Russell
2020-06-10 09:30:58 -04:00
committed by Artem Bilan
parent 3499cd615a
commit 7ec1f5cc4b
2 changed files with 23 additions and 13 deletions

View File

@@ -87,6 +87,7 @@ public class TcpNioClientConnectionFactory extends
try {
SocketChannel socketChannel = SocketChannel.open();
setSocketAttributes(socketChannel.socket());
connect(socketChannel);
TcpNioConnection connection =
this.tcpNioConnectionSupport.createNewConnection(socketChannel, false, isLookupHost(),
getApplicationEventPublisher(), getComponentName());
@@ -98,18 +99,6 @@ public class TcpNioClientConnectionFactory extends
}
TcpConnectionSupport wrappedConnection = wrapConnection(connection);
initializeConnection(wrappedConnection, socketChannel.socket());
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(getHost(), getPort()));
boolean connected = socketChannel.finishConnect();
long timeLeft = getConnectTimeout().toMillis();
while (!connected && timeLeft > 0) {
Thread.sleep(50); // NOSONAR Magic #
connected = socketChannel.finishConnect();
timeLeft -= 50; // NOSONAR Magic #
}
if (!connected) {
throw new IOException("Not connected after connectTimeout");
}
if (getSoTimeout() > 0) {
connection.setLastRead(System.currentTimeMillis());
}
@@ -127,6 +116,21 @@ public class TcpNioClientConnectionFactory extends
}
}
private void connect(SocketChannel socketChannel) throws IOException, InterruptedException {
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(getHost(), getPort()));
boolean connected = socketChannel.finishConnect();
long timeLeft = getConnectTimeout().toMillis();
while (!connected && timeLeft > 0) {
Thread.sleep(50); // NOSONAR Magic #
connected = socketChannel.finishConnect();
timeLeft -= 50; // NOSONAR Magic #
}
if (!connected) {
throw new IOException("Not connected after connectTimeout");
}
}
/**
* When set to true, connections created by this factory attempt
* to use direct buffers where possible.

View File

@@ -142,7 +142,12 @@ public class TcpNioConnectionTests {
assertThat(latch.await(10000, TimeUnit.MILLISECONDS)).isTrue();
TcpNioClientConnectionFactory factory = new TcpNioClientConnectionFactory("localhost",
serverSocket.get().getLocalPort());
factory.setApplicationEventPublisher(nullPublisher);
AtomicReference<String> connectionId = new AtomicReference<>();
factory.setApplicationEventPublisher(event -> {
if (event instanceof TcpConnectionOpenEvent) {
connectionId.set(((TcpConnectionOpenEvent) event).getConnectionId());
}
});
factory.setSoTimeout(100);
factory.start();
try {
@@ -157,6 +162,7 @@ public class TcpNioConnectionTests {
done.countDown();
factory.stop();
serverSocket.get().close();
assertThat(connectionId.get()).startsWith("localhost");
}
@Test