keycloak-memoizeit

cache implement

6/12/2014 12:45:50 PM

Details

diff --git a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
index 8a708a3..2fbb9bd 100755
--- a/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
+++ b/model/api/src/main/java/org/keycloak/models/KeycloakSession.java
@@ -11,6 +11,8 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public interface KeycloakSession extends Provider {
+    // Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
+
     KeycloakTransaction getTransaction();
 
     RealmModel createRealm(String name);
@@ -25,11 +27,9 @@ public interface KeycloakSession extends Provider {
     List<UserModel> getUsers(RealmModel realm);
     List<UserModel> searchForUser(String search, RealmModel realm);
     List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm);
-    Set<RoleModel> getRealmRoleMappings(UserModel user, RealmModel realm);
 
     Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm);
     SocialLinkModel getSocialLink(UserModel user, String socialProvider, RealmModel realm);
-    AuthenticationLinkModel getAuthenticationLink(UserModel user, RealmModel realm);
 
 
     RoleModel getRoleById(String id, RealmModel realm);
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSession.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSession.java
index 24fe250..7d909ec 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSession.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/CacheKeycloakSession.java
@@ -205,11 +205,6 @@ public class CacheKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public Set<RoleModel> getRealmRoleMappings(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
     public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
         return null;  //To change body of implemented methods use File | Settings | File Templates.
     }
@@ -220,11 +215,6 @@ public class CacheKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public AuthenticationLinkModel getAuthenticationLink(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
     public RoleModel getRoleById(String id, RealmModel realm) {
         return null;  //To change body of implemented methods use File | Settings | File Templates.
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
index 5ee0b47..b7dad7d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaKeycloakSession.java
@@ -3,8 +3,10 @@ package org.keycloak.models.jpa;
 import org.keycloak.models.*;
 import org.keycloak.models.jpa.entities.*;
 import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.util.Time;
 
 import javax.persistence.EntityManager;
+import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
@@ -169,22 +171,59 @@ public class JpaKeycloakSession implements KeycloakSession {
 
     @Override
     public List<UserModel> getUsers(RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm", UserEntity.class);
+        RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
+        query.setParameter("realm", realmEntity);
+        List<UserEntity> results = query.getResultList();
+        List<UserModel> users = new ArrayList<UserModel>();
+        for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
+        return users;
     }
 
     @Override
     public List<UserModel> searchForUser(String search, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm and ( lower(u.loginName) like :search or lower(concat(u.firstName, ' ', u.lastName)) like :search or u.email like :search )", UserEntity.class);
+        RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
+        query.setParameter("realm", realmEntity);
+        query.setParameter("search", "%" + search.toLowerCase() + "%");
+        List<UserEntity> results = query.getResultList();
+        List<UserModel> users = new ArrayList<UserModel>();
+        for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
+        return users;
     }
 
     @Override
     public List<UserModel> searchForUserByAttributes(Map<String, String> attributes, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
-    public Set<RoleModel> getRealmRoleMappings(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        StringBuilder builder = new StringBuilder("select u from UserEntity u");
+        boolean first = true;
+        for (Map.Entry<String, String> entry : attributes.entrySet()) {
+            String attribute = null;
+            if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
+                attribute = "lower(loginName)";
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
+                attribute = "lower(firstName)";
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
+                attribute = "lower(lastName)";
+            } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
+                attribute = "lower(email)";
+            }
+            if (attribute == null) continue;
+            if (first) {
+                first = false;
+                builder.append(" where realm = :realm");
+            } else {
+                builder.append(" and ");
+            }
+            builder.append(attribute).append(" like '%").append(entry.getValue().toLowerCase()).append("%'");
+        }
+        String q = builder.toString();
+        TypedQuery<UserEntity> query = em.createQuery(q, UserEntity.class);
+        RealmEntity realmEntity = em.getReference(RealmEntity.class, realm.getId());
+        query.setParameter("realm", realmEntity);
+        List<UserEntity> results = query.getResultList();
+        List<UserModel> users = new ArrayList<UserModel>();
+        for (UserEntity entity : results) users.add(new UserAdapter(realm, em, entity));
+        return users;
     }
 
     private SocialLinkEntity findSocialLink(UserModel user, String socialProvider) {
@@ -217,13 +256,11 @@ public class JpaKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public AuthenticationLinkModel getAuthenticationLink(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
     public RoleModel getRoleById(String id, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        RoleEntity entity = em.find(RoleEntity.class, id);
+        if (entity == null) return null;
+        if (!realm.getId().equals(entity.getRealmId())) return null;
+        return new RoleAdapter(realm, em, entity);
     }
 
     @Override
@@ -237,7 +274,11 @@ public class JpaKeycloakSession implements KeycloakSession {
 
     @Override
     public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
+
+        // Check if client belongs to this realm
+        if (client == null || !realm.getId().equals(client.getRealm().getId())) return null;
+        return new OAuthClientAdapter(realm, client, em);
     }
 
     @Override
@@ -275,46 +316,82 @@ public class JpaKeycloakSession implements KeycloakSession {
 
     @Override
     public UserSessionModel createUserSession(RealmModel realm, UserModel user, String ipAddress) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        UserSessionEntity entity = new UserSessionEntity();
+        entity.setRealmId(realm.getId());
+        entity.setUserId(user.getId());
+        entity.setIpAddress(ipAddress);
+
+        int currentTime = Time.currentTime();
+
+        entity.setStarted(currentTime);
+        entity.setLastSessionRefresh(currentTime);
+
+        em.persist(entity);
+        return new UserSessionAdapter(em, realm, entity);
     }
 
     @Override
     public UserSessionModel getUserSession(String id, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        UserSessionEntity entity = em.find(UserSessionEntity.class, id);
+        return entity != null ? new UserSessionAdapter(em, realm, entity) : null;
     }
 
     @Override
     public List<UserSessionModel> getUserSessions(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        List<UserSessionModel> sessions = new LinkedList<UserSessionModel>();
+        for (UserSessionEntity e : em.createNamedQuery("getUserSessionByUser", UserSessionEntity.class)
+                .setParameter("userId", user.getId()).getResultList()) {
+            sessions.add(new UserSessionAdapter(em, realm, e));
+        }
+        return sessions;
     }
 
     @Override
     public Set<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        Set<UserSessionModel> list = new HashSet<UserSessionModel>();
+        TypedQuery<ClientUserSessionAssociationEntity> query = em.createNamedQuery("getClientUserSessionByClient", ClientUserSessionAssociationEntity.class);
+        String id = client.getId();
+        query.setParameter("clientId", id);
+        List<ClientUserSessionAssociationEntity> results = query.getResultList();
+        for (ClientUserSessionAssociationEntity entity : results) {
+            list.add(new UserSessionAdapter(em, realm, entity.getSession()));
+        }
+        return list;
     }
 
     @Override
     public int getActiveUserSessions(RealmModel realm, ClientModel client) {
-        return 0;  //To change body of implemented methods use File | Settings | File Templates.
+        Query query = em.createNamedQuery("getActiveClientSessions");
+        query.setParameter("clientId", client.getId());
+        Object count = query.getSingleResult();
+        return ((Number)count).intValue();
     }
 
     @Override
     public void removeUserSession(UserSessionModel session) {
-        //To change body of implemented methods use File | Settings | File Templates.
+        em.remove(((UserSessionAdapter) session).getEntity());
     }
 
     @Override
     public void removeUserSessions(RealmModel realm, UserModel user) {
-        //To change body of implemented methods use File | Settings | File Templates.
+        em.createNamedQuery("removeClientUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
+        em.createNamedQuery("removeUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
     }
 
     @Override
     public void removeExpiredUserSessions(RealmModel realm) {
-        //To change body of implemented methods use File | Settings | File Templates.
+        TypedQuery<UserSessionEntity> query = em.createNamedQuery("getUserSessionExpired", UserSessionEntity.class)
+                .setParameter("maxTime", Time.currentTime() - realm.getSsoSessionMaxLifespan())
+                .setParameter("idleTime", Time.currentTime() - realm.getSsoSessionIdleTimeout());
+        List<UserSessionEntity> results = query.getResultList();
+        for (UserSessionEntity entity : results) {
+            em.remove(entity);
+        }
     }
 
     @Override
     public void removeUserSessions(RealmModel realm) {
-        //To change body of implemented methods use File | Settings | File Templates.
+        em.createNamedQuery("removeClientUserSessionByRealm").setParameter("realmId", realm.getId()).executeUpdate();
+        em.createNamedQuery("removeRealmUserSessions").setParameter("realmId", realm.getId()).executeUpdate();
     }
 }
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 9d319a6..f972463 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
@@ -493,7 +493,8 @@ public class RealmAdapter implements RealmModel {
     }
 
     private void removeUser(UserEntity user) {
-        removeUserSessions(user);
+        em.createNamedQuery("removeClientUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
+        em.createNamedQuery("removeUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
 
         em.createQuery("delete from " + UserRoleMappingEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
         em.createQuery("delete from " + SocialLinkEntity.class.getSimpleName() + " where user = :user").setParameter("user", user).executeUpdate();
@@ -733,55 +734,17 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public List<UserModel> getUsers() {
-        TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm", UserEntity.class);
-        query.setParameter("realm", realm);
-        List<UserEntity> results = query.getResultList();
-        List<UserModel> users = new ArrayList<UserModel>();
-        for (UserEntity entity : results) users.add(new UserAdapter(this, em, entity));
-        return users;
+        return session.getUsers(this);
     }
 
     @Override
     public List<UserModel> searchForUser(String search) {
-        TypedQuery<UserEntity> query = em.createQuery("select u from UserEntity u where u.realm = :realm and ( lower(u.loginName) like :search or lower(concat(u.firstName, ' ', u.lastName)) like :search or u.email like :search )", UserEntity.class);
-        query.setParameter("realm", realm);
-        query.setParameter("search", "%" + search.toLowerCase() + "%");
-        List<UserEntity> results = query.getResultList();
-        List<UserModel> users = new ArrayList<UserModel>();
-        for (UserEntity entity : results) users.add(new UserAdapter(this, em, entity));
-        return users;
+        return session.searchForUser(search, this);
     }
 
     @Override
     public List<UserModel> searchForUserByAttributes(Map<String, String> attributes) {
-        StringBuilder builder = new StringBuilder("select u from UserEntity u");
-        boolean first = true;
-        for (Map.Entry<String, String> entry : attributes.entrySet()) {
-            String attribute = null;
-            if (entry.getKey().equals(UserModel.LOGIN_NAME)) {
-                attribute = "lower(loginName)";
-            } else if (entry.getKey().equalsIgnoreCase(UserModel.FIRST_NAME)) {
-                attribute = "lower(firstName)";
-            } else if (entry.getKey().equalsIgnoreCase(UserModel.LAST_NAME)) {
-                attribute = "lower(lastName)";
-            } else if (entry.getKey().equalsIgnoreCase(UserModel.EMAIL)) {
-                attribute = "lower(email)";
-            }
-            if (attribute == null) continue;
-            if (first) {
-                first = false;
-                builder.append(" where ");
-            } else {
-                builder.append(" and ");
-            }
-            builder.append(attribute).append(" like '%").append(entry.getValue().toLowerCase()).append("%'");
-        }
-        String q = builder.toString();
-        TypedQuery<UserEntity> query = em.createQuery(q, UserEntity.class);
-        List<UserEntity> results = query.getResultList();
-        List<UserModel> users = new ArrayList<UserModel>();
-        for (UserEntity entity : results) users.add(new UserAdapter(this, em, entity));
-        return users;
+        return session.searchForUserByAttributes(attributes, this);
     }
 
     @Override
@@ -825,11 +788,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public OAuthClientModel getOAuthClientById(String id) {
-        OAuthClientEntity client = em.find(OAuthClientEntity.class, id);
-
-        // Check if client belongs to this realm
-        if (client == null || !this.realm.getId().equals(client.getRealm().getId())) return null;
-        return new OAuthClientAdapter(this, client, em);
+        return session.getOAuthClientById(id, this);
     }
 
 
@@ -991,11 +950,7 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public RoleModel getRoleById(String id) {
-        RoleEntity entity = null;
-        entity = em.find(RoleEntity.class, id);
-        if (entity == null) return null;
-        if (!getId().equals(entity.getRealmId())) return null;
-        return new RoleAdapter(this, em, entity);
+        return session.getRoleById(id, this);
     }
 
     @Override
@@ -1143,66 +1098,38 @@ public class RealmAdapter implements RealmModel {
 
     @Override
     public UserSessionModel createUserSession(UserModel user, String ipAddress) {
-        UserSessionEntity entity = new UserSessionEntity();
-        entity.setRealmId(realm.getId());
-        entity.setUserId(user.getId());
-        entity.setIpAddress(ipAddress);
-
-        int currentTime = Time.currentTime();
-
-        entity.setStarted(currentTime);
-        entity.setLastSessionRefresh(currentTime);
-
-        em.persist(entity);
-        return new UserSessionAdapter(em, this, entity);
+        return session.createUserSession(this, user, ipAddress);
     }
 
     @Override
     public UserSessionModel getUserSession(String id) {
-        UserSessionEntity entity = em.find(UserSessionEntity.class, id);
-        return entity != null ? new UserSessionAdapter(em, this, entity) : null;
+        return session.getUserSession(id, this);
     }
 
     @Override
     public List<UserSessionModel> getUserSessions(UserModel user) {
-        List<UserSessionModel> sessions = new LinkedList<UserSessionModel>();
-        for (UserSessionEntity e : em.createNamedQuery("getUserSessionByUser", UserSessionEntity.class).setParameter("userId", user.getId()).getResultList()) {
-            sessions.add(new UserSessionAdapter(em, this, e));
-        }
-        return sessions;
+        return session.getUserSessions(user, this);
     }
 
     @Override
     public void removeUserSession(UserSessionModel session) {
-        em.remove(((UserSessionAdapter) session).getEntity());
+        this.session.removeUserSession(session);
     }
 
     @Override
     public void removeUserSessions() {
-        em.createNamedQuery("removeClientUserSessionByRealm").setParameter("realmId", realm.getId()).executeUpdate();
-        em.createNamedQuery("removeRealmUserSessions").setParameter("realmId", realm.getId()).executeUpdate();
+        session.removeUserSessions(this);
 
     }
 
     @Override
     public void removeUserSessions(UserModel user) {
-        removeUserSessions(((UserAdapter) user).getUser());
-    }
-
-    private void removeUserSessions(UserEntity user) {
-        em.createNamedQuery("removeClientUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
-        em.createNamedQuery("removeUserSessionByUser").setParameter("userId", user.getId()).executeUpdate();
+        session.removeUserSessions(this, user);
     }
 
     @Override
     public void removeExpiredUserSessions() {
-        TypedQuery<UserSessionEntity> query = em.createNamedQuery("getUserSessionExpired", UserSessionEntity.class)
-                .setParameter("maxTime", Time.currentTime() - getSsoSessionMaxLifespan())
-                .setParameter("idleTime", Time.currentTime() - getSsoSessionIdleTimeout());
-        List<UserSessionEntity> results = query.getResultList();
-        for (UserSessionEntity entity : results) {
-            em.remove(entity);
-        }
+        session.removeExpiredUserSessions(this);
     }
 
 }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
index 4078453..db58dae 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoKeycloakSession.java
@@ -173,11 +173,6 @@ public class MongoKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public Set<RoleModel> getRealmRoleMappings(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
     public Set<SocialLinkModel> getSocialLinks(UserModel user, RealmModel realm) {
         return null;  //To change body of implemented methods use File | Settings | File Templates.
     }
@@ -188,11 +183,6 @@ public class MongoKeycloakSession implements KeycloakSession {
     }
 
     @Override
-    public AuthenticationLinkModel getAuthenticationLink(UserModel user, RealmModel realm) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    @Override
     public RoleModel getRoleById(String id, RealmModel realm) {
         return null;  //To change body of implemented methods use File | Settings | File Templates.
     }