GH-8785: Propagate WebSocket client connect fail

Fixes https://github.com/spring-projects/spring-integration/issues/8785

The `ClientWebSocketContainer.start()` delegates to the `IntegrationWebSocketConnectionManager`
which performs an async connection to the server.

* Wait for `connectionLatch` in the `ClientWebSocketContainer.start()`
and check for `this.openConnectionException != null` to re-throw.
Mark `ClientWebSocketContainer` as stopped in that case

**Cherry-pick to `6.1.x` & `6.0.x`**
This commit is contained in:
Artem Bilan
2023-11-03 11:57:01 -04:00
committed by Christian Tzolov
parent bcfd81abba
commit 537add5cf0
2 changed files with 30 additions and 3 deletions

View File

@@ -192,6 +192,20 @@ public final class ClientWebSocketContainer extends IntegrationWebSocketContaine
this.openConnectionException = null;
this.connectionLatch = new CountDownLatch(1);
this.connectionManager.start();
try {
this.connectionLatch.await(this.connectionTimeout, TimeUnit.SECONDS);
}
catch (InterruptedException ex) {
logger.error("'clientSession' has not been established during 'openConnection'");
}
if (this.openConnectionException != null) {
// The next 'this.connectionManager.stop()' call resets 'this.openConnectionException' to null
IllegalStateException exceptionToRethrow = new IllegalStateException(this.openConnectionException);
this.connectionManager.stop();
throw exceptionToRethrow;
}
}
}
finally {

View File

@@ -28,6 +28,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import jakarta.websocket.DeploymentException;
import org.apache.tomcat.websocket.Constants;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
@@ -126,10 +127,8 @@ public class ClientWebSocketContainerTests {
failure.set(true);
container.start();
assertThatIllegalStateException()
.isThrownBy(() -> container.getSession(null))
.isThrownBy(container::start)
.withCauseInstanceOf(CancellationException.class);
failure.set(false);
@@ -170,6 +169,20 @@ public class ClientWebSocketContainerTests {
.isEqualTo(ConcurrentWebSocketSessionDecorator.OverflowStrategy.DROP);
}
@Test
public void webSocketContainerFailsOnStartForInvalidUrl() {
StandardWebSocketClient webSocketClient = new StandardWebSocketClient();
ClientWebSocketContainer container =
new ClientWebSocketContainer(webSocketClient, server.getWsBaseUrl() + "/no_such_endpoint");
assertThatIllegalStateException()
.isThrownBy(container::start)
.withCauseExactlyInstanceOf(DeploymentException.class)
.withStackTraceContaining(
"The HTTP response from the server [404] did not permit the HTTP upgrade to WebSocket");
}
private static class TestWebSocketListener implements WebSocketListener {
public final CountDownLatch messageLatch = new CountDownLatch(1);