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) {
|
||||
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);
|
||||
|
||||
logger.tracef("Trigger removing expired user sessions for realm '%s'", realm.getName());
|
||||
|
||||
int cs = em.createNamedQuery("deleteExpiredClientSessions")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("lastSessionRefresh", expiredOffline)
|
||||
.setParameter("lastSessionRefresh", expiredClientOffline)
|
||||
.setParameter("offline", offlineStr)
|
||||
.executeUpdate();
|
||||
|
||||
|
@ -375,10 +381,13 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
|
|||
|
||||
closing(queryClientSessions.getResultStream()).forEach(clientSession -> {
|
||||
PersistentUserSessionAdapter userSession = sessionsById.get(clientSession.getUserSessionId());
|
||||
boolean added = addClientSessionToAuthenticatedClientSessionsIfPresent(userSession, clientSession);
|
||||
if (!added) {
|
||||
// client was removed in the meantime
|
||||
removedClientUUIDs.add(clientSession.getClientId());
|
||||
// check if we have a user session for the client session
|
||||
if (userSession != null) {
|
||||
boolean added = addClientSessionToAuthenticatedClientSessionsIfPresent(userSession, clientSession);
|
||||
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");
|
||||
realm.setOfflineSessionIdleTimeout(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT);
|
||||
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.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
|
||||
userSession) {
|
||||
Set<String> offlineSessions = new HashSet<>();
|
||||
|
|
Loading…
Reference in a new issue