Search in sources :

Example 21 with RemoteCache

use of org.infinispan.client.hotrod.RemoteCache in project keycloak by keycloak.

the class RemoteCacheSessionsLoaderTest method testRemoteCache.

@Test
@Ignore
public void testRemoteCache() throws Exception {
    String cacheName = InfinispanConnectionProvider.USER_SESSION_CACHE_NAME;
    Cache cache1 = createManager(1, cacheName).getCache(cacheName);
    Cache cache2 = cache1.getCacheManager().getCache("local");
    RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache1);
    cache1.clear();
    cache2.clear();
    remoteCache.clear();
    try {
        for (int i = 0; i < COUNT; i++) {
            // Create initial item
            UserSessionEntity session = new UserSessionEntity();
            session.setId("loader-key-" + i);
            session.setRealmId("master");
            session.setBrokerSessionId("!23123123");
            session.setBrokerUserId(null);
            session.setUser("admin");
            session.setLoginUsername("admin");
            session.setIpAddress("123.44.143.178");
            session.setStarted(Time.currentTime());
            session.setLastSessionRefresh(Time.currentTime());
            SessionEntityWrapper<UserSessionEntity> wrappedSession = new SessionEntityWrapper<>(session);
            // Create caches, listeners and finally worker threads
            remoteCache.put("loader-key-" + i, wrappedSession);
            Assert.assertFalse(cache2.containsKey("loader-key-" + i));
            if (i % 1000 == 0) {
                logger.infof("%d sessions added", i);
            }
        }
        // RemoteCacheSessionsLoader loader = new RemoteCacheSessionsLoader(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME, 64) {
        // 
        // @Override
        // protected Cache getCache(KeycloakSession session) {
        // return cache2;
        // }
        // 
        // @Override
        // protected RemoteCache getRemoteCache(KeycloakSession session) {
        // return remoteCache;
        // }
        // 
        // };
        // Just to be able to test serializability
        RemoteCacheSessionsLoader loader = new CustomLoader(cacheName, 64, cache2, remoteCache);
        loader.init(null);
        RemoteCacheSessionsLoaderContext ctx = loader.computeLoaderContext(null);
        Assert.assertEquals(ctx.getSessionsTotal(), COUNT);
        Assert.assertEquals(ctx.getIspnSegmentsCount(), 256);
        // Assert.assertEquals(ctx.getSegmentsCount(), 16);
        Assert.assertEquals(ctx.getSessionsPerSegment(), 64);
        int totalCount = 0;
        logger.infof("segmentsCount: %d", ctx.getSegmentsCount());
        Set<String> visitedKeys = new HashSet<>();
        for (int currentSegment = 0; currentSegment < ctx.getSegmentsCount(); currentSegment++) {
            logger.infof("Loading segment %d", currentSegment);
            loader.loadSessions(null, ctx, new SessionLoader.WorkerContext(currentSegment, currentSegment));
            logger.infof("Loaded %d keys for segment %d", cache2.keySet().size(), currentSegment);
            totalCount = totalCount + cache2.keySet().size();
            visitedKeys.addAll(cache2.keySet());
            cache2.clear();
        }
        Assert.assertEquals(totalCount, COUNT);
        Assert.assertEquals(visitedKeys.size(), COUNT);
        logger.infof("SUCCESS: Loaded %d sessions", totalCount);
    } finally {
        // Finish JVM
        cache1.getCacheManager().stop();
    }
}
Also used : RemoteCacheSessionsLoaderContext(org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheSessionsLoaderContext) SessionEntityWrapper(org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper) SessionLoader(org.keycloak.models.sessions.infinispan.initializer.SessionLoader) RemoteCache(org.infinispan.client.hotrod.RemoteCache) RemoteCacheSessionsLoader(org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheSessionsLoader) Cache(org.infinispan.Cache) RemoteCache(org.infinispan.client.hotrod.RemoteCache) UserSessionEntity(org.keycloak.models.sessions.infinispan.entities.UserSessionEntity) HashSet(java.util.HashSet) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 22 with RemoteCache

use of org.infinispan.client.hotrod.RemoteCache in project keycloak by keycloak.

the class ConcurrencyJDGCacheReplaceTest method createWorker.

