keycloak-memoizeit

Details

diff --git a/distribution/demo-dist/src/main/xslt/standalone.xsl b/distribution/demo-dist/src/main/xslt/standalone.xsl
index 94dd49c..4a18a1d 100755
--- a/distribution/demo-dist/src/main/xslt/standalone.xsl
+++ b/distribution/demo-dist/src/main/xslt/standalone.xsl
@@ -90,9 +90,6 @@
                 <local-cache name="offlineSessions"/>
                 <local-cache name="loginFailures"/>
                 <local-cache name="work"/>
-                <local-cache name="realmVersions">
-                    <transaction mode="BATCH" locking="PESSIMISTIC"/>
-                </local-cache>
             </cache-container>
             <xsl:apply-templates select="node()|@*"/>
         </xsl:copy>
diff --git a/distribution/server-overlay/cli/keycloak-install-ha.cli b/distribution/server-overlay/cli/keycloak-install-ha.cli
index e0ad848..4b8d399 100644
--- a/distribution/server-overlay/cli/keycloak-install-ha.cli
+++ b/distribution/server-overlay/cli/keycloak-install-ha.cli
@@ -8,7 +8,5 @@ embed-server --server-config=standalone-ha.xml
 /subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(mode="SYNC",owners="1")
 /subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(mode="SYNC",owners="1")
 /subsystem=infinispan/cache-container=keycloak/replicated-cache=work:add(mode="SYNC")
-/subsystem=infinispan/cache-container=keycloak/local-cache=realmVersions:add()
-/subsystem=infinispan/cache-container=keycloak/local-cache=realmVersions/transaction=TRANSACTION:add(mode=BATCH,locking=PESSIMISTIC)
 /extension=org.keycloak.keycloak-server-subsystem/:add(module=org.keycloak.keycloak-server-subsystem)
 /subsystem=keycloak-server:add(web-context=auth)
\ No newline at end of file
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
index c9311bd..3bad384 100755
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/DefaultInfinispanConnectionProviderFactory.java
@@ -21,6 +21,7 @@ import org.infinispan.configuration.cache.CacheMode;
 import org.infinispan.configuration.cache.Configuration;
 import org.infinispan.configuration.cache.ConfigurationBuilder;
 import org.infinispan.configuration.global.GlobalConfigurationBuilder;
+import org.infinispan.eviction.EvictionStrategy;
 import org.infinispan.eviction.EvictionType;
 import org.infinispan.manager.DefaultCacheManager;
 import org.infinispan.manager.EmbeddedCacheManager;
@@ -97,6 +98,17 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
             cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
             containerManaged = true;
 
+            cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(true, InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX));
+            cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME, true);
+
+            long maxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+            if (maxEntries <= 0) {
+                maxEntries = InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
+            }
+
+            cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(true, maxEntries));
+            cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
+
             logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
         } catch (Exception e) {
             throw new RuntimeException("Failed to retrieve cache container", e);
@@ -162,12 +174,32 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
                 .transaction().transactionMode(TransactionMode.TRANSACTIONAL);
         counterConfigBuilder.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
         counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC);
-        Configuration counterCacheConfiguration = counterConfigBuilder.build();
 
-        cacheManager.defineConfiguration(InfinispanConnectionProvider.VERSION_CACHE_NAME, counterCacheConfiguration);
+        cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(false, InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX));
+        cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME, true);
 
         cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME,
                 new ConfigurationBuilder().eviction().type(EvictionType.COUNT).size(100).simpleCache(true).build());
+
+        long maxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
+        if (maxEntries <= 0) {
+            maxEntries = InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
+        }
+
+        cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(false, maxEntries));
+        cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
+    }
+
+    private Configuration getRevisionCacheConfig(boolean managed, long maxEntries) {
+        ConfigurationBuilder cb = new ConfigurationBuilder();
+        cb.invocationBatching().enable().transaction().transactionMode(TransactionMode.TRANSACTIONAL);
+        if (!managed) {
+            cb.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
+        }
+        cb.transaction().lockingMode(LockingMode.PESSIMISTIC);
+
+        cb.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(maxEntries);
+        return cb.build();
     }
 
 }
