Infinispan 15.0.3.Final
Closes #29068 Signed-off-by: Pedro Ruivo <pruivo@redhat.com>
This commit is contained in:
parent
8ff1ae0c08
commit
cbce548e71
32 changed files with 170 additions and 303 deletions
|
@ -92,16 +92,12 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-cachestore-remote</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod-jakarta</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
|
@ -88,11 +88,6 @@
|
|||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-cachestore-remote</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- adding it explictly, as Keycloak's parent excludes it to have full control over Jakarta EE vs. Java EE -->
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
*/
|
||||
package org.keycloak.adapters.saml.elytron.infinispan;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.configuration.cache.CacheMode;
|
||||
import org.infinispan.configuration.cache.Configuration;
|
||||
import org.infinispan.factories.ComponentRegistry;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.persistence.manager.PersistenceManager;
|
||||
import org.infinispan.persistence.remote.RemoteStore;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.adapters.saml.AdapterConstants;
|
||||
import org.keycloak.adapters.spi.SessionIdMapper;
|
||||
import org.keycloak.adapters.spi.SessionIdMapperUpdater;
|
||||
|
@ -23,14 +31,6 @@ import org.keycloak.adapters.spi.SessionIdMapperUpdater;
|
|||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
import javax.servlet.ServletContext;
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.configuration.cache.CacheMode;
|
||||
import org.infinispan.configuration.cache.Configuration;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.persistence.manager.PersistenceManager;
|
||||
import org.infinispan.persistence.remote.RemoteStore;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -94,21 +94,19 @@ public class InfinispanSessionCacheIdMapperUpdater {
|
|||
}
|
||||
|
||||
Cache<String, String[]> ssoCache = cacheManager.getCache(cacheName, true);
|
||||
final SsoSessionCacheListener listener = new SsoSessionCacheListener(ssoCache, mapper);
|
||||
SsoSessionCacheListener listener = new SsoSessionCacheListener(ssoCache, mapper);
|
||||
ssoCache.addListener(listener);
|
||||
|
||||
addSsoCacheCrossDcListener(ssoCache, listener);
|
||||
|
||||
LOG.debugv("Added distributed SSO session cache, lookup={0}, cache name={1}", cacheContainerLookup, cacheName);
|
||||
|
||||
SsoCacheSessionIdMapperUpdater updater = new SsoCacheSessionIdMapperUpdater(ssoCache, previousIdMapperUpdater) {
|
||||
return new SsoCacheSessionIdMapperUpdater(ssoCache, previousIdMapperUpdater) {
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
public void close() {
|
||||
ssoCache.stop();
|
||||
}
|
||||
};
|
||||
|
||||
return updater;
|
||||
} catch (NamingException ex) {
|
||||
LOG.warnv("Failed to obtain distributed session cache container, lookup={0}", cacheContainerLookup);
|
||||
return previousIdMapperUpdater;
|
||||
|
@ -137,7 +135,7 @@ public class InfinispanSessionCacheIdMapperUpdater {
|
|||
return;
|
||||
}
|
||||
|
||||
final Set<RemoteStore> stores = getRemoteStores(ssoCache);
|
||||
Set<RemoteStore> stores = getRemoteStores(ssoCache);
|
||||
if (stores == null || stores.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -149,7 +147,7 @@ public class InfinispanSessionCacheIdMapperUpdater {
|
|||
}
|
||||
}
|
||||
|
||||
public static Set<RemoteStore> getRemoteStores(Cache ispnCache) {
|
||||
return ispnCache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(RemoteStore.class);
|
||||
public static Set<RemoteStore> getRemoteStores(Cache<?, ?> ispnCache) {
|
||||
return ComponentRegistry.componentOf(ispnCache, PersistenceManager.class).getStores(RemoteStore.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ spec:
|
|||
expose:
|
||||
type: Route
|
||||
configMapName: "cluster-config"
|
||||
image: quay.io/infinispan/server:14.0.27.Final
|
||||
image: quay.io/infinispan/server:15.0.3.Final
|
||||
configListener:
|
||||
enabled: false
|
||||
container:
|
||||
|
|
|
@ -363,7 +363,7 @@ spec:
|
|||
expose:
|
||||
type: Route
|
||||
configMapName: "cluster-config"
|
||||
image: quay.io/infinispan/server:14.0.27.Final
|
||||
image: quay.io/infinispan/server:15.0.3.Final
|
||||
configListener:
|
||||
enabled: false
|
||||
container:
|
||||
|
|
|
@ -363,7 +363,7 @@ spec:
|
|||
expose:
|
||||
type: Route
|
||||
configMapName: "cluster-config"
|
||||
image: quay.io/infinispan/server:14.0.27.Final
|
||||
image: quay.io/infinispan/server:15.0.3.Final
|
||||
configListener:
|
||||
enabled: false
|
||||
container:
|
||||
|
|
|
@ -59,11 +59,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
|
|
|
@ -20,13 +20,11 @@ package org.keycloak.cluster.infinispan;
|
|||
import org.infinispan.Cache;
|
||||
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
|
||||
import org.infinispan.lifecycle.ComponentStatus;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.notifications.Listener;
|
||||
import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged;
|
||||
import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent;
|
||||
import org.infinispan.persistence.remote.RemoteStore;
|
||||
import org.infinispan.remoting.transport.Address;
|
||||
import org.infinispan.remoting.transport.Transport;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.cluster.ClusterProvider;
|
||||
|
@ -35,10 +33,10 @@ import org.keycloak.common.util.Retry;
|
|||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory;
|
||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||
import org.keycloak.connections.infinispan.TopologyInfo;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
@ -47,7 +45,6 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -72,7 +69,7 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
|
|||
// Just to extract notifications related stuff to separate class
|
||||
private InfinispanNotificationsManager notificationsManager;
|
||||
|
||||
private ExecutorService localExecutor = Executors.newCachedThreadPool(r -> {
|
||||
private final ExecutorService localExecutor = Executors.newCachedThreadPool(r -> {
|
||||
Thread thread = Executors.defaultThreadFactory().newThread(r);
|
||||
thread.setName(this.getClass().getName() + "-" + thread.getName());
|
||||
return thread;
|
||||
|
@ -140,7 +137,7 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
|
|||
static <V extends Serializable> V putIfAbsentWithRetries(CrossDCAwareCacheFactory crossDCAwareCacheFactory, String key, V value, int taskTimeoutInSeconds) {
|
||||
AtomicReference<V> resultRef = new AtomicReference<>();
|
||||
|
||||
Retry.executeWithBackoff((int iteration) -> {
|
||||
Retry.executeWithBackoff(iteration -> {
|
||||
|
||||
try {
|
||||
V result;
|
||||
|
@ -196,17 +193,14 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
|
|||
|
||||
@ViewChanged
|
||||
public void viewChanged(ViewChangedEvent event) {
|
||||
final Set<String> removedNodesAddresses = convertAddresses(event.getOldMembers());
|
||||
final Set<String> newAddresses = convertAddresses(event.getNewMembers());
|
||||
Set<String> removedNodesAddresses = convertAddresses(event.getOldMembers());
|
||||
Set<String> newAddresses = convertAddresses(event.getNewMembers());
|
||||
|
||||
// Use separate thread to avoid potential deadlock
|
||||
localExecutor.execute(() -> {
|
||||
try {
|
||||
EmbeddedCacheManager cacheManager = workCache.getCacheManager();
|
||||
Transport transport = cacheManager.getTransport();
|
||||
|
||||
// Coordinator makes sure that entries for outdated nodes are cleaned up
|
||||
if (transport != null && transport.isCoordinator()) {
|
||||
if (workCache.getCacheManager().isCoordinator()) {
|
||||
|
||||
removedNodesAddresses.removeAll(newAddresses);
|
||||
|
||||
|
@ -230,14 +224,7 @@ public class InfinispanClusterProviderFactory implements ClusterProviderFactory
|
|||
}
|
||||
|
||||
private Set<String> convertAddresses(Collection<Address> addresses) {
|
||||
return addresses.stream().map(new Function<Address, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(Address address) {
|
||||
return address.toString();
|
||||
}
|
||||
|
||||
}).collect(Collectors.toSet());
|
||||
return addresses.stream().map(Object::toString).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.factories.ComponentRegistry;
|
||||
import org.infinispan.persistence.manager.PersistenceManager;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.health.LoadBalancerCheckProvider;
|
||||
|
@ -60,9 +61,7 @@ public class InfinispanMultiSiteLoadBalancerCheckProvider implements LoadBalance
|
|||
return true; // no need to check other caches
|
||||
}
|
||||
|
||||
PersistenceManager persistenceManager = cache.getAdvancedCache()
|
||||
.getComponentRegistry()
|
||||
.getComponent(PersistenceManager.class);
|
||||
var persistenceManager = ComponentRegistry.componentOf(cache, PersistenceManager.class);
|
||||
|
||||
if (persistenceManager != null && !persistenceManager.isAvailable()) {
|
||||
LOG.debugf("PersistenceManager for cache '%s' is down.", cacheName);
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.client.hotrod.ProtocolVersion;
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
|
@ -34,7 +29,7 @@ import org.infinispan.configuration.cache.ConfigurationBuilder;
|
|||
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
|
||||
import org.infinispan.configuration.global.TransportConfigurationBuilder;
|
||||
import org.infinispan.eviction.EvictionStrategy;
|
||||
import org.infinispan.eviction.EvictionType;
|
||||
import org.infinispan.factories.ComponentRegistry;
|
||||
import org.infinispan.factories.GlobalComponentRegistry;
|
||||
import org.infinispan.factories.impl.BasicComponentRegistry;
|
||||
import org.infinispan.factories.impl.ComponentRef;
|
||||
|
@ -48,6 +43,11 @@ import org.jgroups.JChannel;
|
|||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -58,12 +58,12 @@ public class InfinispanUtil {
|
|||
public static final int MAXIMUM_REPLACE_RETRIES = 25;
|
||||
|
||||
// See if we have RemoteStore (external JDG) configured for cross-Data-Center scenario
|
||||
public static Set<RemoteStore> getRemoteStores(Cache ispnCache) {
|
||||
return ispnCache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(RemoteStore.class);
|
||||
public static Set<RemoteStore> getRemoteStores(Cache<?, ?> ispnCache) {
|
||||
return ComponentRegistry.componentOf(ispnCache, PersistenceManager.class).getStores(RemoteStore.class);
|
||||
}
|
||||
|
||||
|
||||
public static RemoteCache getRemoteCache(Cache ispnCache) {
|
||||
public static RemoteCache getRemoteCache(Cache<?, ?> ispnCache) {
|
||||
Set<RemoteStore> remoteStores = getRemoteStores(ispnCache);
|
||||
if (remoteStores.isEmpty()) {
|
||||
return null;
|
||||
|
@ -88,10 +88,9 @@ public class InfinispanUtil {
|
|||
* @param lifespanOrigMs
|
||||
* @return
|
||||
*/
|
||||
public static long toHotrodTimeMs(BasicCache ispnCache, long lifespanOrigMs) {
|
||||
if (ispnCache instanceof RemoteCache && lifespanOrigMs > 2592000000L) {
|
||||
RemoteCache remoteCache = (RemoteCache) ispnCache;
|
||||
ProtocolVersion protocolVersion = remoteCache.getRemoteCacheManager().getConfiguration().version();
|
||||
public static long toHotrodTimeMs(BasicCache<?, ?> ispnCache, long lifespanOrigMs) {
|
||||
if (ispnCache instanceof RemoteCache<?, ?> remoteCache && lifespanOrigMs > 2592000000L) {
|
||||
ProtocolVersion protocolVersion = remoteCache.getRemoteCacheContainer().getConfiguration().version();
|
||||
if (ProtocolVersion.PROTOCOL_VERSION_30.compareTo(protocolVersion) > 0) {
|
||||
return Time.currentTimeMillis() + lifespanOrigMs;
|
||||
}
|
||||
|
@ -166,9 +165,8 @@ public class InfinispanUtil {
|
|||
ConfigurationBuilder cb = createCacheConfigurationBuilder();
|
||||
|
||||
cb.memory()
|
||||
.evictionStrategy(EvictionStrategy.NONE)
|
||||
.evictionType(EvictionType.COUNT)
|
||||
.size(InfinispanConnectionProvider.ACTION_TOKEN_CACHE_DEFAULT_MAX);
|
||||
.whenFull(EvictionStrategy.MANUAL)
|
||||
.maxCount(InfinispanConnectionProvider.ACTION_TOKEN_CACHE_DEFAULT_MAX);
|
||||
cb.expiration()
|
||||
.maxIdle(InfinispanConnectionProvider.ACTION_TOKEN_MAX_IDLE_SECONDS, TimeUnit.SECONDS)
|
||||
.wakeUpInterval(InfinispanConnectionProvider.ACTION_TOKEN_WAKE_UP_INTERVAL_SECONDS, TimeUnit.SECONDS);
|
||||
|
@ -209,7 +207,7 @@ public class InfinispanUtil {
|
|||
* @return the original component that was replaced
|
||||
*/
|
||||
private static <T> T replaceComponent(EmbeddedCacheManager cacheMgr, Class<T> componentType, T replacementComponent, boolean rewire) {
|
||||
GlobalComponentRegistry cr = cacheMgr.getGlobalComponentRegistry();
|
||||
GlobalComponentRegistry cr = GlobalComponentRegistry.of(cacheMgr);
|
||||
BasicComponentRegistry bcr = cr.getComponent(BasicComponentRegistry.class);
|
||||
ComponentRef<T> old = bcr.getComponent(componentType);
|
||||
bcr.replaceComponent(componentType.getName(), replacementComponent, true);
|
||||
|
|
|
@ -17,12 +17,9 @@
|
|||
|
||||
package org.keycloak.connections.infinispan;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.distribution.DistributionManager;
|
||||
import org.infinispan.factories.GlobalComponentRegistry;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.remoting.transport.Address;
|
||||
import org.infinispan.remoting.transport.LocalModeAddress;
|
||||
|
@ -30,12 +27,14 @@ import org.infinispan.remoting.transport.Transport;
|
|||
import org.infinispan.remoting.transport.jgroups.JGroupsAddress;
|
||||
import org.infinispan.remoting.transport.jgroups.JGroupsTransport;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.jgroups.Event;
|
||||
import org.jgroups.JChannel;
|
||||
import org.jgroups.stack.IpAddress;
|
||||
import org.jgroups.util.NameCache;
|
||||
import org.keycloak.Config;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -66,9 +65,9 @@ public class TopologyInfo {
|
|||
}
|
||||
|
||||
if (!embedded) {
|
||||
Transport transport = cacheManager.getTransport();
|
||||
if (transport != null) {
|
||||
nodeName = transport.getAddress().toString();
|
||||
var addr = cacheManager.getAddress();
|
||||
if (addr != null) {
|
||||
nodeName = addr.toString();
|
||||
siteName = cacheManager.getCacheManagerConfiguration().transport().siteId();
|
||||
if (siteName == null) {
|
||||
siteName = config.get("siteName");
|
||||
|
@ -133,7 +132,7 @@ public class TopologyInfo {
|
|||
/**
|
||||
* True if I am primary owner of the key in case of distributed caches. In case of local caches, always return true
|
||||
*/
|
||||
public boolean amIOwner(Cache cache, Object key) {
|
||||
public boolean amIOwner(Cache<?, ?> cache, Object key) {
|
||||
Address myAddress = cache.getCacheManager().getAddress();
|
||||
Address objectOwnerAddress = getOwnerAddress(cache, key);
|
||||
|
||||
|
@ -145,7 +144,7 @@ public class TopologyInfo {
|
|||
/**
|
||||
* Get route to be used as the identifier for sticky session. Return null if I am not able to find the appropriate route (or in case of local mode)
|
||||
*/
|
||||
public String getRouteName(Cache cache, Object key) {
|
||||
public String getRouteName(Cache<?, ?> cache, Object key) {
|
||||
if (cache.getCacheConfiguration().clustering().cacheMode().isClustered() && isGeneratedNodeName) {
|
||||
logger.warn("Clustered configuration used, but node name is not properly set. Make sure to start server with jboss.node.name property identifying cluster node");
|
||||
}
|
||||
|
@ -168,11 +167,11 @@ public class TopologyInfo {
|
|||
// If no logical name exists, create one using physical address
|
||||
if (name == null) {
|
||||
|
||||
Transport transport = cache.getCacheManager().getTransport();
|
||||
JChannel jgroupsChannel = ((JGroupsTransport) transport).getChannel();
|
||||
|
||||
IpAddress ipAddress = (IpAddress) jgroupsChannel.down(new Event(Event.GET_PHYSICAL_ADDRESS, jgroupsAddress));
|
||||
// Physical address might be null if node is no longer a member of the cluster
|
||||
var transport = GlobalComponentRegistry.componentOf(cache.getCacheManager(), Transport.class);
|
||||
var channel = ((JGroupsTransport) transport).getChannel();
|
||||
var ipAddress = (IpAddress) channel.getProtocolStack().getTransport().localPhysicalAddress();
|
||||
// Physical address might be null if node is no longer a member of the cluster.
|
||||
// This seems broken, it is returning the IP/PORT for JGroups!?
|
||||
InetSocketAddress socketAddress = (ipAddress != null) ? new InetSocketAddress(ipAddress.getIpAddress(), ipAddress.getPort()) : new InetSocketAddress(0);
|
||||
name = String.format("%s:%s", socketAddress.getHostString(), socketAddress.getPort());
|
||||
|
||||
|
@ -183,21 +182,16 @@ public class TopologyInfo {
|
|||
}
|
||||
|
||||
|
||||
private Address getOwnerAddress(Cache cache, Object key) {
|
||||
private Address getOwnerAddress(Cache<?, ?> cache, Object key) {
|
||||
DistributionManager dist = cache.getAdvancedCache().getDistributionManager();
|
||||
Address address = (dist != null) && !cache.getCacheConfiguration().clustering().cacheMode().isScattered() ?
|
||||
dist.getCacheTopology().getDistribution(key).primary() :
|
||||
cache.getCacheManager().getAddress();
|
||||
|
||||
return address;
|
||||
return dist == null ? cache.getCacheManager().getAddress() : dist.getCacheTopology().getDistribution(key).primary();
|
||||
}
|
||||
|
||||
|
||||
// See org.wildfly.clustering.server.group.CacheGroup
|
||||
private static org.jgroups.Address toJGroupsAddress(Address address) {
|
||||
if ((address == null) || (address == LocalModeAddress.INSTANCE)) return null;
|
||||
if (address instanceof JGroupsAddress) {
|
||||
JGroupsAddress jgroupsAddress = (JGroupsAddress) address;
|
||||
if (address instanceof JGroupsAddress jgroupsAddress) {
|
||||
return jgroupsAddress.getJGroupsAddress();
|
||||
}
|
||||
throw new IllegalArgumentException(address.toString());
|
||||
|
|
|
@ -202,11 +202,8 @@ public class InfinispanUserLoginFailureProviderFactory implements UserLoginFailu
|
|||
InfinispanCacheInitializer initializer = new InfinispanCacheInitializer(sessionFactory, workCache,
|
||||
new RemoteCacheSessionsLoader(cacheName, sessionsPerSegment), "remoteCacheLoad::" + cacheName, maxErrors,
|
||||
getStalledTimeoutInSeconds(defaultStateTransferTimeout));
|
||||
|
||||
initializer.initCache();
|
||||
initializer.loadSessions();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
log.debugf("Pre-loading login failures from remote cache '%s' finished", cacheName);
|
||||
|
|
|
@ -399,11 +399,8 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
|||
InfinispanCacheInitializer initializer = new InfinispanCacheInitializer(sessionFactory, workCache,
|
||||
new RemoteCacheSessionsLoader(cacheName, sessionsPerSegment), "remoteCacheLoad::" + cacheName, maxErrors,
|
||||
getStalledTimeoutInSeconds(defaultStateTransferTimeout));
|
||||
|
||||
initializer.initCache();
|
||||
initializer.loadSessions();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
log.debugf("Pre-loading sessions from remote cache '%s' finished", cacheName);
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
|
||||
package org.keycloak.models.sessions.infinispan.initializer;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.context.Flag;
|
||||
import org.infinispan.lifecycle.ComponentStatus;
|
||||
import org.infinispan.remoting.transport.Transport;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
|
@ -74,21 +73,15 @@ public abstract class BaseCacheInitializer extends CacheInitializer {
|
|||
}
|
||||
|
||||
|
||||
protected void saveStateToCache(final InitializerState state) {
|
||||
protected void saveStateToCache(InitializerState state) {
|
||||
|
||||
// 3 attempts to send the message (it may fail if some node fails in the meantime)
|
||||
retry(3, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
retry(3, () -> {
|
||||
// Save this synchronously to ensure all nodes read correct state
|
||||
// We ignore cacheStore for now, so that in Cross-DC scenario (with RemoteStore enabled) is the remoteStore ignored.
|
||||
BaseCacheInitializer.this.workCache.getAdvancedCache().
|
||||
withFlags(Flag.IGNORE_RETURN_VALUES, Flag.FORCE_SYNCHRONOUS, Flag.SKIP_CACHE_STORE, Flag.SKIP_CACHE_LOAD)
|
||||
.put(stateKey, state);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package org.keycloak.models.sessions.infinispan.initializer;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.factories.ComponentRegistry;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
|
@ -26,9 +25,9 @@ import org.keycloak.models.KeycloakSessionTask;
|
|||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
/**
|
||||
* Startup initialization for reading persistent userSessions to be filled into infinispan/memory.
|
||||
|
@ -53,18 +52,6 @@ public class InfinispanCacheInitializer extends BaseCacheInitializer {
|
|||
}
|
||||
|
||||
|
||||
public void initCache() {
|
||||
// due to lazy initialization, this might be called from multiple threads simultaneously, therefore, synchronize
|
||||
synchronized (workCache) {
|
||||
final ComponentRegistry cr = this.workCache.getAdvancedCache().getComponentRegistry();
|
||||
// first check if already set, as Infinispan would otherwise throw a RuntimeException
|
||||
if (cr.getComponent(KeycloakSessionFactory.class) != sessionFactory) {
|
||||
cr.registerComponent(sessionFactory, KeycloakSessionFactory.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Just coordinator will run this
|
||||
@Override
|
||||
protected void startLoading() {
|
||||
|
@ -102,7 +89,7 @@ public class InfinispanCacheInitializer extends BaseCacheInitializer {
|
|||
}
|
||||
|
||||
protected void startLoadingImpl(InitializerState state, SessionLoader.LoaderContext loaderCtx) {
|
||||
int errors = 0;
|
||||
final int errors = 0;
|
||||
int segmentToLoad = 0;
|
||||
|
||||
int distributedWorkersCount = 1;
|
||||
|
@ -117,7 +104,7 @@ public class InfinispanCacheInitializer extends BaseCacheInitializer {
|
|||
log.trace("unfinished segments for this iteration: " + segments);
|
||||
}
|
||||
|
||||
final Queue<SessionLoader.WorkerResult> results = new ConcurrentLinkedQueue<>();
|
||||
Queue<SessionLoader.WorkerResult> results = new ConcurrentLinkedQueue<>();
|
||||
|
||||
for (Integer segment : segments) {
|
||||
SessionLoader.WorkerContext workerCtx = sessionLoader.computeWorkerContext(segment);
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
|
||||
package org.keycloak.cluster.infinispan;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.client.hotrod.Flag;
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
|
@ -31,12 +26,17 @@ import org.infinispan.client.hotrod.annotation.ClientListener;
|
|||
import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent;
|
||||
import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent;
|
||||
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
|
||||
import org.infinispan.factories.ComponentRegistry;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.persistence.manager.PersistenceManager;
|
||||
import org.infinispan.persistence.remote.RemoteStore;
|
||||
import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationBuilder;
|
||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Test concurrency for remoteStore (backed by HotRod RemoteCaches) against external JDG. Especially tests "putIfAbsent" contract.
|
||||
*
|
||||
|
@ -46,11 +46,7 @@ import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
|||
*/
|
||||
public class ConcurrencyJDGCachePutTest {
|
||||
|
||||
private static Map<String, EntryInfo> state = new HashMap<>();
|
||||
|
||||
private RemoteCache remoteCache1;
|
||||
private RemoteCache remoteCache2;
|
||||
|
||||
private static final Map<String, EntryInfo> state = new HashMap<>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Init map somehow
|
||||
|
@ -105,7 +101,8 @@ public class ConcurrencyJDGCachePutTest {
|
|||
|
||||
System.out.println("Retrieved cache: " + threadId);
|
||||
|
||||
RemoteStore remoteStore = cache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(RemoteStore.class).iterator().next();
|
||||
RemoteStore<?, ?> remoteStore = ComponentRegistry.componentOf(cache, PersistenceManager.class)
|
||||
.getStores(RemoteStore.class).iterator().next();
|
||||
HotRodListener listener = new HotRodListener();
|
||||
remoteStore.getRemoteCache().addClientListener(listener);
|
||||
|
||||
|
@ -119,14 +116,14 @@ public class ConcurrencyJDGCachePutTest {
|
|||
//private AtomicInteger listenerCount = new AtomicInteger(0);
|
||||
|
||||
@ClientCacheEntryCreated
|
||||
public void created(ClientCacheEntryCreatedEvent event) {
|
||||
String cacheKey = (String) event.getKey();
|
||||
public void created(ClientCacheEntryCreatedEvent<String> event) {
|
||||
String cacheKey = event.getKey();
|
||||
state.get(cacheKey).successfulListenerWrites.incrementAndGet();
|
||||
}
|
||||
|
||||
@ClientCacheEntryModified
|
||||
public void updated(ClientCacheEntryModifiedEvent event) {
|
||||
String cacheKey = (String) event.getKey();
|
||||
public void updated(ClientCacheEntryModifiedEvent<String> event) {
|
||||
String cacheKey = event.getKey();
|
||||
state.get(cacheKey).successfulListenerWrites.incrementAndGet();
|
||||
}
|
||||
|
||||
|
@ -171,7 +168,10 @@ public class ConcurrencyJDGCachePutTest {
|
|||
//Integer existingClusterStartTime = (Integer) cache.putIfAbsent(cacheKey, startupTime);
|
||||
|
||||
// Concurrency works fine with this
|
||||
RemoteCache remoteCache = cache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(RemoteStore.class).iterator().next().getRemoteCache();
|
||||
RemoteCache remoteCache = ComponentRegistry.componentOf(cache, PersistenceManager.class)
|
||||
.getStores(RemoteStore.class)
|
||||
.iterator().next()
|
||||
.getRemoteCache();
|
||||
|
||||
Integer existingClusterStartTime = null;
|
||||
for (int i=0 ; i<10 ; i++) {
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
|
||||
package org.keycloak.cluster.infinispan;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
import org.infinispan.client.hotrod.VersionedValue;
|
||||
|
@ -31,6 +25,7 @@ import org.infinispan.client.hotrod.annotation.ClientCacheEntryModified;
|
|||
import org.infinispan.client.hotrod.annotation.ClientListener;
|
||||
import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent;
|
||||
import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent;
|
||||
import org.infinispan.factories.ComponentRegistry;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
import org.infinispan.persistence.manager.PersistenceManager;
|
||||
import org.infinispan.persistence.remote.RemoteStore;
|
||||
|
@ -39,6 +34,12 @@ import org.junit.Assert;
|
|||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Test that hotrod ClientListeners are correctly executed as expected
|
||||
*
|
||||
|
@ -68,11 +69,11 @@ import org.keycloak.connections.infinispan.InfinispanUtil;
|
|||
public class ConcurrencyJDGRemoteCacheClientListenersTest {
|
||||
|
||||
// Helper map to track if listeners were executed
|
||||
private static Map<String, EntryInfo> state = new HashMap<>();
|
||||
private static final Map<String, EntryInfo> state = new HashMap<>();
|
||||
|
||||
private static AtomicInteger totalListenerCalls = new AtomicInteger(0);
|
||||
private static final AtomicInteger totalListenerCalls = new AtomicInteger(0);
|
||||
|
||||
private static AtomicInteger totalErrors = new AtomicInteger(0);
|
||||
private static final AtomicInteger totalErrors = new AtomicInteger(0);
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
@ -134,7 +135,8 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
|
|||
|
||||
System.out.println("Retrieved cache: " + threadId);
|
||||
|
||||
RemoteStore remoteStore = cache.getAdvancedCache().getComponentRegistry().getComponent(PersistenceManager.class).getStores(RemoteStore.class).iterator().next();
|
||||
RemoteStore<?, ?> remoteStore = ComponentRegistry.componentOf(cache, PersistenceManager.class)
|
||||
.getStores(RemoteStore.class).iterator().next();
|
||||
HotRodListener listener = new HotRodListener(cache, threadId);
|
||||
remoteStore.getRemoteCache().addClientListener(listener);
|
||||
|
||||
|
@ -147,7 +149,7 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
|
|||
|
||||
private final RemoteCache<String, Integer> remoteCache;
|
||||
private final int threadId;
|
||||
private Executor executor;
|
||||
private final Executor executor;
|
||||
|
||||
public HotRodListener(Cache<String, Integer> cache, int threadId) {
|
||||
this.remoteCache = InfinispanUtil.getRemoteCache(cache);
|
||||
|
@ -158,26 +160,15 @@ public class ConcurrencyJDGRemoteCacheClientListenersTest {
|
|||
//private AtomicInteger listenerCount = new AtomicInteger(0);
|
||||
|
||||
@ClientCacheEntryCreated
|
||||
public void created(ClientCacheEntryCreatedEvent event) {
|
||||
String cacheKey = (String) event.getKey();
|
||||
|
||||
executor.execute(() -> {
|
||||
|
||||
event(cacheKey, event.getVersion(), true);
|
||||
|
||||
});
|
||||
public void created(ClientCacheEntryCreatedEvent<String> event) {
|
||||
executor.execute(() -> event(event.getKey(), event.getVersion(), true));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ClientCacheEntryModified
|
||||
public void updated(ClientCacheEntryModifiedEvent event) {
|
||||
String cacheKey = (String) event.getKey();
|
||||
executor.execute(() -> {
|
||||
|
||||
event(cacheKey, event.getVersion(), false);
|
||||
|
||||
});
|
||||
public void updated(ClientCacheEntryModifiedEvent<String> event) {
|
||||
executor.execute(() -> event(event.getKey(), event.getVersion(), false));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,19 +17,11 @@
|
|||
|
||||
package org.keycloak.keys.infinispan;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.configuration.cache.Configuration;
|
||||
import org.infinispan.configuration.cache.ConfigurationBuilder;
|
||||
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
|
||||
import org.infinispan.eviction.EvictionStrategy;
|
||||
import org.infinispan.eviction.EvictionType;
|
||||
import org.infinispan.manager.DefaultCacheManager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
|
@ -40,12 +32,19 @@ import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
|||
import org.keycloak.crypto.PublicKeysWrapper;
|
||||
import org.keycloak.keys.PublicKeyLoader;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class InfinispanKeyStorageProviderTest {
|
||||
|
||||
private Map<String, AtomicInteger> counters = new ConcurrentHashMap<>();
|
||||
private final Map<String, AtomicInteger> counters = new ConcurrentHashMap<>();
|
||||
|
||||
Cache<String, PublicKeysEntry> keys = getKeysCache();
|
||||
Map<String, FutureTask<PublicKeysEntry>> tasksInProgress = new ConcurrentHashMap<>();
|
||||
|
@ -157,14 +156,13 @@ public class InfinispanKeyStorageProviderTest {
|
|||
protected Cache<String, PublicKeysEntry> getKeysCache() {
|
||||
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
|
||||
gcb.jmx().domain(InfinispanConnectionProvider.JMX_DOMAIN).enable();
|
||||
final DefaultCacheManager cacheManager = new DefaultCacheManager(gcb.build());
|
||||
DefaultCacheManager cacheManager = new DefaultCacheManager(gcb.build());
|
||||
|
||||
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||
cb.memory()
|
||||
.evictionStrategy(EvictionStrategy.REMOVE)
|
||||
.evictionType(EvictionType.COUNT)
|
||||
.size(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
|
||||
cb.jmxStatistics().enabled(true);
|
||||
.whenFull(EvictionStrategy.REMOVE)
|
||||
.maxCount(InfinispanConnectionProvider.KEYS_CACHE_DEFAULT_MAX);
|
||||
cb.statistics().enabled(true);
|
||||
Configuration cfg = cb.build();
|
||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.KEYS_CACHE_NAME, cfg);
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
<infinispan
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:infinispan:config:14.0 http://www.infinispan.org/schemas/infinispan-config-14.0.xsd"
|
||||
xmlns="urn:infinispan:config:14.0">
|
||||
xsi:schemaLocation="urn:infinispan:config:15.0 http://www.infinispan.org/schemas/infinispan-config-15.0.xsd"
|
||||
xmlns="urn:infinispan:config:15.0">
|
||||
|
||||
<cache-container name="keycloak">
|
||||
<transport lock-timeout="60000"/>
|
||||
|
|
38
pom.xml
38
pom.xml
|
@ -93,7 +93,7 @@
|
|||
<h2.version>2.2.224</h2.version>
|
||||
<hibernate-orm.plugin.version>6.2.13.Final</hibernate-orm.plugin.version>
|
||||
<hibernate.c3p0.version>6.2.13.Final</hibernate.c3p0.version>
|
||||
<infinispan.version>14.0.27.Final</infinispan.version>
|
||||
<infinispan.version>15.0.3.Final</infinispan.version>
|
||||
|
||||
<!--JAKARTA-->
|
||||
<jakarta.mail.version>2.1.1</jakarta.mail.version>
|
||||
|
@ -311,42 +311,6 @@
|
|||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-jboss-marshalling</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<exclusions>
|
||||
<!-- this conflicts with infinispan-*-jakarta -->
|
||||
<exclusion>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-commons</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-cachestore-remote</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<exclusions>
|
||||
<!-- this conflicts with infinispan-*-jakarta -->
|
||||
<exclusion>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-commons</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus.platform</groupId>
|
||||
<artifactId>quarkus-bom</artifactId>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-commons-jakarta</artifactId>
|
||||
<artifactId>infinispan-commons</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -457,19 +457,9 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod-jakarta</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-cachestore-remote</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>*</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ua-parser</groupId>
|
||||
|
@ -558,11 +548,11 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-commons-jakarta</artifactId>
|
||||
<artifactId>infinispan-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
<infinispan
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:infinispan:config:14.0 http://www.infinispan.org/schemas/infinispan-config-14.0.xsd"
|
||||
xmlns="urn:infinispan:config:14.0">
|
||||
xsi:schemaLocation="urn:infinispan:config:15.0 http://www.infinispan.org/schemas/infinispan-config-15.0.xsd"
|
||||
xmlns="urn:infinispan:config:15.0">
|
||||
|
||||
<cache-container name="keycloak">
|
||||
<transport lock-timeout="60000"/>
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
<infinispan
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:infinispan:config:14.0 http://www.infinispan.org/schemas/infinispan-config-14.0.xsd"
|
||||
xmlns="urn:infinispan:config:14.0">
|
||||
xsi:schemaLocation="urn:infinispan:config:15.0 http://www.infinispan.org/schemas/infinispan-config-15.0.xsd"
|
||||
xmlns="urn:infinispan:config:15.0">
|
||||
|
||||
<cache-container name="keycloak">
|
||||
<local-cache name="default">
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
<!--tag::keycloak-ispn-configmap[] -->
|
||||
<infinispan
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:infinispan:config:14.0 https://www.infinispan.org/schemas/infinispan-config-14.0.xsd
|
||||
urn:infinispan:config:store:remote:14.0 https://www.infinispan.org/schemas/infinispan-cachestore-remote-config-14.0.xsd"
|
||||
xmlns="urn:infinispan:config:14.0">
|
||||
xsi:schemaLocation="urn:infinispan:config:15.0 https://www.infinispan.org/schemas/infinispan-config-15.0.xsd
|
||||
urn:infinispan:config:store:remote:15.0 https://www.infinispan.org/schemas/infinispan-cachestore-remote-config-15.0.xsd"
|
||||
xmlns="urn:infinispan:config:15.0">
|
||||
<!--end::keycloak-ispn-configmap[] -->
|
||||
|
||||
<!-- the statistics="true" attribute is not part of the original KC config and was added by Keycloak Benchmark -->
|
||||
|
@ -47,8 +47,8 @@
|
|||
<!--tag::keycloak-ispn-remotestore[] -->
|
||||
<distributed-cache name="sessions" owners="2" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false"> <!--1-->
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500"> <!--1-->
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="sessions"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -71,8 +71,8 @@
|
|||
<!--end::keycloak-ispn-remotestore[] -->
|
||||
<distributed-cache name="authenticationSessions" owners="2" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="authenticationSessions"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -94,8 +94,8 @@
|
|||
</distributed-cache>
|
||||
<distributed-cache name="offlineSessions" owners="2" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="offlineSessions"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -117,8 +117,8 @@
|
|||
</distributed-cache>
|
||||
<distributed-cache name="clientSessions" owners="2" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="clientSessions"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -140,8 +140,8 @@
|
|||
</distributed-cache>
|
||||
<distributed-cache name="offlineClientSessions" owners="2" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="offlineClientSessions"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -163,8 +163,8 @@
|
|||
</distributed-cache>
|
||||
<distributed-cache name="loginFailures" owners="2" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="loginFailures"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -193,8 +193,8 @@
|
|||
</local-cache>
|
||||
<replicated-cache name="work" statistics="true">
|
||||
<expiration lifespan="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="work"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
@ -229,8 +229,8 @@
|
|||
</encoding>
|
||||
<expiration max-idle="-1" lifespan="-1" interval="300000"/>
|
||||
<memory max-count="-1"/>
|
||||
<persistence passivation="false">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:14.0"
|
||||
<persistence passivation="false" availability-interval="500">
|
||||
<remote-store xmlns="urn:infinispan:config:store:remote:15.0"
|
||||
cache="actionTokens"
|
||||
raw-values="true"
|
||||
shared="true"
|
||||
|
|
|
@ -86,21 +86,11 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-tasks-api</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -48,14 +48,14 @@ public class InfinispanTimeServiceTask implements ServerTask<String> {
|
|||
@Override
|
||||
public String call() {
|
||||
EmbeddedCacheManager cacheManager = context.getCacheManager();
|
||||
Map<String, Object> params = new HashMap();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
if (this.context.getParameters().isPresent())
|
||||
params = this.context.getParameters().get();
|
||||
if (params.containsKey("timeService")) {
|
||||
offset = (int) params.get("timeService");
|
||||
|
||||
// rewire the Time service
|
||||
GlobalComponentRegistry cr = cacheManager.getGlobalComponentRegistry();
|
||||
GlobalComponentRegistry cr = GlobalComponentRegistry.of(cacheManager);
|
||||
BasicComponentRegistry bcr = cr.getComponent(BasicComponentRegistry.class);
|
||||
bcr.replaceComponent(TimeService.class.getName(), KEYCLOAK_TIME_SERVICE, true);
|
||||
cr.rewire();
|
||||
|
|
|
@ -17,29 +17,28 @@
|
|||
|
||||
package org.keycloak.testsuite.rest.resource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
import org.infinispan.stream.CacheCollectors;
|
||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
|
||||
import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
|
||||
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||
import org.keycloak.utils.MediaType;
|
||||
import org.infinispan.stream.CacheCollectors;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
@ -114,12 +113,10 @@ public class TestCacheResource {
|
|||
@Path("/remote-cache-stats")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Map<String, String> getRemoteCacheStats() {
|
||||
RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
|
||||
if (remoteCache == null) {
|
||||
return new HashMap<>();
|
||||
} else {
|
||||
return remoteCache.stats().getStatsMap();
|
||||
}
|
||||
var remoteCache = InfinispanUtil.getRemoteCache(cache);
|
||||
return remoteCache == null ?
|
||||
Collections.emptyMap() :
|
||||
remoteCache.serverStatistics().getStatsMap();
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,11 +124,11 @@ public class TestCacheResource {
|
|||
@Path("/remote-cache-last-session-refresh/{user-session-id}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public int getRemoteCacheLastSessionRefresh(@PathParam("user-session-id") String userSessionId) {
|
||||
RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
|
||||
RemoteCache<String, SessionEntityWrapper<UserSessionEntity>> remoteCache = InfinispanUtil.getRemoteCache(cache);
|
||||
if (remoteCache == null) {
|
||||
return -1;
|
||||
} else {
|
||||
SessionEntityWrapper<UserSessionEntity> userSession = (SessionEntityWrapper<UserSessionEntity>) remoteCache.get(userSessionId);
|
||||
SessionEntityWrapper<UserSessionEntity> userSession = remoteCache.get(userSessionId);
|
||||
if (userSession == null) {
|
||||
return -1;
|
||||
} else {
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-server-hotrod-jakarta</artifactId>
|
||||
<artifactId>infinispan-server-hotrod</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.keycloak</groupId>
|
||||
|
|
|
@ -1819,7 +1819,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
|
|
|
@ -227,7 +227,7 @@
|
|||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core-jakarta</artifactId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
|
|
Loading…
Reference in a new issue