Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion util/src/main/java/io/kubernetes/client/PortForward.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public PortForwardResult forward(String namespace, String name, List<Integer> po
* PortForwardResult contains the result of an Attach call, it includes streams for stdout stderr
* and stdin.
*/
public static class PortForwardResult {
public static class PortForwardResult implements java.io.Closeable {
private WebSocketStreamHandler handler;
private HashMap<Integer, Integer> streams;
private List<Integer> ports;
Expand All @@ -151,6 +151,23 @@ public PortForwardResult(WebSocketStreamHandler handler, List<Integer> ports)
this.ports = ports;
}

/**
* Check if the underlying handler is closed.
*
* @return true if the handler is closed, false otherwise.
*/
public boolean isClosed() {
return handler.isClosed();
}

/**
* Close the underlying WebSocketStreamHandler.
*/
@Override
public void close() {
handler.close();
}

/** Initialize the connection. Must be called after the web socket has been opened. */
public void init() throws IOException {
for (int i = 0; i < ports.size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ public Throwable getError() {
return this.error;
}

/**
* Check if the handler is closed.
*
* @return true if the handler is closed, false otherwise.
*/
public synchronized boolean isClosed() {
return state == State.CLOSED;
}

@Override
public synchronized void close() {
if (state != State.CLOSED) {
Expand Down
37 changes: 37 additions & 0 deletions util/src/test/java/io/kubernetes/client/PortForwardTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,41 @@ void brokenPortPassing() throws IOException, InterruptedException {

assertThat(thrownException).isInstanceOf(IOException.class);
}

@Test
void portForwardResultCloseable() throws IOException {
WebSocketStreamHandler handler = new WebSocketStreamHandler();
List<Integer> ports = new ArrayList<>();
ports.add(80);

final PortForwardResult result = new PortForwardResult(handler, ports);

handler.open("wss", null);

// Initially, handler should not be closed
assertThat(result.isClosed()).isFalse();

// Close the result
result.close();

// After closing, handler should be closed
assertThat(result.isClosed()).isTrue();
}

@Test
void portForwardResultTryWithResources() throws IOException {
WebSocketStreamHandler handler = new WebSocketStreamHandler();
List<Integer> ports = new ArrayList<>();
ports.add(80);

handler.open("wss", null);

try (PortForwardResult result = new PortForwardResult(handler, ports)) {
// Handler should be open inside try block
assertThat(result.isClosed()).isFalse();
}

// Handler should be closed after try-with-resources block
assertThat(handler.isClosed()).isTrue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,24 @@ void handlerReceivingClosed() throws IOException {
}).isInstanceOf(IOException.class);
}

@Test
void handlerIsClosed() throws IOException {
WebSocketStreamHandler handler = new WebSocketStreamHandler();
MockWebSocket mockWebSocket = new MockWebSocket();

handler.open(testProtocol, mockWebSocket);

// Initially, handler should not be closed
assertThat(handler.isClosed()).isFalse();

// Close the handler
handler.close();

// After closing, handler should be closed
assertThat(handler.isClosed()).isTrue();
assertThat(mockWebSocket.closed).isTrue();
}

private static class MockWebSocket implements WebSocket {
byte[] data;
private boolean closed = false;
Expand Down
Loading