Skip to content

Commit

Permalink
Move non application endpoints to separate URL path
Browse files Browse the repository at this point in the history
- Fixes quarkusio#13144
- OpenAPI, Metrics, Micrometer, Health, Health UI endpoints are all now served under /q by default
- Previous behavior can be attained by setting `quarkus.http.framework-root-path` to `/`

Subsequent issue will be created for handling port and binding changes for non application endpoints
  • Loading branch information
kenfinnigan committed Dec 9, 2020
1 parent 337e9fa commit 81c5b7b
Show file tree
Hide file tree
Showing 67 changed files with 402 additions and 167 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ public void initializeJsonRegistry(MicrometerConfig config,
.addBeanClass(JsonMeterRegistryProvider.class)
.setUnremovable().build());
registryProviders.produce(new MicrometerRegistryProviderBuildItem(JsonMeterRegistry.class));
routes.produce(new RouteBuildItem(recorder.route(config.export.json.path), recorder.getHandler()));
routes.produce(new RouteBuildItem.Builder()
.routeFunction(recorder.route(config.export.json.path))
.handler(recorder.getHandler())
.nonApplicationRoute()
.build());
reflectiveClasses.produce(ReflectiveClassBuildItem
.builder("org.HdrHistogram.Histogram",
"org.HdrHistogram.DoubleHistogram",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,18 @@ void createPrometheusRoute(BuildProducer<RouteBuildItem> routes,
log.debug("PROMETHEUS CONFIG: " + pConfig);

// Exact match for resources matched to the root path
routes.produce(new RouteBuildItem(recorder.route(pConfig.path), recorder.getHandler()));
routes.produce(new RouteBuildItem.Builder()
.routeFunction(recorder.route(pConfig.path))
.handler(recorder.getHandler())
.nonApplicationRoute()
.build());

// Match paths that begin with the deployment path
String matchPath = pConfig.path + (pConfig.path.endsWith("/") ? "*" : "/*");
routes.produce(new RouteBuildItem(recorder.route(matchPath), recorder.getHandler()));
routes.produce(new RouteBuildItem.Builder()
.routeFunction(recorder.route(matchPath))
.handler(recorder.getHandler())
.nonApplicationRoute()
.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@
import io.quarkus.smallrye.health.runtime.SmallRyeReadinessHandler;
import io.quarkus.smallrye.health.runtime.SmallRyeWellnessHandler;
import io.quarkus.smallrye.openapi.deployment.spi.AddToOpenAPIDefinitionBuildItem;
import io.quarkus.vertx.http.deployment.FrameworkRootPathBuildItem;
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
import io.quarkus.vertx.http.runtime.HandlerType;
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
import io.smallrye.health.SmallRyeHealthReporter;
import io.smallrye.health.api.HealthGroup;
import io.smallrye.health.api.HealthGroups;
Expand Down Expand Up @@ -193,17 +192,28 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,
warnIfJaxRsPathUsed(index, WELLNESS);

// Register the health handler
routes.produce(new RouteBuildItem(healthConfig.rootPath, new SmallRyeHealthHandler(), HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.route(healthConfig.rootPath)
.handler(new SmallRyeHealthHandler())
.blockingRoute()
.nonApplicationRoute()
.build());

// Register the liveness handler
routes.produce(
new RouteBuildItem(healthConfig.rootPath + healthConfig.livenessPath, new SmallRyeLivenessHandler(),
HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.route(healthConfig.rootPath + healthConfig.livenessPath)
.handler(new SmallRyeLivenessHandler())
.blockingRoute()
.nonApplicationRoute()
.build());

// Register the readiness handler
routes.produce(
new RouteBuildItem(healthConfig.rootPath + healthConfig.readinessPath, new SmallRyeReadinessHandler(),
HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.route(healthConfig.rootPath + healthConfig.readinessPath)
.handler(new SmallRyeReadinessHandler())
.blockingRoute()
.nonApplicationRoute()
.build());

// Find all health groups
Set<String> healthGroups = new HashSet<>();
Expand All @@ -219,21 +229,30 @@ public void defineHealthRoutes(BuildProducer<RouteBuildItem> routes,
}

// Register the health group handlers
routes.produce(
new RouteBuildItem(healthConfig.rootPath + healthConfig.groupPath, new SmallRyeHealthGroupHandler(),
HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.route(healthConfig.rootPath + healthConfig.groupPath)
.handler(new SmallRyeHealthGroupHandler())
.blockingRoute()
.nonApplicationRoute()
.build());

SmallRyeIndividualHealthGroupHandler handler = new SmallRyeIndividualHealthGroupHandler();
for (String healthGroup : healthGroups) {
routes.produce(
new RouteBuildItem(healthConfig.rootPath + healthConfig.groupPath + "/" + healthGroup,
handler, HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.route(healthConfig.rootPath + healthConfig.groupPath + "/" + healthGroup)
.handler(handler)
.blockingRoute()
.nonApplicationRoute()
.build());
}

// Register the wellness handler
routes.produce(
new RouteBuildItem(healthConfig.rootPath + healthConfig.wellnessPath, new SmallRyeWellnessHandler(),
HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.route(healthConfig.rootPath + healthConfig.wellnessPath)
.handler(new SmallRyeWellnessHandler())
.blockingRoute()
.nonApplicationRoute()
.build());

}

Expand Down Expand Up @@ -275,21 +294,17 @@ private void warnIfJaxRsPathUsed(IndexView index, DotName healthAnnotation) {
}

@BuildStep
public void kubernetes(HttpBuildTimeConfig httpConfig,
public void kubernetes(FrameworkRootPathBuildItem frameworkRootPath,
SmallRyeHealthConfig healthConfig,
BuildProducer<KubernetesHealthLivenessPathBuildItem> livenessPathItemProducer,
BuildProducer<KubernetesHealthReadinessPathBuildItem> readinessPathItemProducer) {
if (httpConfig.rootPath == null) {
livenessPathItemProducer
.produce(new KubernetesHealthLivenessPathBuildItem(healthConfig.rootPath + healthConfig.livenessPath));
readinessPathItemProducer
.produce(new KubernetesHealthReadinessPathBuildItem(healthConfig.rootPath + healthConfig.readinessPath));
} else {
String basePath = httpConfig.rootPath.replaceAll("/$", "") + healthConfig.rootPath;
livenessPathItemProducer.produce(new KubernetesHealthLivenessPathBuildItem(basePath + healthConfig.livenessPath));
readinessPathItemProducer
.produce(new KubernetesHealthReadinessPathBuildItem(basePath + healthConfig.readinessPath));
}

livenessPathItemProducer.produce(
new KubernetesHealthLivenessPathBuildItem(
frameworkRootPath.adjustPath(healthConfig.rootPath + healthConfig.livenessPath)));
readinessPathItemProducer.produce(
new KubernetesHealthReadinessPathBuildItem(
frameworkRootPath.adjustPath(healthConfig.rootPath + healthConfig.readinessPath)));
}

@BuildStep
Expand Down Expand Up @@ -413,8 +428,16 @@ void registerHealthUiHandler(
if (shouldInclude(launchMode, healthConfig)) {
Handler<RoutingContext> handler = recorder.uiHandler(smallRyeHealthBuildItem.getHealthUiFinalDestination(),
smallRyeHealthBuildItem.getHealthUiPath(), runtimeConfig);
routeProducer.produce(new RouteBuildItem(healthConfig.ui.rootPath, handler));
routeProducer.produce(new RouteBuildItem(healthConfig.ui.rootPath + "/*", handler));
routeProducer.produce(new RouteBuildItem.Builder()
.route(healthConfig.ui.rootPath)
.handler(handler)
.nonApplicationRoute()
.build());
routeProducer.produce(new RouteBuildItem.Builder()
.route(healthConfig.ui.rootPath + "/*")
.handler(handler)
.nonApplicationRoute()
.build());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ public class DispatchedThreadTest {

@Test
public void check() {
RestAssured.when().get("/health/live").then()
RestAssured.when().get("/q/health/live").then()
.body("status", is("UP"),
"checks.status", contains("UP"),
"checks.name", contains("my-liveness-check"),
"checks.data.thread[0]", stringContainsInOrder("worker"),
"checks.data.thread[0]", not(stringContainsInOrder("loop")),
"checks.data.request[0]", is(true));

RestAssured.when().get("/health/ready").then()
RestAssured.when().get("/q/health/ready").then()
.body("status", is("UP"),
"checks.status", contains("UP"),
"checks.name", contains("my-readiness-check"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public class FailingUnitTest {

@Test
public void testHealthServlet() {
RestAssured.when().get("/health/live").then().statusCode(503);
RestAssured.when().get("/health/ready").then().statusCode(503);
RestAssured.when().get("/health").then().statusCode(503);
RestAssured.when().get("/q/health/live").then().statusCode(503);
RestAssured.when().get("/q/health/ready").then().statusCode(503);
RestAssured.when().get("/q/health").then().statusCode(503);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ public void testHealth() {
// the health check does not set a content type so we need to force the parser
try {
RestAssured.defaultParser = Parser.JSON;
when().get("/health/live").then()
when().get("/q/health/live").then()
.body("status", is("UP"),
"checks.status", contains("UP"),
"checks.name", contains("noScope"));
when().get("/health/live").then()
when().get("/q/health/live").then()
.body("status", is("DOWN"),
"checks.status", contains("DOWN"),
"checks.name", contains("noScope"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ public void testHealth() {
// the health check does not set a content type so we need to force the parser
try {
RestAssured.defaultParser = Parser.JSON;
when().get("/health/ready").then()
when().get("/q/health/ready").then()
.body("status", is("UP"),
"checks.status", contains("UP", "UP"),
"checks.name", containsInAnyOrder("alpha1", "bravo1"));
when().get("/health/ready").then()
when().get("/q/health/ready").then()
.body("status", is("UP"),
"checks.status", contains("UP", "UP"),
"checks.name", containsInAnyOrder("alpha1", "bravo2"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

public class HealthOpenAPITest {

private static final String OPEN_API_PATH = "/openapi";
private static final String OPEN_API_PATH = "/q/openapi";

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void testHealth() {
// the health check does not set a content type so we need to force the parser
try {
RestAssured.defaultParser = Parser.JSON;
RestAssured.when().get("/health/live").then()
RestAssured.when().get("/q/health/live").then()
.body("status", is("UP"),
"checks.status", contains("UP"),
"checks.name", contains("basic"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class WellnessHealthCheckTest {
public void testWellness() {
try {
RestAssured.defaultParser = Parser.JSON;
when().get("/health/well").then()
when().get("/q/health/well").then()
.body("status", is("UP"),
"checks.status", contains("UP"),
"checks.name", contains(WellnessHC.class.getName()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class CustomConfigTest {

@Test
public void shouldUseCustomConfig() {
RestAssured.when().get("/custom").then().statusCode(200).body(containsString("SmallRye Health"));
RestAssured.when().get("/custom/index.html").then().statusCode(200).body(containsString("SmallRye Health"));
RestAssured.when().get("/q/custom").then().statusCode(200).body(containsString("SmallRye Health"));
RestAssured.when().get("/q/custom/index.html").then().statusCode(200).body(containsString("SmallRye Health"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public class DisabledTest {

@Test
public void shouldUseDefaultConfig() {
RestAssured.when().get("/health-ui").then().statusCode(404);
RestAssured.when().get("/q/health-ui").then().statusCode(404);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,9 @@
import io.quarkus.smallrye.metrics.runtime.MetadataHolder;
import io.quarkus.smallrye.metrics.runtime.SmallRyeMetricsRecorder;
import io.quarkus.smallrye.metrics.runtime.TagHolder;
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
import io.quarkus.vertx.http.deployment.FrameworkRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
import io.quarkus.vertx.http.runtime.HandlerType;
import io.smallrye.metrics.MetricProducer;
import io.smallrye.metrics.MetricRegistries;
import io.smallrye.metrics.MetricsRequestHandler;
Expand Down Expand Up @@ -154,7 +153,7 @@ MetricsCapabilityBuildItem metricsCapabilityBuildItem() {
@Record(STATIC_INIT)
void createRoute(BuildProducer<RouteBuildItem> routes,
SmallRyeMetricsRecorder recorder,
HttpRootPathBuildItem httpRoot,
FrameworkRootPathBuildItem frameworkRoot,
BuildProducer<NotFoundPageDisplayableEndpointBuildItem> displayableEndpoints,
LaunchModeBuildItem launchModeBuildItem) {
Function<Router, Route> route = recorder.route(metrics.path + (metrics.path.endsWith("/") ? "*" : "/*"));
Expand All @@ -164,8 +163,18 @@ void createRoute(BuildProducer<RouteBuildItem> routes,
if (launchModeBuildItem.getLaunchMode().isDevOrTest()) {
displayableEndpoints.produce(new NotFoundPageDisplayableEndpointBuildItem(metrics.path));
}
routes.produce(new RouteBuildItem(route, recorder.handler(httpRoot.adjustPath(metrics.path)), HandlerType.BLOCKING));
routes.produce(new RouteBuildItem(slash, recorder.handler(httpRoot.adjustPath(metrics.path)), HandlerType.BLOCKING));
routes.produce(new RouteBuildItem.Builder()
.routeFunction(route)
.handler(recorder.handler(frameworkRoot.adjustPath(metrics.path)))
.blockingRoute()
.nonApplicationRoute()
.build());
routes.produce(new RouteBuildItem.Builder()
.routeFunction(slash)
.handler(recorder.handler(frameworkRoot.adjustPath(metrics.path)))
.blockingRoute()
.nonApplicationRoute()
.build());
}

@BuildStep
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void test() {
when().get("/getvalue/mycounter").then().body(equalTo("2"));

// jax-rs metrics are disabled
when().get("/metrics").then()
when().get("/q/metrics").then()
.body(not(containsString("io.quarkus.smallrye.metrics.deployment.DevModeMetricsTest$MetricsResource")));

// trigger a reload by adding a new metric (mycounter2)
Expand All @@ -95,7 +95,7 @@ public void test() {
when().get("/getvalue/mycounter2").then().body(equalTo("1"));

// jax-rs metrics are enabled
when().get("/metrics").then()
when().get("/q/metrics").then()
.body(containsString("io.quarkus.smallrye.metrics.deployment.DevModeMetricsTest$MetricsResource"));

// disable jax-rs metrics via quarkus.resteasy.metrics.enabled
Expand All @@ -111,7 +111,7 @@ public void test() {
.statusCode(204);

// jax-rs metrics are disabled
when().get("/metrics").then()
when().get("/q/metrics").then()
.body(not(containsString("io.quarkus.smallrye.metrics.deployment.DevModeMetricsTest$MetricsResource")));

// enable jax-rs metrics via quarkus.resteasy.metrics.enabled
Expand All @@ -123,7 +123,7 @@ public void test() {
.statusCode(204);

// jax-rs metrics are enabled
when().get("/metrics").then()
when().get("/q/metrics").then()
.body(containsString("io.quarkus.smallrye.metrics.deployment.DevModeMetricsTest$MetricsResource"));

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class MicrometerMetricsCompatibilityModeTest {

@Test
public void verifyOpenMetricsExport() {
RestAssured.when().get("/metrics").then()
RestAssured.when().get("/q/metrics").then()
.body(containsString("jvm_memory_max_bytes{"),
containsString("jvm_memory_used_bytes{"),
containsString("jvm_memory_committed_bytes{"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.quarkus.vertx.http.deployment.devmode.NotFoundPageDisplayableEndpointBuildItem;
import io.quarkus.vertx.http.runtime.HandlerType;
import io.smallrye.openapi.api.OpenApiConfig;
import io.smallrye.openapi.api.OpenApiConfigImpl;
import io.smallrye.openapi.api.OpenApiDocument;
Expand Down Expand Up @@ -169,7 +168,12 @@ RouteBuildItem handler(LaunchModeBuildItem launch,
}

Handler<RoutingContext> handler = recorder.handler(openApiRuntimeConfig);
return new RouteBuildItem(openApiConfig.path, handler, HandlerType.BLOCKING);
return new RouteBuildItem.Builder()
.route(openApiConfig.path)
.handler(handler)
.blockingRoute()
.nonApplicationRoute()
.build();
}

@BuildStep
Expand Down
Loading

0 comments on commit 81c5b7b

Please sign in to comment.