Simplify configuration for MULTI_SITE
Closes #31807 Signed-off-by: Michal Hajas <mhajas@redhat.com>
This commit is contained in:
parent
3fbe26d2e1
commit
50c07c6e7c
32 changed files with 151 additions and 96 deletions
|
@ -103,6 +103,7 @@ public class Profile {
|
||||||
TRANSIENT_USERS("Transient users for brokering", Type.EXPERIMENTAL),
|
TRANSIENT_USERS("Transient users for brokering", Type.EXPERIMENTAL),
|
||||||
|
|
||||||
MULTI_SITE("Multi-site support", Type.DISABLED_BY_DEFAULT),
|
MULTI_SITE("Multi-site support", Type.DISABLED_BY_DEFAULT),
|
||||||
|
|
||||||
REMOTE_CACHE("Remote caches support. Requires Multi-site support to be enabled as well.", Type.EXPERIMENTAL),
|
REMOTE_CACHE("Remote caches support. Requires Multi-site support to be enabled as well.", Type.EXPERIMENTAL),
|
||||||
|
|
||||||
CLIENT_TYPES("Client Types", Type.EXPERIMENTAL),
|
CLIENT_TYPES("Client Types", Type.EXPERIMENTAL),
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Red Hat, Inc. and/or its affiliates
|
||||||
|
* and other contributors as indicated by the @author tags.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.keycloak.common.util;
|
||||||
|
|
||||||
|
import org.keycloak.common.Profile;
|
||||||
|
|
||||||
|
public class MultiSiteUtils {
|
||||||
|
|
||||||
|
public static boolean isMultiSiteEnabled() {
|
||||||
|
return Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true when user sessions are stored in the database. In multi-site setup this is false when REMOTE_CACHE feature is enabled
|
||||||
|
*/
|
||||||
|
public static boolean isPersistentSessionsEnabled() {
|
||||||
|
return Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) || (isMultiSiteEnabled() && !Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ import org.infinispan.persistence.manager.PersistenceManager;
|
||||||
import org.infinispan.util.concurrent.ActionSequencer;
|
import org.infinispan.util.concurrent.ActionSequencer;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.health.LoadBalancerCheckProvider;
|
import org.keycloak.health.LoadBalancerCheckProvider;
|
||||||
import org.keycloak.health.LoadBalancerCheckProviderFactory;
|
import org.keycloak.health.LoadBalancerCheckProviderFactory;
|
||||||
|
@ -62,7 +63,7 @@ public class RemoteLoadBalancerCheckProviderFactory implements LoadBalancerCheck
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(Config.Scope config) {
|
public boolean isSupported(Config.Scope config) {
|
||||||
return InfinispanUtils.isRemoteInfinispan();
|
return MultiSiteUtils.isMultiSiteEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
package org.keycloak.infinispan.util;
|
package org.keycloak.infinispan.util;
|
||||||
|
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.common.Profile.Feature;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
|
|
||||||
import static org.keycloak.common.Profile.Feature.MULTI_SITE;
|
|
||||||
import static org.keycloak.common.Profile.Feature.REMOTE_CACHE;
|
import static org.keycloak.common.Profile.Feature.REMOTE_CACHE;
|
||||||
|
|
||||||
public final class InfinispanUtils {
|
public final class InfinispanUtils {
|
||||||
|
@ -39,11 +38,11 @@ public final class InfinispanUtils {
|
||||||
|
|
||||||
// true if running with external infinispan mode only
|
// true if running with external infinispan mode only
|
||||||
public static boolean isRemoteInfinispan() {
|
public static boolean isRemoteInfinispan() {
|
||||||
return Profile.isFeatureEnabled(Feature.MULTI_SITE) && Profile.isFeatureEnabled(REMOTE_CACHE);
|
return MultiSiteUtils.isMultiSiteEnabled() || Profile.isFeatureEnabled(REMOTE_CACHE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// true if running with embedded caches.
|
// true if running with embedded caches.
|
||||||
public static boolean isEmbeddedInfinispan() {
|
public static boolean isEmbeddedInfinispan() {
|
||||||
return !Profile.isFeatureEnabled(MULTI_SITE) || !Profile.isFeatureEnabled(REMOTE_CACHE);
|
return !isRemoteInfinispan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ import org.infinispan.persistence.remote.RemoteStore;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.cluster.ClusterProvider;
|
import org.keycloak.cluster.ClusterProvider;
|
||||||
import org.keycloak.common.Profile;
|
|
||||||
import org.keycloak.common.util.Environment;
|
import org.keycloak.common.util.Environment;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.connections.infinispan.InfinispanUtil;
|
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||||
|
@ -77,8 +77,6 @@ import org.keycloak.provider.ProviderEvent;
|
||||||
import org.keycloak.provider.ProviderEventListener;
|
import org.keycloak.provider.ProviderEventListener;
|
||||||
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
import org.keycloak.provider.ServerInfoAwareProviderFactory;
|
||||||
|
|
||||||
import static org.keycloak.common.Profile.Feature.PERSISTENT_USER_SESSIONS;
|
|
||||||
|
|
||||||
public class InfinispanUserSessionProviderFactory implements UserSessionProviderFactory<UserSessionProvider>, ServerInfoAwareProviderFactory, EnvironmentDependentProviderFactory {
|
public class InfinispanUserSessionProviderFactory implements UserSessionProviderFactory<UserSessionProvider>, ServerInfoAwareProviderFactory, EnvironmentDependentProviderFactory {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(InfinispanUserSessionProviderFactory.class);
|
private static final Logger log = Logger.getLogger(InfinispanUserSessionProviderFactory.class);
|
||||||
|
@ -131,7 +129,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
offlineClientSessionsCache = connections.getCache(InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME);
|
offlineClientSessionsCache = connections.getCache(InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
return new PersistentUserSessionProvider(
|
return new PersistentUserSessionProvider(
|
||||||
session,
|
session,
|
||||||
remoteCacheInvoker,
|
remoteCacheInvoker,
|
||||||
|
@ -175,8 +173,9 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
offlineSessionCacheEntryLifespanOverride = config.getInt(CONFIG_OFFLINE_SESSION_CACHE_ENTRY_LIFESPAN_OVERRIDE, -1);
|
offlineSessionCacheEntryLifespanOverride = config.getInt(CONFIG_OFFLINE_SESSION_CACHE_ENTRY_LIFESPAN_OVERRIDE, -1);
|
||||||
offlineClientSessionCacheEntryLifespanOverride = config.getInt(CONFIG_OFFLINE_CLIENT_SESSION_CACHE_ENTRY_LIFESPAN_OVERRIDE, -1);
|
offlineClientSessionCacheEntryLifespanOverride = config.getInt(CONFIG_OFFLINE_CLIENT_SESSION_CACHE_ENTRY_LIFESPAN_OVERRIDE, -1);
|
||||||
maxBatchSize = config.getInt(CONFIG_MAX_BATCH_SIZE, DEFAULT_MAX_BATCH_SIZE);
|
maxBatchSize = config.getInt(CONFIG_MAX_BATCH_SIZE, DEFAULT_MAX_BATCH_SIZE);
|
||||||
|
// Do not use caches for sessions if explicitly disabled or if embedded caches are not used
|
||||||
useCaches = config.getBoolean(CONFIG_USE_CACHES, DEFAULT_USE_CACHES) && InfinispanUtils.isEmbeddedInfinispan();
|
useCaches = config.getBoolean(CONFIG_USE_CACHES, DEFAULT_USE_CACHES) && InfinispanUtils.isEmbeddedInfinispan();
|
||||||
useBatches = config.getBoolean(CONFIG_USE_BATCHES, DEFAULT_USE_BATCHES) && Profile.isFeatureEnabled(PERSISTENT_USER_SESSIONS);
|
useBatches = config.getBoolean(CONFIG_USE_BATCHES, DEFAULT_USE_BATCHES) && MultiSiteUtils.isPersistentSessionsEnabled();
|
||||||
if (useBatches) {
|
if (useBatches) {
|
||||||
asyncQueuePersistentUpdate = new ArrayBlockingQueue<>(1000);
|
asyncQueuePersistentUpdate = new ArrayBlockingQueue<>(1000);
|
||||||
}
|
}
|
||||||
|
@ -204,7 +203,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
|
|
||||||
keyGenerator = new InfinispanKeyGenerator();
|
keyGenerator = new InfinispanKeyGenerator();
|
||||||
checkRemoteCaches(session);
|
checkRemoteCaches(session);
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
initializeLastSessionRefreshStore(factory);
|
initializeLastSessionRefreshStore(factory);
|
||||||
}
|
}
|
||||||
registerClusterListeners(session);
|
registerClusterListeners(session);
|
||||||
|
@ -237,7 +236,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) && useBatches) {
|
if (MultiSiteUtils.isPersistentSessionsEnabled() && useBatches) {
|
||||||
persistentSessionsWorker = new PersistentSessionsWorker(factory,
|
persistentSessionsWorker = new PersistentSessionsWorker(factory,
|
||||||
asyncQueuePersistentUpdate,
|
asyncQueuePersistentUpdate,
|
||||||
maxBatchSize);
|
maxBatchSize);
|
||||||
|
@ -367,7 +366,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache, maxIdleLoader);
|
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache, maxIdleLoader);
|
||||||
|
|
||||||
Runnable onFailover = null;
|
Runnable onFailover = null;
|
||||||
if (useCaches && Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (useCaches && MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
// If persistent sessions are enabled, we want to clear the local caches when a failover of the listener on the remote store changes as we might have missed some of the remote store events
|
// If persistent sessions are enabled, we want to clear the local caches when a failover of the listener on the remote store changes as we might have missed some of the remote store events
|
||||||
// which might have been triggered by another Keycloak site connected to the same remote Infinispan cluster.
|
// which might have been triggered by another Keycloak site connected to the same remote Infinispan cluster.
|
||||||
// Due to this, we can be sure that we never have outdated information in our local cache. All entries will be re-loaded from the remote cache or the database as necessary lazily.
|
// Due to this, we can be sure that we never have outdated information in our local cache. All entries will be re-loaded from the remote cache or the database as necessary lazily.
|
||||||
|
@ -465,7 +464,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(Config.Scope config) {
|
public boolean isSupported(Config.Scope config) {
|
||||||
return InfinispanUtils.isEmbeddedInfinispan() || Profile.isFeatureEnabled(PERSISTENT_USER_SESSIONS);
|
return InfinispanUtils.isEmbeddedInfinispan() || MultiSiteUtils.isPersistentSessionsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -48,6 +48,7 @@ import org.jboss.logging.Logger;
|
||||||
import org.keycloak.cluster.ClusterProvider;
|
import org.keycloak.cluster.ClusterProvider;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.common.Profile.Feature;
|
import org.keycloak.common.Profile.Feature;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Retry;
|
import org.keycloak.common.util.Retry;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
|
@ -134,7 +135,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
SerializeExecutionsByKey<String> serializerOfflineSession,
|
SerializeExecutionsByKey<String> serializerOfflineSession,
|
||||||
SerializeExecutionsByKey<UUID> serializerClientSession,
|
SerializeExecutionsByKey<UUID> serializerClientSession,
|
||||||
SerializeExecutionsByKey<UUID> serializerOfflineClientSession) {
|
SerializeExecutionsByKey<UUID> serializerOfflineClientSession) {
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
throw new IllegalStateException("Persistent user sessions are not enabled");
|
throw new IllegalStateException("Persistent user sessions are not enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.models.sessions.infinispan;
|
package org.keycloak.models.sessions.infinispan;
|
||||||
|
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -231,7 +231,7 @@ public class UserSessionAdapter<T extends SessionRefreshStore & UserSessionProvi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) && offline) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled() && offline) {
|
||||||
// Received the message from the other DC that we should update the lastSessionRefresh in local cluster. Don't update DB in that case.
|
// Received the message from the other DC that we should update the lastSessionRefresh in local cluster. Don't update DB in that case.
|
||||||
// The other DC already did.
|
// The other DC already did.
|
||||||
Boolean ignoreRemoteCacheUpdate = (Boolean) session.getAttribute(CrossDCLastSessionRefreshListener.IGNORE_REMOTE_CACHE_UPDATE);
|
Boolean ignoreRemoteCacheUpdate = (Boolean) session.getAttribute(CrossDCLastSessionRefreshListener.IGNORE_REMOTE_CACHE_UPDATE);
|
||||||
|
|
|
@ -19,7 +19,7 @@ package org.keycloak.models.sessions.infinispan.entities;
|
||||||
|
|
||||||
import org.infinispan.api.annotations.indexing.Basic;
|
import org.infinispan.api.annotations.indexing.Basic;
|
||||||
import org.infinispan.protostream.annotations.ProtoField;
|
import org.infinispan.protostream.annotations.ProtoField;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
|
import org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,14 +71,14 @@ public abstract class SessionEntity {
|
||||||
public abstract int hashCode();
|
public abstract int hashCode();
|
||||||
|
|
||||||
public boolean isOffline() {
|
public boolean isOffline() {
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
throw new IllegalArgumentException("Offline flags are not supported in non-persistent-session environments.");
|
throw new IllegalArgumentException("Offline flags are not supported in non-persistent-session environments.");
|
||||||
}
|
}
|
||||||
return isOffline;
|
return isOffline;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOffline(boolean offline) {
|
public void setOffline(boolean offline) {
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
throw new IllegalArgumentException("Offline flags are not supported in non-persistent-session environments.");
|
throw new IllegalArgumentException("Offline flags are not supported in non-persistent-session environments.");
|
||||||
}
|
}
|
||||||
isOffline = offline;
|
isOffline = offline;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.UUID;
|
||||||
|
|
||||||
import org.infinispan.client.hotrod.RemoteCache;
|
import org.infinispan.client.hotrod.RemoteCache;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.infinispan.util.InfinispanUtils;
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -69,7 +69,7 @@ public class RemoteUserSessionProviderFactory implements UserSessionProviderFact
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(Config.Scope config) {
|
public boolean isSupported(Config.Scope config) {
|
||||||
return InfinispanUtils.isRemoteInfinispan() && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS);
|
return InfinispanUtils.isRemoteInfinispan() && !MultiSiteUtils.isPersistentSessionsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package org.keycloak.models.sessions.infinispan.remotestore;
|
package org.keycloak.models.sessions.infinispan.remotestore;
|
||||||
|
|
||||||
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
|
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Retry;
|
import org.keycloak.common.util.Retry;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -152,7 +152,7 @@ public class RemoteCacheInvoker {
|
||||||
|
|
||||||
VersionedValue<SessionEntityWrapper<V>> versioned = remoteCache.getWithMetadata(key);
|
VersionedValue<SessionEntityWrapper<V>> versioned = remoteCache.getWithMetadata(key);
|
||||||
if (versioned == null) {
|
if (versioned == null) {
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) &&
|
if (MultiSiteUtils.isPersistentSessionsEnabled() &&
|
||||||
(remoteCache.getName().equals(USER_SESSION_CACHE_NAME)
|
(remoteCache.getName().equals(USER_SESSION_CACHE_NAME)
|
||||||
|| remoteCache.getName().equals(CLIENT_SESSION_CACHE_NAME)
|
|| remoteCache.getName().equals(CLIENT_SESSION_CACHE_NAME)
|
||||||
|| remoteCache.getName().equals(OFFLINE_USER_SESSION_CACHE_NAME)
|
|| remoteCache.getName().equals(OFFLINE_USER_SESSION_CACHE_NAME)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package org.keycloak.models.jpa.session;
|
package org.keycloak.models.jpa.session;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
@ -253,7 +253,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
|
||||||
|
|
||||||
expire(realm, expiredClientOffline, expiredOffline, true);
|
expire(realm, expiredClientOffline, expiredOffline, true);
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
|
|
||||||
int expired = Time.currentTime() - Math.max(realm.getSsoSessionIdleTimeout(), realm.getSsoSessionIdleTimeoutRememberMe()) - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
|
int expired = Time.currentTime() - Math.max(realm.getSsoSessionIdleTimeout(), realm.getSsoSessionIdleTimeoutRememberMe()) - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
package org.keycloak.models.session;
|
package org.keycloak.models.session;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelException;
|
import org.keycloak.models.ModelException;
|
||||||
|
@ -216,7 +216,7 @@ public class PersistentUserSessionAdapter implements OfflineUserSessionModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getLoginUsername() {
|
public String getLoginUsername() {
|
||||||
if (isOffline() || !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (isOffline() || !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
return getUser().getUsername();
|
return getUser().getUsername();
|
||||||
} else {
|
} else {
|
||||||
return getData().getLoginUsername();
|
return getData().getLoginUsername();
|
||||||
|
|
|
@ -68,6 +68,7 @@ import org.keycloak.authorization.policy.provider.PolicySpi;
|
||||||
import org.keycloak.authorization.policy.provider.js.DeployedScriptPolicyFactory;
|
import org.keycloak.authorization.policy.provider.js.DeployedScriptPolicyFactory;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.common.crypto.FipsMode;
|
import org.keycloak.common.crypto.FipsMode;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.StreamUtil;
|
import org.keycloak.common.util.StreamUtil;
|
||||||
import org.keycloak.config.DatabaseOptions;
|
import org.keycloak.config.DatabaseOptions;
|
||||||
import org.keycloak.config.HealthOptions;
|
import org.keycloak.config.HealthOptions;
|
||||||
|
@ -644,7 +645,7 @@ class KeycloakProcessor {
|
||||||
JsResource.class.getName())), false));
|
JsResource.class.getName())), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE)) {
|
if (!MultiSiteUtils.isMultiSiteEnabled()) {
|
||||||
buildTimeConditionBuildItemBuildProducer.produce(new BuildTimeConditionBuildItem(index.getIndex().getClassByName(DotName.createSimple(
|
buildTimeConditionBuildItemBuildProducer.produce(new BuildTimeConditionBuildItem(index.getIndex().getClassByName(DotName.createSimple(
|
||||||
LoadBalancerResource.class.getName())), false));
|
LoadBalancerResource.class.getName())), false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ import org.jgroups.protocols.UDP;
|
||||||
import org.jgroups.util.TLS;
|
import org.jgroups.util.TLS;
|
||||||
import org.jgroups.util.TLSClientAuth;
|
import org.jgroups.util.TLSClientAuth;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.config.CachingOptions;
|
import org.keycloak.config.CachingOptions;
|
||||||
import org.keycloak.config.MetricsOptions;
|
import org.keycloak.config.MetricsOptions;
|
||||||
import org.keycloak.infinispan.util.InfinispanUtils;
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
|
@ -297,7 +298,7 @@ public class CacheManagerFactory {
|
||||||
Arrays.stream(CLUSTERED_CACHE_NAMES).forEach(cacheName -> {
|
Arrays.stream(CLUSTERED_CACHE_NAMES).forEach(cacheName -> {
|
||||||
if (cacheName.equals(USER_SESSION_CACHE_NAME) || cacheName.equals(CLIENT_SESSION_CACHE_NAME) || cacheName.equals(OFFLINE_USER_SESSION_CACHE_NAME) || cacheName.equals(OFFLINE_CLIENT_SESSION_CACHE_NAME)) {
|
if (cacheName.equals(USER_SESSION_CACHE_NAME) || cacheName.equals(CLIENT_SESSION_CACHE_NAME) || cacheName.equals(OFFLINE_USER_SESSION_CACHE_NAME) || cacheName.equals(OFFLINE_CLIENT_SESSION_CACHE_NAME)) {
|
||||||
ConfigurationBuilder configurationBuilder = builder.getNamedConfigurationBuilders().get(cacheName);
|
ConfigurationBuilder configurationBuilder = builder.getNamedConfigurationBuilders().get(cacheName);
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
if (configurationBuilder.memory().maxCount() == -1) {
|
if (configurationBuilder.memory().maxCount() == -1) {
|
||||||
logger.infof("Persistent user sessions enabled and no memory limit found in configuration. Setting max entries for %s to 10000 entries.", cacheName);
|
logger.infof("Persistent user sessions enabled and no memory limit found in configuration. Setting max entries for %s to 10000 entries.", cacheName);
|
||||||
configurationBuilder.memory().maxCount(10000);
|
configurationBuilder.memory().maxCount(10000);
|
||||||
|
|
|
@ -122,13 +122,4 @@ public class HealthDistTest {
|
||||||
distribution.stop();
|
distribution.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Launch({ "start-dev", "--features=multi-site" })
|
|
||||||
void testLoadBalancerCheck(KeycloakDistribution distribution) {
|
|
||||||
distribution.setRequestPort(8080);
|
|
||||||
|
|
||||||
when().get("/lb-check").then()
|
|
||||||
.statusCode(200);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,20 @@ import static io.restassured.RestAssured.when;
|
||||||
public class ExternalInfinispanTest {
|
public class ExternalInfinispanTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev", "--features=multi-site", "--cache=ispn", "--cache-config-file=../../../test-classes/ExternalInfinispan/kcb-infinispan-cache-remote-store-config.xml", "--spi-connections-infinispan-quarkus-site-name=ISPN" })
|
@Launch({
|
||||||
void testLoadBalancerCheckFailure() {
|
"start-dev",
|
||||||
|
"--features=multi-site",
|
||||||
|
"--cache=ispn",
|
||||||
|
"--cache-remote-host=localhost",
|
||||||
|
"--cache-remote-username=keycloak",
|
||||||
|
"--cache-remote-password=Password1!",
|
||||||
|
"--cache-remote-tls-enabled=false",
|
||||||
|
"--spi-connections-infinispan-quarkus-site-name=ISPN",
|
||||||
|
"--spi-load-balancer-check-remote-poll-interval=500",
|
||||||
|
"-Dkc.cache-remote-create-caches=true",
|
||||||
|
"--verbose"
|
||||||
|
})
|
||||||
|
void testLoadBalancerCheckFailureWithMultiSite() {
|
||||||
runLoadBalancerCheckFailureTest();
|
runLoadBalancerCheckFailureTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,9 +59,10 @@ public class ExternalInfinispanTest {
|
||||||
"--cache-remote-host=localhost",
|
"--cache-remote-host=localhost",
|
||||||
"--cache-remote-username=keycloak",
|
"--cache-remote-username=keycloak",
|
||||||
"--cache-remote-password=Password1!",
|
"--cache-remote-password=Password1!",
|
||||||
|
"--cache-remote-tls-enabled=false",
|
||||||
"--spi-connections-infinispan-quarkus-site-name=ISPN",
|
"--spi-connections-infinispan-quarkus-site-name=ISPN",
|
||||||
"--spi-load-balancer-check-remote-poll-interval=500",
|
"--spi-load-balancer-check-remote-poll-interval=500",
|
||||||
"-Dkc.cache-remote-tls-enabled=false",
|
"-Dkc.cache-remote-create-caches=true",
|
||||||
"--verbose"
|
"--verbose"
|
||||||
})
|
})
|
||||||
void testLoadBalancerCheckFailureWithRemoteOnlyCaches() {
|
void testLoadBalancerCheckFailureWithRemoteOnlyCaches() {
|
||||||
|
@ -71,7 +84,12 @@ public class ExternalInfinispanTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Launch({ "start-dev", "--features=multi-site", "--cache=ispn", "--cache-config-file=../../../test-classes/ExternalInfinispan/kcb-infinispan-cache-remote-store-config.xml", "-Djboss.site.name=ISPN" })
|
@Launch({
|
||||||
|
"start-dev",
|
||||||
|
"--cache=ispn",
|
||||||
|
"-Djboss.site.name=ISPN",
|
||||||
|
"--verbose"
|
||||||
|
})
|
||||||
void testSiteNameAsSystemProperty(LaunchResult result) {
|
void testSiteNameAsSystemProperty(LaunchResult result) {
|
||||||
((CLIResult) result).assertMessage("System property jboss.site.name is in use. Use --spi-connections-infinispan-quarkus-site-name config option instead");
|
((CLIResult) result).assertMessage("System property jboss.site.name is in use. Use --spi-connections-infinispan-quarkus-site-name config option instead");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,15 +21,15 @@ import org.keycloak.Config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Service Provider Interface (SPI) that allows to plug-in an embedded or remote cache manager instance.
|
* A Service Provider Interface (SPI) that allows to plug-in an embedded or remote cache manager instance.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
public interface ManagedCacheManagerProvider {
|
public interface ManagedCacheManagerProvider {
|
||||||
|
|
||||||
<C> C getEmbeddedCacheManager(Config.Scope config);
|
<C> C getEmbeddedCacheManager(Config.Scope config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A RemoteCacheManager if the feature {@link org.keycloak.common.Profile.Feature#REMOTE_CACHE} is enabled, {@code null} otherwise.
|
* @return A RemoteCacheManager if the features {@link org.keycloak.common.Profile.Feature#REMOTE_CACHE} or {@link org.keycloak.common.Profile.Feature#MULTI_SITE} is enabled, {@code null} otherwise.
|
||||||
*/
|
*/
|
||||||
<C> C getRemoteCacheManager(Config.Scope config);
|
<C> C getRemoteCacheManager(Config.Scope config);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.keycloak.services.resteasy;
|
package org.keycloak.services.resteasy;
|
||||||
|
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.services.error.KcUnrecognizedPropertyExceptionHandler;
|
import org.keycloak.services.error.KcUnrecognizedPropertyExceptionHandler;
|
||||||
|
@ -62,7 +63,7 @@ public class ResteasyKeycloakApplication extends KeycloakApplication {
|
||||||
singletons.add(new ObjectMapperResolver());
|
singletons.add(new ObjectMapperResolver());
|
||||||
classes.add(WelcomeResource.class);
|
classes.add(WelcomeResource.class);
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE)) {
|
if (MultiSiteUtils.isMultiSiteEnabled()) {
|
||||||
// If we are running in multi-site mode, we need to add a resource which to expose
|
// If we are running in multi-site mode, we need to add a resource which to expose
|
||||||
// an endpoint for the load balancer to gather information whether this site should receive requests or not.
|
// an endpoint for the load balancer to gather information whether this site should receive requests or not.
|
||||||
classes.add(LoadBalancerResource.class);
|
classes.add(LoadBalancerResource.class);
|
||||||
|
|
|
@ -212,7 +212,7 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo
|
||||||
addFeaturesOption(commands);
|
addFeaturesOption(commands);
|
||||||
|
|
||||||
var features = getDefaultFeatures();
|
var features = getDefaultFeatures();
|
||||||
if (features.contains("remote-cache") && features.contains("multi-site")) {
|
if (features.contains("remote-cache") || features.contains("multi-site")) {
|
||||||
commands.add("--cache-remote-host=127.0.0.1");
|
commands.add("--cache-remote-host=127.0.0.1");
|
||||||
commands.add("--cache-remote-username=keycloak");
|
commands.add("--cache-remote-username=keycloak");
|
||||||
commands.add("--cache-remote-password=Password1!");
|
commands.add("--cache-remote-password=Password1!");
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -214,7 +215,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak
|
||||||
@Test
|
@Test
|
||||||
@ModelTest
|
@ModelTest
|
||||||
public void testExpiredAuthSessions(KeycloakSession session) {
|
public void testExpiredAuthSessions(KeycloakSession session) {
|
||||||
assumeFalse(Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
assumeFalse(InfinispanUtils.isRemoteInfinispan());
|
||||||
AtomicReference<String> authSessionID = new AtomicReference<>();
|
AtomicReference<String> authSessionID = new AtomicReference<>();
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), mainSession -> {
|
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), mainSession -> {
|
||||||
|
|
|
@ -175,11 +175,11 @@ public class AccessTokenTest extends AbstractKeycloakTest {
|
||||||
testRealms.add(realm);
|
testRealms.add(realm);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loginFormUsernameOrEmailLabel() throws Exception {
|
public void loginFormUsernameOrEmailLabel() throws Exception {
|
||||||
oauth.openLoginForm();
|
oauth.openLoginForm();
|
||||||
|
|
||||||
assertEquals("Username or email", driver.findElement(By.xpath("//label[@for='username']")).getText());
|
assertEquals("Username or email", driver.findElement(By.xpath("//label[@for='username']")).getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,6 +389,8 @@ public class AccessTokenTest extends AbstractKeycloakTest {
|
||||||
@Test
|
@Test
|
||||||
public void accessTokenCodeExpired() {
|
public void accessTokenCodeExpired() {
|
||||||
ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE);
|
ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE);
|
||||||
|
ProfileAssume.assumeFeatureDisabled(Profile.Feature.MULTI_SITE);
|
||||||
|
|
||||||
getTestingClient().testing().setTestingInfinispanTimeService();
|
getTestingClient().testing().setTestingInfinispanTimeService();
|
||||||
RealmManager.realm(adminClient.realm("test")).accessCodeLifeSpan(1);
|
RealmManager.realm(adminClient.realm("test")).accessCodeLifeSpan(1);
|
||||||
oauth.doLogin("test-user@localhost", "password");
|
oauth.doLogin("test-user@localhost", "password");
|
||||||
|
@ -1323,7 +1325,7 @@ public class AccessTokenTest extends AbstractKeycloakTest {
|
||||||
public void accessTokenRequest_ClientEdDSA_RealmEdDSA() throws Exception {
|
public void accessTokenRequest_ClientEdDSA_RealmEdDSA() throws Exception {
|
||||||
conductAccessTokenRequest(Constants.INTERNAL_SIGNATURE_ALGORITHM, Algorithm.EdDSA, Algorithm.EdDSA);
|
conductAccessTokenRequest(Constants.INTERNAL_SIGNATURE_ALGORITHM, Algorithm.EdDSA, Algorithm.EdDSA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void validateECDSASignatures() {
|
public void validateECDSASignatures() {
|
||||||
validateTokenECDSASignature(Algorithm.ES256);
|
validateTokenECDSASignature(Algorithm.ES256);
|
||||||
|
|
|
@ -66,6 +66,8 @@ public class LastSessionRefreshUnitTest extends AbstractKeycloakTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLastSessionRefreshCounters() {
|
public void testLastSessionRefreshCounters() {
|
||||||
ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE);
|
ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE);
|
||||||
|
ProfileAssume.assumeFeatureDisabled(Profile.Feature.MULTI_SITE);
|
||||||
|
|
||||||
testingClient.server().run(new LastSessionRefreshServerCounterTest());
|
testingClient.server().run(new LastSessionRefreshServerCounterTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +113,8 @@ public class LastSessionRefreshUnitTest extends AbstractKeycloakTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLastSessionRefreshIntervals() {
|
public void testLastSessionRefreshIntervals() {
|
||||||
ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE);
|
ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE);
|
||||||
|
ProfileAssume.assumeFeatureDisabled(Profile.Feature.MULTI_SITE);
|
||||||
|
|
||||||
testingClient.server().run(new LastSessionRefreshServerIntervalsTest());
|
testingClient.server().run(new LastSessionRefreshServerIntervalsTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,12 @@
|
||||||
<groupId>org.keycloak.testsuite</groupId>
|
<groupId>org.keycloak.testsuite</groupId>
|
||||||
<artifactId>integration-arquillian-tests-base</artifactId>
|
<artifactId>integration-arquillian-tests-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-quarkus-server</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${jdbc.mvn.groupId}</groupId>
|
<groupId>${jdbc.mvn.groupId}</groupId>
|
||||||
|
@ -118,6 +124,10 @@
|
||||||
<artifactId>infinispan-component-annotations</artifactId>
|
<artifactId>infinispan-component-annotations</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.infinispan</groupId>
|
||||||
|
<artifactId>infinispan-remote-query-server</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -286,12 +296,6 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.infinispan</groupId>
|
|
||||||
<artifactId>infinispan-remote-query-server</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||||
* and other contributors as indicated by the @author tags.
|
* and other contributors as indicated by the @author tags.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -21,6 +21,8 @@ import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
|
import org.keycloak.connections.infinispan.InfinispanUtil;
|
||||||
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.models.cache.infinispan.events.AuthenticationSessionAuthNoteUpdateEvent;
|
import org.keycloak.models.cache.infinispan.events.AuthenticationSessionAuthNoteUpdateEvent;
|
||||||
import org.keycloak.testsuite.model.KeycloakModelTest;
|
import org.keycloak.testsuite.model.KeycloakModelTest;
|
||||||
import org.keycloak.testsuite.model.RequireProvider;
|
import org.keycloak.testsuite.model.RequireProvider;
|
||||||
|
@ -56,7 +58,7 @@ public class CacheExpirationTest extends KeycloakModelTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCacheExpiration() throws Exception {
|
public void testCacheExpiration() throws Exception {
|
||||||
assumeFalse("Embedded caches not available for testing.", Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE) && Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
assumeFalse("Embedded caches not available for testing.", InfinispanUtils.isRemoteInfinispan());
|
||||||
|
|
||||||
log.debugf("Number of previous instances of the class on the heap: %d", getNumberOfInstancesOfClass(AuthenticationSessionAuthNoteUpdateEvent.class));
|
log.debugf("Number of previous instances of the class on the heap: %d", getNumberOfInstancesOfClass(AuthenticationSessionAuthNoteUpdateEvent.class));
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.function.Predicate;
|
||||||
import org.infinispan.commons.CacheConfigurationException;
|
import org.infinispan.commons.CacheConfigurationException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.infinispan.util.InfinispanUtils;
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.testsuite.model.KeycloakModelTest;
|
import org.keycloak.testsuite.model.KeycloakModelTest;
|
||||||
|
@ -60,8 +61,7 @@ public class FeatureEnabledTest extends KeycloakModelTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoteCachesOnly() {
|
public void testRemoteCachesOnly() {
|
||||||
assumeTrue("Remote-Cache Feature disabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
assumeTrue("Remote-Cache Feature disabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE) || MultiSiteUtils.isMultiSiteEnabled());
|
||||||
assumeTrue("Multi-Site Feature disabled", Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE));
|
|
||||||
assertTrue(InfinispanUtils.isRemoteInfinispan());
|
assertTrue(InfinispanUtils.isRemoteInfinispan());
|
||||||
assertFalse(InfinispanUtils.isEmbeddedInfinispan());
|
assertFalse(InfinispanUtils.isEmbeddedInfinispan());
|
||||||
inComittedTransaction(session -> {
|
inComittedTransaction(session -> {
|
||||||
|
@ -72,22 +72,9 @@ public class FeatureEnabledTest extends KeycloakModelTest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemoteAndEmbeddedCaches() {
|
|
||||||
assumeTrue("Multi-Site Feature disabled", Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE));
|
|
||||||
assumeFalse("Remote-Cache Feature enabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
|
||||||
assertFalse(InfinispanUtils.isRemoteInfinispan());
|
|
||||||
assertTrue(InfinispanUtils.isEmbeddedInfinispan());
|
|
||||||
inComittedTransaction(session -> {
|
|
||||||
var clusterProvider = session.getProvider(InfinispanConnectionProvider.class);
|
|
||||||
Arrays.stream(CLUSTERED_CACHE_NAMES).forEach(s -> assertEmbeddedCacheExists(clusterProvider, s));
|
|
||||||
Arrays.stream(CLUSTERED_CACHE_NAMES).forEach(s -> assertRemoteCacheExists(clusterProvider, s));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmbeddedCachesOnly() {
|
public void testEmbeddedCachesOnly() {
|
||||||
assumeFalse("Multi-Site Feature enabled", Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE));
|
assumeFalse("Multi-Site Feature enabled", MultiSiteUtils.isMultiSiteEnabled());
|
||||||
assumeFalse("Remote-Cache Feature enabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
assumeFalse("Remote-Cache Feature enabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE));
|
||||||
assertFalse(InfinispanUtils.isRemoteInfinispan());
|
assertFalse(InfinispanUtils.isRemoteInfinispan());
|
||||||
assertTrue(InfinispanUtils.isEmbeddedInfinispan());
|
assertTrue(InfinispanUtils.isEmbeddedInfinispan());
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.testsuite.model.HotRodServerRule;
|
||||||
import org.keycloak.testsuite.model.KeycloakModelParameters;
|
import org.keycloak.testsuite.model.KeycloakModelParameters;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +67,7 @@ public class CrossDCInfinispan extends KeycloakModelParameters {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CrossDCInfinispan() {
|
public CrossDCInfinispan() {
|
||||||
super(Infinispan.ALLOWED_SPIS, Infinispan.ALLOWED_FACTORIES);
|
super(Infinispan.ALLOWED_SPIS, Stream.concat(Infinispan.ALLOWED_FACTORIES.stream(), RemoteInfinispan.ALLOWED_FACTORIES.stream()).collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -37,6 +37,7 @@ import java.util.stream.Stream;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.infinispan.commons.CacheException;
|
import org.infinispan.commons.CacheException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
|
@ -50,13 +51,13 @@ import org.keycloak.models.UserSessionProvider;
|
||||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||||
import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProvider;
|
import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProvider;
|
||||||
import org.keycloak.models.sessions.infinispan.PersistentUserSessionProvider;
|
import org.keycloak.models.sessions.infinispan.PersistentUserSessionProvider;
|
||||||
import org.keycloak.models.sessions.infinispan.remote.RemoteUserSessionProvider;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.testsuite.model.KeycloakModelTest;
|
import org.keycloak.testsuite.model.KeycloakModelTest;
|
||||||
import org.keycloak.testsuite.model.RequireProvider;
|
import org.keycloak.testsuite.model.RequireProvider;
|
||||||
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -252,6 +253,8 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest {
|
||||||
@Test
|
@Test
|
||||||
@RequireProvider(UserSessionPersisterProvider.class)
|
@RequireProvider(UserSessionPersisterProvider.class)
|
||||||
public void testOfflineSessionLoadingAfterCacheRemoval() {
|
public void testOfflineSessionLoadingAfterCacheRemoval() {
|
||||||
|
assumeTrue("Run only if Embedded Infinispan is used for storing/caching sessions.", InfinispanUtils.isEmbeddedInfinispan());
|
||||||
|
|
||||||
List<String> offlineSessionIds = createOfflineSessions(realmId, userIds);
|
List<String> offlineSessionIds = createOfflineSessions(realmId, userIds);
|
||||||
assertOfflineSessionsExist(realmId, offlineSessionIds);
|
assertOfflineSessionsExist(realmId, offlineSessionIds);
|
||||||
|
|
||||||
|
@ -268,8 +271,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest {
|
||||||
((InfinispanUserSessionProvider) provider).removeLocalUserSessions(realm.getId(), true);
|
((InfinispanUserSessionProvider) provider).removeLocalUserSessions(realm.getId(), true);
|
||||||
} else if (provider instanceof PersistentUserSessionProvider) {
|
} else if (provider instanceof PersistentUserSessionProvider) {
|
||||||
((PersistentUserSessionProvider) provider).removeLocalUserSessions(realm.getId(), true);
|
((PersistentUserSessionProvider) provider).removeLocalUserSessions(realm.getId(), true);
|
||||||
} else if (provider instanceof RemoteUserSessionProvider) {
|
|
||||||
//no-op, session not local
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Unknown UserSessionProvider: " + provider);
|
throw new IllegalStateException("Unknown UserSessionProvider: " + provider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.junit.FixMethodOrder;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.TestRule;
|
import org.junit.rules.TestRule;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Retry;
|
import org.keycloak.common.util.Retry;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
|
@ -298,7 +298,7 @@ public class SessionTimeoutsTest extends KeycloakModelTest {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
// The persistent session will write the update data asynchronously, wait for it to arrive.
|
// The persistent session will write the update data asynchronously, wait for it to arrive.
|
||||||
Retry.executeWithBackoff(iteration -> {
|
Retry.executeWithBackoff(iteration -> {
|
||||||
withRealm(realmId, (session, realm) -> {
|
withRealm(realmId, (session, realm) -> {
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.infinispan.Cache;
|
||||||
import org.infinispan.client.hotrod.RemoteCache;
|
import org.infinispan.client.hotrod.RemoteCache;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.infinispan.util.InfinispanUtils;
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
@ -48,6 +49,7 @@ import org.keycloak.testsuite.model.RequireProvider;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.core.Every.everyItem;
|
import static org.hamcrest.core.Every.everyItem;
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
|
import static org.junit.Assume.assumeFalse;
|
||||||
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.USER_SESSION_CACHE_NAME;
|
import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.USER_SESSION_CACHE_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,6 +159,7 @@ public class UserSessionInitializerTest extends KeycloakModelTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUserSessionPropagationBetweenSites() throws InterruptedException {
|
public void testUserSessionPropagationBetweenSites() throws InterruptedException {
|
||||||
|
assumeFalse("Run only if Infinispan caches are used for storing/caching sessions", MultiSiteUtils.isMultiSiteEnabled() && MultiSiteUtils.isPersistentSessionsEnabled());
|
||||||
AtomicInteger index = new AtomicInteger();
|
AtomicInteger index = new AtomicInteger();
|
||||||
AtomicReference<String> userSessionId = new AtomicReference<>();
|
AtomicReference<String> userSessionId = new AtomicReference<>();
|
||||||
AtomicReference<List<Boolean>> containsSession = new AtomicReference<>(new LinkedList<>());
|
AtomicReference<List<Boolean>> containsSession = new AtomicReference<>(new LinkedList<>());
|
||||||
|
|
|
@ -21,7 +21,7 @@ import org.junit.Assert;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.infinispan.util.InfinispanUtils;
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
|
@ -151,7 +151,7 @@ public class UserSessionPersisterProviderTest extends KeycloakModelTest {
|
||||||
.forEach(userSessionLooper -> persistUserSession(session, userSessionLooper, true));
|
.forEach(userSessionLooper -> persistUserSession(session, userSessionLooper, true));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
inComittedTransaction(session -> {
|
inComittedTransaction(session -> {
|
||||||
// Persist 1 online session
|
// Persist 1 online session
|
||||||
RealmModel realm = session.realms().getRealm(realmId);
|
RealmModel realm = session.realms().getRealm(realmId);
|
||||||
|
@ -581,7 +581,8 @@ public class UserSessionPersisterProviderTest extends KeycloakModelTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMigrateSession() {
|
public void testMigrateSession() {
|
||||||
Assume.assumeTrue(Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS));
|
Assume.assumeTrue(MultiSiteUtils.isPersistentSessionsEnabled());
|
||||||
|
Assume.assumeTrue(InfinispanUtils.isEmbeddedInfinispan());
|
||||||
|
|
||||||
UserSessionModel[] sessions = inComittedTransaction(session -> {
|
UserSessionModel[] sessions = inComittedTransaction(session -> {
|
||||||
// Create some sessions in infinispan
|
// Create some sessions in infinispan
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
|
@ -129,7 +130,7 @@ public class UserSessionProviderModelTest extends KeycloakModelTest {
|
||||||
// skip for persistent user sessions as the periodic task is not used there
|
// skip for persistent user sessions as the periodic task is not used there
|
||||||
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
||||||
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
||||||
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (timer != null && !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
@ -181,7 +182,7 @@ public class UserSessionProviderModelTest extends KeycloakModelTest {
|
||||||
setTimeOffset(0);
|
setTimeOffset(0);
|
||||||
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
||||||
if (timer != null && timerTaskCtx != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (timer != null && timerTaskCtx != null && !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.junit.Assert;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
import org.keycloak.common.util.MultiSiteUtils;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.infinispan.util.InfinispanUtils;
|
import org.keycloak.infinispan.util.InfinispanUtils;
|
||||||
|
@ -126,7 +127,7 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
// skip for persistent user sessions as the periodic task is not used there
|
// skip for persistent user sessions as the periodic task is not used there
|
||||||
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
||||||
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
||||||
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (timer != null && !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +246,7 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
setTimeOffset(0);
|
setTimeOffset(0);
|
||||||
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
||||||
if (timer != null && timerTaskCtx != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (timer != null && timerTaskCtx != null && !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +260,7 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
// skip for persistent user sessions as the periodic task is not used there
|
// skip for persistent user sessions as the periodic task is not used there
|
||||||
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
||||||
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
||||||
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (timer != null && !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
@ -314,14 +315,14 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
session.sessions().createOfflineUserSession(userSession);
|
session.sessions().createOfflineUserSession(userSession);
|
||||||
session.sessions().createOfflineUserSession(origSessions[0]);
|
session.sessions().createOfflineUserSession(origSessions[0]);
|
||||||
|
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) && InfinispanUtils.isEmbeddedInfinispan()) {
|
if (!MultiSiteUtils.isPersistentSessionsEnabled() && InfinispanUtils.isEmbeddedInfinispan()) {
|
||||||
// This does not work with persistent user sessions because we currently have two transactions and the one that creates the offline user sessions is not committing the changes
|
// This does not work with persistent user sessions because we currently have two transactions and the one that creates the offline user sessions is not committing the changes
|
||||||
// try to load user session from persister
|
// try to load user session from persister
|
||||||
Assert.assertEquals(2, persister.loadUserSessionsStream(0, 10, true, "00000000-0000-0000-0000-000000000000").count());
|
Assert.assertEquals(2, persister.loadUserSessionsStream(0, 10, true, "00000000-0000-0000-0000-000000000000").count());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) && InfinispanUtils.isEmbeddedInfinispan()) {
|
if (MultiSiteUtils.isPersistentSessionsEnabled() && InfinispanUtils.isEmbeddedInfinispan()) {
|
||||||
inComittedTransaction(session -> {
|
inComittedTransaction(session -> {
|
||||||
persister = session.getProvider(UserSessionPersisterProvider.class);
|
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||||
Assert.assertEquals(2, persister.loadUserSessionsStream(0, 10, true, "00000000-0000-0000-0000-000000000000").count());
|
Assert.assertEquals(2, persister.loadUserSessionsStream(0, 10, true, "00000000-0000-0000-0000-000000000000").count());
|
||||||
|
@ -333,7 +334,7 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
|
|
||||||
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
||||||
if (timer != null && timerTaskCtx != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
if (timer != null && timerTaskCtx != null && !MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||||
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +503,7 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
// skip the test for CrossDC
|
// skip the test for CrossDC
|
||||||
Assume.assumeFalse(Objects.equals(CONFIG.scope("connectionsInfinispan.default").get("remoteStoreEnabled"), "true"));
|
Assume.assumeFalse(Objects.equals(CONFIG.scope("connectionsInfinispan.default").get("remoteStoreEnabled"), "true"));
|
||||||
// As offline session's timeout is not overriden when PERSISTENT_USER_SESSIONS is enabled
|
// As offline session's timeout is not overriden when PERSISTENT_USER_SESSIONS is enabled
|
||||||
Assume.assumeFalse(Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS));
|
Assume.assumeFalse(MultiSiteUtils.isPersistentSessionsEnabled());
|
||||||
|
|
||||||
createOfflineSessions("user1", 2, new LinkedList<>(), new LinkedList<>());
|
createOfflineSessions("user1", 2, new LinkedList<>(), new LinkedList<>());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue