Properly enable/disable metrics and health endpoints
Closes #11506 Co-authored-by: Dominik Guhr <dguhr@redhat.com>
This commit is contained in:
parent
a14501dd77
commit
e14bd51656
15 changed files with 123 additions and 109 deletions
|
@ -23,17 +23,33 @@ The result is returned in json format and it looks as follows:
|
|||
----
|
||||
{
|
||||
"status": "UP",
|
||||
"checks": [
|
||||
{
|
||||
"name": "Keycloak database connections health check",
|
||||
"status": "UP"
|
||||
}
|
||||
]
|
||||
"checks": []
|
||||
}
|
||||
----
|
||||
|
||||
== Enabling the health checks
|
||||
Is possible to enable the health checks using the build time option `health-enabled`:
|
||||
|
||||
<@kc.build parameters="--health-enabled=true"/>
|
||||
|
||||
By default, no check is returned from the health endpoints.
|
||||
|
||||
== Available Checks
|
||||
|
||||
The table below shows the available checks.
|
||||
|
||||
|===
|
||||
|*Check* | *Description* | *Requires Metrics*
|
||||
|
||||
|Database
|
||||
|Returns the status of the database connection pool.
|
||||
|Yes
|
||||
|
||||
|===
|
||||
|
||||
For some checks, you'll need to also enable metrics as indicated by the `Requires Metrics` column. To enable metrics
|
||||
use the `metrics-enabled` option as follows:
|
||||
|
||||
<@kc.build parameters="--health-enabled=true --metrics-enabled=true"/>
|
||||
|
||||
</@tmpl.guide>
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.keycloak.quarkus.deployment;
|
||||
|
||||
import static org.keycloak.quarkus.runtime.KeycloakRecorder.DEFAULT_HEALTH_ENDPOINT;
|
||||
import static org.keycloak.quarkus.runtime.KeycloakRecorder.DEFAULT_METRICS_ENDPOINT;
|
||||
import static org.keycloak.quarkus.runtime.Providers.getProviderManager;
|
||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getPropertyNames;
|
||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_QUARKUS;
|
||||
|
@ -54,6 +56,7 @@ import java.util.jar.JarEntry;
|
|||
import java.util.jar.JarFile;
|
||||
|
||||
import io.quarkus.agroal.spi.JdbcDataSourceBuildItem;
|
||||
import io.quarkus.arc.deployment.BuildTimeConditionBuildItem;
|
||||
import io.quarkus.datasource.deployment.spi.DevServicesDatasourceResultBuildItem;
|
||||
import io.quarkus.deployment.IsDevelopment;
|
||||
import io.quarkus.deployment.annotations.Consume;
|
||||
|
@ -62,26 +65,21 @@ import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
|
|||
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
|
||||
import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem;
|
||||
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
|
||||
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
|
||||
import io.quarkus.deployment.builditem.StaticInitConfigSourceProviderBuildItem;
|
||||
import io.quarkus.hibernate.orm.deployment.AdditionalJpaModelBuildItem;
|
||||
import io.quarkus.hibernate.orm.deployment.HibernateOrmConfig;
|
||||
import io.quarkus.hibernate.orm.deployment.PersistenceXmlDescriptorBuildItem;
|
||||
import io.quarkus.hibernate.orm.deployment.integration.HibernateOrmIntegrationRuntimeConfiguredBuildItem;
|
||||
import io.quarkus.resteasy.server.common.deployment.ResteasyDeploymentCustomizerBuildItem;
|
||||
import io.quarkus.runtime.LaunchMode;
|
||||
import io.quarkus.runtime.configuration.ProfileManager;
|
||||
import io.quarkus.smallrye.health.runtime.SmallRyeHealthHandler;
|
||||
import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem;
|
||||
import io.quarkus.vertx.http.deployment.RouteBuildItem;
|
||||
import io.smallrye.config.ConfigValue;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.jpa.boot.internal.ParsedPersistenceXmlDescriptor;
|
||||
import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationTarget;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -91,7 +89,6 @@ import org.keycloak.Config;
|
|||
import org.keycloak.config.StorageOptions;
|
||||
import org.keycloak.connections.jpa.JpaConnectionProvider;
|
||||
import org.keycloak.connections.jpa.JpaConnectionSpi;
|
||||
import org.keycloak.models.map.storage.MapStorageSpi;
|
||||
import org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory;
|
||||
import org.keycloak.quarkus.runtime.QuarkusProfile;
|
||||
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
||||
|
@ -119,8 +116,6 @@ import org.keycloak.provider.Provider;
|
|||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.ProviderManager;
|
||||
import org.keycloak.provider.Spi;
|
||||
import org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter;
|
||||
import org.keycloak.quarkus.runtime.dev.QuarkusDevRequestFilter;
|
||||
import org.keycloak.quarkus.runtime.KeycloakRecorder;
|
||||
|
||||
import io.quarkus.deployment.annotations.BuildProducer;
|
||||
|
@ -130,6 +125,7 @@ import io.quarkus.deployment.annotations.Record;
|
|||
import io.quarkus.deployment.builditem.FeatureBuildItem;
|
||||
import io.quarkus.vertx.http.deployment.FilterBuildItem;
|
||||
|
||||
import org.keycloak.quarkus.runtime.services.health.KeycloakReadyHealthCheck;
|
||||
import org.keycloak.quarkus.runtime.storage.database.jpa.NamedJpaConnectionProviderFactory;
|
||||
import org.keycloak.quarkus.runtime.storage.database.jpa.QuarkusJpaMapStorageProviderFactory;
|
||||
import org.keycloak.quarkus.runtime.themes.FlatClasspathThemeResourceProviderFactory;
|
||||
|
@ -153,8 +149,6 @@ class KeycloakProcessor {
|
|||
private static final Logger logger = Logger.getLogger(KeycloakProcessor.class);
|
||||
|
||||
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";
|
||||
|
||||
|
@ -481,48 +475,36 @@ class KeycloakProcessor {
|
|||
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.keycloak", "keycloak-model-map-jpa"));
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
void initializeFilter(BuildProducer<FilterBuildItem> filters, LaunchModeBuildItem launchModeBuildItem) {
|
||||
QuarkusRequestFilter filter = new QuarkusRequestFilter();
|
||||
LaunchMode launchMode = launchModeBuildItem.getLaunchMode();
|
||||
|
||||
if (launchMode.isDevOrTest()) {
|
||||
filter = new QuarkusDevRequestFilter();
|
||||
}
|
||||
|
||||
filters.produce(new FilterBuildItem(filter,FilterBuildItem.AUTHORIZATION - 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Initialize metrics and health endpoints.
|
||||
*
|
||||
* <p>The only reason for manually registering these endpoints is that by default they run as blocking hence
|
||||
* running in a different thread than the worker thread started by {@link QuarkusRequestFilter}.
|
||||
* See https://github.com/quarkusio/quarkus/issues/12990.
|
||||
*
|
||||
* <p>By doing this, custom health checks such as {@link org.keycloak.quarkus.runtime.services.health.KeycloakReadyHealthCheck} is
|
||||
* executed within an active {@link org.keycloak.models.KeycloakSession}, making possible to use it when calculating the
|
||||
* status.
|
||||
*
|
||||
* @param routes
|
||||
*/
|
||||
@Record(ExecutionTime.STATIC_INIT)
|
||||
@BuildStep
|
||||
void initializeMetrics(KeycloakRecorder recorder, BuildProducer<RouteBuildItem> routes, NonApplicationRootPathBuildItem nonAppRootPath) {
|
||||
final Handler<RoutingContext> healthHandler = (isHealthEnabled()) ? new SmallRyeHealthHandler() : new NotFoundHandler();
|
||||
Handler<RoutingContext> metricsHandler;
|
||||
void initializeFilter(BuildProducer<FilterBuildItem> filters, KeycloakRecorder recorder) {
|
||||
filters.produce(new FilterBuildItem(recorder.createRequestFilter(isHealthEnabled() || isMetricsEnabled()),FilterBuildItem.AUTHORIZATION - 10));
|
||||
}
|
||||
|
||||
if (isMetricsEnabled()) {
|
||||
String rootPath = nonAppRootPath.getNormalizedHttpRootPath();
|
||||
metricsHandler = recorder.createMetricsHandler(rootPath.concat(DEFAULT_METRICS_ENDPOINT).replace("//", "/"));
|
||||
} else {
|
||||
metricsHandler = new NotFoundHandler();
|
||||
@BuildStep
|
||||
void disableMetricsEndpoint(BuildProducer<RouteBuildItem> routes) {
|
||||
if (!isMetricsEnabled()) {
|
||||
routes.produce(RouteBuildItem.builder().route(DEFAULT_METRICS_ENDPOINT.concat("/*")).handler(new NotFoundHandler()).build());
|
||||
}
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
void disableHealthEndpoint(BuildProducer<RouteBuildItem> routes, BuildProducer<BuildTimeConditionBuildItem> removeBeans,
|
||||
CombinedIndexBuildItem index) {
|
||||
boolean healthDisabled = !isHealthEnabled();
|
||||
|
||||
if (healthDisabled) {
|
||||
routes.produce(RouteBuildItem.builder().route(DEFAULT_HEALTH_ENDPOINT.concat("/*")).handler(new NotFoundHandler()).build());
|
||||
}
|
||||
|
||||
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(DEFAULT_METRICS_ENDPOINT).handler(metricsHandler).build());
|
||||
boolean metricsDisabled = !isMetricsEnabled();
|
||||
|
||||
if (healthDisabled || metricsDisabled) {
|
||||
// disables the single check we provide which depends on metrics enabled
|
||||
ClassInfo disabledBean = index.getIndex()
|
||||
.getClassByName(DotName.createSimple(KeycloakReadyHealthCheck.class.getName()));
|
||||
removeBeans.produce(new BuildTimeConditionBuildItem(disabledBean.asClass(), false));
|
||||
}
|
||||
}
|
||||
|
||||
@BuildStep
|
||||
|
|
|
@ -6,3 +6,4 @@ db=dev-mem
|
|||
db-username = sa
|
||||
db-password = keycloak
|
||||
health-enabled=true
|
||||
metrics-enabled=true
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.lang.annotation.Annotation;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import io.agroal.api.AgroalDataSource;
|
||||
import io.quarkus.agroal.DataSource;
|
||||
|
@ -40,6 +41,7 @@ import org.keycloak.common.Profile;
|
|||
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||
import org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider;
|
||||
import org.keycloak.quarkus.runtime.integration.QuarkusKeycloakSessionFactory;
|
||||
import org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter;
|
||||
import org.keycloak.quarkus.runtime.storage.database.liquibase.FastServiceLocator;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
@ -54,6 +56,9 @@ import liquibase.servicelocator.ServiceLocator;
|
|||
@Recorder
|
||||
public class KeycloakRecorder {
|
||||
|
||||
public static final String DEFAULT_HEALTH_ENDPOINT = "/health";
|
||||
public static final String DEFAULT_METRICS_ENDPOINT = "/metrics";
|
||||
|
||||
public void configureLiquibase(Map<String, List<String>> services) {
|
||||
ServiceLocator locator = Scope.getCurrentScope().getServiceLocator();
|
||||
if (locator instanceof FastServiceLocator)
|
||||
|
@ -133,4 +138,20 @@ public class KeycloakRecorder {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
public QuarkusRequestFilter createRequestFilter(boolean healthOrMetricsEnabled) {
|
||||
Predicate<RoutingContext> ignoreContext = null;
|
||||
|
||||
if (healthOrMetricsEnabled) {
|
||||
// ignore metrics and health endpoints because they execute in their own worker thread
|
||||
ignoreContext = new Predicate<>() {
|
||||
@Override
|
||||
public boolean test(RoutingContext context) {
|
||||
return context.request().uri().startsWith("/health") || context.request().uri().startsWith("/metrics");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return new QuarkusRequestFilter(ignoreContext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ final class HealthPropertyMappers {
|
|||
public static PropertyMapper[] getHealthPropertyMappers() {
|
||||
return new PropertyMapper[] {
|
||||
fromOption(HealthOptions.HEALTH_ENABLED)
|
||||
.to("quarkus.datasource.health.enabled")
|
||||
.to("quarkus.health.extensions.enabled")
|
||||
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
|
||||
.build()
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ final class MetricsPropertyMappers {
|
|||
public static PropertyMapper[] getMetricsPropertyMappers() {
|
||||
return new PropertyMapper[] {
|
||||
fromOption(MetricsOptions.METRICS_ENABLED)
|
||||
.to("quarkus.datasource.metrics.enabled")
|
||||
.to("quarkus.smallrye-metrics.extensions.enabled")
|
||||
.paramLabel(Boolean.TRUE + "|" + Boolean.FALSE)
|
||||
.build()
|
||||
};
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright 2021 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.dev;
|
||||
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||
*/
|
||||
public class QuarkusDevRequestFilter extends QuarkusRequestFilter {
|
||||
|
||||
@Override
|
||||
public void handle(RoutingContext context) {
|
||||
if (context.request().uri().startsWith("/q/")) {
|
||||
// do not go through Keycloak request filter if serving Quarkus resources such as dev console
|
||||
context.next();
|
||||
return;
|
||||
}
|
||||
super.handle(context);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ package org.keycloak.quarkus.runtime.integration.web;
|
|||
|
||||
import static org.keycloak.services.resources.KeycloakApplication.getSessionFactory;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import org.keycloak.common.ClientConnection;
|
||||
import org.keycloak.common.util.Resteasy;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
@ -49,13 +50,31 @@ public class QuarkusRequestFilter implements Handler<RoutingContext> {
|
|||
// we don't really care about the result because any exception thrown should be handled by the parent class
|
||||
};
|
||||
|
||||
private Predicate<RoutingContext> contextFilter;
|
||||
|
||||
public QuarkusRequestFilter() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public QuarkusRequestFilter(Predicate<RoutingContext> contextFilter) {
|
||||
this.contextFilter = contextFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(RoutingContext context) {
|
||||
if (ignoreContext(context)) {
|
||||
context.next();
|
||||
return;
|
||||
}
|
||||
// our code should always be run as blocking until we don't provide a better support for running non-blocking code
|
||||
// in the event loop
|
||||
context.vertx().executeBlocking(createBlockingHandler(context), false, EMPTY_RESULT);
|
||||
}
|
||||
|
||||
private boolean ignoreContext(RoutingContext context) {
|
||||
return contextFilter != null && contextFilter.test(context);
|
||||
}
|
||||
|
||||
private Handler<Promise<Object>> createBlockingHandler(RoutingContext context) {
|
||||
return promise -> {
|
||||
KeycloakSessionFactory sessionFactory = getSessionFactory();
|
||||
|
|
|
@ -7,6 +7,10 @@ quarkus.banner.enabled=false
|
|||
|
||||
# Disable health checks from extensions, since we provide our own (default is true)
|
||||
quarkus.health.extensions.enabled=false
|
||||
quarkus.datasource.health.enabled=false
|
||||
|
||||
# Enables metrics from other extensions if metrics is enabled
|
||||
quarkus.datasource.metrics.enabled=${quarkus.smallrye-metrics.extensions.enabled}
|
||||
|
||||
# Default transaction timeout
|
||||
quarkus.transaction-manager.default-transaction-timeout=300
|
||||
|
@ -24,3 +28,6 @@ quarkus.package.include-dependency-list=false
|
|||
|
||||
# we do not want running dev services in distribution
|
||||
quarkus.devservices.enabled=false
|
||||
|
||||
# We want to expose non-application paths (e.g. health) at the root path
|
||||
quarkus.http.non-application-root-path=${quarkus.http.root-path}
|
||||
|
|
|
@ -445,7 +445,10 @@ public class ConfigurationTest {
|
|||
public void testResolveHealthOption() {
|
||||
System.setProperty(CLI_ARGS, "--health-enabled=true");
|
||||
SmallRyeConfig config = createConfig();
|
||||
assertEquals("true", config.getConfigValue("quarkus.datasource.health.enabled").getValue());
|
||||
assertEquals("true", config.getConfigValue("quarkus.health.extensions.enabled").getValue());
|
||||
System.setProperty(CLI_ARGS, "");
|
||||
config = createConfig();
|
||||
assertEquals("false", config.getConfigValue("quarkus.health.extensions.enabled").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -320,8 +320,8 @@ public final class RawKeycloakDistribution implements KeycloakDistribution {
|
|||
outputStream.clear();
|
||||
errorStream.clear();
|
||||
exitCode = -1;
|
||||
keycloak = null;
|
||||
shutdownOutputExecutor();
|
||||
keycloak = null;
|
||||
}
|
||||
|
||||
private Path prepareDistribution() {
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.junit.jupiter.api.Test;
|
|||
import org.keycloak.it.junit5.extension.DistributionTest;
|
||||
|
||||
import static io.restassured.RestAssured.when;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
@DistributionTest(keepAlive =true)
|
||||
public class HealthDistTest {
|
||||
|
@ -32,10 +31,16 @@ public class HealthDistTest {
|
|||
void testHealthEndpointNotEnabled() {
|
||||
when().get("/health").then()
|
||||
.statusCode(404);
|
||||
when().get("/q/health").then()
|
||||
.statusCode(404);
|
||||
when().get("/health/live").then()
|
||||
.statusCode(404);
|
||||
when().get("/q/health/live").then()
|
||||
.statusCode(404);
|
||||
when().get("/health/ready").then()
|
||||
.statusCode(404);
|
||||
when().get("/q/health/ready").then()
|
||||
.statusCode(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -47,14 +52,7 @@ public class HealthDistTest {
|
|||
.statusCode(200);
|
||||
when().get("/health/ready").then()
|
||||
.statusCode(200);
|
||||
// Metrics is endpoint independent
|
||||
when().get("/metrics").then()
|
||||
.statusCode(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Launch({ "start-dev", "--health-enabled=true" })
|
||||
void testHealthEndpointDoesNotEnableMetrics() {
|
||||
// Metrics should not be enabled
|
||||
when().get("/metrics").then()
|
||||
.statusCode(404);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public class MetricsDistTest {
|
|||
void testMetricsEndpointNotEnabled() {
|
||||
when().get("/metrics").then()
|
||||
.statusCode(404);
|
||||
when().get("/q/metrics").then()
|
||||
.statusCode(404);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -105,7 +105,7 @@ public class QuarkusPropertiesAutoBuildDistTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@BeforeStartDistribution(EnableDatasourceMetrics.class)
|
||||
@BeforeStartDistribution(EnableQuarkusMetrics.class)
|
||||
@Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
|
||||
@Order(8)
|
||||
void testWrappedBuildPropertyTriggersBuildButGetsIgnoredWhenSetByQuarkus(LaunchResult result) {
|
||||
|
@ -163,11 +163,11 @@ public class QuarkusPropertiesAutoBuildDistTest {
|
|||
}
|
||||
}
|
||||
|
||||
public static class EnableDatasourceMetrics implements Consumer<KeycloakDistribution> {
|
||||
public static class EnableQuarkusMetrics implements Consumer<KeycloakDistribution> {
|
||||
@Override
|
||||
public void accept(KeycloakDistribution distribution) {
|
||||
distribution.setManualStop(true);
|
||||
distribution.setQuarkusProperty("quarkus.datasource.metrics.enabled","true");
|
||||
distribution.setQuarkusProperty("quarkus.smallrye-metrics.extensions.enabled","true");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,9 @@ public class KeycloakSecurityHeadersFilter implements ContainerResponseFilter {
|
|||
public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) {
|
||||
KeycloakSession session = Resteasy.getContextData(KeycloakSession.class);
|
||||
|
||||
SecurityHeadersProvider securityHeadersProvider = session.getProvider(SecurityHeadersProvider.class);
|
||||
securityHeadersProvider.addHeaders(containerRequestContext, containerResponseContext);
|
||||
if (session != null) {
|
||||
SecurityHeadersProvider securityHeadersProvider = session.getProvider(SecurityHeadersProvider.class);
|
||||
securityHeadersProvider.addHeaders(containerRequestContext, containerResponseContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue