Avoid internal server error when root path and non-appliation root path are both set and the wrong metrics/health endpoint is called.
Fixes #17166 Avoid internal server error when root path and non-appliation root path are both set and the wrong metrics/health endpoint is called. Fixes #17166
This commit is contained in:
parent
48519be52b
commit
8a2d645dd4
2 changed files with 126 additions and 5 deletions
|
@ -78,6 +78,7 @@ import io.quarkus.hibernate.orm.deployment.PersistenceXmlDescriptorBuildItem;
|
||||||
import io.quarkus.hibernate.orm.deployment.integration.HibernateOrmIntegrationRuntimeConfiguredBuildItem;
|
import io.quarkus.hibernate.orm.deployment.integration.HibernateOrmIntegrationRuntimeConfiguredBuildItem;
|
||||||
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
|
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
|
||||||
import io.quarkus.runtime.configuration.ProfileManager;
|
import io.quarkus.runtime.configuration.ProfileManager;
|
||||||
|
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
|
||||||
import io.quarkus.vertx.http.deployment.RouteBuildItem;
|
import io.quarkus.vertx.http.deployment.RouteBuildItem;
|
||||||
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
|
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig;
|
||||||
import io.smallrye.config.ConfigValue;
|
import io.smallrye.config.ConfigValue;
|
||||||
|
@ -179,6 +180,10 @@ class KeycloakProcessor {
|
||||||
ClasspathThemeResourceProviderFactory.class,
|
ClasspathThemeResourceProviderFactory.class,
|
||||||
JarThemeProviderFactory.class,
|
JarThemeProviderFactory.class,
|
||||||
JpaMapStorageProviderFactory.class);
|
JpaMapStorageProviderFactory.class);
|
||||||
|
public static final String QUARKUS_HEALTH_ROOT_PROPERTY = "quarkus.smallrye-health.root-path";
|
||||||
|
public static final String QUARKUS_METRICS_PATH_PROPERTY = "quarkus.micrometer.export.prometheus.path";
|
||||||
|
public static final String QUARKUS_DEFAULT_HEALTH_PATH = "health";
|
||||||
|
public static final String QUARKUS_DEFAULT_METRICS_PATH = "metrics";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
DEPLOYEABLE_SCRIPT_PROVIDERS.put(AUTHENTICATORS, KeycloakProcessor::registerScriptAuthenticator);
|
DEPLOYEABLE_SCRIPT_PROVIDERS.put(AUTHENTICATORS, KeycloakProcessor::registerScriptAuthenticator);
|
||||||
|
@ -562,17 +567,20 @@ class KeycloakProcessor {
|
||||||
|
|
||||||
@Record(ExecutionTime.RUNTIME_INIT)
|
@Record(ExecutionTime.RUNTIME_INIT)
|
||||||
@BuildStep
|
@BuildStep
|
||||||
void initializeFilter(BuildProducer<FilterBuildItem> filters, KeycloakRecorder recorder, HttpBuildTimeConfig httpBuildConfig,
|
void initializeFilter(BuildProducer<FilterBuildItem> filters, KeycloakRecorder recorder, ExecutorBuildItem executor, NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem) {
|
||||||
ExecutorBuildItem executor) {
|
|
||||||
String rootPath = httpBuildConfig.rootPath;
|
|
||||||
List<String> ignoredPaths = new ArrayList<>();
|
List<String> ignoredPaths = new ArrayList<>();
|
||||||
|
|
||||||
if (isHealthEnabled()) {
|
if (isHealthEnabled()) {
|
||||||
ignoredPaths.add(rootPath + "health");
|
ignoredPaths.add(nonApplicationRootPathBuildItem.
|
||||||
|
resolvePath(Configuration.getOptionalValue(QUARKUS_HEALTH_ROOT_PROPERTY)
|
||||||
|
.orElse(QUARKUS_DEFAULT_HEALTH_PATH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMetricsEnabled()) {
|
if (isMetricsEnabled()) {
|
||||||
ignoredPaths.add(rootPath + "metrics");
|
ignoredPaths.add(nonApplicationRootPathBuildItem.
|
||||||
|
resolvePath(Configuration.getOptionalValue(QUARKUS_METRICS_PATH_PROPERTY)
|
||||||
|
.orElse(QUARKUS_DEFAULT_METRICS_PATH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
filters.produce(new FilterBuildItem(recorder.createRequestFilter(ignoredPaths, executor.getExecutorProxy()),FilterBuildItem.AUTHORIZATION - 10));
|
filters.produce(new FilterBuildItem(recorder.createRequestFilter(ignoredPaths, executor.getExecutorProxy()),FilterBuildItem.AUTHORIZATION - 10));
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* 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 test.org.keycloak.quarkus.services.health;
|
||||||
|
|
||||||
|
import io.quarkus.test.QuarkusUnitTest;
|
||||||
|
import org.jboss.shrinkwrap.api.ShrinkWrap;
|
||||||
|
import org.jboss.shrinkwrap.api.spec.JavaArchive;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.given;
|
||||||
|
|
||||||
|
class KeycloakPathConfigurationTest {
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static final QuarkusUnitTest test = new QuarkusUnitTest()
|
||||||
|
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
|
||||||
|
.addAsResource("keycloak.conf", "META-INF/keycloak.conf"))
|
||||||
|
.overrideConfigKey("kc.http-relative-path","/auth")
|
||||||
|
.overrideConfigKey("quarkus.http.non-application-root-path", "/q")
|
||||||
|
.overrideConfigKey("quarkus.micrometer.export.prometheus.path", "/prom/metrics");
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHealth() {
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("q/health")
|
||||||
|
.then()
|
||||||
|
.statusCode(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWrongHealthEndpoints() {
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("health")
|
||||||
|
.then()
|
||||||
|
// Health is available under `/q/health` (see non-application-root-path),
|
||||||
|
// so /health should return 404.
|
||||||
|
.statusCode(404);
|
||||||
|
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("auth/health")
|
||||||
|
.then()
|
||||||
|
// Health is available under `/q/health` (see non-application-root-path),
|
||||||
|
// so /auth/health one should return 404.
|
||||||
|
.statusCode(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMetrics() {
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("prom/metrics")
|
||||||
|
.then()
|
||||||
|
.statusCode(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWrongMetricsEndpoints() {
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("metrics")
|
||||||
|
.then()
|
||||||
|
// Metrics is available under `/prom/metrics` (see non-application-root-path),
|
||||||
|
// so /metrics should return 404.
|
||||||
|
.statusCode(404);
|
||||||
|
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("auth/metrics")
|
||||||
|
.then()
|
||||||
|
// Metrics is available under `/prom/metrics` (see non-application-root-path),
|
||||||
|
// so /auth/metrics should return 404.
|
||||||
|
.statusCode(404);
|
||||||
|
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("q/metrics")
|
||||||
|
.then()
|
||||||
|
// Metrics is available under `/prom/metrics` (see non-application-root-path),
|
||||||
|
// so /q/metrics should return 404.
|
||||||
|
.statusCode(404);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAuthEndpointAvailable() {
|
||||||
|
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("auth")
|
||||||
|
.then()
|
||||||
|
.statusCode(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRootUnavailable() {
|
||||||
|
given().basePath("/")
|
||||||
|
.when().get("")
|
||||||
|
.then()
|
||||||
|
// application root is configured to /auth, so we expect 404 on /
|
||||||
|
.statusCode(404);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue