Search in sources :

Example 11 with InfinispanConnectionProvider

use of org.keycloak.connections.infinispan.InfinispanConnectionProvider in project keycloak by keycloak.

the class InfinispanSingleUseTokenStoreProviderFactory method getActionTokenCache.

static Supplier getActionTokenCache(KeycloakSession session) {
    InfinispanConnectionProvider connections = session.getProvider(InfinispanConnectionProvider.class);
    Cache cache = connections.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE);
    RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
    if (remoteCache != null) {
        LOG.debugf("Having remote stores. Using remote cache '%s' for single-use cache of token", remoteCache.getName());
        return () -> {
            // Doing this way as flag is per invocation
            return remoteCache.withFlags(Flag.FORCE_RETURN_VALUE);
        };
    } else {
        LOG.debugf("Not having remote stores. Using normal cache '%s' for single-use cache of token", cache.getName());
        return () -> {
            return cache;
        };
    }
}
Also used : RemoteCache(org.infinispan.client.hotrod.RemoteCache) InfinispanConnectionProvider(org.keycloak.connections.infinispan.InfinispanConnectionProvider) Cache(org.infinispan.Cache) RemoteCache(org.infinispan.client.hotrod.RemoteCache) BasicCache(org.infinispan.commons.api.BasicCache)

Example 12 with InfinispanConnectionProvider

use of org.keycloak.connections.infinispan.InfinispanConnectionProvider in project keycloak by keycloak.

the class InfinispanActionTokenStoreProviderFactory method initActionTokenCache.

private static Cache<ActionTokenReducedKey, ActionTokenValueEntity> initActionTokenCache(KeycloakSession session) {
    InfinispanConnectionProvider connections = session.getProvider(InfinispanConnectionProvider.class);
    Cache<ActionTokenReducedKey, ActionTokenValueEntity> cache = connections.getCache(InfinispanConnectionProvider.ACTION_TOKEN_CACHE);
    return cache;
}
Also used : ActionTokenReducedKey(org.keycloak.models.sessions.infinispan.entities.ActionTokenReducedKey) ActionTokenValueEntity(org.keycloak.models.sessions.infinispan.entities.ActionTokenValueEntity) InfinispanConnectionProvider(org.keycloak.connections.infinispan.InfinispanConnectionProvider)

Example 13 with InfinispanConnectionProvider

use of org.keycloak.connections.infinispan.InfinispanConnectionProvider in project keycloak by keycloak.

the class InfinispanAuthenticationSessionProviderFactory method lazyInit.

private void lazyInit(KeycloakSession session) {
    if (authSessionsCache == null) {
        synchronized (this) {
            if (authSessionsCache == null) {
                InfinispanConnectionProvider connections = session.getProvider(InfinispanConnectionProvider.class);
                authSessionsCache = connections.getCache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME);
                keyGenerator = new InfinispanKeyGenerator();
                ClusterProvider cluster = session.getProvider(ClusterProvider.class);
                cluster.registerListener(AUTHENTICATION_SESSION_EVENTS, this::updateAuthNotes);
                log.debugf("[%s] Registered cluster listeners", authSessionsCache.getCacheManager().getAddress());
            }
        }
    }
}
Also used : ClusterProvider(org.keycloak.cluster.ClusterProvider) InfinispanKeyGenerator(org.keycloak.models.sessions.infinispan.util.InfinispanKeyGenerator) InfinispanConnectionProvider(org.keycloak.connections.infinispan.InfinispanConnectionProvider)

Example 14 with InfinispanConnectionProvider

use of org.keycloak.connections.infinispan.InfinispanConnectionProvider in project keycloak by keycloak.

the class CacheExpirationTest method testCacheExpiration.

@Test
public void testCacheExpiration() throws Exception {
    log.debug("Put two events to the main cache");
    inComittedTransaction(session -> {
        InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
        Cache<String, Object> cache = provider.getCache(InfinispanConnectionProvider.WORK_CACHE_NAME);
        cache.entrySet().stream().filter(me -> me.getValue() instanceof AuthenticationSessionAuthNoteUpdateEvent).forEach((c, me) -> c.remove(me.getKey()));
        cache.put("1-2", AuthenticationSessionAuthNoteUpdateEvent.create("g1", "p1", "r1", Collections.emptyMap()), 20000, TimeUnit.MILLISECONDS);
        cache.put("1-2-3", AuthenticationSessionAuthNoteUpdateEvent.create("g2", "p2", "r2", Collections.emptyMap()), 20000, TimeUnit.MILLISECONDS);
    });
    assumeThat("jmap output format unsupported", getNumberOfInstancesOfClass(AuthenticationSessionAuthNoteUpdateEvent.class), notNullValue());
    // Ensure that instance counting works as expected, there should be at least two instances in memory now.
    // Infinispan server is decoding the client request before processing the request at the cache level,
    // therefore there are sometimes three instances of AuthenticationSessionAuthNoteUpdateEvent class in the memory
    assertThat(getNumberOfInstancesOfClass(AuthenticationSessionAuthNoteUpdateEvent.class), greaterThanOrEqualTo(2));
    log.debug("Starting other nodes and see that they join, receive the data and have their data expired");
    AtomicInteger completedTests = new AtomicInteger(0);
    inIndependentFactories(NUM_EXTRA_FACTORIES, 5 * 60, () -> {
        log.debug("Joining the cluster");
        inComittedTransaction(session -> {
            InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
            Cache<String, Object> cache = provider.getCache(InfinispanConnectionProvider.WORK_CACHE_NAME);
            log.debug("Waiting for caches to join the cluster");
            do {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException(ex);
                }
            } while (!cache.getAdvancedCache().getDistributionManager().isJoinComplete());
            String site = CONFIG.scope("connectionsInfinispan", "default").get("siteName");
            log.debug("Cluster joined " + site);
            log.debug("Waiting for cache to receive the two elements within the cluster");
            do {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException(ex);
                }
            } while (cache.entrySet().stream().filter(me -> me.getValue() instanceof AuthenticationSessionAuthNoteUpdateEvent).count() != 2);
            // access the items in the local cache in the different site (site-2) in order to fetch them from the remote cache
            assertThat(cache.get("1-2"), notNullValue());
            assertThat(cache.get("1-2-3"), notNullValue());
            // this is testing for a situation where an expiration lifespan configuration was missing in a replicated cache;
            // the elements were no longer seen in the cache, still they weren't garbage collected.
            // we must not look into the cache as that would trigger expiration explicitly.
            // original issue: https://issues.redhat.com/browse/KEYCLOAK-18518
            log.debug("Waiting for garbage collection to collect the entries across all caches in JVM");
            do {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException(ex);
                }
            } while (getNumberOfInstancesOfClass(AuthenticationSessionAuthNoteUpdateEvent.class) != 0);
            completedTests.incrementAndGet();
            log.debug("Test completed");
        });
    });
    assertThat(completedTests.get(), is(NUM_EXTRA_FACTORIES));
}
Also used : InfinispanConnectionProvider(org.keycloak.connections.infinispan.InfinispanConnectionProvider) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) Assume.assumeThat(org.junit.Assume.assumeThat) Matchers.notNullValue(org.hamcrest.Matchers.notNullValue) Test(org.junit.Test) KeycloakModelTest(org.keycloak.testsuite.model.KeycloakModelTest) IOException(java.io.IOException) Cache(org.infinispan.Cache) InputStreamReader(java.io.InputStreamReader) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) Matcher(java.util.regex.Matcher) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Assume(org.junit.Assume) AuthenticationSessionAuthNoteUpdateEvent(org.keycloak.models.cache.infinispan.events.AuthenticationSessionAuthNoteUpdateEvent) RequireProvider(org.keycloak.testsuite.model.RequireProvider) Matchers.is(org.hamcrest.Matchers.is) BufferedReader(java.io.BufferedReader) ManagementFactory(java.lang.management.ManagementFactory) Pattern(java.util.regex.Pattern) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Collections(java.util.Collections) AuthenticationSessionAuthNoteUpdateEvent(org.keycloak.models.cache.infinispan.events.AuthenticationSessionAuthNoteUpdateEvent) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) InfinispanConnectionProvider(org.keycloak.connections.infinispan.InfinispanConnectionProvider) Test(org.junit.Test) KeycloakModelTest(org.keycloak.testsuite.model.KeycloakModelTest)

