Do not use LastSessionRefreshPersister with persistent user sessions enabled
Closes #29144 Signed-off-by: Michal Hajas <mhajas@redhat.com>
This commit is contained in:
parent
ba43a10a6d
commit
8b715d3a31
6 changed files with 28 additions and 24 deletions
|
@ -126,7 +126,6 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
remoteCacheInvoker,
|
remoteCacheInvoker,
|
||||||
lastSessionRefreshStore,
|
lastSessionRefreshStore,
|
||||||
offlineLastSessionRefreshStore,
|
offlineLastSessionRefreshStore,
|
||||||
persisterLastSessionRefreshStore,
|
|
||||||
keyGenerator,
|
keyGenerator,
|
||||||
cache,
|
cache,
|
||||||
offlineSessionsCache,
|
offlineSessionsCache,
|
||||||
|
@ -178,7 +177,9 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
|
|
||||||
keyGenerator = new InfinispanKeyGenerator();
|
keyGenerator = new InfinispanKeyGenerator();
|
||||||
checkRemoteCaches(session);
|
checkRemoteCaches(session);
|
||||||
loadPersistentSessions(factory, getMaxErrors(), getSessionsPerSegment());
|
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
||||||
|
initializeLastSessionRefreshStore(factory);
|
||||||
|
}
|
||||||
registerClusterListeners(session);
|
registerClusterListeners(session);
|
||||||
loadSessionsFromRemoteCaches(session);
|
loadSessionsFromRemoteCaches(session);
|
||||||
|
|
||||||
|
@ -234,9 +235,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
return config.getInt("sessionPreloadStalledTimeoutInSeconds", defaultTimeout);
|
return config.getInt("sessionPreloadStalledTimeoutInSeconds", defaultTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void initializeLastSessionRefreshStore(final KeycloakSessionFactory sessionFactory) {
|
||||||
public void loadPersistentSessions(final KeycloakSessionFactory sessionFactory, final int maxErrors, final int sessionsPerSegment) {
|
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -244,10 +243,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
||||||
// Initialize persister for periodically doing bulk DB updates of lastSessionRefresh timestamps of refreshed sessions
|
// Initialize persister for periodically doing bulk DB updates of lastSessionRefresh timestamps of refreshed sessions
|
||||||
persisterLastSessionRefreshStore = new PersisterLastSessionRefreshStoreFactory().createAndInit(session, true);
|
persisterLastSessionRefreshStore = new PersisterLastSessionRefreshStoreFactory().createAndInit(session, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,6 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
|
|
||||||
protected final CrossDCLastSessionRefreshStore lastSessionRefreshStore;
|
protected final CrossDCLastSessionRefreshStore lastSessionRefreshStore;
|
||||||
protected final CrossDCLastSessionRefreshStore offlineLastSessionRefreshStore;
|
protected final CrossDCLastSessionRefreshStore offlineLastSessionRefreshStore;
|
||||||
protected final PersisterLastSessionRefreshStore persisterLastSessionRefreshStore;
|
|
||||||
|
|
||||||
protected final RemoteCacheInvoker remoteCacheInvoker;
|
protected final RemoteCacheInvoker remoteCacheInvoker;
|
||||||
protected final InfinispanKeyGenerator keyGenerator;
|
protected final InfinispanKeyGenerator keyGenerator;
|
||||||
|
@ -116,7 +115,6 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
RemoteCacheInvoker remoteCacheInvoker,
|
RemoteCacheInvoker remoteCacheInvoker,
|
||||||
CrossDCLastSessionRefreshStore lastSessionRefreshStore,
|
CrossDCLastSessionRefreshStore lastSessionRefreshStore,
|
||||||
CrossDCLastSessionRefreshStore offlineLastSessionRefreshStore,
|
CrossDCLastSessionRefreshStore offlineLastSessionRefreshStore,
|
||||||
PersisterLastSessionRefreshStore persisterLastSessionRefreshStore,
|
|
||||||
InfinispanKeyGenerator keyGenerator,
|
InfinispanKeyGenerator keyGenerator,
|
||||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> sessionCache,
|
Cache<String, SessionEntityWrapper<UserSessionEntity>> sessionCache,
|
||||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> offlineSessionCache,
|
Cache<String, SessionEntityWrapper<UserSessionEntity>> offlineSessionCache,
|
||||||
|
@ -153,7 +151,6 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
|
|
||||||
this.lastSessionRefreshStore = lastSessionRefreshStore;
|
this.lastSessionRefreshStore = lastSessionRefreshStore;
|
||||||
this.offlineLastSessionRefreshStore = offlineLastSessionRefreshStore;
|
this.offlineLastSessionRefreshStore = offlineLastSessionRefreshStore;
|
||||||
this.persisterLastSessionRefreshStore = persisterLastSessionRefreshStore;
|
|
||||||
this.remoteCacheInvoker = remoteCacheInvoker;
|
this.remoteCacheInvoker = remoteCacheInvoker;
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
|
|
||||||
|
@ -182,7 +179,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PersisterLastSessionRefreshStore getPersisterLastSessionRefreshStore() {
|
public PersisterLastSessionRefreshStore getPersisterLastSessionRefreshStore() {
|
||||||
return persisterLastSessionRefreshStore;
|
throw new IllegalStateException("PersisterLastSessionRefreshStore is not supported in PersistentUserSessionProvider");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.models.sessions.infinispan;
|
package org.keycloak.models.sessions.infinispan;
|
||||||
|
|
||||||
|
import org.keycloak.common.Profile;
|
||||||
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;
|
||||||
|
@ -230,7 +231,7 @@ public class UserSessionAdapter<T extends SessionRefreshStore & UserSessionProvi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offline) {
|
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) && 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);
|
||||||
|
|
|
@ -26,6 +26,8 @@ import org.keycloak.provider.ProviderFactory;
|
||||||
public interface UserSessionProviderFactory<T extends UserSessionProvider> extends ProviderFactory<T> {
|
public interface UserSessionProviderFactory<T extends UserSessionProvider> extends ProviderFactory<T> {
|
||||||
|
|
||||||
// This is supposed to prefill all userSessions and clientSessions from userSessionPersister to the userSession infinispan/memory storage
|
// This is supposed to prefill all userSessions and clientSessions from userSessionPersister to the userSession infinispan/memory storage
|
||||||
void loadPersistentSessions(KeycloakSessionFactory sessionFactory, final int maxErrors, final int sessionsPerSegment);
|
// This method is no longer used as we don't have offline sessions preloading anymore
|
||||||
|
@Deprecated
|
||||||
|
default void loadPersistentSessions(KeycloakSessionFactory sessionFactory, final int maxErrors, final int sessionsPerSegment) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.testsuite.model.session;
|
||||||
import org.hamcrest.Matchers;
|
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.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;
|
||||||
|
@ -119,15 +120,16 @@ public class UserSessionProviderModelTest extends KeycloakModelTest {
|
||||||
@Test
|
@Test
|
||||||
public void testExpiredClientSessions() {
|
public void testExpiredClientSessions() {
|
||||||
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
||||||
|
// 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) {
|
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
||||||
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);
|
||||||
|
|
||||||
InfinispanTestUtil.setTestingTimeService(kcSession);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InfinispanTestUtil.setTestingTimeService(kcSession);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UserSessionModel[] origSessions = inComittedTransaction(session -> {
|
UserSessionModel[] origSessions = inComittedTransaction(session -> {
|
||||||
// create some user and client sessions
|
// create some user and client sessions
|
||||||
|
@ -172,11 +174,12 @@ public class UserSessionProviderModelTest extends KeycloakModelTest {
|
||||||
} finally {
|
} finally {
|
||||||
setTimeOffset(0);
|
setTimeOffset(0);
|
||||||
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
if (timer != null && timerTaskCtx != null) {
|
// 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)) {
|
||||||
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
|
|
||||||
InfinispanTestUtil.revertTimeService(kcSession);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InfinispanTestUtil.revertTimeService(kcSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,9 +121,10 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
@Test
|
@Test
|
||||||
public void testExpired() {
|
public void testExpired() {
|
||||||
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
||||||
|
// 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) {
|
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +237,8 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
} finally {
|
} finally {
|
||||||
setTimeOffset(0);
|
setTimeOffset(0);
|
||||||
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
if (timer != null) {
|
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
||||||
|
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
||||||
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,9 +249,10 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLoadUserSessionsWithNotDeletedOfflineClientSessions() {
|
public void testLoadUserSessionsWithNotDeletedOfflineClientSessions() {
|
||||||
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
||||||
|
// 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) {
|
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -318,7 +321,9 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
} finally {
|
} finally {
|
||||||
setTimeOffset(0);
|
setTimeOffset(0);
|
||||||
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
if (timer != null) {
|
|
||||||
|
// Enable periodic task again, skip for persistent user sessions as the periodic task is not used there
|
||||||
|
if (timer != null && !Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS)) {
|
||||||
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue