keycloak-aplcache

stress testing

2/12/2016 3:30:36 AM

Changes

Details

diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheRealmProvider.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheRealmProvider.java
index d80b817..a177b95 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheRealmProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/DefaultCacheRealmProvider.java
@@ -120,7 +120,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
 
     protected void runInvalidations() {
         for (String id : realmInvalidations) {
-            cache.invalidateCachedRealmById(id);
+            cache.invalidateRealmById(id);
         }
         for (String id : roleInvalidations) {
             cache.invalidateRoleById(id);
@@ -129,10 +129,10 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
             cache.invalidateGroupById(id);
         }
         for (String id : appInvalidations) {
-            cache.invalidateCachedApplicationById(id);
+            cache.invalidateClientById(id);
         }
         for (String id : clientTemplateInvalidations) {
-            cache.invalidateCachedClientTemplateById(id);
+            cache.invalidateClientTemplateById(id);
         }
     }
 
@@ -193,13 +193,13 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public RealmModel getRealm(String id) {
-        CachedRealm cached = cache.getCachedRealm(id);
+        CachedRealm cached = cache.getRealm(id);
         if (cached == null) {
             RealmModel model = getDelegate().getRealm(id);
             if (model == null) return null;
             if (realmInvalidations.contains(id)) return model;
             cached = new CachedRealm(cache, this, model);
-            cache.addCachedRealm(cached);
+            cache.addRealm(cached);
         } else if (realmInvalidations.contains(id)) {
             return getDelegate().getRealm(id);
         } else if (managedRealms.containsKey(id)) {
@@ -212,13 +212,13 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public RealmModel getRealmByName(String name) {
-        CachedRealm cached = cache.getCachedRealmByName(name);
+        CachedRealm cached = cache.getRealmByName(name);
         if (cached == null) {
             RealmModel model = getDelegate().getRealmByName(name);
             if (model == null) return null;
             if (realmInvalidations.contains(model.getId())) return model;
             cached = new CachedRealm(cache, this, model);
-            cache.addCachedRealm(cached);
+            cache.addRealm(cached);
         } else if (realmInvalidations.contains(cached.getId())) {
             return getDelegate().getRealmByName(name);
         } else if (managedRealms.containsKey(cached.getId())) {
@@ -245,7 +245,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public boolean removeRealm(String id) {
-        cache.invalidateCachedRealmById(id);
+        cache.invalidateRealmById(id);
 
         RealmModel realm = getDelegate().getRealm(id);
         Set<RoleModel> realmRoles = null;
@@ -287,7 +287,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
             } else {
                 cached = new CachedRealmRole(model, realm);
             }
-            cache.addCachedRole(cached);
+            cache.addRole(cached);
 
         } else if (roleInvalidations.contains(id)) {
             return getDelegate().getRoleById(id, realm);
@@ -311,7 +311,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (groupInvalidations.contains(id)) return model;
             cached = new CachedGroup(realm, model);
-            cache.addCachedGroup(cached);
+            cache.addGroup(cached);
 
         } else if (groupInvalidations.contains(id)) {
             return getDelegate().getGroupById(id, realm);
@@ -325,7 +325,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public ClientModel getClientById(String id, RealmModel realm) {
-        CachedClient cached = cache.getApplication(id);
+        CachedClient cached = cache.getClient(id);
         if (cached != null && !cached.getRealm().equals(realm.getId())) {
             cached = null;
         }
@@ -335,7 +335,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (appInvalidations.contains(id)) return model;
             cached = new CachedClient(cache, getDelegate(), realm, model);
-            cache.addCachedClient(cached);
+            cache.addClient(cached);
         } else if (appInvalidations.contains(id)) {
             return getDelegate().getClientById(id, realm);
         } else if (managedApplications.containsKey(id)) {
@@ -345,6 +345,12 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
         managedApplications.put(id, adapter);
         return adapter;
     }
+
+    @Override
+    public ClientModel getClientByClientId(String clientId, RealmModel realm) {
+        return getDelegate().getClientByClientId(clientId, realm);
+    }
+
     @Override
     public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
         CachedClientTemplate cached = cache.getClientTemplate(id);
@@ -357,7 +363,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (clientTemplateInvalidations.contains(id)) return model;
             cached = new CachedClientTemplate(cache, getDelegate(), realm, model);
-            cache.addCachedClientTemplate(cached);
+            cache.addClientTemplate(cached);
         } else if (clientTemplateInvalidations.contains(id)) {
             return getDelegate().getClientTemplateById(id, realm);
         } else if (managedClientTemplates.containsKey(id)) {
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java
index 3c65733..ac8f373 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java
@@ -138,11 +138,11 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
                 realmLookup.remove(realm.getName());
 
                 for (String r : realm.getRealmRoles().values()) {
-                    realmCache.evictCachedRoleById(r);
+                    realmCache.evictRoleById(r);
                 }
 
                 for (String c : realm.getClients().values()) {
-                    realmCache.evictCachedApplicationById(c);
+                    realmCache.evictClientById(c);
                 }
 
                 log.tracev("Realm removed realm={0}", realm.getName());
@@ -150,7 +150,7 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
                 CachedClient client = (CachedClient) object;
 
                 for (String r : client.getRoles().values()) {
-                    realmCache.evictCachedRoleById(r);
+                    realmCache.evictRoleById(r);
                 }
 
                 log.tracev("Client removed client={0}", client.getId());
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
index 4f89237..8dfe923 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
@@ -53,61 +53,61 @@ public class InfinispanRealmCache implements RealmCache {
     }
 
     @Override
-    public CachedRealm getCachedRealm(String id) {
+    public CachedRealm getRealm(String id) {
         return get(id, CachedRealm.class);
     }
 
     @Override
-    public void invalidateCachedRealm(CachedRealm realm) {
+    public void invalidateRealm(CachedRealm realm) {
         logger.tracev("Invalidating realm {0}", realm.getId());
         cache.remove(realm.getId());
         realmLookup.remove(realm.getName());
     }
 
     @Override
-    public void invalidateCachedRealmById(String id) {
+    public void invalidateRealmById(String id) {
         CachedRealm cached = (CachedRealm) cache.remove(id);
         if (cached != null) realmLookup.remove(cached.getName());
     }
 
     @Override
-    public void addCachedRealm(CachedRealm realm) {
+    public void addRealm(CachedRealm realm) {
         logger.tracev("Adding realm {0}", realm.getId());
         cache.putForExternalRead(realm.getId(), realm);
         realmLookup.put(realm.getName(), realm.getId());
     }
 
     @Override
-    public CachedRealm getCachedRealmByName(String name) {
+    public CachedRealm getRealmByName(String name) {
         String id = realmLookup.get(name);
-        return id != null ? getCachedRealm(id) : null;
+        return id != null ? getRealm(id) : null;
     }
 
     @Override
-    public CachedClient getApplication(String id) {
+    public CachedClient getClient(String id) {
         return get(id, CachedClient.class);
     }
 
     @Override
-    public void invalidateApplication(CachedClient app) {
+    public void invalidateClient(CachedClient app) {
         logger.tracev("Removing application {0}", app.getId());
         cache.remove(app.getId());
     }
 
     @Override
-    public void addCachedClient(CachedClient app) {
+    public void addClient(CachedClient app) {
         logger.tracev("Adding application {0}", app.getId());
         cache.putForExternalRead(app.getId(), app);
     }
 
     @Override
-    public void invalidateCachedApplicationById(String id) {
+    public void invalidateClientById(String id) {
         logger.tracev("Removing application {0}", id);
         cache.remove(id);
     }
 
     @Override
-    public void evictCachedApplicationById(String id) {
+    public void evictClientById(String id) {
         logger.tracev("Evicting application {0}", id);
         cache.evict(id);
     }
@@ -124,19 +124,12 @@ public class InfinispanRealmCache implements RealmCache {
     }
 
     @Override
-    public void addCachedGroup(CachedGroup role) {
+    public void addGroup(CachedGroup role) {
         logger.tracev("Adding group {0}", role.getId());
         cache.putForExternalRead(role.getId(), role);
     }
 
     @Override
-    public void invalidateCachedGroupById(String id) {
-        logger.tracev("Removing group {0}", id);
-        cache.remove(id);
-
-    }
-
-    @Override
     public void invalidateGroupById(String id) {
         logger.tracev("Removing group {0}", id);
         cache.remove(id);
@@ -160,23 +153,17 @@ public class InfinispanRealmCache implements RealmCache {
     }
 
     @Override
-    public void evictCachedRoleById(String id) {
+    public void evictRoleById(String id) {
         logger.tracev("Evicting role {0}", id);
         cache.evict(id);
     }
 
     @Override
-    public void addCachedRole(CachedRole role) {
+    public void addRole(CachedRole role) {
         logger.tracev("Adding role {0}", role.getId());
         cache.putForExternalRead(role.getId(), role);
     }
 
-    @Override
-    public void invalidateCachedRoleById(String id) {
-        logger.tracev("Removing role {0}", id);
-        cache.remove(id);
-    }
-
     private <T> T get(String id, Class<T> type) {
         Object o = cache.get(id);
         return o != null && type.isInstance(o) ? type.cast(o) : null;
@@ -194,19 +181,19 @@ public class InfinispanRealmCache implements RealmCache {
     }
 
     @Override
-    public void addCachedClientTemplate(CachedClientTemplate app) {
+    public void addClientTemplate(CachedClientTemplate app) {
         logger.tracev("Adding client template {0}", app.getId());
         cache.putForExternalRead(app.getId(), app);
     }
 
     @Override
-    public void invalidateCachedClientTemplateById(String id) {
+    public void invalidateClientTemplateById(String id) {
         logger.tracev("Removing client template {0}", id);
         cache.remove(id);
     }
 
     @Override
-    public void evictCachedClientTemplateById(String id) {
+    public void evictClientTemplateById(String id) {
         logger.tracev("Evicting client template {0}", id);
         cache.evict(id);
     }
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProvider.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProvider.java
index 162a36a..a15f4f1 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProvider.java
@@ -132,7 +132,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
 
     protected void runInvalidations() {
         for (String id : realmInvalidations) {
-            cache.invalidateCachedRealmById(id);
+            cache.invalidateRealmById(id);
         }
         for (String id : roleInvalidations) {
             cache.invalidateRoleById(id);
@@ -141,10 +141,10 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             cache.invalidateGroupById(id);
         }
         for (String id : appInvalidations) {
-            cache.invalidateCachedApplicationById(id);
+            cache.invalidateClientById(id);
         }
         for (String id : clientTemplateInvalidations) {
-            cache.invalidateCachedClientTemplateById(id);
+            cache.invalidateClientTemplateById(id);
         }
     }
 
@@ -271,7 +271,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public RealmModel getRealm(String id) {
-        CachedRealm cached = cache.getCachedRealm(id);
+        CachedRealm cached = cache.getRealm(id);
         if (cached != null) {
             logger.tracev("by id cache hit: {0}", cached.getName());
         }
@@ -282,7 +282,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (realmInvalidations.contains(id)) return model;
             cached = new RevisionedCachedRealm(loaded, cache, this, model);
-            cache.addCachedRealm(cached);
+            cache.addRealm(cached);
         } else if (realmInvalidations.contains(id)) {
             return getDelegate().getRealm(id);
         } else if (managedRealms.containsKey(id)) {
@@ -295,7 +295,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public RealmModel getRealmByName(String name) {
-        CachedRealm cached = cache.getCachedRealmByName(name);
+        CachedRealm cached = cache.getRealmByName(name);
         if (cached != null) {
             logger.tracev("by name cache hit: {0}", cached.getName());
         }
@@ -305,7 +305,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (realmInvalidations.contains(model.getId())) return model;
             cached = new RevisionedCachedRealm(loaded, cache, this, model);
-            cache.addCachedRealm(cached);
+            cache.addRealm(cached);
         } else if (realmInvalidations.contains(cached.getId())) {
             return getDelegate().getRealmByName(name);
         } else if (managedRealms.containsKey(cached.getId())) {
@@ -332,7 +332,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public boolean removeRealm(String id) {
-        cache.invalidateCachedRealmById(id);
+        cache.invalidateRealmById(id);
 
         RealmModel realm = getDelegate().getRealm(id);
         Set<RoleModel> realmRoles = null;
@@ -376,7 +376,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             } else {
                 cached = new RevisionedCachedRealmRole(loaded, model, realm);
             }
-            cache.addCachedRole(cached);
+            cache.addRole(cached);
 
         } else if (roleInvalidations.contains(id)) {
             return getDelegate().getRoleById(id, realm);
@@ -402,7 +402,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (groupInvalidations.contains(id)) return model;
             cached = new RevisionedCachedGroup(loaded, realm, model);
-            cache.addCachedGroup(cached);
+            cache.addGroup(cached);
 
         } else if (groupInvalidations.contains(id)) {
             return getDelegate().getGroupById(id, realm);
@@ -416,11 +416,11 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public ClientModel getClientById(String id, RealmModel realm) {
-        CachedClient cached = cache.getApplication(id);
+        CachedClient cached = cache.getClient(id);
         if (cached != null && !cached.getRealm().equals(realm.getId())) {
             cached = null;
         }
-        if (cached != null && cached.getClientId().equals("client")) {
+        if (cached != null) {
             logger.tracev("client by id cache hit: {0}", cached.getClientId());
         }
 
@@ -431,7 +431,8 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (appInvalidations.contains(id)) return model;
             cached = new RevisionedCachedClient(loaded, cache, getDelegate(), realm, model);
-            cache.addCachedClient(cached);
+            logger.tracev("adding client by id cache miss: {0}", cached.getClientId());
+            cache.addClient(cached);
         } else if (appInvalidations.contains(id)) {
             return getDelegate().getClientById(id, realm);
         } else if (managedApplications.containsKey(id)) {
@@ -441,6 +442,36 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
         managedApplications.put(id, adapter);
         return adapter;
     }
+
+    @Override
+    public ClientModel getClientByClientId(String clientId, RealmModel realm) {
+        CachedClient cached = cache.getClientByClientId(clientId);
+        if (cached != null && !cached.getRealm().equals(realm.getId())) {
+            cached = null;
+        }
+        if (cached != null) {
+            logger.tracev("client by name cache hit: {0}", cached.getClientId());
+        }
+
+        if (cached == null) {
+            Long loaded = UpdateCounter.current();
+            if (loaded == null) loaded = UpdateCounter.current();
+            ClientModel model = getDelegate().getClientByClientId(clientId, realm);
+            if (model == null) return null;
+            if (appInvalidations.contains(model.getId())) return model;
+            cached = new RevisionedCachedClient(loaded, cache, getDelegate(), realm, model);
+            logger.tracev("adding client by name cache miss: {0}", cached.getClientId());
+            cache.addClient(cached);
+        } else if (appInvalidations.contains(cached.getId())) {
+            return getDelegate().getClientById(cached.getId(), realm);
+        } else if (managedApplications.containsKey(cached.getId())) {
+            return managedApplications.get(cached.getId());
+        }
+        ClientAdapter adapter = new ClientAdapter(realm, cached, this, cache);
+        managedApplications.put(cached.getId(), adapter);
+        return adapter;
+    }
+
     @Override
     public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
         CachedClientTemplate cached = cache.getClientTemplate(id);
@@ -455,7 +486,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
             if (model == null) return null;
             if (clientTemplateInvalidations.contains(id)) return model;
             cached = new RevisionedCachedClientTemplate(loaded, cache, getDelegate(), realm, model);
-            cache.addCachedClientTemplate(cached);
+            cache.addClientTemplate(cached);
         } else if (clientTemplateInvalidations.contains(id)) {
             return getDelegate().getClientTemplateById(id, realm);
         } else if (managedClientTemplates.containsKey(id)) {
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java
index f143ea3..6723048 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java
@@ -37,8 +37,6 @@ import org.keycloak.models.cache.CacheRealmProviderFactory;
 import org.keycloak.models.cache.entities.CachedClient;
 import org.keycloak.models.cache.entities.CachedRealm;
 
-import java.util.concurrent.ConcurrentHashMap;
-
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -49,8 +47,6 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
 
     protected volatile LockingRealmCache realmCache;
 
-    protected final ConcurrentHashMap<String, String> realmLookup = new ConcurrentHashMap<>();
-
     @Override
     public CacheRealmProvider create(KeycloakSession session) {
         lazyInit(session);
@@ -64,7 +60,7 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
                     Cache<String, Object> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
                     Cache<String, Long> counterCache = session.getProvider(InfinispanConnectionProvider.class).getCache(LockingConnectionProviderFactory.VERSION_CACHE_NAME);
                     cache.addListener(new CacheListener());
-                    realmCache = new LockingRealmCache(cache, counterCache, realmLookup);
+                    realmCache = new LockingRealmCache(cache, counterCache);
                 }
             }
         }
@@ -98,7 +94,7 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
                 if (object != null) {
                     if (object instanceof CachedRealm) {
                         CachedRealm realm = (CachedRealm) object;
-                        realmLookup.put(realm.getName(), realm.getId());
+                        realmCache.getRealmLookup().put(realm.getName(), realm.getId());
                         log.tracev("Realm added realm={0}", realm.getName());
                     }
                 }
@@ -136,14 +132,14 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
             if (object instanceof CachedRealm) {
                 CachedRealm realm = (CachedRealm) object;
 
-                realmLookup.remove(realm.getName());
+                realmCache.getRealmLookup().remove(realm.getName());
 
                 for (String r : realm.getRealmRoles().values()) {
-                    realmCache.evictCachedRoleById(r);
+                    realmCache.evictRoleById(r);
                 }
 
                 for (String c : realm.getClients().values()) {
-                    realmCache.evictCachedApplicationById(c);
+                    realmCache.evictClientById(c);
                 }
 
                 log.tracev("Realm removed realm={0}", realm.getName());
@@ -151,7 +147,7 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
                 CachedClient client = (CachedClient) object;
 
                 for (String r : client.getRoles().values()) {
-                    realmCache.evictCachedRoleById(r);
+                    realmCache.evictRoleById(r);
                 }
 
                 log.tracev("Client removed client={0}", client.getId());
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingRealmCache.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingRealmCache.java
index 2460502..5b3060d 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingRealmCache.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingRealmCache.java
@@ -27,7 +27,6 @@ import org.keycloak.models.cache.entities.CachedRealm;
 import org.keycloak.models.cache.entities.CachedRole;
 
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -39,11 +38,11 @@ public class LockingRealmCache implements RealmCache {
     protected final Cache<String, Long> revisions;
     protected final Cache<String, Object> cache;
 
-    protected final ConcurrentHashMap<String, String> realmLookup;
+    protected final ConcurrentHashMap<String, String> realmLookup = new ConcurrentHashMap<>();
+    protected final ConcurrentHashMap<String, String> clientLookup = new ConcurrentHashMap<>();
 
-    public LockingRealmCache(Cache<String, Object> cache, Cache<String, Long> revisions, ConcurrentHashMap<String, String> realmLookup) {
+    public LockingRealmCache(Cache<String, Object> cache, Cache<String, Long> revisions) {
         this.cache = cache;
-        this.realmLookup = realmLookup;
         this.revisions = revisions;
     }
 
@@ -55,6 +54,14 @@ public class LockingRealmCache implements RealmCache {
         return revisions;
     }
 
+    public ConcurrentHashMap<String, String> getRealmLookup() {
+        return realmLookup;
+    }
+
+    public ConcurrentHashMap<String, String> getClientLookup() {
+        return clientLookup;
+    }
+
     public Long getCurrentRevision(String id) {
         return revisions.get(id);
     }
@@ -133,25 +140,25 @@ public class LockingRealmCache implements RealmCache {
     }
 
     @Override
-    public CachedRealm getCachedRealm(String id) {
+    public CachedRealm getRealm(String id) {
         return get(id, CachedRealm.class);
     }
 
     @Override
-    public void invalidateCachedRealm(CachedRealm realm) {
+    public void invalidateRealm(CachedRealm realm) {
         logger.tracev("Invalidating realm {0}", realm.getId());
         invalidateObject(realm.getId());
         realmLookup.remove(realm.getName());
     }
 
     @Override
-    public void invalidateCachedRealmById(String id) {
+    public void invalidateRealmById(String id) {
         CachedRealm cached = (CachedRealm) invalidateObject(id);
         if (cached != null) realmLookup.remove(cached.getName());
     }
 
     @Override
-    public void addCachedRealm(CachedRealm realm) {
+    public void addRealm(CachedRealm realm) {
         logger.tracev("Adding realm {0}", realm.getId());
         addRevisioned(realm.getId(), (Revisioned) realm);
         realmLookup.put(realm.getName(), realm.getId());
@@ -159,36 +166,46 @@ public class LockingRealmCache implements RealmCache {
 
 
     @Override
-    public CachedRealm getCachedRealmByName(String name) {
+    public CachedRealm getRealmByName(String name) {
         String id = realmLookup.get(name);
-        return id != null ? getCachedRealm(id) : null;
+        return id != null ? getRealm(id) : null;
     }
 
     @Override
-    public CachedClient getApplication(String id) {
+    public CachedClient getClient(String id) {
         return get(id, CachedClient.class);
     }
 
+    public CachedClient getClientByClientId(String clientId) {
+        String id = clientLookup.get(clientId);
+        return id != null ? getClient(id) : null;
+    }
+
     @Override
-    public void invalidateApplication(CachedClient app) {
+    public void invalidateClient(CachedClient app) {
         logger.tracev("Removing application {0}", app.getId());
         invalidateObject(app.getId());
+        clientLookup.remove(app.getClientId());
     }
 
     @Override
-    public void addCachedClient(CachedClient app) {
+    public void addClient(CachedClient app) {
         logger.tracev("Adding application {0}", app.getId());
         addRevisioned(app.getId(), (Revisioned) app);
+        clientLookup.put(app.getClientId(), app.getId());
     }
 
     @Override
-    public void invalidateCachedApplicationById(String id) {
+    public void invalidateClientById(String id) {
         CachedClient client = (CachedClient)invalidateObject(id);
-        if (client != null) logger.tracev("Removing application {0}", client.getClientId());
+        if (client != null) {
+            logger.tracev("Removing application {0}", client.getClientId());
+            clientLookup.remove(client.getClientId());
+        }
     }
 
     @Override
-    public void evictCachedApplicationById(String id) {
+    public void evictClientById(String id) {
         logger.tracev("Evicting application {0}", id);
         cache.evict(id);
     }
@@ -205,19 +222,12 @@ public class LockingRealmCache implements RealmCache {
     }
 
     @Override
-    public void addCachedGroup(CachedGroup role) {
+    public void addGroup(CachedGroup role) {
         logger.tracev("Adding group {0}", role.getId());
         addRevisioned(role.getId(), (Revisioned) role);
     }
 
     @Override
-    public void invalidateCachedGroupById(String id) {
-        logger.tracev("Removing group {0}", id);
-        invalidateObject(id);
-
-    }
-
-    @Override
     public void invalidateGroupById(String id) {
         logger.tracev("Removing group {0}", id);
         invalidateObject(id);
@@ -241,24 +251,18 @@ public class LockingRealmCache implements RealmCache {
     }
 
     @Override
-    public void evictCachedRoleById(String id) {
+    public void evictRoleById(String id) {
         logger.tracev("Evicting role {0}", id);
         cache.evict(id);
     }
 
     @Override
-    public void addCachedRole(CachedRole role) {
+    public void addRole(CachedRole role) {
         logger.tracev("Adding role {0}", role.getId());
         addRevisioned(role.getId(), (Revisioned) role);
     }
 
     @Override
-    public void invalidateCachedRoleById(String id) {
-        logger.tracev("Removing role {0}", id);
-        invalidateObject(id);
-    }
-
-    @Override
     public CachedClientTemplate getClientTemplate(String id) {
         return get(id, CachedClientTemplate.class);
     }
@@ -270,19 +274,19 @@ public class LockingRealmCache implements RealmCache {
     }
 
     @Override
-    public void addCachedClientTemplate(CachedClientTemplate app) {
+    public void addClientTemplate(CachedClientTemplate app) {
         logger.tracev("Adding client template {0}", app.getId());
         addRevisioned(app.getId(), (Revisioned) app);
     }
 
     @Override
-    public void invalidateCachedClientTemplateById(String id) {
+    public void invalidateClientTemplateById(String id) {
         logger.tracev("Removing client template {0}", id);
         invalidateObject(id);
     }
 
     @Override
-    public void evictCachedClientTemplateById(String id) {
+    public void evictClientTemplateById(String id) {
         logger.tracev("Evicting client template {0}", id);
         cache.evict(id);
     }
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java
index 41dc8d8..14e2850 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java
@@ -415,6 +415,9 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public PublicKey getPublicKey() {
+        if (updated != null) return updated.getPublicKey();
+        if (publicKey != null) return publicKey;
+        publicKey = cached.getPublicKey();
         if (publicKey != null) return publicKey;
         publicKey = KeycloakModelUtils.getPublicKey(getPublicKeyPem());
         return publicKey;
@@ -429,6 +432,9 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public X509Certificate getCertificate() {
+        if (updated != null) return updated.getCertificate();
+        if (certificate != null) return certificate;
+        certificate = cached.getCertificate();
         if (certificate != null) return certificate;
         certificate = KeycloakModelUtils.getCertificate(getCertificatePem());
         return certificate;
@@ -456,7 +462,14 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public PrivateKey getPrivateKey() {
-        if (privateKey != null) return privateKey;
+        if (updated != null) return updated.getPrivateKey();
+        if (privateKey != null) {
+            return privateKey;
+        }
+        privateKey = cached.getPrivateKey();
+        if (privateKey != null) {
+            return privateKey;
+        }
         privateKey = KeycloakModelUtils.getPrivateKey(getPrivateKeyPem());
         return privateKey;
     }
@@ -635,10 +648,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public ClientModel getClientByClientId(String clientId) {
-        if (updated != null) return updated.getClientByClientId(clientId);
-        String id = cached.getClients().get(clientId);
-        if (id == null) return null;
-        return getClientById(id);
+        return cacheSession.getClientByClientId(clientId, this);
     }
 
     @Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index 15544c6..5466a77 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -50,6 +50,8 @@ import java.util.Set;
 @Table(name="CLIENT", uniqueConstraints = {@UniqueConstraint(columnNames = {"REALM_ID", "CLIENT_ID"})})
 @NamedQueries({
         @NamedQuery(name="getClientsByRealm", query="select client from ClientEntity client where client.realm = :realm"),
+        @NamedQuery(name="findClientIdByClientId", query="select client.id from ClientEntity client where client.clientId = :clientId and client.realm.id = :realm"),
+        @NamedQuery(name="findClientByClientId", query="select client from ClientEntity client where client.clientId = :clientId and client.realm.id = :realm"),
 })
 public class ClientEntity {
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
index 86bc5a2..55b6087 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
@@ -177,6 +177,17 @@ public class JpaRealmProvider implements RealmProvider {
     }
 
     @Override
+    public ClientModel getClientByClientId(String clientId, RealmModel realm) {
+        TypedQuery<ClientEntity> query = em.createNamedQuery("findClientByClientId", ClientEntity.class);
+        query.setParameter("clientId", clientId);
+        query.setParameter("realm", realm.getId());
+        List<ClientEntity> results = query.getResultList();
+        if (results.isEmpty()) return null;
+        ClientEntity entity = results.get(0);
+        return new ClientAdapter(realm, em, session, entity);
+    }
+
+    @Override
     public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
         ClientTemplateEntity app = em.find(ClientTemplateEntity.class, id);
 
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index 4d632ec..eb03e53 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -811,7 +811,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public ClientModel getClientByClientId(String clientId) {
-        return getClientNameMap().get(clientId);
+        return session.realms().getClientByClientId(clientId, this);
     }
 
     private static final String BROWSER_HEADER_PREFIX = "_browser_header.";
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
index 323bbbe..ddfbdef 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoRealmProvider.java
@@ -163,6 +163,17 @@ public class MongoRealmProvider implements RealmProvider {
     }
 
     @Override
+    public ClientModel getClientByClientId(String clientId, RealmModel realm) {
+        DBObject query = new QueryBuilder()
+                .and("realmId").is(realm.getId())
+                .and("clientId").is(clientId)
+                .get();
+        MongoClientEntity appEntity = getMongoStore().loadSingleEntity(MongoClientEntity.class, query, invocationContext);
+        return appEntity == null ? null : new ClientAdapter(session, realm, appEntity, invocationContext);
+
+    }
+
+    @Override
     public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
         MongoClientTemplateEntity appData = getMongoStore().loadEntity(MongoClientTemplateEntity.class, id, invocationContext);
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index bae4589..ca7626c 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -807,12 +807,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
 
     @Override
     public ClientModel getClientByClientId(String clientId) {
-        DBObject query = new QueryBuilder()
-                .and("realmId").is(getId())
-                .and("clientId").is(clientId)
-                .get();
-        MongoClientEntity appEntity = getMongoStore().loadSingleEntity(MongoClientEntity.class, query, invocationContext);
-        return appEntity == null ? null : new ClientAdapter(session, this, appEntity, invocationContext);
+        return session.realms().getClientByClientId(clientId, this);
     }
 
     @Override
diff --git a/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index ca3e35b..727cabc 100755
--- a/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -127,7 +127,7 @@ public class CachedClient implements Serializable {
     protected void cacheRoles(RealmCache cache, RealmModel realm, ClientModel model) {
         for (RoleModel role : model.getRoles()) {
             roles.put(role.getName(), role.getId());
-            cache.addCachedRole(new CachedClientRole(id, role, realm));
+            cache.addRole(new CachedClientRole(id, role, realm));
         }
     }
 
diff --git a/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
index 42ed3bc..29b9331 100755
--- a/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
+++ b/server-spi/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java
@@ -39,6 +39,10 @@ import org.keycloak.models.cache.RealmCache;
 import org.keycloak.common.util.MultivaluedHashMap;
 
 import java.io.Serializable;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -89,8 +93,11 @@ public class CachedRealm implements Serializable {
     protected PasswordPolicy passwordPolicy;
     protected OTPPolicy otpPolicy;
 
+    protected transient PublicKey publicKey;
     protected String publicKeyPem;
+    protected transient PrivateKey privateKey;
     protected String privateKeyPem;
+    protected transient X509Certificate certificate;
     protected String certificatePem;
     protected String codeSecret;
 
@@ -179,8 +186,11 @@ public class CachedRealm implements Serializable {
         otpPolicy = model.getOTPPolicy();
 
         publicKeyPem = model.getPublicKeyPem();
+        publicKey = model.getPublicKey();
         privateKeyPem = model.getPrivateKeyPem();
+        privateKey = model.getPrivateKey();
         certificatePem = model.getCertificatePem();
+        certificate = model.getCertificate();
         codeSecret = model.getCodeSecret();
 
         loginTheme = model.getLoginTheme();
@@ -265,7 +275,7 @@ public class CachedRealm implements Serializable {
         for (ClientTemplateModel template : model.getClientTemplates()) {
             clientTemplates.add(template.getId());
             CachedClientTemplate cachedClient = new CachedClientTemplate(cache, delegate, model, template);
-            cache.addCachedClientTemplate(cachedClient);
+            cache.addClientTemplate(cachedClient);
         }
     }
 
@@ -273,7 +283,7 @@ public class CachedRealm implements Serializable {
         for (ClientModel client : model.getClients()) {
             clients.put(client.getClientId(), client.getId());
             CachedClient cachedClient = new CachedClient(cache, delegate, model, client);
-            cache.addCachedClient(cachedClient);
+            cache.addClient(cachedClient);
         }
     }
 
@@ -281,7 +291,7 @@ public class CachedRealm implements Serializable {
         for (RoleModel role : model.getRoles()) {
             realmRoles.put(role.getName(), role.getId());
             CachedRole cachedRole = new CachedRealmRole(role, model);
-            cache.addCachedRole(cachedRole);
+            cache.addRole(cachedRole);
         }
     }
 
@@ -584,4 +594,16 @@ public class CachedRealm implements Serializable {
     public List<String> getClientTemplates() {
         return clientTemplates;
     }
+
+    public PublicKey getPublicKey() {
+        return publicKey;
+    }
+
+    public PrivateKey getPrivateKey() {
+        return privateKey;
+    }
+
+    public X509Certificate getCertificate() {
+        return certificate;
+    }
 }
diff --git a/server-spi/src/main/java/org/keycloak/models/cache/RealmCache.java b/server-spi/src/main/java/org/keycloak/models/cache/RealmCache.java
index 909223b..2b7b339 100755
--- a/server-spi/src/main/java/org/keycloak/models/cache/RealmCache.java
+++ b/server-spi/src/main/java/org/keycloak/models/cache/RealmCache.java
@@ -30,35 +30,33 @@ import org.keycloak.models.cache.entities.CachedRole;
 public interface RealmCache {
     void clear();
 
-    CachedRealm getCachedRealm(String id);
+    CachedRealm getRealm(String id);
 
-    void invalidateCachedRealm(CachedRealm realm);
+    void invalidateRealm(CachedRealm realm);
 
-    void addCachedRealm(CachedRealm realm);
+    void addRealm(CachedRealm realm);
 
-    CachedRealm getCachedRealmByName(String name);
+    CachedRealm getRealmByName(String name);
 
-    void invalidateCachedRealmById(String id);
+    void invalidateRealmById(String id);
 
-    CachedClient getApplication(String id);
+    CachedClient getClient(String id);
 
-    void invalidateApplication(CachedClient app);
+    void invalidateClient(CachedClient app);
 
-    void evictCachedApplicationById(String id);
+    void evictClientById(String id);
 
-    void addCachedClient(CachedClient app);
+    void addClient(CachedClient app);
 
-    void invalidateCachedApplicationById(String id);
+    void invalidateClientById(String id);
 
     CachedRole getRole(String id);
 
     void invalidateRole(CachedRole role);
 
-    void evictCachedRoleById(String id);
+    void evictRoleById(String id);
 
-    void addCachedRole(CachedRole role);
-
-    void invalidateCachedRoleById(String id);
+    void addRole(CachedRole role);
 
     void invalidateRoleById(String id);
 
@@ -66,9 +64,7 @@ public interface RealmCache {
 
     void invalidateGroup(CachedGroup role);
 
-    void addCachedGroup(CachedGroup role);
-
-    void invalidateCachedGroupById(String id);
+    void addGroup(CachedGroup role);
 
     void invalidateGroupById(String id);
 
@@ -76,10 +72,10 @@ public interface RealmCache {
 
     void invalidateClientTemplate(CachedClientTemplate app);
 
-    void evictCachedClientTemplateById(String id);
+    void evictClientTemplateById(String id);
 
-    void addCachedClientTemplate(CachedClientTemplate app);
+    void addClientTemplate(CachedClientTemplate app);
 
-    void invalidateCachedClientTemplateById(String id);
+    void invalidateClientTemplateById(String id);
 
 }
diff --git a/server-spi/src/main/java/org/keycloak/models/RealmProvider.java b/server-spi/src/main/java/org/keycloak/models/RealmProvider.java
index ad9e2d1..59568a3 100755
--- a/server-spi/src/main/java/org/keycloak/models/RealmProvider.java
+++ b/server-spi/src/main/java/org/keycloak/models/RealmProvider.java
@@ -35,8 +35,11 @@ public interface RealmProvider extends Provider {
     RealmModel getRealm(String id);
     RealmModel getRealmByName(String name);
 
-    RoleModel getRoleById(String id, RealmModel realm);
     ClientModel getClientById(String id, RealmModel realm);
+    ClientModel getClientByClientId(String clientId, RealmModel realm);
+
+
+    RoleModel getRoleById(String id, RealmModel realm);
     ClientTemplateModel getClientTemplateById(String id, RealmModel realm);
     GroupModel getGroupById(String id, RealmModel realm);
 
diff --git a/testsuite/stress/src/main/java/org/keycloak/test/stress/MaxRateExecutor.java b/testsuite/stress/src/main/java/org/keycloak/test/stress/MaxRateExecutor.java
index c1f0a6b..cfc9cd5 100755
--- a/testsuite/stress/src/main/java/org/keycloak/test/stress/MaxRateExecutor.java
+++ b/testsuite/stress/src/main/java/org/keycloak/test/stress/MaxRateExecutor.java
@@ -88,9 +88,9 @@ public class MaxRateExecutor {
             StressTest stressTest = future.get();
             if (i < jobs - threads - 5) completionService.submit(stressTest);
         }
+        long end = System.currentTimeMillis() - start;
         executor.shutdown();
         executor.awaitTermination(10, TimeUnit.SECONDS);
-        long end = System.currentTimeMillis() - start;
         RateResult rate = new RateResult(result, threads, end);
         return rate;
     }
@@ -116,10 +116,10 @@ public class MaxRateExecutor {
     public void printResult(RateResult result) {
         System.out.println("Threads: " + result.getThreads());
         System.out.println("Total Time: " + result.getTime());
+        System.out.println("Rate: " + ((double)result.getResult().getIterations()) / ((double)result.getTime()));
         System.out.println("Successes: " + result.getResult().getSuccess());
         System.out.println("Iterations: " + result.getResult().getIterations());
-        System.out.println("Average time: " + result.getResult().getAverageTime());
-        System.out.println("Rate: " + result.getResult().getRate());
+        System.out.println("Average time per iteration: " + result.getResult().getAverageTime());
 
     }
 
@@ -127,7 +127,7 @@ public class MaxRateExecutor {
 
         for (RateResult result : allResults) {
             System.out.println("*******************");
-            printSummary();
+            printSummary(result);
         }
     }
     public void printSummary(RateResult result) {
diff --git a/testsuite/stress/src/test/java/org/keycloak/test/LoginLogoutTest.java b/testsuite/stress/src/test/java/org/keycloak/test/LoginLogoutTest.java
index 1348c64..351f8f4 100755
--- a/testsuite/stress/src/test/java/org/keycloak/test/LoginLogoutTest.java
+++ b/testsuite/stress/src/test/java/org/keycloak/test/LoginLogoutTest.java
@@ -88,8 +88,9 @@ Rate: 0.030480835174883793
             }
         };
         MaxRateExecutor executor = new MaxRateExecutor();
-        executor.best(factory, 4);
+        executor.best(factory, 10);
         executor.printResults();
+        executor.printSummary();
     }
 
 }