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);
}
@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);

View file

@ -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);
@ -353,6 +357,25 @@ public class LockingCacheRealmProvider implements CacheRealmProvider {
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
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;
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}
@ -187,6 +193,31 @@ public class JpaRealmProvider implements RealmProvider {
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
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
ClientTemplateEntity app = em.find(ClientTemplateEntity.class, id);

View file

@ -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

View file

@ -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;

View file

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

View file

@ -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

View file

@ -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);

View file

@ -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();

View file

@ -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 $