private static Thread createWorker(Cache<String, SessionEntityWrapper<UserSessionEntity>> cache, int threadId) {
    System.out.println("Retrieved cache: " + threadId);
    RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
    if (threadId == 1) {
        remoteCache1 = remoteCache;
    } else {
        remoteCache2 = remoteCache;
    }
    AtomicInteger counter = threadId == 1 ? successfulListenerWrites : successfulListenerWrites2;
    HotRodListener listener = new HotRodListener(cache, remoteCache, counter);
    remoteCache.addClientListener(listener);
    return new RemoteCacheWorker(remoteCache, threadId);
// return new CacheWorker(cache, threadId);
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RemoteCache(org.infinispan.client.hotrod.RemoteCache)

Example 23 with RemoteCache

use of org.infinispan.client.hotrod.RemoteCache in project keycloak by keycloak.

the class RemoteCacheSessionsLoader method computeLoaderContext.

@Override
public RemoteCacheSessionsLoaderContext computeLoaderContext(KeycloakSession session) {
    RemoteCache remoteCache = getRemoteCache(session);
    int sessionsTotal = remoteCache.size();
    int ispnSegments = getIspnSegmentsCount(remoteCache);
    return new RemoteCacheSessionsLoaderContext(ispnSegments, sessionsPerSegment, sessionsTotal);
}
Also used : RemoteCache(org.infinispan.client.hotrod.RemoteCache)

Example 24 with RemoteCache

use of org.infinispan.client.hotrod.RemoteCache in project keycloak by keycloak.

the class InfinispanUserSessionProvider method importUserSessions.

@Override
public void importUserSessions(Collection<UserSessionModel> persistentUserSessions, boolean offline) {
    if (persistentUserSessions == null || persistentUserSessions.isEmpty()) {
        return;
    }
    Map<UUID, SessionEntityWrapper<AuthenticatedClientSessionEntity>> clientSessionsById = new HashMap<>();
    Map<String, SessionEntityWrapper<UserSessionEntity>> sessionsById = persistentUserSessions.stream().map((UserSessionModel persistentUserSession) -> {
        UserSessionEntity userSessionEntityToImport = createUserSessionEntityInstance(persistentUserSession);
        for (Map.Entry<String, AuthenticatedClientSessionModel> entry : persistentUserSession.getAuthenticatedClientSessions().entrySet()) {
            String clientUUID = entry.getKey();
            AuthenticatedClientSessionModel clientSession = entry.getValue();
            AuthenticatedClientSessionEntity clientSessionToImport = createAuthenticatedClientSessionInstance(clientSession, userSessionEntityToImport.getRealmId(), offline);
            // Update timestamp to same value as userSession. LastSessionRefresh of userSession from DB will have correct value
            clientSessionToImport.setTimestamp(userSessionEntityToImport.getLastSessionRefresh());
            clientSessionsById.put(clientSessionToImport.getId(), new SessionEntityWrapper<>(clientSessionToImport));
            // Update userSession entity with the clientSession
            AuthenticatedClientSessionStore clientSessions = userSessionEntityToImport.getAuthenticatedClientSessions();
            clientSessions.put(clientUUID, clientSessionToImport.getId());
        }
        return userSessionEntityToImport;
    }).map(SessionEntityWrapper::new).collect(Collectors.toMap(sessionEntityWrapper -> sessionEntityWrapper.getEntity().getId(), Function.identity()));
    // Directly put all entities to the infinispan cache
    Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = CacheDecorators.skipCacheLoaders(getCache(offline));
    boolean importWithExpiration = sessionsById.size() == 1;
    if (importWithExpiration) {
        importSessionsWithExpiration(sessionsById, cache, offline ? SessionTimeouts::getOfflineSessionLifespanMs : SessionTimeouts::getUserSessionLifespanMs, offline ? SessionTimeouts::getOfflineSessionMaxIdleMs : SessionTimeouts::getUserSessionMaxIdleMs);
    } else {
        cache.putAll(sessionsById);
    }
    // put all entities to the remoteCache (if exists)
    RemoteCache remoteCache = InfinispanUtil.getRemoteCache(cache);
    if (remoteCache != null) {
        Map<String, SessionEntityWrapper<UserSessionEntity>> sessionsByIdForTransport = sessionsById.values().stream().map(SessionEntityWrapper::forTransport).collect(Collectors.toMap(sessionEntityWrapper -> sessionEntityWrapper.getEntity().getId(), Function.identity()));
        if (importWithExpiration) {
            importSessionsWithExpiration(sessionsByIdForTransport, remoteCache, offline ? SessionTimeouts::getOfflineSessionLifespanMs : SessionTimeouts::getUserSessionLifespanMs, offline ? SessionTimeouts::getOfflineSessionMaxIdleMs : SessionTimeouts::getUserSessionMaxIdleMs);
        } else {
            Retry.executeWithBackoff((int iteration) -> {
                try {
                    remoteCache.putAll(sessionsByIdForTransport);
                } catch (HotRodClientException re) {
                    if (log.isDebugEnabled()) {
                        log.debugf(re, "Failed to put import %d sessions to remoteCache. Iteration '%s'. Will try to retry the task", sessionsByIdForTransport.size(), iteration);
                    }
                    // Rethrow the exception. Retry will take care of handle the exception and eventually retry the operation.
                    throw re;
                }
            }, 10, 10);
        }
    }
    // Import client sessions
    Cache<UUID, SessionEntityWrapper<AuthenticatedClientSessionEntity>> clientSessCache = offline ? offlineClientSessionCache : clientSessionCache;
    clientSessCache = CacheDecorators.skipCacheLoaders(clientSessCache);
    if (importWithExpiration) {
        importSessionsWithExpiration(clientSessionsById, clientSessCache, offline ? SessionTimeouts::getOfflineClientSessionLifespanMs : SessionTimeouts::getClientSessionLifespanMs, offline ? SessionTimeouts::getOfflineClientSessionMaxIdleMs : SessionTimeouts::getClientSessionMaxIdleMs);
    } else {
        clientSessCache.putAll(clientSessionsById);
    }
    // put all entities to the remoteCache (if exists)
    RemoteCache remoteCacheClientSessions = InfinispanUtil.getRemoteCache(clientSessCache);
    if (remoteCacheClientSessions != null) {
        Map<UUID, SessionEntityWrapper<AuthenticatedClientSessionEntity>> sessionsByIdForTransport = clientSessionsById.values().stream().map(SessionEntityWrapper::forTransport).collect(Collectors.toMap(sessionEntityWrapper -> sessionEntityWrapper.getEntity().getId(), Function.identity()));
        if (importWithExpiration) {
            importSessionsWithExpiration(sessionsByIdForTransport, remoteCacheClientSessions, offline ? SessionTimeouts::getOfflineClientSessionLifespanMs : SessionTimeouts::getClientSessionLifespanMs, offline ? SessionTimeouts::getOfflineClientSessionMaxIdleMs : SessionTimeouts::getClientSessionMaxIdleMs);
        } else {
            Retry.executeWithBackoff((int iteration) -> {
                try {
                    remoteCacheClientSessions.putAll(sessionsByIdForTransport);
                } catch (HotRodClientException re) {
                    if (log.isDebugEnabled()) {
                        log.debugf(re, "Failed to put import %d client sessions to remoteCache. Iteration '%s'. Will try to retry the task", sessionsByIdForTransport.size(), iteration);
                    }
                    // Rethrow the exception. Retry will take care of handle the exception and eventually retry the operation.
                    throw re;
                }
            }, 10, 10);
        }
    }
}
Also used : UserSessionProvider(org.keycloak.models.UserSessionProvider) RemoveUserSessionsEvent(org.keycloak.models.sessions.infinispan.events.RemoveUserSessionsEvent) BiFunction(java.util.function.BiFunction) Cache(org.infinispan.Cache) RemoteCache(org.infinispan.client.hotrod.RemoteCache) FuturesHelper(org.keycloak.models.sessions.infinispan.util.FuturesHelper) ClusterProvider(org.keycloak.cluster.ClusterProvider) PersisterLastSessionRefreshStore(org.keycloak.models.sessions.infinispan.changes.sessions.PersisterLastSessionRefreshStore) Future(java.util.concurrent.Future) RealmRemovedSessionEvent(org.keycloak.models.sessions.infinispan.events.RealmRemovedSessionEvent) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) Map(java.util.Map) SessionEntity(org.keycloak.models.sessions.infinispan.entities.SessionEntity) Time(org.keycloak.common.util.Time) InfinispanUtil(org.keycloak.connections.infinispan.InfinispanUtil) OfflineUserSessionModel(org.keycloak.models.OfflineUserSessionModel) RealmModel(org.keycloak.models.RealmModel) UserSessionPersisterProvider(org.keycloak.models.session.UserSessionPersisterProvider) CrossDCLastSessionRefreshStore(org.keycloak.models.sessions.infinispan.changes.sessions.CrossDCLastSessionRefreshStore) SessionPredicate(org.keycloak.models.sessions.infinispan.stream.SessionPredicate) Predicate(java.util.function.Predicate) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) Objects(java.util.Objects) UserProvider(org.keycloak.models.UserProvider) InfinispanChangelogBasedTransaction(org.keycloak.models.sessions.infinispan.changes.InfinispanChangelogBasedTransaction) Stream(java.util.stream.Stream) Flag(org.infinispan.context.Flag) AuthenticatedClientSessionEntity(org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionEntity) DeviceActivityManager(org.keycloak.device.DeviceActivityManager) ClientModel(org.keycloak.models.ClientModel) Mappers(org.keycloak.models.sessions.infinispan.stream.Mappers) InfinispanKeyGenerator(org.keycloak.models.sessions.infinispan.util.InfinispanKeyGenerator) Logger(org.jboss.logging.Logger) UserSessionSpi(org.keycloak.models.UserSessionSpi) HashMap(java.util.HashMap) Function(java.util.function.Function) HotRodClientException(org.infinispan.client.hotrod.exceptions.HotRodClientException) UserModel(org.keycloak.models.UserModel) AuthenticatedClientSessionStore(org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionStore) SessionTimeouts(org.keycloak.models.sessions.infinispan.util.SessionTimeouts) BasicCache(org.infinispan.commons.api.BasicCache) UserSessionPredicate(org.keycloak.models.sessions.infinispan.stream.UserSessionPredicate) StreamSupport(java.util.stream.StreamSupport) Retry(org.keycloak.common.util.Retry) UserSessionEntity(org.keycloak.models.sessions.infinispan.entities.UserSessionEntity) RemoteCacheInvoker(org.keycloak.models.sessions.infinispan.remotestore.RemoteCacheInvoker) Iterator(java.util.Iterator) SessionUpdateTask(org.keycloak.models.sessions.infinispan.changes.SessionUpdateTask) KeycloakSession(org.keycloak.models.KeycloakSession) UserSessionModel(org.keycloak.models.UserSessionModel) CacheCollectors(org.infinispan.stream.CacheCollectors) Comparators(org.keycloak.models.sessions.infinispan.stream.Comparators) Tasks(org.keycloak.models.sessions.infinispan.changes.Tasks) SessionEntityWrapper(org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) ModelException(org.keycloak.models.ModelException) StreamsUtil.paginatedStream(org.keycloak.utils.StreamsUtil.paginatedStream) SessionEventsSenderTransaction(org.keycloak.models.sessions.infinispan.events.SessionEventsSenderTransaction) Collections(java.util.Collections) OfflineUserSessionModel(org.keycloak.models.OfflineUserSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) HotRodClientException(org.infinispan.client.hotrod.exceptions.HotRodClientException) SessionEntityWrapper(org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper) AuthenticatedClientSessionEntity(org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionEntity) RemoteCache(org.infinispan.client.hotrod.RemoteCache) UUID(java.util.UUID) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) AuthenticatedClientSessionStore(org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionStore) UserSessionEntity(org.keycloak.models.sessions.infinispan.entities.UserSessionEntity)

