Skip to content

Commit e88269c

Browse files
authored
Merge pull request #4448 from kubernetes-client/copilot/add-websocket-handler-state-check
Make PortForwardResult implement Closeable and expose handler state
2 parents 4f8d7fd + cfdb408 commit e88269c

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

util/src/main/java/io/kubernetes/client/PortForward.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public PortForwardResult forward(String namespace, String name, List<Integer> po
133133
* PortForwardResult contains the result of an Attach call, it includes streams for stdout stderr
134134
* and stdin.
135135
*/
136-
public static class PortForwardResult {
136+
public static class PortForwardResult implements java.io.Closeable {
137137
private WebSocketStreamHandler handler;
138138
private HashMap<Integer, Integer> streams;
139139
private List<Integer> ports;
@@ -151,6 +151,23 @@ public PortForwardResult(WebSocketStreamHandler handler, List<Integer> ports)
151151
this.ports = ports;
152152
}
153153

154+
/**
155+
* Check if the underlying handler is closed.
156+
*
157+
* @return true if the handler is closed, false otherwise.
158+
*/
159+
public boolean isClosed() {
160+
return handler.isClosed();
161+
}
162+
163+
/**
164+
* Close the underlying WebSocketStreamHandler.
165+
*/
166+
@Override
167+
public void close() {
168+
handler.close();
169+
}
170+
154171
/** Initialize the connection. Must be called after the web socket has been opened. */
155172
public void init() throws IOException {
156173
for (int i = 0; i < ports.size(); i++) {

util/src/main/java/io/kubernetes/client/util/WebSocketStreamHandler.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ public Throwable getError() {
117117
return this.error;
118118
}
119119

120+
/**
121+
* Check if the handler is closed.
122+
*
123+
* @return true if the handler is closed, false otherwise.
124+
*/
125+
public synchronized boolean isClosed() {
126+
return state == State.CLOSED;
127+
}
128+
120129
@Override
121130
public synchronized void close() {
122131
if (state != State.CLOSED) {

util/src/test/java/io/kubernetes/client/PortForwardTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,41 @@ void brokenPortPassing() throws IOException, InterruptedException {
190190

191191
assertThat(thrownException).isInstanceOf(IOException.class);
192192
}
193+
194+
@Test
195+
void portForwardResultCloseable() throws IOException {
196+
WebSocketStreamHandler handler = new WebSocketStreamHandler();
197+
List<Integer> ports = new ArrayList<>();
198+
ports.add(80);
199+
200+
final PortForwardResult result = new PortForwardResult(handler, ports);
201+
202+
handler.open("wss", null);
203+
204+
// Initially, handler should not be closed
205+
assertThat(result.isClosed()).isFalse();
206+
207+
// Close the result
208+
result.close();
209+
210+
// After closing, handler should be closed
211+
assertThat(result.isClosed()).isTrue();
212+
}
213+
214+
@Test
215+
void portForwardResultTryWithResources() throws IOException {
216+
WebSocketStreamHandler handler = new WebSocketStreamHandler();
217+
List<Integer> ports = new ArrayList<>();
218+
ports.add(80);
219+
220+
handler.open("wss", null);
221+
222+
try (PortForwardResult result = new PortForwardResult(handler, ports)) {
223+
// Handler should be open inside try block
224+
assertThat(result.isClosed()).isFalse();
225+
}
226+
227+
// Handler should be closed after try-with-resources block
228+
assertThat(handler.isClosed()).isTrue();
229+
}
193230
}

util/src/test/java/io/kubernetes/client/WebsocketStreamHandlerTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,24 @@ void handlerReceivingClosed() throws IOException {
168168
}).isInstanceOf(IOException.class);
169169
}
170170

171+
@Test
172+
void handlerIsClosed() throws IOException {
173+
WebSocketStreamHandler handler = new WebSocketStreamHandler();
174+
MockWebSocket mockWebSocket = new MockWebSocket();
175+
176+
handler.open(testProtocol, mockWebSocket);
177+
178+
// Initially, handler should not be closed
179+
assertThat(handler.isClosed()).isFalse();
180+
181+
// Close the handler
182+
handler.close();
183+
184+
// After closing, handler should be closed
185+
assertThat(handler.isClosed()).isTrue();
186+
assertThat(mockWebSocket.closed).isTrue();
187+
}
188+
171189
private static class MockWebSocket implements WebSocket {
172190
byte[] data;
173191
private boolean closed = false;

0 commit comments

Comments
 (0)