diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f190e0aa7f..f2bceefd19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -373,7 +373,7 @@ jobs: timeout-minutes: 150 strategy: matrix: - variant: [ "remote-cache,multi-site" ] + variant: [ "clusterless,multi-site" ] fail-fast: false steps: - uses: actions/checkout@v4 @@ -384,7 +384,7 @@ jobs: - name: Run base tests without cache run: | - TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh remote-cache` + TESTS=`testsuite/integration-arquillian/tests/base/testsuites/suite.sh clusterless` echo "Tests: $TESTS" ./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus -Pinfinispan-server -Dauth.server.feature=${{ matrix.variant }} -Dauth.server.feature.disable=persistent-user-sessions -Dtest=$TESTS -pl testsuite/integration-arquillian/tests/base 2>&1 | misc/log/trimmer.sh diff --git a/common/src/main/java/org/keycloak/common/Profile.java b/common/src/main/java/org/keycloak/common/Profile.java index 6d646783d1..5eccefa970 100755 --- a/common/src/main/java/org/keycloak/common/Profile.java +++ b/common/src/main/java/org/keycloak/common/Profile.java @@ -104,7 +104,7 @@ public class Profile { 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), + CLUSTERLESS("Store all session data, work cache and login failure data in an external Infinispan cluster.", Type.EXPERIMENTAL), CLIENT_TYPES("Client Types", Type.EXPERIMENTAL), diff --git a/common/src/main/java/org/keycloak/common/util/MultiSiteUtils.java b/common/src/main/java/org/keycloak/common/util/MultiSiteUtils.java index eca522b707..b0770ec851 100644 --- a/common/src/main/java/org/keycloak/common/util/MultiSiteUtils.java +++ b/common/src/main/java/org/keycloak/common/util/MultiSiteUtils.java @@ -29,6 +29,6 @@ public class MultiSiteUtils { * @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)); + return Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) || (isMultiSiteEnabled() && !Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS)); } } diff --git a/core/src/main/java/org/keycloak/TokenVerifier.java b/core/src/main/java/org/keycloak/TokenVerifier.java index c120f48711..9dbafbce91 100755 --- a/core/src/main/java/org/keycloak/TokenVerifier.java +++ b/core/src/main/java/org/keycloak/TokenVerifier.java @@ -115,7 +115,7 @@ public class TokenVerifier { return true; } - }; + } public static class TokenTypeCheck implements Predicate { @@ -134,7 +134,7 @@ public class TokenVerifier { } throw new VerificationException("Token type is incorrect. Expected '" + tokenTypes.toString() + "' but was '" + t.getType() + "'"); } - }; + } public static class AudienceCheck implements Predicate { @@ -162,7 +162,7 @@ public class TokenVerifier { throw new VerificationException("Expected audience not available in the token"); } - }; + } public static class IssuedForCheck implements Predicate { @@ -317,7 +317,7 @@ public class TokenVerifier { /** * Sets the key for verification of HMAC-based signature. * @param secretKey - * @return + * @return */ public TokenVerifier secretKey(SecretKey secretKey) { this.secretKey = secretKey; diff --git a/model/infinispan/src/main/java/org/keycloak/infinispan/util/InfinispanUtils.java b/model/infinispan/src/main/java/org/keycloak/infinispan/util/InfinispanUtils.java index 46e29a0269..9339c37a93 100644 --- a/model/infinispan/src/main/java/org/keycloak/infinispan/util/InfinispanUtils.java +++ b/model/infinispan/src/main/java/org/keycloak/infinispan/util/InfinispanUtils.java @@ -24,7 +24,7 @@ import org.keycloak.common.Profile; import org.keycloak.common.util.MultiSiteUtils; import org.keycloak.provider.ProviderConfigurationBuilder; -import static org.keycloak.common.Profile.Feature.REMOTE_CACHE; +import static org.keycloak.common.Profile.Feature.CLUSTERLESS; public final class InfinispanUtils { @@ -42,7 +42,7 @@ public final class InfinispanUtils { // true if running with external infinispan mode only public static boolean isRemoteInfinispan() { - return MultiSiteUtils.isMultiSiteEnabled() || Profile.isFeatureEnabled(REMOTE_CACHE); + return MultiSiteUtils.isMultiSiteEnabled() || Profile.isFeatureEnabled(CLUSTERLESS); } // true if running with embedded caches. diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/legacy/infinispan/CacheManagerFactory.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/legacy/infinispan/CacheManagerFactory.java index 2edc5491e2..121a41e738 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/legacy/infinispan/CacheManagerFactory.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/storage/legacy/infinispan/CacheManagerFactory.java @@ -299,7 +299,7 @@ public class CacheManagerFactory { logger.debug("Removing all distributed caches."); for (String cacheName : CLUSTERED_CACHE_NAMES) { if (hasRemoteStore(builders.get(cacheName))) { - logger.warnf("remote-store configuration detected for cache '%s'. Explicit cache configuration ignored when using '%s' or '%s' Features.", cacheName, Profile.Feature.REMOTE_CACHE.getKey(), Profile.Feature.MULTI_SITE.getKey()); + logger.warnf("remote-store configuration detected for cache '%s'. Explicit cache configuration ignored when using '%s' or '%s' Features.", cacheName, Profile.Feature.CLUSTERLESS.getKey(), Profile.Feature.MULTI_SITE.getKey()); } builders.remove(cacheName); } @@ -456,10 +456,10 @@ public class CacheManagerFactory { Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE.getKey(), Profile.Feature.MULTI_SITE.getKey()); throw new RuntimeException("The features " + Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE.getKey() + " and " + Profile.Feature.MULTI_SITE.getKey() + " must not be enabled at the same time."); } - if (Profile.isFeatureEnabled(Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE) && Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE)) { + if (Profile.isFeatureEnabled(Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE) && Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS)) { logger.fatalf("Feature %s is now deprecated.%nFor multi-site (cross-dc) support, enable only %s.", - Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE.getKey(), Profile.Feature.REMOTE_CACHE.getKey()); - throw new RuntimeException("The features " + Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE.getKey() + " and " + Profile.Feature.REMOTE_CACHE.getKey() + " must not be enabled at the same time."); + Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE.getKey(), Profile.Feature.CLUSTERLESS.getKey()); + throw new RuntimeException("The features " + Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE.getKey() + " and " + Profile.Feature.CLUSTERLESS.getKey() + " must not be enabled at the same time."); } if (!Profile.isFeatureEnabled(Profile.Feature.CACHE_EMBEDDED_REMOTE_STORE)) { if (builder.getNamedConfigurationBuilders().values().stream().anyMatch(CacheManagerFactory::hasRemoteStore)) { diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/ExternalInfinispanTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/ExternalInfinispanTest.java index 40c1ae7b9c..60df0f7830 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/ExternalInfinispanTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/ExternalInfinispanTest.java @@ -54,7 +54,7 @@ public class ExternalInfinispanTest { @Test @Launch({ "start-dev", - "--features=multi-site,remote-cache", + "--features=multi-site,clusterless", "--cache=ispn", "--cache-remote-host=127.0.0.1", "--cache-remote-username=keycloak", diff --git a/server-spi-private/src/main/java/org/keycloak/cluster/ManagedCacheManagerProvider.java b/server-spi-private/src/main/java/org/keycloak/cluster/ManagedCacheManagerProvider.java index 6bd92f0b18..16bd66eac8 100644 --- a/server-spi-private/src/main/java/org/keycloak/cluster/ManagedCacheManagerProvider.java +++ b/server-spi-private/src/main/java/org/keycloak/cluster/ManagedCacheManagerProvider.java @@ -29,7 +29,7 @@ public interface ManagedCacheManagerProvider { C getEmbeddedCacheManager(Config.Scope config); /** - * @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. + * @return A RemoteCacheManager if the features {@link org.keycloak.common.Profile.Feature#CLUSTERLESS} or {@link org.keycloak.common.Profile.Feature#MULTI_SITE} is enabled, {@code null} otherwise. */ C getRemoteCacheManager(Config.Scope config); } diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java index b264476bde..9e4d155630 100755 --- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java +++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java @@ -100,7 +100,6 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -172,7 +171,7 @@ public class AuthenticationManager { // Parameter of LogoutEndpoint public static final String INITIATING_IDP_PARAM = "initiating_idp"; - private static final TokenTypeCheck VALIDATE_IDENTITY_COOKIE = new TokenTypeCheck(Arrays.asList(TokenUtil.TOKEN_TYPE_KEYCLOAK_ID)); + private static final TokenTypeCheck VALIDATE_IDENTITY_COOKIE = new TokenTypeCheck(List.of(TokenUtil.TOKEN_TYPE_KEYCLOAK_ID)); public static boolean isSessionValid(RealmModel realm, UserSessionModel userSession) { if (userSession == null) { @@ -186,7 +185,7 @@ public class AuthenticationManager { userSession.isRememberMe(), TimeUnit.SECONDS.toMillis(userSession.getLastSessionRefresh()), realm); boolean sessionIdleOk = idle > currentTime - - ((Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) || Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE)) ? 0 : TimeUnit.SECONDS.toMillis(SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS)); + ((Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) || Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS)) ? 0 : TimeUnit.SECONDS.toMillis(SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS)); boolean sessionMaxOk = lifespan == -1L || lifespan > currentTime; return sessionIdleOk && sessionMaxOk; } @@ -205,7 +204,7 @@ public class AuthenticationManager { userSession.isRememberMe(), TimeUnit.SECONDS.toMillis(clientSession.getTimestamp()), realm, client); boolean sessionIdleOk = idle > currentTime - - ((Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) || Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE)) ? 0 : TimeUnit.SECONDS.toMillis(SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS)); + ((Profile.isFeatureEnabled(Profile.Feature.PERSISTENT_USER_SESSIONS) || Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS)) ? 0 : TimeUnit.SECONDS.toMillis(SessionTimeoutHelper.IDLE_TIMEOUT_WINDOW_SECONDS)); boolean sessionMaxOk = lifespan == -1L || lifespan > currentTime; return sessionIdleOk && sessionMaxOk; } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/AbstractQuarkusDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/AbstractQuarkusDeployableContainer.java index 4472194084..17f2199a6d 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/AbstractQuarkusDeployableContainer.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/AbstractQuarkusDeployableContainer.java @@ -212,7 +212,7 @@ public abstract class AbstractQuarkusDeployableContainer implements DeployableCo addFeaturesOption(commands); var features = getDefaultFeatures(); - if (features.contains("remote-cache") || features.contains("multi-site")) { + if (features.contains("clusterless") || features.contains("multi-site")) { commands.add("--cache-remote-host=127.0.0.1"); commands.add("--cache-remote-username=keycloak"); commands.add("--cache-remote-password=Password1!"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java index 0bd9271238..693256caa9 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java @@ -391,7 +391,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { @Test public void accessTokenCodeExpired() { - ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE); + ProfileAssume.assumeFeatureDisabled(Profile.Feature.CLUSTERLESS); ProfileAssume.assumeFeatureDisabled(Profile.Feature.MULTI_SITE); getTestingClient().testing().setTestingInfinispanTimeService(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java index 26e7d424d4..f2e21edd8b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/LastSessionRefreshUnitTest.java @@ -65,7 +65,7 @@ public class LastSessionRefreshUnitTest extends AbstractKeycloakTest { @Test public void testLastSessionRefreshCounters() { - ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE); + ProfileAssume.assumeFeatureDisabled(Profile.Feature.CLUSTERLESS); ProfileAssume.assumeFeatureDisabled(Profile.Feature.MULTI_SITE); testingClient.server().run(new LastSessionRefreshServerCounterTest()); @@ -112,7 +112,7 @@ public class LastSessionRefreshUnitTest extends AbstractKeycloakTest { @Test public void testLastSessionRefreshIntervals() { - ProfileAssume.assumeFeatureDisabled(Profile.Feature.REMOTE_CACHE); + ProfileAssume.assumeFeatureDisabled(Profile.Feature.CLUSTERLESS); ProfileAssume.assumeFeatureDisabled(Profile.Feature.MULTI_SITE); testingClient.server().run(new LastSessionRefreshServerIntervalsTest()); diff --git a/testsuite/integration-arquillian/tests/base/testsuites/remote-cache-suite b/testsuite/integration-arquillian/tests/base/testsuites/clusterless-suite similarity index 100% rename from testsuite/integration-arquillian/tests/base/testsuites/remote-cache-suite rename to testsuite/integration-arquillian/tests/base/testsuites/clusterless-suite diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/EmbeddedInfinispanSplitBrainTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/EmbeddedInfinispanSplitBrainTest.java index dd47190404..89b54fe253 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/EmbeddedInfinispanSplitBrainTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/EmbeddedInfinispanSplitBrainTest.java @@ -37,7 +37,7 @@ public class EmbeddedInfinispanSplitBrainTest extends KeycloakModelTest { public static final TestRule SKIPPED_PROFILES = (base, description) -> { // We skip split-brain tests for the REMOTE_CACHE and MULTI_SITE features as neither of these architectures // utilise embedded distributed/replicated caches - Assume.assumeFalse(Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE)); + Assume.assumeFalse(Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS)); Assume.assumeFalse(Profile.isFeatureEnabled(Profile.Feature.MULTI_SITE)); return base; }; diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/FeatureEnabledTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/FeatureEnabledTest.java index 99f484d7c5..e78715d532 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/FeatureEnabledTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/infinispan/FeatureEnabledTest.java @@ -18,7 +18,6 @@ package org.keycloak.testsuite.model.infinispan; import java.util.Arrays; -import java.util.function.Predicate; import org.infinispan.commons.CacheConfigurationException; import org.junit.Test; @@ -36,12 +35,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; -import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.ACTION_TOKEN_CACHE; -import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME; import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.CLUSTERED_CACHE_NAMES; import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.LOCAL_CACHE_NAMES; -import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME; -import static org.keycloak.connections.infinispan.InfinispanConnectionProvider.WORK_CACHE_NAME; /** * Checks if the correct embedded or remote cache is started based on {@link org.keycloak.common.Profile.Feature}. @@ -61,7 +56,7 @@ public class FeatureEnabledTest extends KeycloakModelTest { @Test public void testRemoteCachesOnly() { - assumeTrue("Remote-Cache Feature disabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE) || MultiSiteUtils.isMultiSiteEnabled()); + assumeTrue("Clusterless Feature disabled", Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS) || MultiSiteUtils.isMultiSiteEnabled()); assertTrue(InfinispanUtils.isRemoteInfinispan()); assertFalse(InfinispanUtils.isEmbeddedInfinispan()); inComittedTransaction(session -> { @@ -75,7 +70,7 @@ public class FeatureEnabledTest extends KeycloakModelTest { @Test public void testEmbeddedCachesOnly() { assumeFalse("Multi-Site Feature enabled", MultiSiteUtils.isMultiSiteEnabled()); - assumeFalse("Remote-Cache Feature enabled", Profile.isFeatureEnabled(Profile.Feature.REMOTE_CACHE)); + assumeFalse("Clusterless Feature enabled", Profile.isFeatureEnabled(Profile.Feature.CLUSTERLESS)); assertFalse(InfinispanUtils.isRemoteInfinispan()); assertTrue(InfinispanUtils.isEmbeddedInfinispan()); inComittedTransaction(session -> {