Joost den Boer
Joost den Boer

Reputation: 5047

Get live http port value of Quarkus application

A service endpoint needs to return a url to another endpoint of the same service. How to get the actual real live http port the Quarkus service is running on?

When starting the service with quarkus dev the service runs on 8080, but when running tests it runs on 8081. The quarkus.http.port value is always 8080 regardless whether the service run in test or not.

Th endpoint resource gets the properties quarkus.http.port and quarkus.http.host config properties injected to determine the url to return, but when running a QuarkusTest test case, the url still contains 8080 instead of 8081. Using the ConfigProvider.getConfig() instead of injecting the values makes no difference.

Therefore the test case is not able to perform a next request based on the received url.

So how to get the actual http port value, the one Quarkus reports when starting up?

Update: I have now worked around it by adding %test.quarkus.http.port=8081 to the application properties, but in my opinion Quarkus should report the real http address in quarkus.http.port regardless which profile is active.

Upvotes: 1

Views: 256

Answers (1)

zforgo
zforgo

Reputation: 3316

According to documentation

While Quarkus will listen on port 8080 by default, when running tests it defaults to 8081. This allows you to run tests while having the application running in parallel.
...
You can configure the ports used by tests by configuring quarkus.http.test-port for HTTP and quarkus.http.test-ssl-port for HTTPS in your application.properties

To determine the bound http port, you can use io.vertx.core.http.HttpServerRequest like:

@Path("/hello")
public class ExampleResource {

    @Context
    HttpServerRequest serverRequest;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getPort() {

        var port = serverRequest.localAddress().port();
        Log.infof("current port is: %s ", port);
        return port;
    }
}

But if you want to create an URL for an endpoint (like a sophisticated 201-Created response with Location header), I suggest to use jakarta.ws.rs.core.UriBuilder

@Path("/hello")
public class ExampleResource {


    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/{id}")
    public String get(@PathParam("id") String id) {
        return "Got id: " + id;
    }

    @POST
    public Response create() {
        var uri = UriBuilder.
                fromMethod(ExampleResource.class, "get")
                .build("newId");
        return Response.created(uri).build();
    }
}

Now, this test case will pass

@QuarkusTest
class ExampleResourceTest {

    @Test
    void testCreate() {
        var loc = given()
                .when().post("/hello")
                .then()
                .statusCode(201)

                .extract().header("Location");
        assertEquals(8081, URI.create(loc).getPort());
    }
}

Upvotes: 0

Related Questions