Skip to content

Commit e773668

Browse files
graebmbgklika
andauthored
Add eventstream.ServerListener.getBoundPort() (#491)
Lets users pass 0 to let OS autodetermine the port, and then query which port was selected. Co-authored-by: Vitaly Khalmansky <[email protected]>
1 parent a6505fb commit e773668

File tree

5 files changed

+63
-4
lines changed

5 files changed

+63
-4
lines changed

src/main/java/software/amazon/awssdk/crt/eventstream/ServerListener.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class ServerListener extends CrtResource {
1919
private final CompletableFuture<Void> shutdownComplete = new CompletableFuture<>();
2020
private TlsContext tlsContext = null;
2121
private final ServerBootstrap serverBootstrap;
22+
private int boundPort = -1;
2223

2324
/**
2425
* Instantiates a server listener. Once this function completes, the server is configured
@@ -36,9 +37,13 @@ public ServerListener(final String hostName, short port, final SocketOptions soc
3637
final ServerListenerHandler handler) {
3738

3839
long tlsContextPtr = tlsContext != null ? tlsContext.getNativeHandle(): 0;
39-
acquireNativeHandle(serverListenerNew(this, hostName.getBytes(StandardCharsets.UTF_8), port,
40+
long serverHandler = serverListenerNew(this, hostName.getBytes(StandardCharsets.UTF_8), port,
4041
socketOptions.getNativeHandle(), tlsContextPtr, serverBootstrap.getNativeHandle(),
41-
handler));
42+
handler);
43+
44+
boundPort = getBoundPort(serverHandler);
45+
46+
acquireNativeHandle(serverHandler);
4247

4348
if (tlsContext != null) {
4449
addReferenceTo(tlsContext);
@@ -60,6 +65,13 @@ protected boolean canReleaseReferencesImmediately() {
6065
return false;
6166
}
6267

68+
/**
69+
* @return the port which the listener socket is bound to.
70+
*/
71+
public int getBoundPort() {
72+
return boundPort;
73+
}
74+
6375
/**
6476
* Invoked from JNI. Completes the shutdownComplete future.
6577
*/
@@ -78,6 +90,8 @@ private static native long serverListenerNew(ServerListener serverListener, byte
7890
short port, long socketOptionsHandle,
7991
long tlsContextHandle, long bootstrapHandle,
8092
ServerListenerHandler handler);
93+
private static native int getBoundPort(long serverListener);
94+
8195
private static native void release(long serverListenerPtr);
8296

8397
}

src/native/event_stream_rpc_server.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,23 @@ jlong JNICALL Java_software_amazon_awssdk_crt_eventstream_ServerListener_serverL
578578
return (jlong)NULL;
579579
}
580580

581+
JNIEXPORT
582+
jint JNICALL Java_software_amazon_awssdk_crt_eventstream_ServerListener_getBoundPort(
583+
JNIEnv *env,
584+
jclass jni_class,
585+
jlong jni_server_listener) {
586+
(void)env;
587+
(void)jni_class;
588+
struct aws_event_stream_rpc_server_listener *listener =
589+
(struct aws_event_stream_rpc_server_listener *)jni_server_listener;
590+
if (!listener) {
591+
aws_jni_throw_runtime_exception(env, "ServerListener.getBoundPort: Invalid serverListener");
592+
return (jshort)-1;
593+
}
594+
595+
return (jint)aws_event_stream_rpc_server_listener_get_bound_port(listener);
596+
}
597+
581598
JNIEXPORT
582599
void JNICALL Java_software_amazon_awssdk_crt_eventstream_ServerListener_release(
583600
JNIEnv *env,

src/test/java/software/amazon/awssdk/crt/test/ServerListenerTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,34 @@ public void onConnectionShutdown(ServerConnection serverConnection, int errorCod
5353
socketOptions.close();
5454
}
5555

56+
@Test
57+
public void testSetupWith0PortAndTearDown() throws ExecutionException, InterruptedException, TimeoutException {
58+
SocketOptions socketOptions = new SocketOptions();
59+
socketOptions.connectTimeoutMs = 3000;
60+
socketOptions.domain = SocketOptions.SocketDomain.IPv4;
61+
socketOptions.type = SocketOptions.SocketType.STREAM;
62+
63+
EventLoopGroup elGroup = new EventLoopGroup(1);
64+
ServerBootstrap bootstrap = new ServerBootstrap(elGroup);
65+
ServerListener listener = new ServerListener("127.0.0.1", (short)0, socketOptions, null, bootstrap, new ServerListenerHandler() {
66+
public ServerConnectionHandler onNewConnection(ServerConnection serverConnection, int errorCode) {
67+
return null;
68+
}
69+
70+
public void onConnectionShutdown(ServerConnection serverConnection, int errorCode) {
71+
}
72+
});
73+
74+
int boundPort = listener.getBoundPort();
75+
assertTrue(boundPort > 0);
76+
listener.close();
77+
listener.getShutdownCompleteFuture().get(1, TimeUnit.SECONDS);
78+
bootstrap.close();
79+
elGroup.close();
80+
elGroup.getShutdownCompleteFuture().get(1, TimeUnit.SECONDS);
81+
socketOptions.close();
82+
}
83+
5684
@Test
5785
public void testBindErrorPropagates() throws ExecutionException, InterruptedException, TimeoutException {
5886
SocketOptions socketOptions = new SocketOptions();

0 commit comments

Comments
 (0)