KEYCLOAK-18941 ExecutionException when computed future - InfinispanCacheInitializer
This commit is contained in:
parent
b42f765c2a
commit
6886bd6651
2 changed files with 89 additions and 5 deletions
|
@ -228,13 +228,19 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
|
||||||
public void removeExpired(RealmModel realm) {
|
public void removeExpired(RealmModel realm) {
|
||||||
int expiredOffline = Time.currentTime() - realm.getOfflineSessionIdleTimeout() - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
|
int expiredOffline = Time.currentTime() - realm.getOfflineSessionIdleTimeout() - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
|
||||||
|
|
||||||
|
// prefer client session timeout if set
|
||||||
|
int expiredClientOffline = expiredOffline;
|
||||||
|
if (realm.getClientOfflineSessionIdleTimeout() > 0) {
|
||||||
|
expiredClientOffline = Time.currentTime() - realm.getClientOfflineSessionIdleTimeout() - SessionTimeoutHelper.PERIODIC_CLEANER_IDLE_TIMEOUT_WINDOW_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
String offlineStr = offlineToString(true);
|
String offlineStr = offlineToString(true);
|
||||||
|
|
||||||
logger.tracef("Trigger removing expired user sessions for realm '%s'", realm.getName());
|
logger.tracef("Trigger removing expired user sessions for realm '%s'", realm.getName());
|
||||||
|
|
||||||
int cs = em.createNamedQuery("deleteExpiredClientSessions")
|
int cs = em.createNamedQuery("deleteExpiredClientSessions")
|
||||||
.setParameter("realmId", realm.getId())
|
.setParameter("realmId", realm.getId())
|
||||||
.setParameter("lastSessionRefresh", expiredOffline)
|
.setParameter("lastSessionRefresh", expiredClientOffline)
|
||||||
.setParameter("offline", offlineStr)
|
.setParameter("offline", offlineStr)
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
|
|
||||||
|
@ -375,10 +381,13 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
|
||||||
|
|
||||||
closing(queryClientSessions.getResultStream()).forEach(clientSession -> {
|
closing(queryClientSessions.getResultStream()).forEach(clientSession -> {
|
||||||
PersistentUserSessionAdapter userSession = sessionsById.get(clientSession.getUserSessionId());
|
PersistentUserSessionAdapter userSession = sessionsById.get(clientSession.getUserSessionId());
|
||||||
boolean added = addClientSessionToAuthenticatedClientSessionsIfPresent(userSession, clientSession);
|
// check if we have a user session for the client session
|
||||||
if (!added) {
|
if (userSession != null) {
|
||||||
// client was removed in the meantime
|
boolean added = addClientSessionToAuthenticatedClientSessionsIfPresent(userSession, clientSession);
|
||||||
removedClientUUIDs.add(clientSession.getClientId());
|
if (!added) {
|
||||||
|
// client was removed in the meantime
|
||||||
|
removedClientUUIDs.add(clientSession.getClientId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,9 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
RealmModel realm = s.realms().createRealm("test");
|
RealmModel realm = s.realms().createRealm("test");
|
||||||
realm.setOfflineSessionIdleTimeout(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
realm.setOfflineSessionIdleTimeout(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
||||||
realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
|
realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName()));
|
||||||
|
realm.setOfflineSessionMaxLifespanEnabled(true);
|
||||||
|
realm.setClientOfflineSessionIdleTimeout(999999999);
|
||||||
|
realm.setClientOfflineSessionMaxLifespan(999999999);
|
||||||
this.realmId = realm.getId();
|
this.realmId = realm.getId();
|
||||||
this.kcSession = s;
|
this.kcSession = s;
|
||||||
|
|
||||||
|
@ -222,6 +225,78 @@ public class UserSessionProviderOfflineModelTest extends KeycloakModelTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadUserSessionsWithNotDeletedOfflineClientSessions() {
|
||||||
|
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
|
||||||
|
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
|
||||||
|
TimerProvider.TimerTaskContext timerTaskCtx = null;
|
||||||
|
if (timer != null) {
|
||||||
|
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
|
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
InfinispanTestUtil.setTestingTimeService(kcSession);
|
||||||
|
|
||||||
|
try {
|
||||||
|
UserSessionModel[] origSessions = inComittedTransaction(session -> {
|
||||||
|
// Create some online sessions in infinispan
|
||||||
|
return UserSessionPersisterProviderTest.createSessions(session, realmId);
|
||||||
|
});
|
||||||
|
|
||||||
|
inComittedTransaction(session -> {
|
||||||
|
RealmModel realm = session.realms().getRealm(realmId);
|
||||||
|
sessionManager = new UserSessionManager(session);
|
||||||
|
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||||
|
|
||||||
|
session.sessions().getUserSessionsStream(realm, realm.getClientByClientId("test-app")).collect(Collectors.toList())
|
||||||
|
.forEach(userSession -> createOfflineSessionIncludeClientSessions(session, userSession));
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info("Persisted 3 sessions to UserSessionPersisterProvider");
|
||||||
|
|
||||||
|
inComittedTransaction(session -> {
|
||||||
|
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||||
|
|
||||||
|
Assert.assertEquals(3, persister.getUserSessionsCount(true));
|
||||||
|
});
|
||||||
|
|
||||||
|
inComittedTransaction(session -> {
|
||||||
|
RealmModel realm = session.realms().getRealm(realmId);
|
||||||
|
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||||
|
|
||||||
|
// Expire everything except offline client sessions
|
||||||
|
Time.setOffset(7000000);
|
||||||
|
|
||||||
|
persister.removeExpired(realm);
|
||||||
|
});
|
||||||
|
|
||||||
|
inComittedTransaction(session -> {
|
||||||
|
RealmModel realm = session.realms().getRealm(realmId);
|
||||||
|
sessionManager = new UserSessionManager(session);
|
||||||
|
persister = session.getProvider(UserSessionPersisterProvider.class);
|
||||||
|
|
||||||
|
Assert.assertEquals(0, persister.getUserSessionsCount(true));
|
||||||
|
|
||||||
|
// create two offline user sessions
|
||||||
|
UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername(realm, "user1"), "user1", "ip1", null, false, null, null);
|
||||||
|
session.sessions().createOfflineUserSession(userSession);
|
||||||
|
session.sessions().createOfflineUserSession(origSessions[0]);
|
||||||
|
|
||||||
|
// try to load user session from persister
|
||||||
|
Assert.assertEquals(2, persister.loadUserSessionsStream(0, 10, true, "00000000-0000-0000-0000-000000000000").count());
|
||||||
|
});
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
Time.setOffset(0);
|
||||||
|
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
|
||||||
|
if (timer != null) {
|
||||||
|
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
InfinispanTestUtil.revertTimeService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Set<String> createOfflineSessionIncludeClientSessions(KeycloakSession session, UserSessionModel
|
private static Set<String> createOfflineSessionIncludeClientSessions(KeycloakSession session, UserSessionModel
|
||||||
userSession) {
|
userSession) {
|
||||||
Set<String> offlineSessions = new HashSet<>();
|
Set<String> offlineSessions = new HashSet<>();
|
||||||
|
|
Loading…
Reference in a new issue