Refactor and remove deprecated Infinispan methods from DefaultInfinispanConnectionProviderFactory

Closes #28752

Signed-off-by: Pedro Ruivo <pruivo@redhat.com>
This commit is contained in:
Pedro Ruivo 2024-04-15 19:35:29 +01:00 committed by Alexander Schwartz
parent 63cb137b37
commit 2494ad6950
4 changed files with 97 additions and 187 deletions

View file

@ -24,7 +24,6 @@ import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.eviction.EvictionStrategy; import org.infinispan.eviction.EvictionStrategy;
import org.infinispan.eviction.EvictionType;
import org.infinispan.jboss.marshalling.core.JBossUserMarshaller; import org.infinispan.jboss.marshalling.core.JBossUserMarshaller;
import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.manager.EmbeddedCacheManager;
@ -46,12 +45,9 @@ import org.keycloak.models.cache.infinispan.events.RealmUpdatedEvent;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.PostMigrationEvent; import org.keycloak.models.utils.PostMigrationEvent;
import org.keycloak.provider.InvalidationHandler.ObjectType; import org.keycloak.provider.InvalidationHandler.ObjectType;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderConfigurationBuilder;
import org.keycloak.provider.ProviderEvent; import org.keycloak.provider.ProviderEvent;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
@ -59,6 +55,23 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Supplier; import java.util.function.Supplier;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.ACTION_TOKEN_CACHE;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.OFFLINE_USER_SESSION_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.REALM_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.USER_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.USER_SESSION_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.WORK_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanUtil.configureTransport; import static org.keycloak.connections.infinispan.InfinispanUtil.configureTransport;
import static org.keycloak.connections.infinispan.InfinispanUtil.createCacheConfigurationBuilder; import static org.keycloak.connections.infinispan.InfinispanUtil.createCacheConfigurationBuilder;
import static org.keycloak.connections.infinispan.InfinispanUtil.getActionTokenCacheConfig; import static org.keycloak.connections.infinispan.InfinispanUtil.getActionTokenCacheConfig;
@ -200,34 +213,14 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
protected EmbeddedCacheManager initContainerManaged(EmbeddedCacheManager cacheManager) { protected EmbeddedCacheManager initContainerManaged(EmbeddedCacheManager cacheManager) {
containerManaged = true; containerManaged = true;
long realmRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME).getCacheConfiguration().memory().size(); defineRevisionCache(cacheManager, REALM_CACHE_NAME, REALM_REVISIONS_CACHE_NAME, REALM_REVISIONS_CACHE_DEFAULT_MAX);
realmRevisionsMaxEntries = realmRevisionsMaxEntries > 0 defineRevisionCache(cacheManager, USER_CACHE_NAME, USER_REVISIONS_CACHE_NAME, USER_REVISIONS_CACHE_DEFAULT_MAX);
? 2 * realmRevisionsMaxEntries defineRevisionCache(cacheManager, AUTHORIZATION_CACHE_NAME, AUTHORIZATION_REVISIONS_CACHE_NAME, AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX);
: InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX;
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(realmRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, true);
long userRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().memory().size();
userRevisionsMaxEntries = userRevisionsMaxEntries > 0
? 2 * userRevisionsMaxEntries
: InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(userRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME, true); cacheManager.getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME, true); cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, true); cacheManager.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, true);
long authzRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME).getCacheConfiguration().memory().size();
authzRevisionsMaxEntries = authzRevisionsMaxEntries > 0
? 2 * authzRevisionsMaxEntries
: InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX;
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, getRevisionCacheConfig(authzRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, true);
this.topologyInfo = new TopologyInfo(cacheManager, config, false, getId()); this.topologyInfo = new TopologyInfo(cacheManager, config, false, getId());
logger.debugv("Using container managed Infinispan cache container, lookup={0}", cacheManager); logger.debugv("Using container managed Infinispan cache container, lookup={0}", cacheManager);
@ -267,21 +260,24 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
logger.debug("Started embedded Infinispan cache container"); logger.debug("Started embedded Infinispan cache container");
ConfigurationBuilder modelCacheConfigBuilder = createCacheConfigurationBuilder(); var localConfiguration = createCacheConfigurationBuilder().build();
Configuration modelCacheConfiguration = modelCacheConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_CACHE_NAME, modelCacheConfiguration); // local caches first
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME, modelCacheConfiguration); defineLocalCache(cacheManager, REALM_CACHE_NAME, REALM_REVISIONS_CACHE_NAME, localConfiguration, REALM_REVISIONS_CACHE_DEFAULT_MAX);
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_CACHE_NAME, modelCacheConfiguration); defineLocalCache(cacheManager, AUTHORIZATION_CACHE_NAME, AUTHORIZATION_REVISIONS_CACHE_NAME, localConfiguration, AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX);
defineLocalCache(cacheManager, USER_CACHE_NAME, USER_REVISIONS_CACHE_NAME, localConfiguration, USER_REVISIONS_CACHE_DEFAULT_MAX);
ConfigurationBuilder sessionConfigBuilder = createCacheConfigurationBuilder(); cacheManager.defineConfiguration(InfinispanConnectionProvider.KEYS_CACHE_NAME, getKeysCacheConfig());
cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME, true);
var builder = createCacheConfigurationBuilder();
if (clustered) { if (clustered) {
sessionConfigBuilder.simpleCache(false); builder.simpleCache(false);
String sessionsMode = config.get("sessionsMode", "distributed"); String sessionsMode = config.get("sessionsMode", "distributed");
if (sessionsMode.equalsIgnoreCase("replicated")) { if (sessionsMode.equalsIgnoreCase("replicated")) {
sessionConfigBuilder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC); builder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC);
} else if (sessionsMode.equalsIgnoreCase("distributed")) { } else if (sessionsMode.equalsIgnoreCase("distributed")) {
sessionConfigBuilder.clustering().cacheMode(async ? CacheMode.DIST_ASYNC : CacheMode.DIST_SYNC); builder.clustering().cacheMode(async ? CacheMode.DIST_ASYNC : CacheMode.DIST_SYNC);
} else { } else {
throw new RuntimeException("Invalid value for sessionsMode"); throw new RuntimeException("Invalid value for sessionsMode");
} }
@ -292,130 +288,68 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
int l1Lifespan = config.getInt("l1Lifespan", 600000); int l1Lifespan = config.getInt("l1Lifespan", 600000);
boolean l1Enabled = l1Lifespan > 0; boolean l1Enabled = l1Lifespan > 0;
Boolean awaitInitialTransfer = config.getBoolean("awaitInitialTransfer", true); Boolean awaitInitialTransfer = config.getBoolean("awaitInitialTransfer", true);
sessionConfigBuilder.clustering() builder.clustering()
.hash() .hash()
.numOwners(owners) .numOwners(owners)
.numSegments(config.getInt("sessionsSegments", 60)) .numSegments(config.getInt("sessionsSegments", 60))
.l1() .l1()
.enabled(l1Enabled) .enabled(l1Enabled)
.lifespan(l1Lifespan) .lifespan(l1Lifespan)
.stateTransfer().awaitInitialTransfer(awaitInitialTransfer).timeout(30, TimeUnit.SECONDS) .stateTransfer().awaitInitialTransfer(awaitInitialTransfer).timeout(30, TimeUnit.SECONDS);
.build();
} }
// Base configuration doesn't contain any remote stores // Base configuration doesn't contain any remote stores
Configuration sessionCacheConfigurationBase = sessionConfigBuilder.build(); var clusteredConfiguration = builder.build();
boolean jdgEnabled = config.getBoolean("remoteStoreEnabled", false); defineClusteredCache(cacheManager, USER_SESSION_CACHE_NAME, clusteredConfiguration);
defineClusteredCache(cacheManager, OFFLINE_USER_SESSION_CACHE_NAME, clusteredConfiguration);
defineClusteredCache(cacheManager, CLIENT_SESSION_CACHE_NAME, clusteredConfiguration);
defineClusteredCache(cacheManager, OFFLINE_CLIENT_SESSION_CACHE_NAME, clusteredConfiguration);
defineClusteredCache(cacheManager, LOGIN_FAILURE_CACHE_NAME, clusteredConfiguration);
if (jdgEnabled) { var actionTokenBuilder = getActionTokenCacheConfig();
sessionConfigBuilder = createCacheConfigurationBuilder();
sessionConfigBuilder.read(sessionCacheConfigurationBase);
configureRemoteCacheStore(sessionConfigBuilder, async, InfinispanConnectionProvider.USER_SESSION_CACHE_NAME);
}
Configuration sessionCacheConfiguration = sessionConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME, sessionCacheConfiguration);
if (jdgEnabled) {
sessionConfigBuilder = createCacheConfigurationBuilder();
sessionConfigBuilder.read(sessionCacheConfigurationBase);
configureRemoteCacheStore(sessionConfigBuilder, async, InfinispanConnectionProvider.OFFLINE_USER_SESSION_CACHE_NAME);
}
sessionCacheConfiguration = sessionConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.OFFLINE_USER_SESSION_CACHE_NAME, sessionCacheConfiguration);
if (jdgEnabled) {
sessionConfigBuilder = createCacheConfigurationBuilder();
sessionConfigBuilder.read(sessionCacheConfigurationBase);
configureRemoteCacheStore(sessionConfigBuilder, async, InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME);
}
sessionCacheConfiguration = sessionConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME, sessionCacheConfiguration);
if (jdgEnabled) {
sessionConfigBuilder = createCacheConfigurationBuilder();
sessionConfigBuilder.read(sessionCacheConfigurationBase);
configureRemoteCacheStore(sessionConfigBuilder, async, InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME);
}
sessionCacheConfiguration = sessionConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME, sessionCacheConfiguration);
if (jdgEnabled) {
sessionConfigBuilder = createCacheConfigurationBuilder();
sessionConfigBuilder.read(sessionCacheConfigurationBase);
configureRemoteCacheStore(sessionConfigBuilder, async, InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME);
}
sessionCacheConfiguration = sessionConfigBuilder.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME, sessionCacheConfiguration);
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME, sessionCacheConfigurationBase);
// Retrieve caches to enforce rebalance
cacheManager.getCache(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.OFFLINE_USER_SESSION_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME, true);
cacheManager.getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME, true);
ConfigurationBuilder replicationConfigBuilder = createCacheConfigurationBuilder();
if (clustered) { if (clustered) {
replicationConfigBuilder.simpleCache(false); actionTokenBuilder.simpleCache(false);
replicationConfigBuilder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC); actionTokenBuilder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC);
} }
defineClusteredCache(cacheManager, ACTION_TOKEN_CACHE, actionTokenBuilder.build());
if (jdgEnabled) { defineClusteredCache(cacheManager, AUTHENTICATION_SESSIONS_CACHE_NAME, clusteredConfiguration);
configureRemoteCacheStore(replicationConfigBuilder, async, InfinispanConnectionProvider.WORK_CACHE_NAME);
}
Configuration replicationEvictionCacheConfiguration = replicationConfigBuilder var workBuilder = createCacheConfigurationBuilder()
.expiration().enableReaper().wakeUpInterval(15, TimeUnit.SECONDS) .expiration().enableReaper().wakeUpInterval(15, TimeUnit.SECONDS);
.build();
cacheManager.defineConfiguration(InfinispanConnectionProvider.WORK_CACHE_NAME, replicationEvictionCacheConfiguration);
cacheManager.getCache(InfinispanConnectionProvider.WORK_CACHE_NAME, true);
long realmRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME).getCacheConfiguration().memory().size();
realmRevisionsMaxEntries = realmRevisionsMaxEntries > 0
? 2 * realmRevisionsMaxEntries
: InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX;
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(realmRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, true);
long userRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().memory().size();
userRevisionsMaxEntries = userRevisionsMaxEntries > 0
? 2 * userRevisionsMaxEntries
: InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(userRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
cacheManager.defineConfiguration(InfinispanConnectionProvider.KEYS_CACHE_NAME, getKeysCacheConfig());
cacheManager.getCache(InfinispanConnectionProvider.KEYS_CACHE_NAME, true);
final ConfigurationBuilder actionTokenCacheConfigBuilder = getActionTokenCacheConfig();
if (clustered) { if (clustered) {
actionTokenCacheConfigBuilder.simpleCache(false); workBuilder.simpleCache(false);
actionTokenCacheConfigBuilder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC); workBuilder.clustering().cacheMode(async ? CacheMode.REPL_ASYNC : CacheMode.REPL_SYNC);
} }
if (jdgEnabled) { defineClusteredCache(cacheManager, WORK_CACHE_NAME, builder.build());
configureRemoteActionTokenCacheStore(actionTokenCacheConfigBuilder, async);
}
cacheManager.defineConfiguration(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, actionTokenCacheConfigBuilder.build());
cacheManager.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE, true);
long authzRevisionsMaxEntries = cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME).getCacheConfiguration().memory().size();
authzRevisionsMaxEntries = authzRevisionsMaxEntries > 0
? 2 * authzRevisionsMaxEntries
: InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_DEFAULT_MAX;
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, getRevisionCacheConfig(authzRevisionsMaxEntries));
cacheManager.getCache(InfinispanConnectionProvider.AUTHORIZATION_REVISIONS_CACHE_NAME, true);
return cacheManager; return cacheManager;
} }
private void defineLocalCache(EmbeddedCacheManager cacheManager, String cacheName, String revCacheName, Configuration configuration, long defaultMaxEntries) {
cacheManager.defineConfiguration(cacheName, configuration);
defineRevisionCache(cacheManager, cacheName, revCacheName, defaultMaxEntries);
}
private void defineRevisionCache(EmbeddedCacheManager cacheManager, String cacheName, String revCacheName, long defaultMaxEntries) {
var maxCount = cacheManager.getCache(cacheName).getCacheConfiguration().memory().maxCount();
maxCount = maxCount > 0 ? 2 * maxCount : defaultMaxEntries;
cacheManager.defineConfiguration(revCacheName, getRevisionCacheConfig(maxCount));
cacheManager.getCache(revCacheName);
}
private void defineClusteredCache(EmbeddedCacheManager cacheManager, String cacheName, Configuration baseConfiguration) {
// copy base configuration
var builder = createCacheConfigurationBuilder();
builder.read(baseConfiguration);
if (config.getBoolean("remoteStoreEnabled", false)) {
configureRemoteCacheStore(builder, config.getBoolean("async", false), cacheName);
}
cacheManager.defineConfiguration(cacheName, builder.build());
cacheManager.getCache(cacheName);
}
private Configuration getRevisionCacheConfig(long maxEntries) { private Configuration getRevisionCacheConfig(long maxEntries) {
ConfigurationBuilder cb = createCacheConfigurationBuilder(); ConfigurationBuilder cb = createCacheConfigurationBuilder();
cb.simpleCache(false); cb.simpleCache(false);
@ -430,9 +364,8 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
} }
cb.memory() cb.memory()
.evictionStrategy(EvictionStrategy.REMOVE) .whenFull(EvictionStrategy.REMOVE)
.evictionType(EvictionType.COUNT) .maxCount(maxEntries);
.size(maxEntries);
return cb.build(); return cb.build();
} }
@ -446,10 +379,10 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
// the same key media type to allow segmentation. Also, the number of segments in an embedded cache needs to match number of segments in the remote store. // the same key media type to allow segmentation. Also, the number of segments in an embedded cache needs to match number of segments in the remote store.
boolean segmented = config.getBoolean("segmented", false); boolean segmented = config.getBoolean("segmented", false);
//noinspection removal
builder.persistence() builder.persistence()
.passivation(false) .passivation(false)
.addStore(RemoteStoreConfigurationBuilder.class) .addStore(RemoteStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false) .ignoreModifications(false)
.purgeOnStartup(false) .purgeOnStartup(false)
.preload(false) .preload(false)
@ -467,36 +400,6 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
.enabled(async); .enabled(async);
} }
private void configureRemoteActionTokenCacheStore(ConfigurationBuilder builder, boolean async) {
String jdgServer = config.get("remoteStoreHost", "127.0.0.1");
Integer jdgPort = config.getInt("remoteStorePort", 11222);
// After upgrade to Infinispan 12.1.7.Final it's required that both remote store and embedded cache use
// the same key media type to allow segmentation. Also, the number of segments in an embedded cache needs to match number of segments in the remote store.
boolean segmented = config.getBoolean("segmented", false);
builder.persistence()
.passivation(false)
.addStore(RemoteStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false)
.purgeOnStartup(false)
.preload(true)
.shared(true)
.remoteCacheName(InfinispanConnectionProvider.ACTION_TOKEN_CACHE)
.segmented(segmented)
.rawValues(true)
.forceReturnValues(false)
.marshaller(KeycloakHotRodMarshallerFactory.class.getName())
.protocolVersion(getHotrodVersion())
.addServer()
.host(jdgServer)
.port(jdgPort)
.async()
.enabled(async);
}
private ProtocolVersion getHotrodVersion() { private ProtocolVersion getHotrodVersion() {
String hotrodVersionStr = config.get("hotrodProtocolVersion", ProtocolVersion.DEFAULT_PROTOCOL_VERSION.toString()); String hotrodVersionStr = config.get("hotrodProtocolVersion", ProtocolVersion.DEFAULT_PROTOCOL_VERSION.toString());
ProtocolVersion hotrodVersion = ProtocolVersion.parseVersion(hotrodVersionStr); ProtocolVersion hotrodVersion = ProtocolVersion.parseVersion(hotrodVersionStr);
@ -513,9 +416,8 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
ConfigurationBuilder cb = createCacheConfigurationBuilder(); ConfigurationBuilder cb = createCacheConfigurationBuilder();
cb.memory() cb.memory()
.evictionStrategy(EvictionStrategy.REMOVE) .whenFull(EvictionStrategy.REMOVE)
.evictionType(EvictionType.COUNT) .maxCount(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
.size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
cb.expiration().maxIdle(InfinispanConnectionProvider.KEYS_CACHE_MAX_IDLE_SECONDS, TimeUnit.SECONDS); cb.expiration().maxIdle(InfinispanConnectionProvider.KEYS_CACHE_MAX_IDLE_SECONDS, TimeUnit.SECONDS);
@ -531,11 +433,9 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
} }
}); });
cluster.registerListener(REALM_INVALIDATION_EVENTS, (ClusterEvent event) -> { cluster.registerListener(REALM_INVALIDATION_EVENTS, (ClusterEvent event) -> {
if (event instanceof RealmUpdatedEvent) { if (event instanceof RealmUpdatedEvent rr) {
RealmUpdatedEvent rr = (RealmUpdatedEvent) event;
sessionFactory.invalidate(null, ObjectType.REALM, rr.getId()); sessionFactory.invalidate(null, ObjectType.REALM, rr.getId());
} else if (event instanceof RealmRemovedEvent) { } else if (event instanceof RealmRemovedEvent rr) {
RealmRemovedEvent rr = (RealmRemovedEvent) event;
sessionFactory.invalidate(null, ObjectType.REALM, rr.getId()); sessionFactory.invalidate(null, ObjectType.REALM, rr.getId());
} }
}); });

View file

@ -19,6 +19,7 @@ import org.keycloak.connections.infinispan.InfinispanUtil;
import java.io.IOException; import java.io.IOException;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.ACTION_TOKEN_CACHE; import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.ACTION_TOKEN_CACHE;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME; import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME; import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME;
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME; import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME;
@ -73,10 +74,10 @@ public class HotRodServerRule extends ExternalResource {
// create remote keycloak caches // create remote keycloak caches
createKeycloakCaches(async, USER_SESSION_CACHE_NAME, OFFLINE_USER_SESSION_CACHE_NAME, CLIENT_SESSION_CACHE_NAME, createKeycloakCaches(async, USER_SESSION_CACHE_NAME, OFFLINE_USER_SESSION_CACHE_NAME, CLIENT_SESSION_CACHE_NAME,
OFFLINE_CLIENT_SESSION_CACHE_NAME, LOGIN_FAILURE_CACHE_NAME, WORK_CACHE_NAME, ACTION_TOKEN_CACHE); OFFLINE_CLIENT_SESSION_CACHE_NAME, LOGIN_FAILURE_CACHE_NAME, WORK_CACHE_NAME, ACTION_TOKEN_CACHE, AUTHENTICATION_SESSIONS_CACHE_NAME);
getCaches(USER_SESSION_CACHE_NAME, OFFLINE_USER_SESSION_CACHE_NAME, CLIENT_SESSION_CACHE_NAME, OFFLINE_CLIENT_SESSION_CACHE_NAME, getCaches(USER_SESSION_CACHE_NAME, OFFLINE_USER_SESSION_CACHE_NAME, CLIENT_SESSION_CACHE_NAME, OFFLINE_CLIENT_SESSION_CACHE_NAME,
LOGIN_FAILURE_CACHE_NAME, WORK_CACHE_NAME, ACTION_TOKEN_CACHE); LOGIN_FAILURE_CACHE_NAME, WORK_CACHE_NAME, ACTION_TOKEN_CACHE, AUTHENTICATION_SESSIONS_CACHE_NAME);
// Use Keycloak time service in remote caches // Use Keycloak time service in remote caches
InfinispanUtil.setTimeServiceToKeycloakTime(hotRodCacheManager); InfinispanUtil.setTimeServiceToKeycloakTime(hotRodCacheManager);

View file

@ -1,5 +1,9 @@
<infinispan> <infinispan>
<jgroups> <jgroups>
<stack name="bridge" extends="udp">
<UDP mcast_addr="228.6.7.12"/>
<LOCAL_PING stack.combine="REPLACE" stack.position="PING"/>
</stack>
<!-- Extends the default UDP stack. --> <!-- Extends the default UDP stack. -->
<stack name="xsite" extends="udp"> <stack name="xsite" extends="udp">
<UDP bind_addr="${jgroups.bind.address,jgroups.udp.address:127.0.0.1}" <UDP bind_addr="${jgroups.bind.address,jgroups.udp.address:127.0.0.1}"
@ -23,14 +27,14 @@
thread_pool.thread_dumps_threshold="${jgroups.thread_dumps_threshold:10000}" thread_pool.thread_dumps_threshold="${jgroups.thread_dumps_threshold:10000}"
/> />
<LOCAL_PING stack.combine="REPLACE" stack.position="PING"/>
<!-- Adds RELAY2 for cross-site replication. --> <!-- Adds RELAY2 for cross-site replication. -->
<!-- Names the local site as site-1. --> <!-- Names the local site as site-1. -->
<!-- Specifies 1000 nodes as the maximum number of site masters. --> <!-- Specifies 1000 nodes as the maximum number of site masters. -->
<relay.RELAY2 site="site-1" xmlns="urn:org:jgroups" max_site_masters="1000"/> <relay.RELAY2 site="site-1" xmlns="urn:org:jgroups" max_site_masters="1000"/>
<!-- Uses the default UDP stack for inter-cluster communication. --> <!-- Uses the default UDP stack for inter-cluster communication. -->
<!-- Names all sites that act as backup locations. --> <!-- Names all sites that act as backup locations. -->
<remote-sites default-stack="udp"> <remote-sites default-stack="bridge">
<remote-site name="site-1"/> <remote-site name="site-1"/>
<remote-site name="site-2"/> <remote-site name="site-2"/>
</remote-sites> </remote-sites>
@ -38,7 +42,7 @@
</jgroups> </jgroups>
<cache-container name="site-1" statistics="true"> <cache-container name="site-1" statistics="true">
<!-- Use the "xsite" stack for cluster transport. --> <!-- Use the "xsite" stack for cluster transport. -->
<transport cluster="site-1" stack="xsite"/> <transport cluster="external-site-1" stack="xsite"/>
<serialization marshaller="org.infinispan.jboss.marshalling.commons.GenericJBossMarshaller"/> <serialization marshaller="org.infinispan.jboss.marshalling.commons.GenericJBossMarshaller"/>
</cache-container> </cache-container>

View file

@ -1,5 +1,9 @@
<infinispan> <infinispan>
<jgroups> <jgroups>
<stack name="bridge" extends="udp">
<UDP mcast_addr="228.6.7.12"/>
<LOCAL_PING stack.combine="REPLACE" stack.position="PING"/>
</stack>
<!-- Extends the default UDP stack. --> <!-- Extends the default UDP stack. -->
<stack name="xsite" extends="udp"> <stack name="xsite" extends="udp">
<UDP bind_addr="${jgroups.bind.address,jgroups.udp.address:127.0.0.1}" <UDP bind_addr="${jgroups.bind.address,jgroups.udp.address:127.0.0.1}"
@ -23,13 +27,14 @@
thread_pool.thread_dumps_threshold="${jgroups.thread_dumps_threshold:10000}" thread_pool.thread_dumps_threshold="${jgroups.thread_dumps_threshold:10000}"
/> />
<LOCAL_PING stack.combine="REPLACE" stack.position="PING"/>
<!-- Adds RELAY2 for cross-site replication. --> <!-- Adds RELAY2 for cross-site replication. -->
<!-- Names the local site as site-2. --> <!-- Names the local site as site-2. -->
<!-- Specifies 1000 nodes as the maximum number of site masters. --> <!-- Specifies 1000 nodes as the maximum number of site masters. -->
<relay.RELAY2 site="site-2" xmlns="urn:org:jgroups" max_site_masters="1000"/> <relay.RELAY2 site="site-2" xmlns="urn:org:jgroups" max_site_masters="1000"/>
<!-- Uses the default UDP stack for inter-cluster communication. --> <!-- Uses the default UDP stack for inter-cluster communication. -->
<!-- Names all sites that act as backup locations. --> <!-- Names all sites that act as backup locations. -->
<remote-sites default-stack="udp"> <remote-sites default-stack="bridge">
<remote-site name="site-1"/> <remote-site name="site-1"/>
<remote-site name="site-2"/> <remote-site name="site-2"/>
</remote-sites> </remote-sites>
@ -37,7 +42,7 @@
</jgroups> </jgroups>
<cache-container name="site-2" statistics="true"> <cache-container name="site-2" statistics="true">
<!-- Use the "xsite" stack for cluster transport. --> <!-- Use the "xsite" stack for cluster transport. -->
<transport cluster="site-2" stack="xsite"/> <transport cluster="external-site-2" stack="xsite"/>
<serialization marshaller="org.infinispan.jboss.marshalling.commons.GenericJBossMarshaller"/> <serialization marshaller="org.infinispan.jboss.marshalling.commons.GenericJBossMarshaller"/>
</cache-container> </cache-container>