Remove PERSISTENT_USER_SESSIONS_No_CACHE feature
Closes #29264 Signed-off-by: Michal Hajas <mhajas@redhat.com>
This commit is contained in:
parent
8b715d3a31
commit
128bba34d3
11 changed files with 38 additions and 125 deletions
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
|
@ -309,10 +309,6 @@ jobs:
|
||||||
if: needs.conditional.outputs.ci-store == 'true'
|
if: needs.conditional.outputs.ci-store == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 150
|
timeout-minutes: 150
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
variant: ["persistent-user-sessions,persistent-user-sessions-no-cache", "persistent-user-sessions"]
|
|
||||||
fail-fast: false
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -324,7 +320,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh persistent-sessions`
|
TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh persistent-sessions`
|
||||||
echo "Tests: $TESTS"
|
echo "Tests: $TESTS"
|
||||||
./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus -Dauth.server.feature=${{ matrix.variant }} -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh
|
./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus -Dauth.server.feature="persistent-user-sessions" -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh
|
||||||
|
|
||||||
- name: Upload JVM Heapdumps
|
- name: Upload JVM Heapdumps
|
||||||
if: always()
|
if: always()
|
||||||
|
|
|
@ -107,7 +107,6 @@ public class Profile {
|
||||||
HOSTNAME_V2("Hostname Options V2", Type.DEFAULT, 2),
|
HOSTNAME_V2("Hostname Options V2", Type.DEFAULT, 2),
|
||||||
|
|
||||||
PERSISTENT_USER_SESSIONS("Persistent online user sessions across restarts and upgrades", Type.EXPERIMENTAL),
|
PERSISTENT_USER_SESSIONS("Persistent online user sessions across restarts and upgrades", Type.EXPERIMENTAL),
|
||||||
PERSISTENT_USER_SESSIONS_NO_CACHE("No caching for online user sessions when they are persisted", Type.EXPERIMENTAL),
|
|
||||||
|
|
||||||
OID4VC_VCI("Support for the OID4VCI protocol as part of OID4VC.", Type.EXPERIMENTAL),
|
OID4VC_VCI("Support for the OID4VCI protocol as part of OID4VC.", Type.EXPERIMENTAL),
|
||||||
|
|
||||||
|
|
|
@ -203,13 +203,11 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
|
|
||||||
AuthenticatedClientSessionAdapter adapter = new AuthenticatedClientSessionAdapter(session, this, entity, client, userSession, clientSessionTx, false);
|
AuthenticatedClientSessionAdapter adapter = new AuthenticatedClientSessionAdapter(session, this, entity, client, userSession, clientSessionTx, false);
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
if (userSession.isOffline()) {
|
||||||
if (userSession.isOffline()) {
|
// If this is an offline session, and the referred online session doesn't exist anymore, don't register the client session in the transaction.
|
||||||
// If this is an offline session, and the referred online session doesn't exist anymore, don't register the client session in the transaction.
|
// Instead keep it transient and it will be added to the offline session only afterward. This is expected by SessionTimeoutsTest.testOfflineUserClientIdleTimeoutSmallerThanSessionOneRefresh.
|
||||||
// Instead keep it transient and it will be added to the offline session only afterward. This is expected by SessionTimeoutsTest.testOfflineUserClientIdleTimeoutSmallerThanSessionOneRefresh.
|
if (sessionTx.get(realm, userSession.getId(), false) == null) {
|
||||||
if (sessionTx.get(realm, userSession.getId(), false) == null) {
|
return adapter;
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,10 +408,6 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||||
return userSession;
|
return userSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try lookup userSession from remoteCache
|
// Try lookup userSession from remoteCache
|
||||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
|
Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
|
||||||
RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
|
RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
|
||||||
|
|
|
@ -62,9 +62,8 @@ public class ClientSessionPersistentChangelogBasedTransaction extends Persistent
|
||||||
SessionUpdatesList<AuthenticatedClientSessionEntity> myUpdates = getUpdates(offline).get(key);
|
SessionUpdatesList<AuthenticatedClientSessionEntity> myUpdates = getUpdates(offline).get(key);
|
||||||
if (myUpdates == null) {
|
if (myUpdates == null) {
|
||||||
SessionEntityWrapper<AuthenticatedClientSessionEntity> wrappedEntity = null;
|
SessionEntityWrapper<AuthenticatedClientSessionEntity> wrappedEntity = null;
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
wrappedEntity = getCache(offline).get(key);
|
||||||
wrappedEntity = getCache(offline).get(key);
|
|
||||||
}
|
|
||||||
if (wrappedEntity == null) {
|
if (wrappedEntity == null) {
|
||||||
LOG.debugf("client-session not found in cache for sessionId=%s, offline=%s, loading from persister", key, offline);
|
LOG.debugf("client-session not found in cache for sessionId=%s, offline=%s, loading from persister", key, offline);
|
||||||
wrappedEntity = getSessionEntityFromPersister(realm, client, userSession, offline);
|
wrappedEntity = getSessionEntityFromPersister(realm, client, userSession, offline);
|
||||||
|
|
|
@ -75,10 +75,6 @@ public class InfinispanChangelogBasedTransaction<K, V extends SessionEntity> ext
|
||||||
public void addTask(K key, SessionUpdateTask<V> task) {
|
public void addTask(K key, SessionUpdateTask<V> task) {
|
||||||
SessionUpdatesList<V> myUpdates = updates.get(key);
|
SessionUpdatesList<V> myUpdates = updates.get(key);
|
||||||
if (myUpdates == null) {
|
if (myUpdates == null) {
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE) && (Objects.equals(cacheName, USER_SESSION_CACHE_NAME) || Objects.equals(cacheName, CLIENT_SESSION_CACHE_NAME) || Objects.equals(cacheName, OFFLINE_USER_SESSION_CACHE_NAME) || Objects.equals(cacheName, OFFLINE_CLIENT_SESSION_CACHE_NAME))) {
|
|
||||||
throw new IllegalStateException("Can't load from cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup entity from cache
|
// Lookup entity from cache
|
||||||
SessionEntityWrapper<V> wrappedEntity = cache.get(key);
|
SessionEntityWrapper<V> wrappedEntity = cache.get(key);
|
||||||
if (wrappedEntity == null) {
|
if (wrappedEntity == null) {
|
||||||
|
|
|
@ -77,39 +77,34 @@ abstract public class PersistentSessionsChangelogBasedTransaction<K, V extends S
|
||||||
throw new IllegalStateException("Cache name is not valid for persistent user sessions: " + cache.getName());
|
throw new IllegalStateException("Cache name is not valid for persistent user sessions: " + cache.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
changesPerformers = List.of(
|
||||||
changesPerformers = List.of(
|
new JpaChangesPerformer<>(cache.getName(), batchingQueue),
|
||||||
new JpaChangesPerformer<>(cache.getName(), batchingQueue)
|
new EmbeddedCachesChangesPerformer<>(cache) {
|
||||||
);
|
@Override
|
||||||
} else {
|
public boolean shouldConsumeChange(V entity) {
|
||||||
changesPerformers = List.of(
|
return !entity.isOffline();
|
||||||
new JpaChangesPerformer<>(cache.getName(), batchingQueue),
|
|
||||||
new EmbeddedCachesChangesPerformer<>(cache) {
|
|
||||||
@Override
|
|
||||||
public boolean shouldConsumeChange(V entity) {
|
|
||||||
return !entity.isOffline();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new EmbeddedCachesChangesPerformer<>(offlineCache){
|
|
||||||
@Override
|
|
||||||
public boolean shouldConsumeChange(V entity) {
|
|
||||||
return entity.isOffline();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new RemoteCachesChangesPerformer<>(session, cache, remoteCacheInvoker) {
|
|
||||||
@Override
|
|
||||||
public boolean shouldConsumeChange(V entity) {
|
|
||||||
return !entity.isOffline();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new RemoteCachesChangesPerformer<>(session, offlineCache, remoteCacheInvoker) {
|
|
||||||
@Override
|
|
||||||
public boolean shouldConsumeChange(V entity) {
|
|
||||||
return entity.isOffline();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
},
|
||||||
}
|
new EmbeddedCachesChangesPerformer<>(offlineCache){
|
||||||
|
@Override
|
||||||
|
public boolean shouldConsumeChange(V entity) {
|
||||||
|
return entity.isOffline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new RemoteCachesChangesPerformer<>(session, cache, remoteCacheInvoker) {
|
||||||
|
@Override
|
||||||
|
public boolean shouldConsumeChange(V entity) {
|
||||||
|
return !entity.isOffline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new RemoteCachesChangesPerformer<>(session, offlineCache, remoteCacheInvoker) {
|
||||||
|
@Override
|
||||||
|
public boolean shouldConsumeChange(V entity) {
|
||||||
|
return entity.isOffline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.offlineCache = offlineCache;
|
this.offlineCache = offlineCache;
|
||||||
this.lifespanMsLoader = lifespanMsLoader;
|
this.lifespanMsLoader = lifespanMsLoader;
|
||||||
|
@ -216,10 +211,6 @@ abstract public class PersistentSessionsChangelogBasedTransaction<K, V extends S
|
||||||
PersistentSessionUpdateTask<V> task = (PersistentSessionUpdateTask<V>) originalTask;
|
PersistentSessionUpdateTask<V> task = (PersistentSessionUpdateTask<V>) originalTask;
|
||||||
SessionUpdatesList<V> myUpdates = getUpdates(task.isOffline()).get(key);
|
SessionUpdatesList<V> myUpdates = getUpdates(task.isOffline()).get(key);
|
||||||
if (myUpdates == null) {
|
if (myUpdates == null) {
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
|
||||||
throw new IllegalStateException("Can't load from cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup entity from cache
|
// Lookup entity from cache
|
||||||
SessionEntityWrapper<V> wrappedEntity = getCache(task.isOffline()).get(key);
|
SessionEntityWrapper<V> wrappedEntity = getCache(task.isOffline()).get(key);
|
||||||
if (wrappedEntity == null) {
|
if (wrappedEntity == null) {
|
||||||
|
|
|
@ -53,9 +53,7 @@ public class UserSessionPersistentChangelogBasedTransaction extends PersistentSe
|
||||||
SessionUpdatesList<UserSessionEntity> myUpdates = getUpdates(offline).get(key);
|
SessionUpdatesList<UserSessionEntity> myUpdates = getUpdates(offline).get(key);
|
||||||
if (myUpdates == null) {
|
if (myUpdates == null) {
|
||||||
SessionEntityWrapper<UserSessionEntity> wrappedEntity = null;
|
SessionEntityWrapper<UserSessionEntity> wrappedEntity = null;
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
wrappedEntity = getCache(offline).get(key);
|
||||||
wrappedEntity = getCache(offline).get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wrappedEntity == null) {
|
if (wrappedEntity == null) {
|
||||||
LOG.debugf("user-session not found in cache for sessionId=%s offline=%s, loading from persister", key, offline);
|
LOG.debugf("user-session not found in cache for sessionId=%s offline=%s, loading from persister", key, offline);
|
||||||
|
@ -115,10 +113,6 @@ public class UserSessionPersistentChangelogBasedTransaction extends PersistentSe
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE)) {
|
|
||||||
return ((PersistentUserSessionProvider) kcSession.getProvider(UserSessionProvider.class)).wrapPersistentEntity(persistentUserSession.getRealm(), offline, persistentUserSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG.debugf("Attempting to import user-session for sessionId=%s offline=%s", sessionId, offline);
|
LOG.debugf("Attempting to import user-session for sessionId=%s offline=%s", sessionId, offline);
|
||||||
SessionEntityWrapper<UserSessionEntity> ispnUserSessionEntity = ((PersistentUserSessionProvider) kcSession.getProvider(UserSessionProvider.class)).importUserSession(persistentUserSession, offline);
|
SessionEntityWrapper<UserSessionEntity> ispnUserSessionEntity = ((PersistentUserSessionProvider) kcSession.getProvider(UserSessionProvider.class)).importUserSession(persistentUserSession, offline);
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class CacheManagerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
DISTRIBUTED_REPLICATED_CACHE_NAMES.forEach(cacheName -> {
|
DISTRIBUTED_REPLICATED_CACHE_NAMES.forEach(cacheName -> {
|
||||||
if (!Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE) && Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) &&
|
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) &&
|
||||||
(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))) {
|
(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 (configurationBuilder.memory().maxSize() == null && configurationBuilder.memory().maxCount() == -1) {
|
if (configurationBuilder.memory().maxSize() == null && configurationBuilder.memory().maxCount() == -1) {
|
||||||
|
@ -222,11 +222,6 @@ public class CacheManagerFactory {
|
||||||
SSLContext sslContext = createSSLContext();
|
SSLContext sslContext = createSSLContext();
|
||||||
|
|
||||||
DISTRIBUTED_REPLICATED_CACHE_NAMES.forEach(cacheName -> {
|
DISTRIBUTED_REPLICATED_CACHE_NAMES.forEach(cacheName -> {
|
||||||
if (Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE) &&
|
|
||||||
(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))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PersistenceConfigurationBuilder persistenceCB = builder.getNamedConfigurationBuilders().get(cacheName).persistence();
|
PersistenceConfigurationBuilder persistenceCB = builder.getNamedConfigurationBuilders().get(cacheName).persistence();
|
||||||
|
|
||||||
//if specified via command line -> cannot be defined in the xml file
|
//if specified via command line -> cannot be defined in the xml file
|
||||||
|
|
|
@ -219,13 +219,6 @@
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
|
|
||||||
<profile>
|
|
||||||
<id>jpa+persistentsessions</id>
|
|
||||||
<properties>
|
|
||||||
<keycloak.model.parameters>Jpa,PersistentUserSessionsNoCache</keycloak.model.parameters>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
<id>jpa+infinispan+client-storage</id>
|
<id>jpa+infinispan+client-storage</id>
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2020 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.testsuite.model.parameters;
|
|
||||||
|
|
||||||
import org.keycloak.common.Profile;
|
|
||||||
import org.keycloak.common.profile.PropertiesProfileConfigResolver;
|
|
||||||
import org.keycloak.testsuite.model.Config;
|
|
||||||
import org.keycloak.testsuite.model.KeycloakModelParameters;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class PersistentUserSessionsNoCache extends KeycloakModelParameters {
|
|
||||||
|
|
||||||
public PersistentUserSessionsNoCache() {
|
|
||||||
super(Collections.emptySet(), Collections.emptySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateConfig(Config cf) {
|
|
||||||
updateConfigForJpa(cf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateConfigForJpa(Config cf) {
|
|
||||||
System.getProperties().put(PropertiesProfileConfigResolver.getPropertyKey(Profile.Feature.PERSISTENT_USER_SESSIONS), "enabled");
|
|
||||||
System.getProperties().put(PropertiesProfileConfigResolver.getPropertyKey(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE), "enabled");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -158,9 +158,6 @@ public class UserSessionInitializerTest extends KeycloakModelTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUserSessionPropagationBetweenSites() throws InterruptedException {
|
public void testUserSessionPropagationBetweenSites() throws InterruptedException {
|
||||||
// When user sessions are not stored in the cache, this test doesn't make sense
|
|
||||||
Assume.assumeThat(Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS_NO_CACHE), Matchers.not(true));
|
|
||||||
|
|
||||||
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<>());
|
||||||
|
|
Loading…
Reference in a new issue