keycloak-uncached

javadoc

2/12/2016 2:38:12 PM

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 a177b95..b998b8c 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
@@ -352,6 +352,25 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
     }
 
     @Override
+    public boolean removeClient(String id, RealmModel realm) {
+        ClientModel client = getClientById(id, realm);
+        if (client == null) return false;
+        registerApplicationInvalidation(id);
+        registerRealmInvalidation(realm.getId());
+        cache.invalidateClientById(id);
+        cache.invalidateRealmById(realm.getId());
+
+
+
+        Set<RoleModel> roles = client.getRoles();
+        for (RoleModel role : roles) {
+            registerRoleInvalidation(role.getId());
+        }
+        return getDelegate().removeClient(id, realm);
+    }
+
+
+    @Override
     public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
         CachedClientTemplate cached = cache.getClientTemplate(id);
         if (cached != null && !cached.getRealm().equals(realm.getId())) {
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 a15f4f1..4edb046 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
@@ -105,6 +105,10 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
         return delegate;
     }
 
+    public LockingRealmCache getCache() {
+        return cache;
+    }
+
     @Override
     public void registerRealmInvalidation(String id) {
         realmInvalidations.add(id);
@@ -354,6 +358,25 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
     }
 
     @Override
+    public boolean removeClient(String id, RealmModel realm) {
+        ClientModel client = getClientById(id, realm);
+        if (client == null) return false;
+
+        registerApplicationInvalidation(id);
+        registerRealmInvalidation(realm.getId());
+        cache.invalidateClientById(id);
+        cache.invalidateRealmById(realm.getId());
+
+
+
+        Set<RoleModel> roles = client.getRoles();
+        for (RoleModel role : roles) {
+            registerRoleInvalidation(role.getId());
+        }
+        return getDelegate().removeClient(id, realm);
+    }
+
+    @Override
     public void close() {
         if (delegate != null) delegate.close();
     }
@@ -445,7 +468,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
 
     @Override
     public ClientModel getClientByClientId(String clientId, RealmModel realm) {
-        CachedClient cached = cache.getClientByClientId(clientId);
+        CachedClient cached = cache.getClientByClientId(realm, clientId);
         if (cached != null && !cached.getRealm().equals(realm.getId())) {
             cached = null;
         }
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 6723048..23f8e53 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
@@ -146,6 +146,8 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
             } else if (object instanceof CachedClient) {
                 CachedClient client = (CachedClient) object;
 
+                realmCache.getClientLookup().remove(client.getRealm() + "." + client.getClientId());
+
                 for (String r : client.getRoles().values()) {
                     realmCache.evictRoleById(r);
                 }
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 5b3060d..a77c59b 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
@@ -19,6 +19,7 @@ package org.keycloak.models.cache.infinispan.locking;
 
 import org.infinispan.Cache;
 import org.jboss.logging.Logger;
+import org.keycloak.models.RealmModel;
 import org.keycloak.models.cache.RealmCache;
 import org.keycloak.models.cache.entities.CachedClient;
 import org.keycloak.models.cache.entities.CachedClientTemplate;
@@ -176,8 +177,8 @@ public class LockingRealmCache implements RealmCache {
         return get(id, CachedClient.class);
     }
 
-    public CachedClient getClientByClientId(String clientId) {
-        String id = clientLookup.get(clientId);
+    public CachedClient getClientByClientId(RealmModel realm, String clientId) {
+        String id = clientLookup.get(realm.getId() + "." + clientId);
         return id != null ? getClient(id) : null;
     }
 
@@ -185,14 +186,14 @@ public class LockingRealmCache implements RealmCache {
     public void invalidateClient(CachedClient app) {
         logger.tracev("Removing application {0}", app.getId());
         invalidateObject(app.getId());
-        clientLookup.remove(app.getClientId());
+        clientLookup.remove(getClientIdKey(app));
     }
 
     @Override
     public void addClient(CachedClient app) {
         logger.tracev("Adding application {0}", app.getId());
         addRevisioned(app.getId(), (Revisioned) app);
-        clientLookup.put(app.getClientId(), app.getId());
+        clientLookup.put(getClientIdKey(app), app.getId());
     }
 
     @Override
@@ -200,10 +201,14 @@ public class LockingRealmCache implements RealmCache {
         CachedClient client = (CachedClient)invalidateObject(id);
         if (client != null) {
             logger.tracev("Removing application {0}", client.getClientId());
-            clientLookup.remove(client.getClientId());
+            clientLookup.remove(getClientIdKey(client));
         }
     }
 
+    protected String getClientIdKey(CachedClient client) {
+        return client.getRealm() + "." + client.getClientId();
+    }
+
     @Override
     public void evictClientById(String id) {
         logger.tracev("Evicting application {0}", id);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
index 76aa238..684d102 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java
@@ -191,7 +191,7 @@ public class RealmEntity {
     @Column(name="ADMIN_EVENTS_DETAILS_ENABLED")
     protected boolean adminEventsDetailsEnabled;
     
-    @OneToOne
+    @OneToOne(fetch = FetchType.LAZY)
     @JoinColumn(name="MASTER_ADMIN_CLIENT")
     protected ClientEntity masterAdminClient;
 
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 55b6087..ce245de 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
@@ -17,6 +17,7 @@
 
 package org.keycloak.models.jpa;
 
+import org.jboss.logging.Logger;
 import org.keycloak.migration.MigrationModel;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientTemplateModel;
@@ -43,6 +44,7 @@ import java.util.List;
  * @version $Revision: 1 $
  */
 public class JpaRealmProvider implements RealmProvider {
+    protected static final Logger logger = Logger.getLogger(JpaRealmProvider.class);
     private final KeycloakSession session;
     protected EntityManager em;
 
@@ -115,7 +117,6 @@ public class JpaRealmProvider implements RealmProvider {
         if (realm == null) {
             return false;
         }
-
         RealmAdapter adapter = new RealmAdapter(session, em, realm);
         session.users().preRemove(adapter);
         int num = em.createNamedQuery("deleteGroupRoleMappingsByRealm")
@@ -144,6 +145,11 @@ public class JpaRealmProvider implements RealmProvider {
 
         em.flush();
         em.clear();
+        realm = em.find(RealmEntity.class, id);
+        if (realm != null) {
+            logger.error("WTF is the realm still there after a removal????????");
+        }
+
         return true;
     }
 
@@ -188,6 +194,31 @@ public class JpaRealmProvider implements RealmProvider {
     }
 
     @Override
+    public boolean removeClient(String id, RealmModel realm) {
+        ClientModel client = getClientById(id, realm);
+        if (client == null) return false;
+
+        session.users().preRemove(realm, client);
+
+        for (RoleModel role : client.getRoles()) {
+            client.removeRole(role);
+        }
+
+
+        ClientEntity clientEntity = ((ClientAdapter)client).getEntity();
+        em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", clientEntity).executeUpdate();
+        em.flush();
+        em.remove(clientEntity);  // i have no idea why, but this needs to come before deleteScopeMapping
+        try {
+            em.flush();
+        } catch (RuntimeException e) {
+            logger.errorv("Unable to delete client entity: {0} from realm {1}", client.getClientId(), realm.getName());
+            throw e;
+        }
+        return true;
+    }
+
+    @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 eb03e53..da66a3b 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
@@ -17,6 +17,7 @@
 
 package org.keycloak.models.jpa;
 
+import org.jboss.logging.Logger;
 import org.keycloak.connections.jpa.util.JpaUtils;
 import org.keycloak.common.enums.SslRequired;
 import org.keycloak.models.AuthenticationExecutionModel;
@@ -65,6 +66,7 @@ import java.util.Set;
  * @version $Revision: 1 $
  */
 public class RealmAdapter implements RealmModel {
+    protected static final Logger logger = Logger.getLogger(RealmAdapter.class);
     protected RealmEntity realm;
     protected EntityManager em;
     protected volatile transient PublicKey publicKey;
@@ -774,34 +776,7 @@ public class RealmAdapter implements RealmModel {
         if (id == null) return false;
         ClientModel client = getClientById(id);
         if (client == null) return false;
-
-        session.users().preRemove(this, client);
-
-        for (RoleModel role : client.getRoles()) {
-            client.removeRole(role);
-        }
-
-        ClientEntity clientEntity = null;
-        Iterator<ClientEntity> it = realm.getClients().iterator();
-        while (it.hasNext()) {
-            ClientEntity ae = it.next();
-            if (ae.getId().equals(id)) {
-                clientEntity = ae;
-                it.remove();
-                break;
-            }
-        }
-        for (ClientEntity a : realm.getClients()) {
-            if (a.getId().equals(id)) {
-                clientEntity = a;
-            }
-        }
-        if (clientEntity == null) return false;
-        em.createNamedQuery("deleteScopeMappingByClient").setParameter("client", clientEntity).executeUpdate();
-        em.remove(clientEntity);
-        em.flush();
-
-        return true;
+        return session.realms().removeClient(id, this);
     }
 
     @Override
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 ddfbdef..c5d70fb 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 boolean removeClient(String id, RealmModel realm) {
+        if (id == null) return false;
+        ClientModel client = getClientById(id, realm);
+        if (client == null) return false;
+
+        session.users().preRemove(realm, client);
+
+        return getMongoStore().removeEntity(MongoClientEntity.class, id, invocationContext);
+    }
+
+    @Override
     public ClientModel getClientByClientId(String clientId, RealmModel realm) {
         DBObject query = new QueryBuilder()
                 .and("realmId").is(realm.getId())
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 ca7626c..701cced 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
@@ -868,10 +868,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         if (id == null) return false;
         ClientModel client = getClientById(id);
         if (client == null) return false;
-
-        session.users().preRemove(this, client);
-
-        return getMongoStore().removeEntity(MongoClientEntity.class, id, invocationContext);
+        return session.realms().removeClient(id, this);
     }
 
     @Override
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 59568a3..2b3f5fa 100755
--- a/server-spi/src/main/java/org/keycloak/models/RealmProvider.java
+++ b/server-spi/src/main/java/org/keycloak/models/RealmProvider.java
@@ -40,6 +40,9 @@ public interface RealmProvider extends Provider {
 
 
     RoleModel getRoleById(String id, RealmModel realm);
+
+    boolean removeClient(String id, RealmModel realm);
+
     ClientTemplateModel getClientTemplateById(String id, RealmModel realm);
     GroupModel getGroupById(String id, RealmModel realm);
 
diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
index dbaaad2..55695a0 100755
--- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java
@@ -211,10 +211,11 @@ public class RealmManager implements RealmImporter {
     public boolean removeRealm(RealmModel realm) {
         List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
 
+        ClientModel masterAdminClient = realm.getMasterAdminClient();
         boolean removed = model.removeRealm(realm.getId());
         if (removed) {
-            if (realm.getMasterAdminClient() != null) {
-                new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminClient());
+            if (masterAdminClient != null) {
+                new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), masterAdminClient);
             }
 
             UserSessionProvider sessions = session.sessions();
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 cfc9cd5..e56aa83 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
@@ -11,7 +11,8 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 /**
- * Executes all test threads until completion.
+ * Executes a test N number of times.  This is done multiple times over an ever expanding amount of threads to determine
+ * when the computer is saturated and you can't eek out any more concurrent requests.
  *
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $