8877 Make KeycloakMetricsHandler aware of context-path

Adapt KeycloakMetricsHandler to consider custom relative paths via `kc.http.relative-path`
or --http-relative-path=/auth. Previously only the fixed path /metrics was allowed which did not work
with custom context-paths.

- Adapted KeycloakProcessor to Pedros proposal from 0b28d71dd0
- Removed unnecessary KeycloakMetricsHandler
- Added MetricsDistTest

Fixes #8877
This commit is contained in:
Thomas Darimont 2021-11-22 21:46:28 +01:00 committed by Pedro Igor
parent 48835576da
commit 50060775f6
4 changed files with 16 additions and 35 deletions

View file

@ -67,6 +67,7 @@ import io.quarkus.hibernate.orm.deployment.PersistenceXmlDescriptorBuildItem;
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.smallrye.health.runtime.SmallRyeHealthHandler;
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
import io.quarkus.vertx.http.deployment.RouteBuildItem;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
@ -117,7 +118,6 @@ import org.keycloak.representations.provider.ScriptProviderDescriptor;
import org.keycloak.representations.provider.ScriptProviderMetadata;
import org.keycloak.quarkus.runtime.integration.web.NotFoundHandler;
import org.keycloak.services.ServicesLogger;
import org.keycloak.quarkus.runtime.services.health.KeycloakMetricsHandler;
import org.keycloak.theme.FolderThemeProviderFactory;
import org.keycloak.transaction.JBossJtaTransactionManagerLookup;
import org.keycloak.quarkus.runtime.Environment;
@ -132,6 +132,7 @@ class KeycloakProcessor {
private static final String JAR_FILE_SEPARATOR = "!/";
private static final String DEFAULT_HEALTH_ENDPOINT = "/health";
private static final String DEFAULT_METRICS_ENDPOINT = "/metrics";
private static final Map<String, Function<ScriptProviderMetadata, ProviderFactory>> DEPLOYEABLE_SCRIPT_PROVIDERS = new HashMap<>();
private static final String KEYCLOAK_SCRIPTS_JSON_PATH = "META-INF/keycloak-scripts.json";
@ -344,14 +345,16 @@ class KeycloakProcessor {
*
* @param routes
*/
@Record(ExecutionTime.STATIC_INIT)
@BuildStep
void initializeMetrics(BuildProducer<RouteBuildItem> routes) {
void initializeMetrics(KeycloakRecorder recorder, BuildProducer<RouteBuildItem> routes, NonApplicationRootPathBuildItem nonAppRootPath) {
Handler<RoutingContext> healthHandler;
Handler<RoutingContext> metricsHandler;
if (isMetricsEnabled()) {
healthHandler = new SmallRyeHealthHandler();
metricsHandler = new KeycloakMetricsHandler();
String rootPath = nonAppRootPath.getNormalizedHttpRootPath();
metricsHandler = recorder.createMetricsHandler(rootPath.concat(DEFAULT_METRICS_ENDPOINT).replace("//", "/"));
} else {
healthHandler = new NotFoundHandler();
metricsHandler = new NotFoundHandler();
@ -360,7 +363,7 @@ class KeycloakProcessor {
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT).handler(healthHandler).build());
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/live")).handler(healthHandler).build());
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/ready")).handler(healthHandler).build());
routes.produce(RouteBuildItem.builder().route(KeycloakMetricsHandler.DEFAULT_METRICS_ENDPOINT).handler(metricsHandler).build());
routes.produce(RouteBuildItem.builder().route(DEFAULT_METRICS_ENDPOINT).handler(metricsHandler).build());
}
@BuildStep

View file

@ -27,6 +27,9 @@ import org.infinispan.configuration.parsing.ConfigurationBuilderHolder;
import org.infinispan.configuration.parsing.ParserRegistry;
import org.infinispan.jboss.marshalling.core.JBossUserMarshaller;
import org.infinispan.manager.DefaultCacheManager;
import io.quarkus.smallrye.metrics.runtime.SmallRyeMetricsHandler;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import org.keycloak.common.Profile;
import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
@ -152,4 +155,10 @@ public class KeycloakRecorder {
}
});
}
public Handler<RoutingContext> createMetricsHandler(String path) {
SmallRyeMetricsHandler metricsHandler = new SmallRyeMetricsHandler();
metricsHandler.setMetricsPath(path);
return metricsHandler;
}
}

View file

@ -1,29 +0,0 @@
/*
* Copyright 2020 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.quarkus.runtime.services.health;
import io.quarkus.smallrye.metrics.runtime.SmallRyeMetricsHandler;
public class KeycloakMetricsHandler extends SmallRyeMetricsHandler {
public static final String DEFAULT_METRICS_ENDPOINT = "/metrics";
public KeycloakMetricsHandler() {
setMetricsPath(DEFAULT_METRICS_ENDPOINT);
}
}

View file

@ -20,7 +20,6 @@ package org.keycloak.it.cli.dist;
import static io.restassured.RestAssured.when;
import static org.hamcrest.Matchers.containsString;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.keycloak.it.junit5.extension.DistributionTest;
@ -37,7 +36,6 @@ public class MetricsDistTest {
.body(containsString("base_gc_total"));
}
@Disabled("https://github.com/keycloak/keycloak/pull/8878")
@Test
@Launch({ "start-dev", "--http-relative-path=/auth", "--metrics-enabled=true" })
void testMetricsEndpointUsingRelativePath() {