diff --git a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
index 0fc2bc0..143056c 100755
--- a/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
+++ b/model/infinispan/src/main/java/org/keycloak/connections/infinispan/InfinispanConnectionProvider.java
@@ -25,15 +25,21 @@ import org.keycloak.provider.Provider;
  */
 public interface InfinispanConnectionProvider extends Provider {
 
-    public static final String VERSION_CACHE_NAME = "realmVersions";
-    static final String REALM_CACHE_NAME = "realms";
-    static final String USER_CACHE_NAME = "users";
-    static final String SESSION_CACHE_NAME = "sessions";
-    static final String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
-    static final String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
-    static final String WORK_CACHE_NAME = "work";
+    String REALM_CACHE_NAME = "realms";
+    String REALM_REVISIONS_CACHE_NAME = "realmRevisions";
+    int REALM_REVISIONS_CACHE_DEFAULT_MAX = 10000;
+
+    String USER_CACHE_NAME = "users";
+    String USER_REVISIONS_CACHE_NAME = "userRevisions";
+    int USER_REVISIONS_CACHE_DEFAULT_MAX = 100000;
+
+    String SESSION_CACHE_NAME = "sessions";
+    String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
+    String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
+    String WORK_CACHE_NAME = "work";
     String AUTHORIZATION_CACHE_NAME = "authorization";
 
+
     <K, V> Cache<K, V> getCache(String name);
 
 }
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java
index e41913d..bf2b1c2 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java
@@ -139,6 +139,7 @@ public abstract class CacheManager {
 
     public void clear() {
         cache.clear();
+        revisions.clear();
     }
 
     public void addInvalidations(Predicate<Map.Entry<String, Revisioned>> predicate, Set<String> invalidations) {
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 f32ac69..40c4e09 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
@@ -48,7 +48,7 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
             synchronized (this) {
                 if (realmCache == null) {
                     Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
-                    Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.VERSION_CACHE_NAME);
+                    Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME);
                     realmCache = new RealmCacheManager(cache, revisions);
                 }
             }
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java
index 9e93d55..e0409b1 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java
@@ -55,7 +55,7 @@ public class InfinispanCacheUserProviderFactory implements CacheUserProviderFact
             synchronized (this) {
                 if (userCache == null) {
                     Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_CACHE_NAME);
-                    Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.VERSION_CACHE_NAME);
+                    Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME);
                     userCache = new UserCacheManager(cache, revisions);
                 }
             }
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheManager.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheManager.java
index e1fb79c..d3564d0 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheManager.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheManager.java
@@ -45,6 +45,7 @@ public class UserCacheManager extends CacheManager {
     @Override
     public void clear() {
         cache.clear();
+        revisions.clear();
     }
 
     @Override
diff --git a/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java b/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java
index 8b4840a..20b54ea 100755
--- a/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java
+++ b/wildfly/server-subsystem/src/main/java/org/keycloak/subsystem/server/extension/KeycloakServerDeploymentProcessor.java
@@ -63,7 +63,6 @@ public class KeycloakServerDeploymentProcessor implements DeploymentUnitProcesso
             st.addDependency(cacheContainerService.append("offlineSessions"));
             st.addDependency(cacheContainerService.append("loginFailures"));
             st.addDependency(cacheContainerService.append("work"));
-            st.addDependency(cacheContainerService.append("realmVersions"));
         }
     }
 
diff --git a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
index 96d4780..35b4229 100755
--- a/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
+++ b/wildfly/server-subsystem/src/main/resources/subsystem-templates/keycloak-infinispan.xml
@@ -33,9 +33,6 @@
                 <local-cache name="offlineSessions"/>
                 <local-cache name="loginFailures"/>
                 <local-cache name="work"/>
-                <local-cache name="realmVersions">
-                    <transaction mode="BATCH" locking="PESSIMISTIC"/>
-                </local-cache>
                 <local-cache name="authorization">
                     <eviction max-entries="100" strategy="LRU"/>
                 </local-cache>
@@ -99,9 +96,6 @@
                 <distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
                 <distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
                 <replicated-cache name="work" mode="SYNC" />
-                <local-cache name="realmVersions">
-                    <transaction mode="BATCH" locking="PESSIMISTIC"/>
-                </local-cache>
             </cache-container>
             <cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
                 <transport lock-timeout="60000"/>