[KEYCLOAK-4125] - Fixing when running in a cluster

This commit is contained in:
Pedro Igor 2016-12-21 20:04:08 -02:00
parent 3e8d4e4eb6
commit df7a68b709
9 changed files with 98 additions and 135 deletions

View file

@ -21,6 +21,7 @@ package org.keycloak.models.authorization.infinispan;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -51,7 +52,7 @@ public class CachedPolicyStore implements PolicyStore {
private static final String POLICY_ID_CACHE_PREFIX = "policy-id-"; private static final String POLICY_ID_CACHE_PREFIX = "policy-id-";
private final Cache<String, List<CachedPolicy>> cache; private final Cache<String, Map<String, List<CachedPolicy>>> cache;
private final KeycloakSession session; private final KeycloakSession session;
private final CacheTransaction transaction; private final CacheTransaction transaction;
private final List<String> cacheKeys; private final List<String> cacheKeys;
@ -78,7 +79,7 @@ public class CachedPolicyStore implements PolicyStore {
String id = policy.getId(); String id = policy.getId();
this.transaction.whenRollback(() -> { this.transaction.whenRollback(() -> {
cache.remove(getCacheKeyForPolicy(id)); resolveResourceServerCache(resourceServer.getId()).remove(getCacheKeyForPolicy(id));
}); });
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
@ -90,14 +91,13 @@ public class CachedPolicyStore implements PolicyStore {
@Override @Override
public void delete(String id) { public void delete(String id) {
Policy policy = findById(id, null); Policy policy = getDelegate().findById(id, null);
if (policy == null) { if (policy == null) {
return; return;
} }
ResourceServer resourceServer = policy.getResourceServer(); ResourceServer resourceServer = policy.getResourceServer();
getDelegate().delete(id); getDelegate().delete(id);
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
cache.remove(getCacheKeyForPolicy(id));
invalidateCache(resourceServer.getId()); invalidateCache(resourceServer.getId());
}); });
} }
@ -105,13 +105,15 @@ public class CachedPolicyStore implements PolicyStore {
@Override @Override
public Policy findById(String id, String resourceServerId) { public Policy findById(String id, String resourceServerId) {
String cacheKeyForPolicy = getCacheKeyForPolicy(id); String cacheKeyForPolicy = getCacheKeyForPolicy(id);
List<CachedPolicy> cached = this.cache.get(cacheKeyForPolicy); List<CachedPolicy> cached = resolveResourceServerCache(resourceServerId).get(cacheKeyForPolicy);
if (cached == null) { if (cached == null) {
Policy policy = getDelegate().findById(id, resourceServerId); Policy policy = getDelegate().findById(id, resourceServerId);
if (policy != null) { if (policy != null) {
return createAdapter(updatePolicyCache(policy)); CachedPolicy cachedPolicy = new CachedPolicy(policy);
resolveResourceServerCache(resourceServerId).put(cacheKeyForPolicy, Arrays.asList(cachedPolicy));
return createAdapter(cachedPolicy);
} }
return null; return null;
@ -137,12 +139,12 @@ public class CachedPolicyStore implements PolicyStore {
@Override @Override
public List<Policy> findByResource(String resourceId, String resourceServerId) { public List<Policy> findByResource(String resourceId, String resourceServerId) {
return cacheResult(new StringBuilder("findByResource").append(resourceServerId).append(resourceId).toString(), () -> getDelegate().findByResource(resourceId, resourceServerId)); return cacheResult(resourceServerId, new StringBuilder("findByResource").append(resourceId).toString(), () -> getDelegate().findByResource(resourceId, resourceServerId));
} }
@Override @Override
public List<Policy> findByResourceType(String resourceType, String resourceServerId) { public List<Policy> findByResourceType(String resourceType, String resourceServerId) {
return cacheResult(new StringBuilder("findByResourceType").append(resourceServerId).append(resourceType).toString(), () -> getDelegate().findByResourceType(resourceType, resourceServerId)); return cacheResult(resourceServerId, new StringBuilder("findByResourceType").append(resourceType).toString(), () -> getDelegate().findByResourceType(resourceType, resourceServerId));
} }
@Override @Override
@ -150,7 +152,7 @@ public class CachedPolicyStore implements PolicyStore {
List<Policy> policies = new ArrayList<>(); List<Policy> policies = new ArrayList<>();
for (String scopeId : scopeIds) { for (String scopeId : scopeIds) {
policies.addAll(cacheResult(new StringBuilder("findByScopeIds").append(resourceServerId).append(scopeId).toString(), () -> getDelegate().findByScopeIds(Arrays.asList(scopeId), resourceServerId))); policies.addAll(cacheResult(resourceServerId, new StringBuilder("findByScopeIds").append(scopeId).toString(), () -> getDelegate().findByScopeIds(Arrays.asList(scopeId), resourceServerId)));
} }
return policies; return policies;
@ -158,7 +160,7 @@ public class CachedPolicyStore implements PolicyStore {
@Override @Override
public List<Policy> findByType(String type, String resourceServerId) { public List<Policy> findByType(String type, String resourceServerId) {
return cacheResult(new StringBuilder("findByType").append(resourceServerId).append(type).toString(), () -> getDelegate().findByType(type, resourceServerId)); return cacheResult(resourceServerId, new StringBuilder("findByType").append(type).toString(), () -> getDelegate().findByType(type, resourceServerId));
} }
@Override @Override
@ -388,11 +390,10 @@ public class CachedPolicyStore implements PolicyStore {
this.updated = getDelegate().findById(getId(), cached.getResourceServerId()); this.updated = getDelegate().findById(getId(), cached.getResourceServerId());
if (this.updated == null) throw new IllegalStateException("Not found in database"); if (this.updated == null) throw new IllegalStateException("Not found in database");
transaction.whenCommit(() -> { transaction.whenCommit(() -> {
cache.remove(getCacheKeyForPolicy(getId()));
invalidateCache(cached.getResourceServerId()); invalidateCache(cached.getResourceServerId());
}); });
transaction.whenRollback(() -> { transaction.whenRollback(() -> {
cache.remove(getCacheKeyForPolicy(getId())); resolveResourceServerCache(cached.getResourceServerId()).remove(getCacheKeyForPolicy(getId()));
}); });
} }
@ -408,23 +409,12 @@ public class CachedPolicyStore implements PolicyStore {
return cachedStoreFactory; return cachedStoreFactory;
} }
private CachedPolicy updatePolicyCache(Policy policy) {
CachedPolicy cached = new CachedPolicy(policy);
List<CachedPolicy> cache = new ArrayList<>();
cache.add(cached);
this.cache.put(getCacheKeyForPolicy(policy.getId()), cache);
return cached;
}
private void invalidateCache(String resourceServerId) { private void invalidateCache(String resourceServerId) {
cacheKeys.forEach(cacheKey -> cache.keySet().stream().filter(key -> key.startsWith(cacheKey + resourceServerId)).forEach(cache::remove)); cache.remove(resourceServerId);
} }
private List<Policy> cacheResult(String key, Supplier<List<Policy>> provider) { private List<Policy> cacheResult(String resourceServerId, String key, Supplier<List<Policy>> provider) {
List<CachedPolicy> cached = cache.computeIfAbsent(key, (Function<String, List<CachedPolicy>>) o -> { List<CachedPolicy> cached = resolveResourceServerCache(resourceServerId).computeIfAbsent(key, (Function<String, List<CachedPolicy>>) o -> {
List<Policy> result = provider.get(); List<Policy> result = provider.get();
if (result.isEmpty()) { if (result.isEmpty()) {
@ -440,4 +430,8 @@ public class CachedPolicyStore implements PolicyStore {
return cached.stream().map(cachedPolicy -> createAdapter(cachedPolicy)).collect(Collectors.toList()); return cached.stream().map(cachedPolicy -> createAdapter(cachedPolicy)).collect(Collectors.toList());
} }
private Map<String, List<CachedPolicy>> resolveResourceServerCache(String id) {
return cache.computeIfAbsent(id, key -> new HashMap<>());
}
} }

View file

@ -18,9 +18,10 @@
package org.keycloak.models.authorization.infinispan; package org.keycloak.models.authorization.infinispan;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.infinispan.Cache; import org.infinispan.Cache;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
@ -44,7 +45,7 @@ public class CachedResourceServerStore implements ResourceServerStore {
private final CacheTransaction transaction; private final CacheTransaction transaction;
private StoreFactory storeFactory; private StoreFactory storeFactory;
private ResourceServerStore delegate; private ResourceServerStore delegate;
private final Cache<String, List> cache; private final Cache<String, Map<String, List<CachedResourceServer>>> cache;
public CachedResourceServerStore(KeycloakSession session, CacheTransaction transaction, StoreFactory storeFactory) { public CachedResourceServerStore(KeycloakSession session, CacheTransaction transaction, StoreFactory storeFactory) {
this.session = session; this.session = session;
@ -58,34 +59,33 @@ public class CachedResourceServerStore implements ResourceServerStore {
public ResourceServer create(String clientId) { public ResourceServer create(String clientId) {
ResourceServer resourceServer = getDelegate().create(clientId); ResourceServer resourceServer = getDelegate().create(clientId);
this.transaction.whenRollback(() -> cache.remove(getCacheKeyForResourceServer(resourceServer.getId()))); this.transaction.whenRollback(() -> resolveResourceServerCache(resourceServer.getId()).remove(getCacheKeyForResourceServer(resourceServer.getId())));
return createAdapter(new CachedResourceServer(resourceServer)); return createAdapter(new CachedResourceServer(resourceServer));
} }
@Override @Override
public void delete(String id) { public void delete(String id) {
ResourceServer resourceServer = getDelegate().findById(id);
getDelegate().delete(id); getDelegate().delete(id);
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
List<CachedResourceServer> servers = cache.remove(getCacheKeyForResourceServer(id)); cache.remove(id);
cache.remove(resourceServer.getClientId());
if (servers != null) {
CachedResourceServer entry = servers.get(0);
cache.remove(getCacheKeyForResourceServerClientId(entry.getClientId()));
}
}); });
} }
@Override @Override
public ResourceServer findById(String id) { public ResourceServer findById(String id) {
String cacheKeyForResourceServer = getCacheKeyForResourceServer(id); String cacheKeyForResourceServer = getCacheKeyForResourceServer(id);
List<ResourceServer> cached = this.cache.get(cacheKeyForResourceServer); List<CachedResourceServer> cached = resolveResourceServerCache(id).get(cacheKeyForResourceServer);
if (cached == null) { if (cached == null) {
ResourceServer resourceServer = getDelegate().findById(id); ResourceServer resourceServer = getDelegate().findById(id);
if (resourceServer != null) { if (resourceServer != null) {
return createAdapter(updateResourceServerCache(resourceServer)); CachedResourceServer cachedResourceServer = new CachedResourceServer(resourceServer);
resolveResourceServerCache(id).put(cacheKeyForResourceServer, Arrays.asList(cachedResourceServer));
return createAdapter(cachedResourceServer);
} }
return null; return null;
@ -97,20 +97,20 @@ public class CachedResourceServerStore implements ResourceServerStore {
@Override @Override
public ResourceServer findByClient(String id) { public ResourceServer findByClient(String id) {
String cacheKeyForResourceServer = getCacheKeyForResourceServerClientId(id); String cacheKeyForResourceServer = getCacheKeyForResourceServerClientId(id);
List<String> cached = this.cache.get(cacheKeyForResourceServer); List<CachedResourceServer> cached = resolveResourceServerCache(id).get(cacheKeyForResourceServer);
if (cached == null) { if (cached == null) {
ResourceServer resourceServer = getDelegate().findByClient(id); ResourceServer resourceServer = getDelegate().findByClient(id);
if (resourceServer != null) { if (resourceServer != null) {
cache.put(cacheKeyForResourceServer, Arrays.asList(resourceServer.getId())); resolveResourceServerCache(cacheKeyForResourceServer).put(cacheKeyForResourceServer, Arrays.asList(new CachedResourceServer(resourceServer)));
return findById(resourceServer.getId()); return findById(resourceServer.getId());
} }
return null; return null;
} }
return findById(cached.get(0)); return createAdapter(cached.get(0));
} }
private String getCacheKeyForResourceServer(String id) { private String getCacheKeyForResourceServer(String id) {
@ -173,7 +173,10 @@ public class CachedResourceServerStore implements ResourceServerStore {
if (this.updated == null) { if (this.updated == null) {
this.updated = getDelegate().findById(getId()); this.updated = getDelegate().findById(getId());
if (this.updated == null) throw new IllegalStateException("Not found in database"); if (this.updated == null) throw new IllegalStateException("Not found in database");
transaction.whenCommit(() -> cache.remove(getCacheKeyForResourceServer(getId()))); transaction.whenCommit(() -> {
cache.remove(getId());
cache.remove(getClientId());
});
} }
return this.updated; return this.updated;
@ -181,14 +184,7 @@ public class CachedResourceServerStore implements ResourceServerStore {
}; };
} }
private CachedResourceServer updateResourceServerCache(ResourceServer resourceServer) { private Map<String, List<CachedResourceServer>> resolveResourceServerCache(String id) {
CachedResourceServer cached = new CachedResourceServer(resourceServer); return cache.computeIfAbsent(id, key -> new HashMap<>());
List<ResourceServer> cache = new ArrayList<>();
cache.add(cached);
this.cache.put(getCacheKeyForResourceServer(resourceServer.getId()), cache);
return cached;
} }
} }

View file

@ -21,6 +21,7 @@ package org.keycloak.models.authorization.infinispan;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -53,7 +54,7 @@ public class CachedResourceStore implements ResourceStore {
private final List<String> cacheKeys; private final List<String> cacheKeys;
private StoreFactory storeFactory; private StoreFactory storeFactory;
private ResourceStore delegate; private ResourceStore delegate;
private final Cache<String, List<CachedResource>> cache; private final Cache<String, Map<String, List<CachedResource>>> cache;
public CachedResourceStore(KeycloakSession session, CacheTransaction transaction, StoreFactory storeFactory) { public CachedResourceStore(KeycloakSession session, CacheTransaction transaction, StoreFactory storeFactory) {
this.session = session; this.session = session;
@ -63,6 +64,7 @@ public class CachedResourceStore implements ResourceStore {
cacheKeys = new ArrayList<>(); cacheKeys = new ArrayList<>();
cacheKeys.add("findByOwner"); cacheKeys.add("findByOwner");
cacheKeys.add("findByUri"); cacheKeys.add("findByUri");
cacheKeys.add("findByName");
this.storeFactory = storeFactory; this.storeFactory = storeFactory;
} }
@ -71,12 +73,11 @@ public class CachedResourceStore implements ResourceStore {
Resource resource = getDelegate().create(name, getStoreFactory().getResourceServerStore().findById(resourceServer.getId()), owner); Resource resource = getDelegate().create(name, getStoreFactory().getResourceServerStore().findById(resourceServer.getId()), owner);
this.transaction.whenRollback(() -> { this.transaction.whenRollback(() -> {
cache.remove(getCacheKeyForResource(resource.getId())); resolveResourceServerCache(resourceServer.getId()).remove(getCacheKeyForResource(resource.getId()));
}); });
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
invalidateCache(resourceServer.getId()); invalidateCache(resourceServer.getId());
getCachedStoreFactory().getPolicyStore().notifyChange(resource);
}); });
return createAdapter(new CachedResource(resource)); return createAdapter(new CachedResource(resource));
@ -84,35 +85,29 @@ public class CachedResourceStore implements ResourceStore {
@Override @Override
public void delete(String id) { public void delete(String id) {
Resource resource = findById(id, null); Resource resource = getDelegate().findById(id, null);
if (resource == null) { if (resource == null) {
return; return;
} }
ResourceServer resourceServer = resource.getResourceServer(); ResourceServer resourceServer = resource.getResourceServer();
getDelegate().delete(id); getDelegate().delete(id);
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
List<CachedResource> resources = cache.remove(getCacheKeyForResource(id));
if (resources != null) {
CachedResource entry = resources.get(0);
cache.remove(getCacheKeyForResourceName(entry.getName(), entry.getResourceServerId()));
}
invalidateCache(resourceServer.getId()); invalidateCache(resourceServer.getId());
getCachedStoreFactory().getPolicyStore().notifyChange(resource);
}); });
} }
@Override @Override
public Resource findById(String id, String resourceServerId) { public Resource findById(String id, String resourceServerId) {
String cacheKeyForResource = getCacheKeyForResource(id); String cacheKeyForResource = getCacheKeyForResource(id);
List<CachedResource> cached = this.cache.get(cacheKeyForResource); List<CachedResource> cached = resolveResourceServerCache(resourceServerId).get(cacheKeyForResource);
if (cached == null) { if (cached == null) {
Resource resource = getDelegate().findById(id, resourceServerId); Resource resource = getDelegate().findById(id, resourceServerId);
if (resource != null) { if (resource != null) {
return createAdapter(updateResourceCache(resource)); CachedResource cachedResource = new CachedResource(resource);
resolveResourceServerCache(resourceServerId).put(cacheKeyForResource, Arrays.asList(cachedResource));
return createAdapter(cachedResource);
} }
return null; return null;
@ -123,12 +118,12 @@ public class CachedResourceStore implements ResourceStore {
@Override @Override
public List<Resource> findByOwner(String ownerId, String resourceServerId) { public List<Resource> findByOwner(String ownerId, String resourceServerId) {
return cacheResult(new StringBuilder("findByOwner").append(resourceServerId).append(ownerId).toString(), () -> getDelegate().findByOwner(ownerId, resourceServerId)); return cacheResult(resourceServerId, new StringBuilder("findByOwner").append(ownerId).toString(), () -> getDelegate().findByOwner(ownerId, resourceServerId));
} }
@Override @Override
public List<Resource> findByUri(String uri, String resourceServerId) { public List<Resource> findByUri(String uri, String resourceServerId) {
return cacheResult(new StringBuilder("findByUri").append(resourceServerId).append(uri).toString(), () -> getDelegate().findByUri(uri, resourceServerId)); return cacheResult(resourceServerId, new StringBuilder("findByUri").append(uri).toString(), () -> getDelegate().findByUri(uri, resourceServerId));
} }
@Override @Override
@ -149,13 +144,14 @@ public class CachedResourceStore implements ResourceStore {
@Override @Override
public Resource findByName(String name, String resourceServerId) { public Resource findByName(String name, String resourceServerId) {
String cacheKeyForResource = getCacheKeyForResourceName(name, resourceServerId); String cacheKeyForResource = getCacheKeyForResourceName(name, resourceServerId);
List<CachedResource> cached = this.cache.get(cacheKeyForResource); List<CachedResource> cached = resolveResourceServerCache(resourceServerId).get(cacheKeyForResource);
if (cached == null) { if (cached == null) {
Resource resource = getDelegate().findByName(name, resourceServerId); Resource resource = getDelegate().findByName(name, resourceServerId);
if (resource != null) { if (resource != null) {
cache.put(cacheKeyForResource, Arrays.asList(new CachedResource(resource))); invalidateCache(resourceServerId);
resolveResourceServerCache(resourceServerId).put(cacheKeyForResource, Arrays.asList(new CachedResource(resource)));
return findById(resource.getId(), resourceServerId); return findById(resource.getId(), resourceServerId);
} }
@ -280,15 +276,14 @@ public class CachedResourceStore implements ResourceStore {
private Resource getDelegateForUpdate() { private Resource getDelegateForUpdate() {
if (this.updated == null) { if (this.updated == null) {
this.updated = getDelegate().findById(getId(), cached.getResourceServerId()); String resourceServerId = cached.getResourceServerId();
this.updated = getDelegate().findById(getId(), resourceServerId);
if (this.updated == null) throw new IllegalStateException("Not found in database"); if (this.updated == null) throw new IllegalStateException("Not found in database");
transaction.whenCommit(() -> { transaction.whenCommit(() -> {
cache.remove(getCacheKeyForResource(cached.getId())); invalidateCache(resourceServerId);
invalidateCache(cached.getResourceServerId());
getCachedStoreFactory().getPolicyStore().notifyChange(updated);
}); });
transaction.whenRollback(() -> { transaction.whenRollback(() -> {
cache.remove(getCacheKeyForResource(cached.getId())); resolveResourceServerCache(resourceServerId).remove(getCacheKeyForResource(cached.getId()));
}); });
} }
@ -301,19 +296,8 @@ public class CachedResourceStore implements ResourceStore {
return session.getProvider(CachedStoreFactoryProvider.class); return session.getProvider(CachedStoreFactoryProvider.class);
} }
private CachedResource updateResourceCache(Resource resource) { private List<Resource> cacheResult(String resourceServerId, String key, Supplier<List<Resource>> provider) {
CachedResource cached = new CachedResource(resource); List<CachedResource> cached = resolveResourceServerCache(resourceServerId).computeIfAbsent(key, (Function<String, List<CachedResource>>) o -> {
List cache = new ArrayList<>();
cache.add(cached);
this.cache.put(getCacheKeyForResource(resource.getId()), cache);
return cached;
}
private List<Resource> cacheResult(String key, Supplier<List<Resource>> provider) {
List<CachedResource> cached = cache.computeIfAbsent(key, (Function<String, List<CachedResource>>) o -> {
List<Resource> result = provider.get(); List<Resource> result = provider.get();
if (result.isEmpty()) { if (result.isEmpty()) {
@ -327,10 +311,20 @@ public class CachedResourceStore implements ResourceStore {
return Collections.emptyList(); return Collections.emptyList();
} }
return cached.stream().map(this::createAdapter).collect(Collectors.toList()); List<Resource> adapters = new ArrayList<>();
for (CachedResource resource : cached) {
adapters.add(createAdapter(resource));
}
return adapters;
} }
private void invalidateCache(String resourceServerId) { private void invalidateCache(String resourceServerId) {
cacheKeys.forEach(cacheKey -> cache.keySet().stream().filter(key -> key.startsWith(cacheKey + resourceServerId)).forEach(cache::remove)); cache.remove(resourceServerId);
}
private Map<String, List<CachedResource>> resolveResourceServerCache(String id) {
return cache.computeIfAbsent(id, key -> new HashMap<>());
} }
} }

View file

@ -18,13 +18,12 @@
package org.keycloak.models.authorization.infinispan; package org.keycloak.models.authorization.infinispan;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.infinispan.Cache; import org.infinispan.Cache;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.model.Scope;
import org.keycloak.authorization.store.ScopeStore; import org.keycloak.authorization.store.ScopeStore;
@ -43,7 +42,7 @@ public class CachedScopeStore implements ScopeStore {
private static final String SCOPE_ID_CACHE_PREFIX = "scp-id-"; private static final String SCOPE_ID_CACHE_PREFIX = "scp-id-";
private static final String SCOPE_NAME_CACHE_PREFIX = "scp-name-"; private static final String SCOPE_NAME_CACHE_PREFIX = "scp-name-";
private final Cache<String, List> cache; private final Cache<String, Map<String, List<CachedScope>>> cache;
private final KeycloakSession session; private final KeycloakSession session;
private final CacheTransaction transaction; private final CacheTransaction transaction;
private ScopeStore delegate; private ScopeStore delegate;
@ -61,9 +60,9 @@ public class CachedScopeStore implements ScopeStore {
public Scope create(String name, ResourceServer resourceServer) { public Scope create(String name, ResourceServer resourceServer) {
Scope scope = getDelegate().create(name, getStoreFactory().getResourceServerStore().findById(resourceServer.getId())); Scope scope = getDelegate().create(name, getStoreFactory().getResourceServerStore().findById(resourceServer.getId()));
this.transaction.whenRollback(() -> cache.remove(getCacheKeyForScope(scope.getId()))); this.transaction.whenRollback(() -> resolveResourceServerCache(resourceServer.getId()).remove(getCacheKeyForScope(scope.getId())));
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
getCachedStoreFactory().getPolicyStore().notifyChange(scope); invalidateCache(resourceServer.getId());
}); });
return createAdapter(new CachedScope(scope)); return createAdapter(new CachedScope(scope));
@ -71,33 +70,29 @@ public class CachedScopeStore implements ScopeStore {
@Override @Override
public void delete(String id) { public void delete(String id) {
Scope scope = findById(id, null); Scope scope = getDelegate().findById(id, null);
if (scope == null) { if (scope == null) {
return; return;
} }
ResourceServer resourceServer = scope.getResourceServer();
getDelegate().delete(id); getDelegate().delete(id);
this.transaction.whenCommit(() -> { this.transaction.whenCommit(() -> {
List<CachedScope> scopes = cache.remove(getCacheKeyForScope(id)); invalidateCache(resourceServer.getId());
if (scopes != null) {
CachedScope entry = scopes.get(0);
cache.remove(getCacheKeyForScopeName(entry.getName(), entry.getResourceServerId()));
}
getCachedStoreFactory().getPolicyStore().notifyChange(scope);
}); });
} }
@Override @Override
public Scope findById(String id, String resourceServerId) { public Scope findById(String id, String resourceServerId) {
String cacheKeyForScope = getCacheKeyForScope(id); String cacheKeyForScope = getCacheKeyForScope(id);
List<CachedScope> cached = this.cache.get(cacheKeyForScope); List<CachedScope> cached = resolveResourceServerCache(resourceServerId).get(cacheKeyForScope);
if (cached == null) { if (cached == null) {
Scope scope = getDelegate().findById(id, resourceServerId); Scope scope = getDelegate().findById(id, resourceServerId);
if (scope != null) { if (scope != null) {
return createAdapter(updateScopeCache(scope)); CachedScope cachedScope = new CachedScope(scope);
resolveResourceServerCache(resourceServerId).put(cacheKeyForScope, Arrays.asList(cachedScope));
return createAdapter(cachedScope);
} }
return null; return null;
@ -108,21 +103,21 @@ public class CachedScopeStore implements ScopeStore {
@Override @Override
public Scope findByName(String name, String resourceServerId) { public Scope findByName(String name, String resourceServerId) {
String cacheKeyForScope = getCacheKeyForScopeName(name, resourceServerId); String cacheKeyForScope = getCacheKeyForScopeName(name);
List<String> cached = this.cache.get(cacheKeyForScope); List<CachedScope> cached = resolveResourceServerCache(resourceServerId).get(cacheKeyForScope);
if (cached == null) { if (cached == null) {
Scope scope = getDelegate().findByName(name, resourceServerId); Scope scope = getDelegate().findByName(name, resourceServerId);
if (scope != null) { if (scope != null) {
cache.put(cacheKeyForScope, Arrays.asList(scope.getId())); resolveResourceServerCache(resourceServerId).put(cacheKeyForScope, Arrays.asList(new CachedScope(scope)));
return findById(scope.getId(), resourceServerId); return findById(scope.getId(), resourceServerId);
} }
return null; return null;
} }
return findById(cached.get(0), resourceServerId); return createAdapter(cached.get(0));
} }
@Override @Override
@ -139,8 +134,8 @@ public class CachedScopeStore implements ScopeStore {
return SCOPE_ID_CACHE_PREFIX + id; return SCOPE_ID_CACHE_PREFIX + id;
} }
private String getCacheKeyForScopeName(String name, String resourceServerId) { private String getCacheKeyForScopeName(String name) {
return SCOPE_NAME_CACHE_PREFIX + name + "-" + resourceServerId; return SCOPE_NAME_CACHE_PREFIX + name;
} }
private ScopeStore getDelegate() { private ScopeStore getDelegate() {
@ -197,11 +192,11 @@ public class CachedScopeStore implements ScopeStore {
this.updated = getDelegate().findById(getId(), cached.getResourceServerId()); this.updated = getDelegate().findById(getId(), cached.getResourceServerId());
if (this.updated == null) throw new IllegalStateException("Not found in database"); if (this.updated == null) throw new IllegalStateException("Not found in database");
transaction.whenCommit(() -> { transaction.whenCommit(() -> {
cache.remove(getCacheKeyForScope(getId())); invalidateCache(cached.getResourceServerId());
getCachedStoreFactory().getPolicyStore().notifyChange(updated);
}); });
transaction.whenRollback(() -> { transaction.whenRollback(() -> {
cache.remove(getCacheKeyForScope(cached.getId())); resolveResourceServerCache(cached.getResourceServerId()).remove(getCacheKeyForScope(cached.getId()));
resolveResourceServerCache(cached.getResourceServerId()).remove(getCacheKeyForScopeName(cached.getName()));
}); });
} }
@ -214,15 +209,11 @@ public class CachedScopeStore implements ScopeStore {
return session.getProvider(CachedStoreFactoryProvider.class); return session.getProvider(CachedStoreFactoryProvider.class);
} }
private CachedScope updateScopeCache(Scope scope) { private void invalidateCache(String resourceServerId) {
CachedScope cached = new CachedScope(scope); cache.remove(resourceServerId);
}
List cache = new ArrayList(); private Map<String, List<CachedScope>> resolveResourceServerCache(String id) {
return cache.computeIfAbsent(id, key -> new HashMap<>());
cache.add(cached);
this.transaction.whenCommit(() -> this.cache.put(getCacheKeyForScope(scope.getId()), cache));
return cached;
} }
} }

View file

@ -56,6 +56,6 @@ public class InfinispanStoreProviderFactory implements CachedStoreProviderFactor
@Override @Override
public boolean isSupported() { public boolean isSupported() {
return false; return true;
} }
} }

View file

@ -58,9 +58,6 @@
<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button>
<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button>
<button data-ng-click="nextPage()" class="next" ng-disabled="policies.length < query.max">{{:: 'next-page' | translate}}</button> <button data-ng-click="nextPage()" class="next" ng-disabled="policies.length < query.max">{{:: 'next-page' | translate}}</button>
<select class="first" data-ng-model="query.max"
ng-options="size for size in listSizes" data-ng-change="firstPage()">
</select>
</div> </div>
</td> </td>
</tr> </tr>

View file

@ -60,9 +60,6 @@
<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button>
<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button>
<button data-ng-click="nextPage()" class="next" ng-disabled="policies.length < query.max">{{:: 'next-page' | translate}}</button> <button data-ng-click="nextPage()" class="next" ng-disabled="policies.length < query.max">{{:: 'next-page' | translate}}</button>
<select class="first" data-ng-model="query.max"
ng-options="size for size in listSizes" data-ng-change="firstPage()">
</select>
</div> </div>
</td> </td>
</tr> </tr>

View file

@ -67,9 +67,6 @@
<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button>
<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button>
<button data-ng-click="nextPage()" class="next" ng-disabled="resources.length < query.max">{{:: 'next-page' | translate}}</button> <button data-ng-click="nextPage()" class="next" ng-disabled="resources.length < query.max">{{:: 'next-page' | translate}}</button>
<select class="first" data-ng-model="query.max"
ng-options="size for size in listSizes" data-ng-change="firstPage()">
</select>
</div> </div>
</td> </td>
</tr> </tr>

View file

@ -39,9 +39,6 @@
<button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button> <button data-ng-click="firstPage()" class="first" ng-disabled="query.first == 0">{{:: 'first-page' | translate}}</button>
<button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button> <button data-ng-click="previousPage()" class="prev" ng-disabled="query.first == 0">{{:: 'previous-page' | translate}}</button>
<button data-ng-click="nextPage()" class="next" ng-disabled="scopes.length < query.max">{{:: 'next-page' | translate}}</button> <button data-ng-click="nextPage()" class="next" ng-disabled="scopes.length < query.max">{{:: 'next-page' | translate}}</button>
<select class="first" data-ng-model="query.max"
ng-options="size for size in listSizes" data-ng-change="firstPage()">
</select>
</div> </div>
</td> </td>
</tr> </tr>