keycloak-uncached
Changes
misc/CrossDataCenter.md 64(+31 -33)
model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java 2(+1 -1)
model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java 10(+4 -6)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/CacheDecorators.java 18(+18 -0)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java 9(+5 -4)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java 85(+65 -20)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java 5(+3 -2)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshStoreFactory.java 5(+3 -2)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java 7(+4 -3)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java 11(+6 -5)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/KeycloakRemoteStore.java 176(+0 -176)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/KeycloakRemoteStoreConfiguration.java 55(+0 -55)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/KeycloakRemoteStoreConfigurationBuilder.java 78(+0 -78)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java 22(+11 -11)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java 12(+6 -6)
model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java 5(+1 -4)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGSessionsCacheTest.java 4(+2 -2)
model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java 7(+4 -3)
testsuite/integration-arquillian/servers/auth-server/jboss/common/crossdc/cross-dc-setup.cli 93(+38 -55)
testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestCacheResource.java 5(+3 -2)
Details
misc/CrossDataCenter.md 64(+31 -33)
diff --git a/misc/CrossDataCenter.md b/misc/CrossDataCenter.md
index 21dd586..b5a5670 100644
--- a/misc/CrossDataCenter.md
+++ b/misc/CrossDataCenter.md
@@ -116,64 +116,62 @@ Keycloak servers setup
<cache-container name="keycloak" jndi-name="infinispan/Keycloak" module="org.keycloak.keycloak-model-infinispan">
```
-3.3) Add the `store` under `work` cache:
+3.3) Add the `remote-store` under `work` cache:
```xml
<replicated-cache name="work" mode="SYNC">
- <store class="org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
- <property name="rawValues">true</property>
+ <remote-store cache="work" remote-servers="remote-cache" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
+ <property name="rawValues">true</property>
<property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
- <property name="remoteCacheName">work</property>
- <property name="sessionCache">false</property>
- </store>
+ </remote-store>
</replicated-cache>
```
-3.5) Add the `store` like this under `sessions` cache:
+3.5) Add the `remote-store` like this under `sessions` cache:
```xml
<distributed-cache name="sessions" mode="SYNC" owners="1">
- <store class="org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
- <property name="remoteCacheName">sessions</property>
- <property name="useConfigTemplateFromCache">work</property>
- <property name="sessionCache">true</property>
- </store>
+ <remote-store cache="sessions" remote-servers="remote-cache" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
+ <property name="rawValues">true</property>
+ <property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
+ </remote-store>
</distributed-cache>
```
-3.6) Same for `offlineSessions` and `loginFailures` caches (The only difference from `sessions` cache is, that `remoteCacheName` property value are different:
+3.6) Same for `offlineSessions`, `loginFailures`, and `actionTokens` caches (the only difference from `sessions` cache is that `cache` property value are different):
```xml
<distributed-cache name="offlineSessions" mode="SYNC" owners="1">
- <store class="org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
- <property name="remoteCacheName">offlineSessions</property>
- <property name="useConfigTemplateFromCache">work</property>
- <property name="sessionCache">true</property>
- </store>
+ <remote-store cache="offlineSessions" remote-servers="remote-cache" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
+ <property name="rawValues">true</property>
+ <property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
+ </remote-store>
</distributed-cache>
<distributed-cache name="loginFailures" mode="SYNC" owners="1">
- <store class="org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
- <property name="remoteCacheName">loginFailures</property>
- <property name="useConfigTemplateFromCache">work</property>
- <property name="sessionCache">true</property>
- </store>
+ <remote-store cache="loginFailures" remote-servers="remote-cache" passivation="false" fetch-state="false" purge="false" preload="false" shared="true">
+ <property name="rawValues">true</property>
+ <property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
+ </remote-store>
</distributed-cache>
-```
-
-3.7) The configuration of `actionTokens` cache have different `remoteCacheName`, `sessionCache` and the `preload` attribute:
-```xml
<distributed-cache name="actionTokens" mode="SYNC" owners="2">
<eviction max-entries="-1" strategy="NONE"/>
<expiration max-idle="-1" interval="300000"/>
- <store class="org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder" passivation="false" fetch-state="false" purge="false" preload="true" shared="true">
- <property name="remoteCacheName">actionTokens</property>
- <property name="useConfigTemplateFromCache">work</property>
- <property name="sessionCache">false</property>
- </store>
+ <remote-store cache="actionTokens" remote-servers="remote-cache" passivation="false" fetch-state="false" purge="false" preload="true" shared="true">
+ <property name="rawValues">true</property>
+ <property name="marshaller">org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory</property>
+ </remote-store>
</distributed-cache>
-```
+```
+
+3.7) Add outbound socket binding for the remote store into `socket-binding-group` configuration:
+
+```xml
+<outbound-socket-binding name="remote-cache">
+ <remote-destination host="${remote.cache.host:localhost}" port="${remote.cache.port:11222}"/>
+</outbound-socket-binding>
+```
3.8) The configuration of distributed cache `authenticationSessions` and other caches is left unchanged.
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java
index d95e4a4..5513777 100644
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProvider.java
@@ -25,7 +25,7 @@ import org.infinispan.manager.EmbeddedCacheManager;
*/
public class DefaultInfinispanConnectionProvider implements InfinispanConnectionProvider {
- private EmbeddedCacheManager cacheManager;
+ private final EmbeddedCacheManager cacheManager;
private final String siteName;
private final String nodeName;
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 6c84385..c657e44 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
@@ -41,9 +41,9 @@ import org.keycloak.Config;
import org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
-import org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder;
import javax.naming.InitialContext;
+import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -157,7 +157,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
this.nodeName = generateNodeName();
}
- logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
+ logger.debugv("Using container managed Infinispan cache container, lookup={0}", cacheContainerLookup);
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve cache container", e);
}
@@ -354,8 +354,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
builder.persistence()
.passivation(false)
- .addStore(KeycloakRemoteStoreConfigurationBuilder.class)
- .sessionCache(sessionCache)
+ .addStore(RemoteStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false)
.purgeOnStartup(false)
@@ -382,8 +381,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
builder.persistence()
.passivation(false)
- .addStore(KeycloakRemoteStoreConfigurationBuilder.class)
- .sessionCache(false)
+ .addStore(RemoteStoreConfigurationBuilder.class)
.fetchPersistentState(false)
.ignoreModifications(false)
.purgeOnStartup(false)
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/CacheDecorators.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/CacheDecorators.java
index e9b3288..23e5fb1 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/CacheDecorators.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/CacheDecorators.java
@@ -26,13 +26,31 @@ import org.infinispan.context.Flag;
*/
public class CacheDecorators {
+ /**
+ * Adds {@link Flag#CACHE_MODE_LOCAL} flag to the cache.
+ * @param cache
+ * @return Cache with the flag applied.
+ */
public static <K, V> AdvancedCache<K, V> localCache(Cache<K, V> cache) {
return cache.getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL);
}
+ /**
+ * Adds {@link Flag#SKIP_CACHE_LOAD} and {@link Flag#SKIP_CACHE_STORE} flags to the cache.
+ * @param cache
+ * @return Cache with the flags applied.
+ */
public static <K, V> AdvancedCache<K, V> skipCacheLoaders(Cache<K, V> cache) {
return cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_LOAD, Flag.SKIP_CACHE_STORE);
}
+ /**
+ * Adds {@link Flag#SKIP_CACHE_STORE} flag to the cache.
+ * @param cache
+ * @return Cache with the flags applied.
+ */
+ public static <K, V> AdvancedCache<K, V> skipCacheStore(Cache<K, V> cache) {
+ return cache.getAdvancedCache().withFlags(Flag.SKIP_CACHE_STORE);
+ }
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java
index e5a7a47..1950992 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/InfinispanChangelogBasedTransaction.java
@@ -27,6 +27,7 @@ import org.jboss.logging.Logger;
import org.keycloak.models.AbstractKeycloakTransaction;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.sessions.infinispan.CacheDecorators;
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
import org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheInvoker;
@@ -172,17 +173,17 @@ public class InfinispanChangelogBasedTransaction<K, V extends SessionEntity> ext
switch (operation) {
case REMOVE:
// Just remove it
- cache
+ CacheDecorators.skipCacheStore(cache)
.getAdvancedCache().withFlags(Flag.IGNORE_RETURN_VALUES)
.remove(key);
break;
case ADD:
- cache
+ CacheDecorators.skipCacheStore(cache)
.getAdvancedCache().withFlags(Flag.IGNORE_RETURN_VALUES)
.put(key, sessionWrapper, task.getLifespanMs(), TimeUnit.MILLISECONDS);
break;
case ADD_IF_ABSENT:
- SessionEntityWrapper<V> existing = cache.putIfAbsent(key, sessionWrapper);
+ SessionEntityWrapper<V> existing = CacheDecorators.skipCacheStore(cache).putIfAbsent(key, sessionWrapper);
if (existing != null) {
logger.debugf("Existing entity in cache for key: %s . Will update it", key);
@@ -210,7 +211,7 @@ public class InfinispanChangelogBasedTransaction<K, V extends SessionEntity> ext
SessionEntityWrapper<V> newVersionEntity = generateNewVersionAndWrapEntity(session, oldVersionEntity.getLocalMetadata());
// Atomic cluster-aware replace
- replaced = cache.replace(key, oldVersionEntity, newVersionEntity);
+ replaced = CacheDecorators.skipCacheStore(cache).replace(key, oldVersionEntity, newVersionEntity);
// Replace fail. Need to load latest entity from cache, apply updates again and try to replace in cache again
if (!replaced) {
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java
index 254cd38..0a3a5bf 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/SessionEntityWrapper.java
@@ -29,6 +29,7 @@ import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith;
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
+import org.jboss.logging.Logger;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -36,11 +37,12 @@ import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
@SerializeWith(SessionEntityWrapper.ExternalizerImpl.class)
public class SessionEntityWrapper<S extends SessionEntity> {
+ private static final Logger log = Logger.getLogger(SessionEntityWrapper.class);
+
private UUID version;
private final S entity;
private final Map<String, String> localMetadata;
-
protected SessionEntityWrapper(UUID version, Map<String, String> localMetadata, S entity) {
if (version == null) {
throw new IllegalArgumentException("Version UUID can't be null");
@@ -52,13 +54,34 @@ public class SessionEntityWrapper<S extends SessionEntity> {
}
public SessionEntityWrapper(Map<String, String> localMetadata, S entity) {
- this(UUID.randomUUID(),localMetadata, entity);
+ this(UUID.randomUUID(), localMetadata, entity);
}
public SessionEntityWrapper(S entity) {
this(new ConcurrentHashMap<>(), entity);
}
+ private SessionEntityWrapper(S entity, boolean forTransport) {
+ if (! forTransport) {
+ throw new IllegalArgumentException("This constructor is only for transport entities");
+ }
+
+ this.version = null;
+ this.localMetadata = null;
+ this.entity = entity;
+ }
+
+ public static <S extends SessionEntity> SessionEntityWrapper<S> forTransport(S entity) {
+ return new SessionEntityWrapper<>(entity, true);
+ }
+
+ public SessionEntityWrapper<S> forTransport() {
+ return new SessionEntityWrapper<>(this.entity, true);
+ }
+
+ private boolean isForTransport() {
+ return this.version == null;
+ }
public UUID getVersion() {
return version;
@@ -68,16 +91,21 @@ public class SessionEntityWrapper<S extends SessionEntity> {
this.version = version;
}
-
public S getEntity() {
return entity;
}
public String getLocalMetadataNote(String key) {
+ if (isForTransport()) {
+ throw new IllegalStateException("This entity is only intended for transport");
+ }
return localMetadata.get(key);
}
public void putLocalMetadataNote(String key, String value) {
+ if (isForTransport()) {
+ throw new IllegalStateException("This entity is only intended for transport");
+ }
localMetadata.put(key, value);
}
@@ -87,6 +115,9 @@ public class SessionEntityWrapper<S extends SessionEntity> {
}
public void putLocalMetadataNoteInt(String key, int value) {
+ if (isForTransport()) {
+ throw new IllegalStateException("This entity is only intended for transport");
+ }
localMetadata.put(key, String.valueOf(value));
}
@@ -122,31 +153,45 @@ public class SessionEntityWrapper<S extends SessionEntity> {
public static class ExternalizerImpl implements Externalizer<SessionEntityWrapper> {
+ private static final int VERSION_1 = 1;
@Override
public void writeObject(ObjectOutput output, SessionEntityWrapper obj) throws IOException {
- MarshallUtil.marshallUUID(obj.version, output, false);
- MarshallUtil.marshallMap(obj.localMetadata, output);
- output.writeObject(obj.getEntity());
- }
-
+ output.write(VERSION_1);
- @Override
- public SessionEntityWrapper readObject(ObjectInput input) throws IOException, ClassNotFoundException {
- UUID objVersion = MarshallUtil.unmarshallUUID(input, false);
-
- Map<String, String> localMetadata = MarshallUtil.unmarshallMap(input, new MarshallUtil.MapBuilder<String, String, Map<String, String>>() {
+ final boolean forTransport = obj.isForTransport();
+ output.writeBoolean(forTransport);
- @Override
- public Map<String, String> build(int size) {
- return new ConcurrentHashMap<>(size);
- }
+ if (! forTransport) {
+ output.writeLong(obj.getVersion().getMostSignificantBits());
+ output.writeLong(obj.getVersion().getLeastSignificantBits());
+ MarshallUtil.marshallMap(obj.localMetadata, output);
+ }
- });
+ output.writeObject(obj.entity);
+ }
- SessionEntity entity = (SessionEntity) input.readObject();
- return new SessionEntityWrapper<>(objVersion, localMetadata, entity);
+ @Override
+ public SessionEntityWrapper readObject(ObjectInput input) throws IOException, ClassNotFoundException {
+ byte version = input.readByte();
+
+ if (version != VERSION_1) {
+ throw new IOException("Invalid version: " + version);
+ }
+ final boolean forTransport = input.readBoolean();
+
+ if (forTransport) {
+ final SessionEntity entity = (SessionEntity) input.readObject();
+ log.debugf("Loaded entity from remote store: %s", entity);
+ return new SessionEntityWrapper(entity);
+ } else {
+ UUID sessionVersion = new UUID(input.readLong(), input.readLong());
+ ConcurrentHashMap<String, String> map = MarshallUtil.unmarshallMap(input, (size) -> new ConcurrentHashMap<>(size));
+ final SessionEntity entity = (SessionEntity) input.readObject();
+ log.debugf("Found entity locally: %s", entity);
+ return new SessionEntityWrapper(sessionVersion, map, entity);
+ }
}
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java
index 40cbb31..892ecfe 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshListener.java
@@ -28,6 +28,7 @@ import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
+import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
import org.keycloak.models.utils.KeycloakModelUtils;
@@ -43,11 +44,11 @@ public class LastSessionRefreshListener implements ClusterListener {
private final boolean offline;
private final KeycloakSessionFactory sessionFactory;
- private final Cache<String, SessionEntityWrapper> cache;
+ private final Cache<String, SessionEntityWrapper<UserSessionEntity>> cache;
private final boolean distributed;
private final String myAddress;
- public LastSessionRefreshListener(KeycloakSession session, Cache<String, SessionEntityWrapper> cache, boolean offline) {
+ public LastSessionRefreshListener(KeycloakSession session, Cache<String, SessionEntityWrapper<UserSessionEntity>> cache, boolean offline) {
this.sessionFactory = session.getKeycloakSessionFactory();
this.cache = cache;
this.offline = offline;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshStoreFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshStoreFactory.java
index 21ed476..d7b8559 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshStoreFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/sessions/LastSessionRefreshStoreFactory.java
@@ -22,6 +22,7 @@ import org.keycloak.cluster.ClusterProvider;
import org.keycloak.common.util.Time;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
+import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
import org.keycloak.timer.TimerProvider;
/**
@@ -39,12 +40,12 @@ public class LastSessionRefreshStoreFactory {
public static final int DEFAULT_MAX_COUNT = 100;
- public LastSessionRefreshStore createAndInit(KeycloakSession kcSession, Cache<String, SessionEntityWrapper> cache, boolean offline) {
+ public LastSessionRefreshStore createAndInit(KeycloakSession kcSession, Cache<String, SessionEntityWrapper<UserSessionEntity>> cache, boolean offline) {
return createAndInit(kcSession, cache, DEFAULT_TIMER_INTERVAL_MS, DEFAULT_MAX_INTERVAL_BETWEEN_MESSAGES_SECONDS, DEFAULT_MAX_COUNT, offline);
}
- public LastSessionRefreshStore createAndInit(KeycloakSession kcSession, Cache<String, SessionEntityWrapper> cache, long timerIntervalMs, int maxIntervalBetweenMessagesSeconds, int maxCount, boolean offline) {
+ public LastSessionRefreshStore createAndInit(KeycloakSession kcSession, Cache<String, SessionEntityWrapper<UserSessionEntity>> cache, long timerIntervalMs, int maxIntervalBetweenMessagesSeconds, int maxCount, boolean offline) {
String eventKey = offline ? "lastSessionRefreshes-offline" : "lastSessionRefreshes";
LastSessionRefreshStore store = createStoreInstance(maxIntervalBetweenMessagesSeconds, maxCount, eventKey);
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
index 48d1965..f9e21e1 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java
@@ -303,8 +303,9 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
if (remoteCache != null) {
- UserSessionEntity remoteSessionEntity = (UserSessionEntity) remoteCache.get(id);
- if (remoteSessionEntity != null) {
+ SessionEntityWrapper<UserSessionEntity> remoteSessionEntityWrapper = (SessionEntityWrapper<UserSessionEntity>) remoteCache.get(id);
+ if (remoteSessionEntityWrapper != null) {
+ UserSessionEntity remoteSessionEntity = remoteSessionEntityWrapper.getEntity();
log.debugf("getUserSessionWithPredicate(%s): remote cache contains session entity %s", id, remoteSessionEntity);
UserSessionModel remoteSessionAdapter = wrap(realm, remoteSessionEntity, offline);
@@ -399,7 +400,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
FuturesHelper futures = new FuturesHelper();
- // Each cluster node cleanups just local sessions, which are those owned by himself (+ few more taking l1 cache into account)
+ // Each cluster node cleanups just local sessions, which are those owned by itself (+ few more taking l1 cache into account)
Cache<String, SessionEntityWrapper<UserSessionEntity>> localCache = CacheDecorators.localCache(sessionCache);
Cache<String, SessionEntityWrapper<UserSessionEntity>> localCacheStoreIgnore = CacheDecorators.skipCacheLoaders(localCache);
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java
index ea37382..ccc9b84 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java
@@ -39,6 +39,7 @@ import org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheInvoker;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.entities.LoginFailureEntity;
import org.keycloak.models.sessions.infinispan.entities.LoginFailureKey;
+import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
import org.keycloak.models.sessions.infinispan.events.AbstractUserSessionClusterListener;
import org.keycloak.models.sessions.infinispan.events.ClientRemovedSessionEvent;
@@ -204,7 +205,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
InfinispanConnectionProvider ispn = session.getProvider(InfinispanConnectionProvider.class);
- Cache sessionsCache = ispn.getCache(InfinispanConnectionProvider.SESSION_CACHE_NAME);
+ Cache<String, SessionEntityWrapper<UserSessionEntity>> sessionsCache = ispn.getCache(InfinispanConnectionProvider.SESSION_CACHE_NAME);
boolean sessionsRemoteCache = checkRemoteCache(session, sessionsCache, (RealmModel realm) -> {
return realm.getSsoSessionIdleTimeout() * 1000;
});
@@ -214,7 +215,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
}
- Cache offlineSessionsCache = ispn.getCache(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME);
+ Cache<String, SessionEntityWrapper<UserSessionEntity>> offlineSessionsCache = ispn.getCache(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME);
boolean offlineSessionsRemoteCache = checkRemoteCache(session, offlineSessionsCache, (RealmModel realm) -> {
return realm.getOfflineSessionIdleTimeout() * 1000;
});
@@ -223,13 +224,13 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
offlineLastSessionRefreshStore = new LastSessionRefreshStoreFactory().createAndInit(session, offlineSessionsCache, true);
}
- Cache loginFailuresCache = ispn.getCache(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME);
+ Cache<LoginFailureKey, SessionEntityWrapper<LoginFailureEntity>> loginFailuresCache = ispn.getCache(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME);
boolean loginFailuresRemoteCache = checkRemoteCache(session, loginFailuresCache, (RealmModel realm) -> {
return realm.getMaxDeltaTimeSeconds() * 1000;
});
}
- private boolean checkRemoteCache(KeycloakSession session, Cache ispnCache, RemoteCacheInvoker.MaxIdleTimeLoader maxIdleLoader) {
+ private <K, V extends SessionEntity> boolean checkRemoteCache(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> ispnCache, RemoteCacheInvoker.MaxIdleTimeLoader maxIdleLoader) {
Set<RemoteStore> remoteStores = InfinispanUtil.getRemoteStores(ispnCache);
if (remoteStores.isEmpty()) {
@@ -238,7 +239,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
} else {
log.infof("Remote store configured for cache '%s'", ispnCache.getName());
- RemoteCache remoteCache = remoteStores.iterator().next().getRemoteCache();
+ RemoteCache<K, SessionEntityWrapper<V>> remoteCache = (RemoteCache) remoteStores.iterator().next().getRemoteCache();
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache, maxIdleLoader);
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java
index 8891469..3559c82 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheInvoker.java
@@ -82,23 +82,22 @@ public class RemoteCacheInvoker {
}
- private <K, V extends SessionEntity> void runOnRemoteCache(RemoteCache<K, V> remoteCache, long maxIdleMs, K key, SessionUpdateTask<V> task, SessionEntityWrapper<V> sessionWrapper) {
- V session = sessionWrapper.getEntity();
+ private <K, V extends SessionEntity> void runOnRemoteCache(RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long maxIdleMs, K key, SessionUpdateTask<V> task, SessionEntityWrapper<V> sessionWrapper) {
+ final V session = sessionWrapper.getEntity();
SessionUpdateTask.CacheOperation operation = task.getOperation(session);
switch (operation) {
case REMOVE:
- // REMOVE already handled at remote cache store level
- //remoteCache.remove(key);
+ remoteCache.remove(key);
break;
case ADD:
- remoteCache.put(key, session, task.getLifespanMs(), TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
+ remoteCache.put(key, sessionWrapper.forTransport(), task.getLifespanMs(), TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
break;
case ADD_IF_ABSENT:
final int currentTime = Time.currentTime();
- SessionEntity existing = remoteCache
+ SessionEntityWrapper<V> existing = remoteCache
.withFlags(Flag.FORCE_RETURN_VALUE)
- .putIfAbsent(key, session, -1, TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
+ .putIfAbsent(key, sessionWrapper.forTransport(), -1, TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
if (existing != null) {
logger.debugf("Existing entity in remote cache for key: %s . Will update it", key);
@@ -116,23 +115,24 @@ public class RemoteCacheInvoker {
}
- private <K, V extends SessionEntity> void replace(RemoteCache<K, V> remoteCache, long lifespanMs, long maxIdleMs, K key, SessionUpdateTask<V> task) {
+ private <K, V extends SessionEntity> void replace(RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long lifespanMs, long maxIdleMs, K key, SessionUpdateTask<V> task) {
boolean replaced = false;
while (!replaced) {
- VersionedValue<V> versioned = remoteCache.getVersioned(key);
+ VersionedValue<SessionEntityWrapper<V>> versioned = remoteCache.getVersioned(key);
if (versioned == null) {
logger.warnf("Not found entity to replace for key '%s'", key);
return;
}
- V session = versioned.getValue();
+ SessionEntityWrapper<V> sessionWrapper = versioned.getValue();
+ final V session = sessionWrapper.getEntity();
// Run task on the remote session
task.runUpdate(session);
logger.debugf("Before replaceWithVersion. Entity to write version %d: %s", versioned.getVersion(), session);
- replaced = remoteCache.replaceWithVersion(key, session, versioned.getVersion(), lifespanMs, TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
+ replaced = remoteCache.replaceWithVersion(key, SessionEntityWrapper.forTransport(session), versioned.getVersion(), lifespanMs, TimeUnit.MILLISECONDS, maxIdleMs, TimeUnit.MILLISECONDS);
if (!replaced) {
logger.debugf("Failed to replace entity '%s' version %d. Will retry again", key, versioned.getVersion());
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java
index 04e14f5..1639c78 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionListener.java
@@ -47,7 +47,7 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
protected static final Logger logger = Logger.getLogger(RemoteCacheSessionListener.class);
private Cache<K, SessionEntityWrapper<V>> cache;
- private RemoteCache<K, V> remoteCache;
+ private RemoteCache<K, SessionEntityWrapper<V>> remoteCache;
private boolean distributed;
private String myAddress;
private ClientListenerExecutorDecorator<K> executor;
@@ -57,7 +57,7 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
}
- protected void init(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> cache, RemoteCache<K, V> remoteCache) {
+ protected void init(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> cache, RemoteCache<K, SessionEntityWrapper<V>> remoteCache) {
this.cache = cache;
this.remoteCache = remoteCache;
@@ -113,10 +113,10 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
replaceRetries++;
SessionEntityWrapper<V> localEntityWrapper = cache.get(key);
- VersionedValue<V> remoteSessionVersioned = remoteCache.getVersioned(key);
+ VersionedValue<SessionEntityWrapper<V>> remoteSessionVersioned = remoteCache.getVersioned(key);
// Probably already removed
- if (remoteSessionVersioned == null) {
+ if (remoteSessionVersioned == null || remoteSessionVersioned.getValue() == null) {
logger.debugf("Entity '%s' not present in remoteCache. Ignoring replace",
key.toString());
return;
@@ -134,7 +134,7 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
sleepInterval = sleepInterval << 1;
}
}
- SessionEntity remoteSession = remoteSessionVersioned.getValue();
+ SessionEntity remoteSession = remoteSessionVersioned.getValue().getEntity();
logger.debugf("Read session entity from the remote cache: %s . replaceRetries=%d", remoteSession.toString(), replaceRetries);
@@ -201,7 +201,7 @@ public class RemoteCacheSessionListener<K, V extends SessionEntity> {
}
- public static <K, V extends SessionEntity> RemoteCacheSessionListener createListener(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> cache, RemoteCache<K, V> remoteCache) {
+ public static <K, V extends SessionEntity> RemoteCacheSessionListener createListener(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> cache, RemoteCache<K, SessionEntityWrapper<V>> remoteCache) {
/*boolean isCoordinator = InfinispanUtil.isCoordinator(cache);
// Just cluster coordinator will fetch userSessions from remote cache.
diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
index 789fc16..b96b9bd 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/remotestore/RemoteCacheSessionsLoader.java
@@ -29,7 +29,6 @@ import org.jboss.logging.Logger;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
-import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
import org.keycloak.models.sessions.infinispan.initializer.BaseCacheInitializer;
import org.keycloak.models.sessions.infinispan.initializer.OfflinePersistentUserSessionLoader;
import org.keycloak.models.sessions.infinispan.initializer.SessionLoader;
@@ -116,9 +115,7 @@ public class RemoteCacheSessionsLoader implements SessionLoader {
for (Map.Entry<byte[], byte[]> entry : remoteObjects.entrySet()) {
try {
Object key = marshaller.objectFromByteBuffer(entry.getKey());
- SessionEntity entity = (SessionEntity) marshaller.objectFromByteBuffer(entry.getValue());
-
- SessionEntityWrapper entityWrapper = new SessionEntityWrapper(entity);
+ SessionEntityWrapper entityWrapper = (SessionEntityWrapper) marshaller.objectFromByteBuffer(entry.getValue());
decoratedCache.putAsync(key, entityWrapper);
} catch (Exception e) {
diff --git a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGSessionsCacheTest.java b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGSessionsCacheTest.java
index a4091a1..5e79226 100644
--- a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGSessionsCacheTest.java
+++ b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/ConcurrencyJDGSessionsCacheTest.java
@@ -39,8 +39,8 @@ import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionEntity;
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
-import org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder;
import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
+import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationBuilder;
/**
* Test concurrency for remoteStore (backed by HotRod RemoteCaches) against external JDG. Especially tests "replaceWithVersion" contract.
@@ -207,7 +207,7 @@ public class ConcurrencyJDGSessionsCacheTest {
private static EmbeddedCacheManager createManager(int threadId) {
- return new TestCacheManagerFactory().createManager(threadId, InfinispanConnectionProvider.SESSION_CACHE_NAME, KeycloakRemoteStoreConfigurationBuilder.class);
+ return new TestCacheManagerFactory().createManager(threadId, InfinispanConnectionProvider.SESSION_CACHE_NAME, RemoteStoreConfigurationBuilder.class);
}
diff --git a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java
index 6b4eec1..0fc8d7e 100644
--- a/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java
+++ b/model/infinispan/src/test/java/org/keycloak/cluster/infinispan/TestCacheManagerFactory.java
@@ -19,11 +19,12 @@ package org.keycloak.cluster.infinispan;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
+import org.infinispan.configuration.cache.StoreConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.persistence.remote.configuration.ExhaustedAction;
-import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationBuilder;
+import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationChildBuilder;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -31,7 +32,7 @@ import org.infinispan.persistence.remote.configuration.RemoteStoreConfigurationB
class TestCacheManagerFactory {
- <T extends RemoteStoreConfigurationBuilder> EmbeddedCacheManager createManager(int threadId, String cacheName, Class<T> builderClass) {
+ <T extends StoreConfigurationBuilder<?, T> & RemoteStoreConfigurationChildBuilder<T>> EmbeddedCacheManager createManager(int threadId, String cacheName, Class<T> builderClass) {
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("jgroups.tcp.port", "53715");
GlobalConfigurationBuilder gcb = new GlobalConfigurationBuilder();
@@ -57,7 +58,7 @@ class TestCacheManagerFactory {
}
- private <T extends RemoteStoreConfigurationBuilder> Configuration getCacheBackedByRemoteStore(int threadId, String cacheName, Class<T> builderClass) {
+ private <T extends StoreConfigurationBuilder<?, T> & RemoteStoreConfigurationChildBuilder<T>> Configuration getCacheBackedByRemoteStore(int threadId, String cacheName, Class<T> builderClass) {
ConfigurationBuilder cacheConfigBuilder = new ConfigurationBuilder();
String host = "localhost";
diff --git a/services/src/main/java/org/keycloak/executors/DefaultExecutorsProviderFactory.java b/services/src/main/java/org/keycloak/executors/DefaultExecutorsProviderFactory.java
index aa8f83b..adc761d 100644
--- a/services/src/main/java/org/keycloak/executors/DefaultExecutorsProviderFactory.java
+++ b/services/src/main/java/org/keycloak/executors/DefaultExecutorsProviderFactory.java
@@ -44,8 +44,8 @@ public class DefaultExecutorsProviderFactory implements ExecutorsProviderFactory
protected static final Logger logger = Logger.getLogger(DefaultExecutorsProviderFactory.class);
- private int DEFAULT_MIN_THREADS = 4;
- private int DEFAULT_MAX_THREADS = 16;
+ private static final int DEFAULT_MIN_THREADS = 4;
+ private static final int DEFAULT_MAX_THREADS = 16;
private static final String MANAGED_EXECUTORS_SERVICE_JNDI_PREFIX = "java:jboss/ee/concurrency/executor/";
diff --git a/testsuite/integration-arquillian/servers/auth-server/jboss/common/crossdc/cross-dc-setup.cli b/testsuite/integration-arquillian/servers/auth-server/jboss/common/crossdc/cross-dc-setup.cli
index 3a0a7b0..3eee2fc 100644
--- a/testsuite/integration-arquillian/servers/auth-server/jboss/common/crossdc/cross-dc-setup.cli
+++ b/testsuite/integration-arquillian/servers/auth-server/jboss/common/crossdc/cross-dc-setup.cli
@@ -8,105 +8,88 @@ echo *** Update jgoups subsystem ***
echo *** Update infinispan subsystem ***
/subsystem=infinispan/cache-container=keycloak:write-attribute(name=module, value=org.keycloak.keycloak-model-infinispan)
+echo ** Add remote socket binding to infinispan server **
+/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-cache:add(host=${remote.cache.host:localhost}, port=${remote.cache.port:11222})
+
echo ** Update replicated-cache work element **
-/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=custom:add( \
- class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
+/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=remote:add( \
passivation=false, \
fetch-state=false, \
purge=false, \
preload=false, \
- shared=true \
-)
-
-/subsystem=infinispan/cache-container=keycloak/replicated-cache=work/store=custom:write-attribute( \
- name=properties, value={ \
+ shared=true, \
+ remote-servers=["remote-cache"], \
+ cache=work, \
+ properties={ \
rawValues=true, \
- marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory, \
- remoteCacheName=work, \
- sessionCache=false \
+ marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory \
} \
)
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:write-attribute(name=statistics-enabled,value=true)
echo ** Update distributed-cache sessions element **
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=custom:add( \
- class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=remote:add( \
passivation=false, \
fetch-state=false, \
purge=false, \
preload=false, \
- shared=true \
-)
-
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions/store=custom:write-attribute( \
- name=properties, value={ \
- remoteCacheName=sessions, \
- useConfigTemplateFromCache=work, \
- sessionCache=true \
+ shared=true, \
+ remote-servers=["remote-cache"], \
+ cache=sessions, \
+ properties={ \
+ rawValues=true, \
+ marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory \
} \
)
-
/subsystem=infinispan/cache-container=keycloak/distributed-cache=sessions:write-attribute(name=statistics-enabled,value=true)
echo ** Update distributed-cache offlineSessions element **
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=custom:add( \
- class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=remote:add( \
passivation=false, \
fetch-state=false, \
purge=false, \
preload=false, \
- shared=true \
-)
-
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions/store=custom:write-attribute( \
- name=properties, value={ \
- remoteCacheName=offlineSessions, \
- useConfigTemplateFromCache=work, \
- sessionCache=true \
+ shared=true, \
+ remote-servers=["remote-cache"], \
+ cache=offlineSessions, \
+ properties={ \
+ rawValues=true, \
+ marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory \
} \
)
-
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:write-attribute(name=statistics-enabled,value=true)
echo ** Update distributed-cache loginFailures element **
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=custom:add( \
- class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=remote:add( \
passivation=false, \
fetch-state=false, \
purge=false, \
preload=false, \
- shared=true \
-)
-
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures/store=custom:write-attribute( \
- name=properties, value={ \
- remoteCacheName=loginFailures, \
- useConfigTemplateFromCache=work, \
- sessionCache=true \
+ shared=true, \
+ remote-servers=["remote-cache"], \
+ cache=loginFailures, \
+ properties={ \
+ rawValues=true, \
+ marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory \
} \
)
-
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:write-attribute(name=statistics-enabled,value=true)
echo ** Update distributed-cache actionTokens element **
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=custom:add( \
- class=org.keycloak.models.sessions.infinispan.remotestore.KeycloakRemoteStoreConfigurationBuilder, \
+/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=remote:add( \
passivation=false, \
fetch-state=false, \
purge=false, \
- preload=true, \
- shared=true \
-)
-
-/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens/store=custom:write-attribute( \
- name=properties, value={ \
- remoteCacheName=actionTokens, \
- useConfigTemplateFromCache=work, \
- sessionCache=false \
+ preload=false, \
+ shared=true, \
+ cache=actionTokens, \
+ remote-servers=["remote-cache"], \
+ properties={ \
+ rawValues=true, \
+ marshaller=org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory \
} \
)
-
/subsystem=infinispan/cache-container=keycloak/distributed-cache=actionTokens:write-attribute(name=statistics-enabled,value=true)
echo ** Update distributed-cache authenticationSessions element **
diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestCacheResource.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestCacheResource.java
index 1954cb8..d1e7be1 100644
--- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestCacheResource.java
+++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/resource/TestCacheResource.java
@@ -35,6 +35,7 @@ import org.infinispan.remoting.transport.Transport;
import org.jgroups.JChannel;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
import org.keycloak.models.sessions.infinispan.util.InfinispanUtil;
import org.keycloak.testsuite.rest.representation.JGroupsStats;
@@ -136,11 +137,11 @@ public class TestCacheResource {
if (remoteCache == null) {
return -1;
} else {
- UserSessionEntity userSession = (UserSessionEntity) remoteCache.get(userSessionId);
+ SessionEntityWrapper<UserSessionEntity> userSession = (SessionEntityWrapper<UserSessionEntity>) remoteCache.get(userSessionId);
if (userSession == null) {
return -1;
} else {
- return userSession.getLastSessionRefresh();
+ return userSession.getEntity().getLastSessionRefresh();
}
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java
index 3007cab..e7d9026 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/crossdc/BruteForceCrossDCTest.java
@@ -222,10 +222,10 @@ public class BruteForceCrossDCTest extends AbstractAdminCrossDCTest {
log.infof("%s: dc0User1=%d, dc0user2=%d, dc1user1=%d, dc1user2=%d, dc0CacheSize=%d, dc1CacheSize=%d", prefixMessage, dc0user1, dc0user2, dc1user1, dc1user2, dc0CacheSize, dc1CacheSize);
- Assert.assertEquals(dc0user1, expectedUser1);
- Assert.assertEquals(dc0user2, expectedUser2);
- Assert.assertEquals(dc1user1, expectedUser1);
- Assert.assertEquals(dc1user2, expectedUser2);
+ Assert.assertEquals(expectedUser1, dc0user1);
+ Assert.assertEquals(expectedUser2, dc0user2);
+ Assert.assertEquals(expectedUser1, dc1user1);
+ Assert.assertEquals(expectedUser2, dc1user2);
Assert.assertEquals(expectedCacheSize, dc0CacheSize);
Assert.assertEquals(expectedCacheSize, dc1CacheSize);
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java
index 5b8c559..8946127 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java
@@ -34,6 +34,7 @@ import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
import org.keycloak.models.sessions.infinispan.changes.sessions.LastSessionRefreshStore;
import org.keycloak.models.sessions.infinispan.changes.sessions.LastSessionRefreshStoreFactory;
import org.keycloak.models.sessions.infinispan.changes.sessions.SessionData;
+import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Retry;
@@ -168,7 +169,7 @@ public class LastSessionRefreshUnitTest extends AbstractKeycloakTest {
};
- Cache<String, SessionEntityWrapper> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.SESSION_CACHE_NAME);
+ Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.SESSION_CACHE_NAME);
return factory.createAndInit(session, cache, timerIntervalMs, maxIntervalBetweenMessagesSeconds, 10, false);
}