diff --git a/vertx-core/src/main/java/io/vertx/core/net/impl/NetServerImpl.java b/vertx-core/src/main/java/io/vertx/core/net/impl/NetServerImpl.java index e4f10b4b84e..8461abbba4b 100644 --- a/vertx-core/src/main/java/io/vertx/core/net/impl/NetServerImpl.java +++ b/vertx-core/src/main/java/io/vertx/core/net/impl/NetServerImpl.java @@ -555,11 +555,13 @@ private void bind( } }); } - // Update port to actual port when it is not a domain socket as wildcard port 0 might have been used + // Update port and address to actual values when it is not a domain socket as wildcard port 0 might have been used + var actualLocalAddress = localAddress; if (bindAddress.isInetSocket()) { actualPort = ((InetSocketAddress)ch.localAddress()).getPort(); + actualLocalAddress = SocketAddress.inetSocketAddress(actualPort, localAddress.host()); } - metrics = createMetrics(localAddress); + metrics = createMetrics(actualLocalAddress); promise.complete(ch); } else { promise.fail(res.cause()); diff --git a/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeHttpServerMetrics.java b/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeHttpServerMetrics.java index dc9e19e9375..684065d8aa2 100644 --- a/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeHttpServerMetrics.java +++ b/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeHttpServerMetrics.java @@ -14,7 +14,6 @@ import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.ServerWebSocket; -import io.vertx.core.http.WebSocketBase; import io.vertx.core.net.SocketAddress; import io.vertx.core.spi.metrics.HttpServerMetrics; import io.vertx.core.spi.observability.HttpRequest; @@ -31,6 +30,11 @@ public class FakeHttpServerMetrics extends FakeTCPMetrics implements HttpServerM private final ConcurrentMap webSockets = new ConcurrentHashMap<>(); private final Set requests = ConcurrentHashMap.newKeySet(); + private final SocketAddress socketAddress; + + public FakeHttpServerMetrics(SocketAddress socketAddress) { + this.socketAddress = socketAddress; + } public WebSocketMetric getWebSocketMetric(ServerWebSocket ws) { return webSockets.get(ws.path()); @@ -44,6 +48,10 @@ public HttpServerMetric getResponseMetric(String uri) { return requests.stream().filter(m -> m.uri.equals(uri)).findFirst().orElse(null); } + public SocketAddress socketAddress() { + return socketAddress; + } + @Override public HttpServerMetric requestBegin(SocketMetric socketMetric, HttpRequest request) { HttpServerMetric metric = new HttpServerMetric(request, socketMetric); diff --git a/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeVertxMetrics.java b/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeVertxMetrics.java index 802d15d5245..94e1733ab36 100644 --- a/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeVertxMetrics.java +++ b/vertx-core/src/test/java/io/vertx/test/fakemetrics/FakeVertxMetrics.java @@ -55,7 +55,7 @@ public EventBusMetrics createEventBusMetrics() { } public HttpServerMetrics createHttpServerMetrics(HttpServerOptions options, SocketAddress localAddress) { - return new FakeHttpServerMetrics(); + return new FakeHttpServerMetrics(localAddress); } public HttpClientMetrics createHttpClientMetrics(HttpClientOptions options) { diff --git a/vertx-core/src/test/java/io/vertx/tests/metrics/MetricsPortTest.java b/vertx-core/src/test/java/io/vertx/tests/metrics/MetricsPortTest.java new file mode 100644 index 00000000000..9d4adc76746 --- /dev/null +++ b/vertx-core/src/test/java/io/vertx/tests/metrics/MetricsPortTest.java @@ -0,0 +1,57 @@ +package io.vertx.tests.metrics; + +import io.vertx.core.Vertx; +import io.vertx.core.VertxOptions; +import io.vertx.core.http.HttpClientRequest; +import io.vertx.core.http.HttpServerOptions; +import io.vertx.core.http.RequestOptions; +import io.vertx.core.metrics.MetricsOptions; +import io.vertx.test.core.TestUtils; +import io.vertx.test.fakemetrics.FakeHttpServerMetrics; +import io.vertx.test.fakemetrics.FakeMetricsBase; +import io.vertx.test.fakemetrics.FakeMetricsFactory; +import io.vertx.test.http.HttpTestBase; +import org.junit.Test; + +public class MetricsPortTest extends HttpTestBase { + + @Override + protected HttpServerOptions createBaseServerOptions() { + return new HttpServerOptions().setPort(0).setHost(DEFAULT_HTTP_HOST); + } + + @Override + protected VertxOptions getOptions() { + VertxOptions options = super.getOptions(); + options.setMetricsOptions(new MetricsOptions().setEnabled(true)); + return options; + } + + @Override + protected Vertx createVertx(VertxOptions options) { + return Vertx.builder().with(options) + .withMetrics(new FakeMetricsFactory()) + .build(); + } + + @Test + public void actualPortInMetricsWhenDynamicPortIsUsed() throws Exception { + server.requestHandler(req -> { + FakeHttpServerMetrics metrics = FakeMetricsBase.getMetrics(server); + + assertEquals(server.actualPort(), metrics.socketAddress().port()); + + req.response().end(); + testComplete(); + }); + + startServer(); + + var requestOptions = new RequestOptions() + .setPort(server.actualPort()); + + client.request(new RequestOptions(requestOptions).setURI(TestUtils.randomAlphaString(16))).onComplete(onSuccess(HttpClientRequest::send)); + await(); + } + +}