diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSessionSpi.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSessionSpi.java
index f0b53a44e4..7e4e8e6144 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSessionSpi.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSessionSpi.java
@@ -12,7 +12,7 @@ public class CacheKeycloakSessionSpi implements Spi {
@Override
public String getName() {
- return "cacheKeycloakSession";
+ return "modelCache";
}
@Override
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheKeycloakSession.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheKeycloakSession.java
new file mode 100755
index 0000000000..afc35e30d3
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheKeycloakSession.java
@@ -0,0 +1,281 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.models.OAuthClientModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.RoleModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserModel;
+import org.keycloak.models.UserSessionModel;
+import org.keycloak.models.UsernameLoginFailureModel;
+import org.keycloak.models.cache.entities.CachedApplication;
+import org.keycloak.models.cache.entities.CachedApplicationRole;
+import org.keycloak.models.cache.entities.CachedOAuthClient;
+import org.keycloak.models.cache.entities.CachedRealm;
+import org.keycloak.models.cache.entities.CachedRealmRole;
+import org.keycloak.models.cache.entities.CachedRole;
+import org.keycloak.provider.ProviderSession;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class NoCacheKeycloakSession implements CacheKeycloakSession {
+ protected ProviderSession providerSession;
+ protected KeycloakSession sessionDelegate;
+ protected KeycloakTransaction transactionDelegate;
+ protected boolean transactionActive;
+ protected boolean setRollbackOnly;
+
+ public NoCacheKeycloakSession(ProviderSession providerSession) {
+ this.providerSession = providerSession;
+ }
+
+ @Override
+ public KeycloakSession getDelegate() {
+ if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
+ if (sessionDelegate != null) return sessionDelegate;
+ sessionDelegate = providerSession.getProvider(KeycloakSession.class);
+ transactionDelegate = sessionDelegate.getTransaction();
+ if (!transactionDelegate.isActive()) {
+ transactionDelegate.begin();
+ if (setRollbackOnly) {
+ transactionDelegate.setRollbackOnly();
+ }
+ }
+ return sessionDelegate;
+ }
+
+ @Override
+ public void registerRealmInvalidation(String id) {
+ }
+
+ @Override
+ public void registerApplicationInvalidation(String id) {
+ }
+
+ @Override
+ public void registerRoleInvalidation(String id) {
+ }
+
+ @Override
+ public void registerOAuthClientInvalidation(String id) {
+ }
+
+ @Override
+ public KeycloakTransaction getTransaction() {
+ return new KeycloakTransaction() {
+ @Override
+ public void begin() {
+ transactionActive = true;
+ }
+
+ @Override
+ public void commit() {
+ if (sessionDelegate == null) return;
+ try {
+ sessionDelegate.getTransaction().commit();
+ } finally {
+ }
+ }
+
+ @Override
+ public void rollback() {
+ setRollbackOnly = true;
+ if (sessionDelegate == null) return;
+ try {
+ sessionDelegate.getTransaction().rollback();
+ } finally {
+ }
+ }
+
+ @Override
+ public void setRollbackOnly() {
+ setRollbackOnly = true;
+ if (sessionDelegate == null) return;
+ sessionDelegate.getTransaction().setRollbackOnly();
+ setRollbackOnly = true;
+ }
+
+ @Override
+ public boolean getRollbackOnly() {
+ return setRollbackOnly;
+ }
+
+ @Override
+ public boolean isActive() {
+ return transactionActive;
+ }
+ };
+ }
+
+ @Override
+ public RealmModel createRealm(String name) {
+ return getDelegate().createRealm(name);
+ }
+
+ @Override
+ public RealmModel createRealm(String id, String name) {
+ return getDelegate().createRealm(id, name);
+ }
+
+ @Override
+ public RealmModel getRealm(String id) {
+ return getDelegate().getRealm(id);
+ }
+
+ @Override
+ public RealmModel getRealmByName(String name) {
+ return getDelegate().getRealmByName(name);
+ }
+
+ @Override
+ public UserModel getUserById(String id, RealmModel realm) {
+ return getDelegate().getUserById(id, realm);
+ }
+
+ @Override
+ public UserModel getUserByUsername(String username, RealmModel realm) {
+ return getDelegate().getUserByUsername(username, realm);
+ }
+
+ @Override
+ public UserModel getUserByEmail(String email, RealmModel realm) {
+ return getDelegate().getUserByEmail(email, realm);
+ }
+
+ @Override
+ public List getRealms() {
+ // we don't cache this for now
+ return getDelegate().getRealms();
+ }
+
+ @Override
+ public boolean removeRealm(String id) {
+ return getDelegate().removeRealm(id);
+ }
+
+ @Override
+ public void removeAllData() {
+ getDelegate().removeAllData();
+ }
+
+ @Override
+ public void close() {
+ if (sessionDelegate != null) sessionDelegate.close();
+ }
+
+ @Override
+ public UserModel getUserBySocialLink(SocialLinkModel socialLink, RealmModel realm) {
+ return getDelegate().getUserBySocialLink(socialLink, realm);
+ }
+
+ @Override
+ public List getUsers(RealmModel realm) {
+ return getDelegate().getUsers(realm);
+ }
+
+ @Override
+ public List searchForUser(String search, RealmModel realm) {
+ return getDelegate().searchForUser(search, realm);
+ }
+
+ @Override
+ public List searchForUserByAttributes(Map attributes, RealmModel realm) {
+ return getDelegate().searchForUserByAttributes(attributes, realm);
+ }
+
+ @Override
+ public Set getSocialLinks(UserModel user, RealmModel realm) {
+ return getDelegate().getSocialLinks(user, realm);
+ }
+
+ @Override
+ public SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm) {
+ return getDelegate().getSocialLink(user, socialProvider, realm);
+ }
+
+ @Override
+ public RoleModel getRoleById(String id, RealmModel realm) {
+ return getDelegate().getRoleById(id, realm);
+ }
+
+ @Override
+ public ApplicationModel getApplicationById(String id, RealmModel realm) {
+ return getDelegate().getApplicationById(id, realm);
+ }
+
+ @Override
+ public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
+ return getDelegate().getOAuthClientById(id, realm);
+ }
+
+ @Override
+ public UsernameLoginFailureModel getUserLoginFailure(String username, RealmModel realm) {
+ return getDelegate().getUserLoginFailure(username, realm);
+ }
+
+ @Override
+ public UsernameLoginFailureModel addUserLoginFailure(String username, RealmModel realm) {
+ return getDelegate().addUserLoginFailure(username, realm);
+ }
+
+ @Override
+ public List getAllUserLoginFailures(RealmModel realm) {
+ return getDelegate().getAllUserLoginFailures(realm);
+ }
+
+ @Override
+ public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
+ return getDelegate().createUserSession(realm, user, ipAddress);
+ }
+
+ @Override
+ public UserSessionModel getUserSession(String id, RealmModel realm) {
+ return getDelegate().getUserSession(id, realm);
+ }
+
+ @Override
+ public List getUserSessions(UserModel user, RealmModel realm) {
+ return getDelegate().getUserSessions(user, realm);
+ }
+
+ @Override
+ public Set getUserSessions(RealmModel realm, ClientModel client) {
+ return getDelegate().getUserSessions(realm, client);
+ }
+
+ @Override
+ public int getActiveUserSessions(RealmModel realm, ClientModel client) {
+ return getDelegate().getActiveUserSessions(realm, client);
+ }
+
+ @Override
+ public void removeUserSession(UserSessionModel session) {
+ getDelegate().removeUserSession(session);
+ }
+
+ @Override
+ public void removeUserSessions(RealmModel realm, UserModel user) {
+ getDelegate().removeUserSessions(realm, user);
+ }
+
+ @Override
+ public void removeExpiredUserSessions(RealmModel realm) {
+ getDelegate().removeExpiredUserSessions(realm);
+ }
+
+ @Override
+ public void removeUserSessions(RealmModel realm) {
+ getDelegate().removeUserSessions(realm);
+ }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheKeycloakSessionFactory.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheKeycloakSessionFactory.java
new file mode 100755
index 0000000000..d3691a420c
--- /dev/null
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/NoCacheKeycloakSessionFactory.java
@@ -0,0 +1,30 @@
+package org.keycloak.models.cache;
+
+import org.keycloak.Config;
+import org.keycloak.provider.ProviderSession;
+
+/**
+ * @author Bill Burke
+ * @version $Revision: 1 $
+ */
+public class NoCacheKeycloakSessionFactory implements CacheKeycloakSessionFactory {
+ @Override
+ public CacheKeycloakSession create(ProviderSession providerSession) {
+ return new NoCacheKeycloakSession(providerSession);
+ }
+
+ @Override
+ public void close() {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public void init(Config.Scope config) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public String getId() {
+ return "none";
+ }
+}
diff --git a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheKeycloakSessionFactory b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheKeycloakSessionFactory
index 0cf4453cbe..57939b6b76 100755
--- a/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheKeycloakSessionFactory
+++ b/model/invalidation-cache/model-adapters/src/main/resources/META-INF/services/org.keycloak.models.cache.CacheKeycloakSessionFactory
@@ -1 +1,2 @@
-org.keycloak.models.cache.SimpleCacheKeycloakSessionFactory
\ No newline at end of file
+org.keycloak.models.cache.SimpleCacheKeycloakSessionFactory
+org.keycloak.models.cache.NoCacheKeycloakSessionFactory
\ No newline at end of file
diff --git a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
index 5366d04527..3d61794eb7 100755
--- a/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
+++ b/model/tests/src/test/java/org/keycloak/model/test/AbstractModelTest.java
@@ -40,7 +40,7 @@ public class AbstractModelTest {
providerSessionFactory = KeycloakApplication.createProviderSessionFactory();
ProviderSession providerSession = providerSessionFactory.createSession();
- KeycloakSession identitySession = providerSession.getProvider(CacheKeycloakSession.class);
+ KeycloakSession identitySession = providerSession.getProvider(CacheKeycloakSession.class, "simple");
try {
identitySession.getTransaction().begin();
new ApplianceBootstrap().bootstrap(identitySession, "/auth");
@@ -59,7 +59,7 @@ public class AbstractModelTest {
public void before() throws Exception {
providerSession = providerSessionFactory.createSession();
- identitySession = providerSession.getProvider(CacheKeycloakSession.class);
+ identitySession = providerSession.getProvider(CacheKeycloakSession.class, "simple");
identitySession.getTransaction().begin();
realmManager = new RealmManager(identitySession);
}
@@ -70,7 +70,7 @@ public class AbstractModelTest {
providerSession.close();
providerSession = providerSessionFactory.createSession();
- identitySession = providerSession.getProvider(CacheKeycloakSession.class);
+ identitySession = providerSession.getProvider(CacheKeycloakSession.class, "simple");
try {
identitySession.getTransaction().begin();
@@ -105,7 +105,7 @@ public class AbstractModelTest {
providerSession.close();
providerSession = providerSessionFactory.createSession();
- identitySession = providerSession.getProvider(CacheKeycloakSession.class);
+ identitySession = providerSession.getProvider(CacheKeycloakSession.class, "simple");
identitySession.getTransaction().begin();
realmManager = new RealmManager(identitySession);
}
diff --git a/project-integrations/aerogear-ups/auth-server/pom.xml b/project-integrations/aerogear-ups/auth-server/pom.xml
index 349dd1388b..07ec63136e 100755
--- a/project-integrations/aerogear-ups/auth-server/pom.xml
+++ b/project-integrations/aerogear-ups/auth-server/pom.xml
@@ -47,6 +47,11 @@
keycloak-model-api
${project.version}
+
+ org.keycloak
+ keycloak-invalidation-cache-model
+ ${project.version}
+
org.keycloak
keycloak-model-jpa
diff --git a/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/keycloak-server.json b/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/keycloak-server.json
index 33b4c94817..e321f7f013 100755
--- a/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/keycloak-server.json
+++ b/project-integrations/aerogear-ups/auth-server/src/main/webapp/WEB-INF/keycloak-server.json
@@ -7,6 +7,10 @@
"provider": "jpa"
},
+ "modelCache": {
+ "provider": "${keycloak.model.cache.provider:simple}"
+ },
+
"timer": {
"provider": "basic"
},
diff --git a/server/pom.xml b/server/pom.xml
index 849c862297..9185e34a3b 100755
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -42,6 +42,11 @@
keycloak-model-api
${project.version}
+
+ org.keycloak
+ keycloak-invalidation-cache-model
+ ${project.version}
+
org.keycloak
keycloak-model-jpa
diff --git a/server/src/main/resources/META-INF/keycloak-server.json b/server/src/main/resources/META-INF/keycloak-server.json
index 7bc7ffd591..23752151a0 100755
--- a/server/src/main/resources/META-INF/keycloak-server.json
+++ b/server/src/main/resources/META-INF/keycloak-server.json
@@ -14,6 +14,10 @@
"provider": "jpa"
},
+ "modelCache": {
+ "provider": "${keycloak.model.cache.provider:simple}"
+ },
+
"timer": {
"provider": "basic"
},
diff --git a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
index bc3370f53e..a1e1ec17ff 100755
--- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
@@ -23,6 +23,10 @@
}
},
+ "modelCache": {
+ "provider": "${keycloak.model.cache.provider:simple}"
+ },
+
"timer": {
"provider": "basic"
},
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/perf/AccessTokenPerfTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/perf/AccessTokenPerfTest.java
index 91027d3553..ca22ebddf5 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/perf/AccessTokenPerfTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/perf/AccessTokenPerfTest.java
@@ -234,7 +234,7 @@ public class AccessTokenPerfTest {
@Test
public void perfJaxrsClientLogin()
{
- long ITERATIONS = 10;
+ long ITERATIONS = 100;
JaxrsClientLogin login = new JaxrsClientLogin();
long start = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
@@ -248,7 +248,7 @@ public class AccessTokenPerfTest {
@Test
public void perfBrowserLogin()
{
- long ITERATIONS = 10;
+ long ITERATIONS = 100;
long start = System.currentTimeMillis();
BrowserLogin login = new BrowserLogin();
for (int i = 0; i < ITERATIONS; i++) {
@@ -260,7 +260,7 @@ public class AccessTokenPerfTest {
@Test
public void multiThread() throws Exception {
- int num_threads = 10;
+ int num_threads = 20;
Thread[] threads = new Thread[num_threads];
for (int i = 0; i < num_threads; i++) {
threads[i] = new Thread(new Runnable() {