diff --git a/docs/guides/server/caching.adoc b/docs/guides/server/caching.adoc index 25c7cf3b9de..f23806ae154 100644 --- a/docs/guides/server/caching.adoc +++ b/docs/guides/server/caching.adoc @@ -125,6 +125,8 @@ This cache is needed for the Brute Force Protection feature to work in a multi-n Action tokens are used for scenarios when a user needs to confirm an action asynchronously, for example in the emails sent by the forgot password flow. The `actionTokens` distributed cache is used to track metadata about action tokens. +TIP: You can see the applied Infinispan configuration in the logs by configuring `--log-level=info,org.keycloak.connections.infinispan:debug`. + === Volatile user sessions By default, regular user sessions are stored in the database and loaded on-demand to the cache. diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java index 516277a188f..eaf79305186 100755 --- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java @@ -29,8 +29,12 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Collectors; import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.commons.configuration.io.ConfigurationWriter; +import org.infinispan.commons.io.StringBuilderWriter; import org.infinispan.commons.util.Version; import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.global.GlobalConfiguration; +import org.infinispan.configuration.parsing.ParserRegistry; import org.infinispan.health.CacheHealth; import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; @@ -178,6 +182,16 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon protected EmbeddedCacheManager createEmbeddedCacheManager(KeycloakSession session) { var holder = session.getProvider(CacheEmbeddedConfigProvider.class).configuration(); + + StringBuilderWriter sw = new StringBuilderWriter(); + ParserRegistry parser = new ParserRegistry(); + try (ConfigurationWriter w = ConfigurationWriter.to(sw).prettyPrint(true).build()) { + var globalConfig = holder.getGlobalConfigurationBuilder().build(); + var cacheConfigs = holder.getNamedConfigurationBuilders().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().build())); + parser.serialize(w, globalConfig, cacheConfigs); + logger.debugf("Infinispan configuration:\n%s", sw); + } + var cm = new DefaultCacheManager(holder, true); cm.getCache(KEYS_CACHE_NAME, true); cm.getCache(CRL_CACHE_NAME, true); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java index 46bc7b0c848..b00696d9346 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java @@ -128,6 +128,13 @@ public class ClusterConfigDistTest { result.assertClusteredCache(); } + @Test + @Launch({ "start", "--cache=ispn", "--log-level=info,org.keycloak.connections.infinispan:debug", "--http-enabled=true", "--hostname-strict=false"}) + void testPrintCacheConfigurationsDebug(CLIResult result) { + result.assertStarted(); + result.assertMessage("Infinispan configuration"); + } + @Test @EnabledOnOs(value = { OS.LINUX, OS.MAC }, disabledReason = "different shell escaping behaviour on Windows.") @Launch({ "start", "--db=dev-file", "--log-level=info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true", "--hostname-strict=false" })