Example 25 with RemoteCache

use of org.infinispan.client.hotrod.RemoteCache in project keycloak by keycloak.

the class InfinispanNotificationsManager method create.

// Create and init manager including all listeners etc
public static InfinispanNotificationsManager create(KeycloakSession session, Cache<String, Serializable> workCache, String myAddress, String mySite, Set<RemoteStore> remoteStores) {
    RemoteCache workRemoteCache = null;
    if (!remoteStores.isEmpty()) {
        RemoteStore remoteStore = remoteStores.iterator().next();
        workRemoteCache = remoteStore.getRemoteCache();
        if (mySite == null) {
            throw new IllegalStateException("Multiple datacenters available, but site name is not configured! Check your configuration");
        }
    }
    ExecutorService listenersExecutor = workRemoteCache == null ? null : session.getProvider(ExecutorsProvider.class).getExecutor("work-cache-event-listener");
    InfinispanNotificationsManager manager = new InfinispanNotificationsManager(workCache, workRemoteCache, myAddress, mySite, listenersExecutor);
    // We need CacheEntryListener for communication within current DC
    workCache.addListener(manager.new CacheEntryListener());
    logger.debugf("Added listener for infinispan cache: %s", workCache.getName());
    // Added listener for remoteCache to notify other DCs
    if (workRemoteCache != null) {
        workRemoteCache.addClientListener(manager.new HotRodListener(workRemoteCache));
        logger.debugf("Added listener for HotRod remoteStore cache: %s", workRemoteCache.getName());
    }
    return manager;
}
Also used : RemoteCache(org.infinispan.client.hotrod.RemoteCache) ExecutorService(java.util.concurrent.ExecutorService) RemoteStore(org.infinispan.persistence.remote.RemoteStore)

Aggregations

RemoteCache (org.infinispan.client.hotrod.RemoteCache)26 SessionEntityWrapper (org.keycloak.models.sessions.infinispan.changes.SessionEntityWrapper)9 Cache (org.infinispan.Cache)8 Map (java.util.Map)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 HotRodClientException (org.infinispan.client.hotrod.exceptions.HotRodClientException)5 RemoteStore (org.infinispan.persistence.remote.RemoteStore)5 UUID (java.util.UUID)4 BasicCache (org.infinispan.commons.api.BasicCache)4 Logger (org.jboss.logging.Logger)4 KeycloakSession (org.keycloak.models.KeycloakSession)4 RealmModel (org.keycloak.models.RealmModel)4 UserSessionEntity (org.keycloak.models.sessions.infinispan.entities.UserSessionEntity)4 HashMap (java.util.HashMap)3 Objects (java.util.Objects)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 TimeUnit (java.util.concurrent.TimeUnit)3 BiFunction (java.util.function.BiFunction)3 Function (java.util.function.Function)3 Collectors (java.util.stream.Collectors)3