Example 15 with InfinispanConnectionProvider

use of org.keycloak.connections.infinispan.InfinispanConnectionProvider in project keycloak by keycloak.

the class UserSessionInitializerTest method testUserSessionPropagationBetweenSites.

@Test
@RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID)
public void testUserSessionPropagationBetweenSites() throws InterruptedException {
    AtomicInteger index = new AtomicInteger();
    AtomicReference<String> userSessionId = new AtomicReference<>();
    AtomicReference<List<Boolean>> containsSession = new AtomicReference<>(new LinkedList<>());
    Object lock = new Object();
    Optional<HotRodServerRule> hotRodServer = getParameters(HotRodServerRule.class).findFirst();
    inIndependentFactories(4, 300, () -> {
        synchronized (lock) {
            if (index.incrementAndGet() == 1) {
                // create a user session in the first node
                UserSessionModel userSessionModel = withRealm(realmId, (session, realm) -> {
                    final UserModel user = session.users().getUserByUsername(realm, "user1");
                    return session.sessions().createUserSession(realm, user, "un1", "ip1", "auth", false, null, null);
                });
                userSessionId.set(userSessionModel.getId());
            } else {
                // try to get the user session at other nodes and also at different sites
                inComittedTransaction(session -> {
                    InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
                    Cache<String, Object> localSessions = provider.getCache(USER_SESSION_CACHE_NAME);
                    containsSession.get().add(localSessions.containsKey(userSessionId.get()));
                    if (hotRodServer.isPresent()) {
                        RemoteCache<String, Object> remoteSessions = provider.getRemoteCache(USER_SESSION_CACHE_NAME);
                        containsSession.get().add(remoteSessions.containsKey(userSessionId.get()));
                    }
                });
            }
        }
    });
    assertThat(containsSession.get(), everyItem(is(true)));
    // 3 nodes (first node just creates the session), with Hot Rod server we have local + remote cache, without just local cache
    int size = hotRodServer.isPresent() ? 6 : 3;
    assertThat(containsSession.get().size(), is(size));
}
Also used : HotRodServerRule(org.keycloak.testsuite.model.HotRodServerRule) UserSessionModel(org.keycloak.models.UserSessionModel) AtomicReference(java.util.concurrent.atomic.AtomicReference) UserModel(org.keycloak.models.UserModel) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LinkedList(java.util.LinkedList) List(java.util.List) InfinispanConnectionProvider(org.keycloak.connections.infinispan.InfinispanConnectionProvider) Test(org.junit.Test) KeycloakModelTest(org.keycloak.testsuite.model.KeycloakModelTest) RequireProvider(org.keycloak.testsuite.model.RequireProvider)

Aggregations

InfinispanConnectionProvider (org.keycloak.connections.infinispan.InfinispanConnectionProvider)16 Cache (org.infinispan.Cache)5 SessionEntityWrapper (org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper)5 RemoteCache (org.infinispan.client.hotrod.RemoteCache)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)3 Test (org.junit.Test)3 KeycloakModelTest (org.keycloak.testsuite.model.KeycloakModelTest)3 LinkedList (java.util.LinkedList)2 List (java.util.List)2 UUID (java.util.UUID)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 KeycloakSession (org.keycloak.models.KeycloakSession)2 KeycloakSessionTask (org.keycloak.models.KeycloakSessionTask)2 RealmModel (org.keycloak.models.RealmModel)2 UserModel (org.keycloak.models.UserModel)2 LoginFailureKey (org.keycloak.models.sessions.infinispan.entities.LoginFailureKey)2 InfinispanCacheInitializer (org.keycloak.models.sessions.infinispan.initializer.InfinispanCacheInitializer)2 RemoteCacheSessionsLoader (org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheSessionsLoader)2 SessionTimeouts (org.keycloak.models.sessions.infinispan.util.SessionTimeouts)2 RequireProvider (org.keycloak.testsuite.model.RequireProvider)2