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