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();
}
}
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);
}
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);
}
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);
}
}
}
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;
}
Aggregations