This commit is contained in:
Bill Burke 2016-02-12 11:38:12 -05:00
parent 860a104828
commit 4ff1848681
12 changed files with 111 additions and 43 deletions

View file

@ -351,6 +351,25 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
return getDelegate().getClientByClientId(clientId, realm); return getDelegate().getClientByClientId(clientId, realm);
} }
@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 @Override
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) { public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
CachedClientTemplate cached = cache.getClientTemplate(id); CachedClientTemplate cached = cache.getClientTemplate(id);

View file

@ -105,6 +105,10 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
return delegate; return delegate;
} }
public LockingRealmCache getCache() {
return cache;
}
@Override @Override
public void registerRealmInvalidation(String id) { public void registerRealmInvalidation(String id) {
realmInvalidations.add(id); realmInvalidations.add(id);
@ -353,6 +357,25 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
return didIt; return didIt;
} }
@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 @Override
public void close() { public void close() {
if (delegate != null) delegate.close(); if (delegate != null) delegate.close();
@ -445,7 +468,7 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
@Override @Override
public ClientModel getClientByClientId(String clientId, RealmModel realm) { 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())) { if (cached != null && !cached.getRealm().equals(realm.getId())) {
cached = null; cached = null;
} }

View file

@ -146,6 +146,8 @@ public class LockingCacheRealmProviderFactory implements CacheRealmProviderFacto
} else if (object instanceof CachedClient) { } else if (object instanceof CachedClient) {
CachedClient client = (CachedClient) object; CachedClient client = (CachedClient) object;
realmCache.getClientLookup().remove(client.getRealm() + "." + client.getClientId());
for (String r : client.getRoles().values()) { for (String r : client.getRoles().values()) {
realmCache.evictRoleById(r); realmCache.evictRoleById(r);
} }

View file

@ -19,6 +19,7 @@ package org.keycloak.models.cache.infinispan.locking;
import org.infinispan.Cache; import org.infinispan.Cache;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.models.RealmModel;
import org.keycloak.models.cache.RealmCache; import org.keycloak.models.cache.RealmCache;
import org.keycloak.models.cache.entities.CachedClient; import org.keycloak.models.cache.entities.CachedClient;
import org.keycloak.models.cache.entities.CachedClientTemplate; import org.keycloak.models.cache.entities.CachedClientTemplate;
@ -176,8 +177,8 @@ public class LockingRealmCache implements RealmCache {
return get(id, CachedClient.class); return get(id, CachedClient.class);
} }
public CachedClient getClientByClientId(String clientId) { public CachedClient getClientByClientId(RealmModel realm, String clientId) {
String id = clientLookup.get(clientId); String id = clientLookup.get(realm.getId() + "." + clientId);
return id != null ? getClient(id) : null; return id != null ? getClient(id) : null;
} }
@ -185,14 +186,14 @@ public class LockingRealmCache implements RealmCache {
public void invalidateClient(CachedClient app) { public void invalidateClient(CachedClient app) {
logger.tracev("Removing application {0}", app.getId()); logger.tracev("Removing application {0}", app.getId());
invalidateObject(app.getId()); invalidateObject(app.getId());
clientLookup.remove(app.getClientId()); clientLookup.remove(getClientIdKey(app));
} }
@Override @Override
public void addClient(CachedClient app) { public void addClient(CachedClient app) {
logger.tracev("Adding application {0}", app.getId()); logger.tracev("Adding application {0}", app.getId());
addRevisioned(app.getId(), (Revisioned) app); addRevisioned(app.getId(), (Revisioned) app);
clientLookup.put(app.getClientId(), app.getId()); clientLookup.put(getClientIdKey(app), app.getId());
} }
@Override @Override
@ -200,10 +201,14 @@ public class LockingRealmCache implements RealmCache {
CachedClient client = (CachedClient)invalidateObject(id); CachedClient client = (CachedClient)invalidateObject(id);
if (client != null) { if (client != null) {
logger.tracev("Removing application {0}", client.getClientId()); 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 @Override
public void evictClientById(String id) { public void evictClientById(String id) {
logger.tracev("Evicting application {0}", id); logger.tracev("Evicting application {0}", id);

View file

@ -17,6 +17,7 @@
package org.keycloak.models.jpa; package org.keycloak.models.jpa;
import org.jboss.logging.Logger;
import org.keycloak.migration.MigrationModel; import org.keycloak.migration.MigrationModel;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientTemplateModel; import org.keycloak.models.ClientTemplateModel;
@ -43,6 +44,7 @@ import java.util.List;
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class JpaRealmProvider implements RealmProvider { public class JpaRealmProvider implements RealmProvider {
protected static final Logger logger = Logger.getLogger(JpaRealmProvider.class);
private final KeycloakSession session; private final KeycloakSession session;
protected EntityManager em; protected EntityManager em;
@ -115,7 +117,6 @@ public class JpaRealmProvider implements RealmProvider {
if (realm == null) { if (realm == null) {
return false; return false;
} }
RealmAdapter adapter = new RealmAdapter(session, em, realm); RealmAdapter adapter = new RealmAdapter(session, em, realm);
session.users().preRemove(adapter); session.users().preRemove(adapter);
int num = em.createNamedQuery("deleteGroupRoleMappingsByRealm") int num = em.createNamedQuery("deleteGroupRoleMappingsByRealm")
@ -144,6 +145,11 @@ public class JpaRealmProvider implements RealmProvider {
em.flush(); em.flush();
em.clear(); em.clear();
realm = em.find(RealmEntity.class, id);
if (realm != null) {
logger.error("WTF is the realm still there after a removal????????");
}
return true; return true;
} }
@ -187,6 +193,31 @@ public class JpaRealmProvider implements RealmProvider {
return new ClientAdapter(realm, em, session, entity); return new ClientAdapter(realm, em, session, entity);
} }
@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 @Override
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) { public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
ClientTemplateEntity app = em.find(ClientTemplateEntity.class, id); ClientTemplateEntity app = em.find(ClientTemplateEntity.class, id);

View file

@ -17,6 +17,7 @@
package org.keycloak.models.jpa; package org.keycloak.models.jpa;
import org.jboss.logging.Logger;
import org.keycloak.connections.jpa.util.JpaUtils; import org.keycloak.connections.jpa.util.JpaUtils;
import org.keycloak.common.enums.SslRequired; import org.keycloak.common.enums.SslRequired;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;
@ -65,6 +66,7 @@ import java.util.Set;
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
public class RealmAdapter implements RealmModel { public class RealmAdapter implements RealmModel {
protected static final Logger logger = Logger.getLogger(RealmAdapter.class);
protected RealmEntity realm; protected RealmEntity realm;
protected EntityManager em; protected EntityManager em;
protected volatile transient PublicKey publicKey; protected volatile transient PublicKey publicKey;
@ -774,34 +776,7 @@ public class RealmAdapter implements RealmModel {
if (id == null) return false; if (id == null) return false;
ClientModel client = getClientById(id); ClientModel client = getClientById(id);
if (client == null) return false; if (client == null) return false;
return session.realms().removeClient(id, this);
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;
} }
@Override @Override

View file

@ -191,7 +191,7 @@ public class RealmEntity {
@Column(name="ADMIN_EVENTS_DETAILS_ENABLED") @Column(name="ADMIN_EVENTS_DETAILS_ENABLED")
protected boolean adminEventsDetailsEnabled; protected boolean adminEventsDetailsEnabled;
@OneToOne @OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="MASTER_ADMIN_CLIENT") @JoinColumn(name="MASTER_ADMIN_CLIENT")
protected ClientEntity masterAdminClient; protected ClientEntity masterAdminClient;

View file

@ -162,6 +162,17 @@ public class MongoRealmProvider implements RealmProvider {
return new ClientAdapter(session, realm, appData, invocationContext); return new ClientAdapter(session, realm, appData, invocationContext);
} }
@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 @Override
public ClientModel getClientByClientId(String clientId, RealmModel realm) { public ClientModel getClientByClientId(String clientId, RealmModel realm) {
DBObject query = new QueryBuilder() DBObject query = new QueryBuilder()

View file

@ -868,10 +868,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
if (id == null) return false; if (id == null) return false;
ClientModel client = getClientById(id); ClientModel client = getClientById(id);
if (client == null) return false; if (client == null) return false;
return session.realms().removeClient(id, this);
session.users().preRemove(this, client);
return getMongoStore().removeEntity(MongoClientEntity.class, id, invocationContext);
} }
@Override @Override

View file

@ -40,6 +40,9 @@ public interface RealmProvider extends Provider {
RoleModel getRoleById(String id, RealmModel realm); RoleModel getRoleById(String id, RealmModel realm);
boolean removeClient(String id, RealmModel realm);
ClientTemplateModel getClientTemplateById(String id, RealmModel realm); ClientTemplateModel getClientTemplateById(String id, RealmModel realm);
GroupModel getGroupById(String id, RealmModel realm); GroupModel getGroupById(String id, RealmModel realm);

View file

@ -211,10 +211,11 @@ public class RealmManager implements RealmImporter {
public boolean removeRealm(RealmModel realm) { public boolean removeRealm(RealmModel realm) {
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders(); List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
ClientModel masterAdminClient = realm.getMasterAdminClient();
boolean removed = model.removeRealm(realm.getId()); boolean removed = model.removeRealm(realm.getId());
if (removed) { if (removed) {
if (realm.getMasterAdminClient() != null) { if (masterAdminClient != null) {
new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), realm.getMasterAdminClient()); new ClientManager(this).removeClient(getKeycloakAdminstrationRealm(), masterAdminClient);
} }
UserSessionProvider sessions = session.sessions(); UserSessionProvider sessions = session.sessions();

View file

@ -11,7 +11,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; 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> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $