[KEYCLOAK-4913] - Caching more query methods
This commit is contained in:
parent
8d40ee17f1
commit
37a98fba20
10 changed files with 249 additions and 26 deletions
|
@ -26,6 +26,8 @@ import java.util.Collections;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -44,7 +46,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
|||
@Override
|
||||
public Resource getDelegateForUpdate() {
|
||||
if (updated == null) {
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getResourceServerId());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUri(), cached.getScopesIds(), cached.getResourceServerId());
|
||||
updated = cacheSession.getResourceStoreDelegate().findById(cached.getId(), cached.getResourceServerId());
|
||||
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||
}
|
||||
|
@ -164,6 +166,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
|||
@Override
|
||||
public void updateScopes(Set<Scope> scopes) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUri(), scopes.stream().map(scope1 -> scope1.getId()).collect(Collectors.toSet()), cached.getResourceServerId());
|
||||
updated.updateScopes(scopes);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.keycloak.models.cache.infinispan.CacheManager;
|
|||
import org.keycloak.models.cache.infinispan.RealmCacheManager;
|
||||
import org.keycloak.models.cache.infinispan.authorization.events.AuthorizationCacheInvalidationEvent;
|
||||
import org.keycloak.models.cache.infinispan.authorization.stream.InResourceServerPredicate;
|
||||
import org.keycloak.models.cache.infinispan.authorization.stream.InScopePredicate;
|
||||
import org.keycloak.models.cache.infinispan.entities.Revisioned;
|
||||
import org.keycloak.models.cache.infinispan.events.InvalidationEvent;
|
||||
|
||||
|
@ -65,19 +66,36 @@ public class StoreFactoryCacheManager extends CacheManager {
|
|||
public void scopeUpdated(String id, String name, String serverId, Set<String> invalidations) {
|
||||
invalidations.add(id);
|
||||
invalidations.add(StoreFactoryCacheSession.getScopeByNameCacheKey(name, serverId));
|
||||
invalidations.add(StoreFactoryCacheSession.getResourceByScopeCacheKey(id, serverId));
|
||||
}
|
||||
|
||||
public void scopeRemoval(String id, String name, String serverId, Set<String> invalidations) {
|
||||
scopeUpdated(id, name, serverId, invalidations);
|
||||
addInvalidations(InScopePredicate.create().scope(id), invalidations);
|
||||
}
|
||||
|
||||
public void resourceUpdated(String id, String name, String serverId, Set<String> invalidations) {
|
||||
public void resourceUpdated(String id, String name, String type, String uri, Set<String> scopes, String serverId, Set<String> invalidations) {
|
||||
invalidations.add(id);
|
||||
invalidations.add(StoreFactoryCacheSession.getResourceByNameCacheKey(name, serverId));
|
||||
|
||||
if (type != null) {
|
||||
invalidations.add(StoreFactoryCacheSession.getResourceByTypeCacheKey(type, serverId));
|
||||
}
|
||||
|
||||
if (uri != null) {
|
||||
invalidations.add(StoreFactoryCacheSession.getResourceByUriCacheKey(uri, serverId));
|
||||
}
|
||||
|
||||
if (scopes != null) {
|
||||
for (String scope : scopes) {
|
||||
invalidations.add(StoreFactoryCacheSession.getResourceByScopeCacheKey(scope, serverId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void resourceRemoval(String id, String name, String serverId, Set<String> invalidations) {
|
||||
resourceUpdated(id, name, serverId, invalidations);
|
||||
public void resourceRemoval(String id, String name, String type, String uri, String owner, Set<String> scopes, String serverId, Set<String> invalidations) {
|
||||
resourceUpdated(id, name, type, uri, scopes, serverId, invalidations);
|
||||
invalidations.add(StoreFactoryCacheSession.getResourceByOwnerCacheKey(owner, serverId));
|
||||
}
|
||||
|
||||
public void policyUpdated(String id, String name, String serverId, Set<String> invalidations) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.keycloak.models.cache.infinispan.authorization.entities.CachedResourc
|
|||
import org.keycloak.models.cache.infinispan.authorization.entities.CachedScope;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.PolicyListQuery;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.ResourceListQuery;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.ResourceScopeListQuery;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.ResourceServerListQuery;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.ScopeListQuery;
|
||||
import org.keycloak.models.cache.infinispan.authorization.events.PolicyRemovedEvent;
|
||||
|
@ -48,11 +49,16 @@ import org.keycloak.models.cache.infinispan.authorization.events.ScopeUpdatedEve
|
|||
import org.keycloak.models.cache.infinispan.events.InvalidationEvent;
|
||||
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -233,12 +239,12 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
|
|||
invalidationEvents.add(ScopeUpdatedEvent.create(id, name, serverId));
|
||||
}
|
||||
|
||||
public void registerResourceInvalidation(String id, String name, String serverId) {
|
||||
cache.resourceUpdated(id, name, serverId, invalidations);
|
||||
public void registerResourceInvalidation(String id, String name, String type, String uri, Set<String> scopes, String serverId) {
|
||||
cache.resourceUpdated(id, name, type, uri, scopes, serverId, invalidations);
|
||||
ResourceAdapter adapter = managedResources.get(id);
|
||||
if (adapter != null) adapter.invalidateFlag();
|
||||
|
||||
invalidationEvents.add(ResourceUpdatedEvent.create(id, name, serverId));
|
||||
invalidationEvents.add(ResourceUpdatedEvent.create(id, name, type, uri, scopes, serverId));
|
||||
}
|
||||
|
||||
public void registerPolicyInvalidation(String id, String name, String serverId) {
|
||||
|
@ -277,6 +283,22 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
|
|||
return "resource.name." + name + "." + serverId;
|
||||
}
|
||||
|
||||
public static String getResourceByOwnerCacheKey(String owner, String serverId) {
|
||||
return "resource.owner." + owner + "." + serverId;
|
||||
}
|
||||
|
||||
public static String getResourceByTypeCacheKey(String type, String serverId) {
|
||||
return "resource.type." + type + "." + serverId;
|
||||
}
|
||||
|
||||
public static String getResourceByUriCacheKey(String uri, String serverId) {
|
||||
return "resource.uri." + uri + "." + serverId;
|
||||
}
|
||||
|
||||
public static String getResourceByScopeCacheKey(String scopeId, String serverId) {
|
||||
return "resource.scope." + scopeId + "." + serverId;
|
||||
}
|
||||
|
||||
public static String getPolicyByNameCacheKey(String name, String serverId) {
|
||||
return "policy.name." + name + "." + serverId;
|
||||
}
|
||||
|
@ -451,7 +473,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
|
|||
@Override
|
||||
public Resource create(String name, ResourceServer resourceServer, String owner) {
|
||||
Resource resource = getResourceStoreDelegate().create(name, resourceServer, owner);
|
||||
registerResourceInvalidation(resource.getId(), resource.getName(), resourceServer.getId());
|
||||
registerResourceInvalidation(resource.getId(), resource.getName(), resource.getType(), resource.getUri(), resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toSet()), resourceServer.getId());
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
@ -462,8 +484,8 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
|
|||
if (resource == null) return;
|
||||
|
||||
cache.invalidateObject(id);
|
||||
invalidationEvents.add(ResourceRemovedEvent.create(id, resource.getName(), resource.getResourceServer().getId()));
|
||||
cache.resourceRemoval(id, resource.getName(), resource.getResourceServer().getId(), invalidations);
|
||||
invalidationEvents.add(ResourceRemovedEvent.create(id, resource.getName(), resource.getType(), resource.getUri(), resource.getOwner(), resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toSet()), resource.getResourceServer().getId()));
|
||||
cache.resourceRemoval(id, resource.getName(), resource.getType(), resource.getUri(), resource.getOwner(), resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toSet()), resource.getResourceServer().getId(), invalidations);
|
||||
getResourceStoreDelegate().delete(id);
|
||||
|
||||
}
|
||||
|
@ -523,12 +545,48 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
|
|||
|
||||
@Override
|
||||
public List<Resource> findByOwner(String ownerId, String resourceServerId) {
|
||||
return getResourceStoreDelegate().findByOwner(ownerId, resourceServerId);
|
||||
if (ownerId == null) return null;
|
||||
String cacheKey = getResourceByOwnerCacheKey(ownerId, resourceServerId);
|
||||
ResourceListQuery query = cache.get(cacheKey, ResourceListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("resource by owner cache hit: {0}", ownerId);
|
||||
}
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
List<Resource> model = getResourceStoreDelegate().findByOwner(ownerId, resourceServerId);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(cacheKey)) return model;
|
||||
query = new ResourceListQuery(loaded, cacheKey, model.stream().map(resource -> resource.getId()).collect(Collectors.toSet()), resourceServerId);
|
||||
cache.addRevisioned(query, startupRevision);
|
||||
return model;
|
||||
} else if (invalidations.contains(cacheKey)) {
|
||||
return getResourceStoreDelegate().findByOwner(ownerId, resourceServerId);
|
||||
} else {
|
||||
return query.getResources().stream().map(resourceId -> findById(resourceId, resourceServerId)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource> findByUri(String uri, String resourceServerId) {
|
||||
return getResourceStoreDelegate().findByUri(uri, resourceServerId);
|
||||
if (uri == null) return null;
|
||||
String cacheKey = getResourceByUriCacheKey(uri, resourceServerId);
|
||||
ResourceListQuery query = cache.get(cacheKey, ResourceListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("resource by uri cache hit: {0}", uri);
|
||||
}
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
List<Resource> model = getResourceStoreDelegate().findByUri(uri, resourceServerId);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(cacheKey)) return model;
|
||||
query = new ResourceListQuery(loaded, cacheKey, model.stream().map(resource -> resource.getId()).collect(Collectors.toSet()), resourceServerId);
|
||||
cache.addRevisioned(query, startupRevision);
|
||||
return model;
|
||||
} else if (invalidations.contains(cacheKey)) {
|
||||
return getResourceStoreDelegate().findByUri(uri, resourceServerId);
|
||||
} else {
|
||||
return query.getResources().stream().map(resourceId -> findById(resourceId, resourceServerId)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -543,12 +601,58 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
|
|||
|
||||
@Override
|
||||
public List<Resource> findByScope(List<String> ids, String resourceServerId) {
|
||||
return getResourceStoreDelegate().findByScope(ids, resourceServerId);
|
||||
if (ids == null) return null;
|
||||
List<Resource> result = new ArrayList<>();
|
||||
Iterator<String> iterator = ids.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
String id = iterator.next();
|
||||
String cacheKey = getResourceByScopeCacheKey(id, resourceServerId);
|
||||
ResourceScopeListQuery query = cache.get(cacheKey, ResourceScopeListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("resource by scope cache hit: {0}", id);
|
||||
if (invalidations.contains(cacheKey)) {
|
||||
result.addAll(getResourceStoreDelegate().findByScope(ids, resourceServerId));
|
||||
} else {
|
||||
result.addAll(query.getResources().stream().map(resourceId -> findById(resourceId, resourceServerId)).collect(Collectors.toList()));
|
||||
}
|
||||
} else if (invalidations.contains(id)) {
|
||||
result.addAll(getResourceStoreDelegate().findByScope(ids, resourceServerId));
|
||||
} else {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
List<Resource> model = getResourceStoreDelegate().findByScope(Arrays.asList(id), resourceServerId);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(cacheKey)) return model;
|
||||
query = new ResourceScopeListQuery(loaded, cacheKey, id, model.stream().map(resource -> resource.getId()).collect(Collectors.toSet()), resourceServerId);
|
||||
cache.addRevisioned(query, startupRevision);
|
||||
result.addAll(query.getResources().stream().map(resourceId -> findById(resourceId, resourceServerId)).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Resource> findByType(String type, String resourceServerId) {
|
||||
return getResourceStoreDelegate().findByType(type, resourceServerId);
|
||||
if (type == null) return null;
|
||||
String cacheKey = getResourceByTypeCacheKey(type, resourceServerId);
|
||||
ResourceListQuery query = cache.get(cacheKey, ResourceListQuery.class);
|
||||
if (query != null) {
|
||||
logger.tracev("resource by type cache hit: {0}", type);
|
||||
}
|
||||
if (query == null) {
|
||||
Long loaded = cache.getCurrentRevision(cacheKey);
|
||||
List<Resource> model = getResourceStoreDelegate().findByType(type, resourceServerId);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(cacheKey)) return model;
|
||||
query = new ResourceListQuery(loaded, cacheKey, model.stream().map(resource -> resource.getId()).collect(Collectors.toSet()), resourceServerId);
|
||||
cache.addRevisioned(query, startupRevision);
|
||||
return model;
|
||||
} else if (invalidations.contains(cacheKey)) {
|
||||
return getResourceStoreDelegate().findByType(type, resourceServerId);
|
||||
} else {
|
||||
return query.getResources().stream().map(resourceId -> findById(resourceId, resourceServerId)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.models.cache.infinispan.authorization.entities;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface InScope {
|
||||
String getScopeId();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.keycloak.models.cache.infinispan.authorization.entities;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.keycloak.models.cache.infinispan.entities.AbstractRevisioned;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ResourceScopeListQuery extends ResourceListQuery implements InScope {
|
||||
|
||||
private final String scopeId;
|
||||
|
||||
public ResourceScopeListQuery(Long revision, String id, String scopeId, Set<String> resources, String serverId) {
|
||||
super(revision, id, resources, serverId);
|
||||
this.scopeId = scopeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScopeId() {
|
||||
return scopeId;
|
||||
}
|
||||
}
|
|
@ -29,12 +29,20 @@ public class ResourceRemovedEvent extends InvalidationEvent implements Authoriza
|
|||
|
||||
private String id;
|
||||
private String name;
|
||||
private String owner;
|
||||
private String serverId;
|
||||
private String type;
|
||||
private String uri;
|
||||
private Set<String> scopes;
|
||||
|
||||
public static ResourceRemovedEvent create(String id, String name, String serverId) {
|
||||
public static ResourceRemovedEvent create(String id, String name, String type, String uri, String owner, Set<String> scopes, String serverId) {
|
||||
ResourceRemovedEvent event = new ResourceRemovedEvent();
|
||||
event.id = id;
|
||||
event.name = name;
|
||||
event.type = type;
|
||||
event.uri = uri;
|
||||
event.owner = owner;
|
||||
event.scopes = scopes;
|
||||
event.serverId = serverId;
|
||||
return event;
|
||||
}
|
||||
|
@ -51,6 +59,6 @@ public class ResourceRemovedEvent extends InvalidationEvent implements Authoriza
|
|||
|
||||
@Override
|
||||
public void addInvalidations(StoreFactoryCacheManager cache, Set<String> invalidations) {
|
||||
cache.resourceRemoval(id, name, serverId, invalidations);
|
||||
cache.resourceRemoval(id, name, type, uri, owner, scopes, serverId, invalidations);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,11 +30,17 @@ public class ResourceUpdatedEvent extends InvalidationEvent implements Authoriza
|
|||
private String id;
|
||||
private String name;
|
||||
private String serverId;
|
||||
private String type;
|
||||
private String uri;
|
||||
private Set<String> scopes;
|
||||
|
||||
public static ResourceUpdatedEvent create(String id, String name, String serverId) {
|
||||
public static ResourceUpdatedEvent create(String id, String name, String type, String uri, Set<String> scopes, String serverId) {
|
||||
ResourceUpdatedEvent event = new ResourceUpdatedEvent();
|
||||
event.id = id;
|
||||
event.name = name;
|
||||
event.type = type;
|
||||
event.uri = uri;
|
||||
event.scopes = scopes;
|
||||
event.serverId = serverId;
|
||||
return event;
|
||||
}
|
||||
|
@ -51,6 +57,6 @@ public class ResourceUpdatedEvent extends InvalidationEvent implements Authoriza
|
|||
|
||||
@Override
|
||||
public void addInvalidations(StoreFactoryCacheManager cache, Set<String> invalidations) {
|
||||
cache.resourceUpdated(id, name, serverId, invalidations);
|
||||
cache.resourceUpdated(id, name, type, uri, scopes, serverId, invalidations);
|
||||
}
|
||||
}
|
||||
|
|
35
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/stream/InScopePredicate.java
vendored
Executable file
35
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/stream/InScopePredicate.java
vendored
Executable file
|
@ -0,0 +1,35 @@
|
|||
package org.keycloak.models.cache.infinispan.authorization.stream;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.InResourceServer;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.InScope;
|
||||
import org.keycloak.models.cache.infinispan.entities.Revisioned;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class InScopePredicate implements Predicate<Map.Entry<String, Revisioned>>, Serializable {
|
||||
private String scopeId;
|
||||
|
||||
public static InScopePredicate create() {
|
||||
return new InScopePredicate();
|
||||
}
|
||||
|
||||
public InScopePredicate scope(String id) {
|
||||
scopeId = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Map.Entry<String, Revisioned> entry) {
|
||||
Object value = entry.getValue();
|
||||
if (value == null) return false;
|
||||
if (!(value instanceof InScope)) return false;
|
||||
|
||||
return scopeId.equals(((InScope)value).getScopeId());
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -238,10 +239,7 @@ public class AuthorizationTokenService {
|
|||
|
||||
if ("$KC_SCOPE_PERMISSION".equals(key)) {
|
||||
ScopeStore scopeStore = authorization.getStoreFactory().getScopeStore();
|
||||
List<Scope> scopes = entry.getValue().stream().map(scopeName -> {
|
||||
Scope byName = scopeStore.findByName(scopeName, resourceServer.getId());
|
||||
return byName;
|
||||
}).collect(Collectors.toList());
|
||||
List<Scope> scopes = entry.getValue().stream().map(scopeName -> scopeStore.findByName(scopeName, resourceServer.getId())).filter(scope -> Objects.nonNull(scope)).collect(Collectors.toList());
|
||||
return Arrays.asList(new ResourcePermission(null, scopes, resourceServer)).stream();
|
||||
} else {
|
||||
Resource entryResource = storeFactory.getResourceStore().findById(key, resourceServer.getId());
|
||||
|
|
|
@ -23,8 +23,10 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -319,10 +321,7 @@ public class EntitlementService {
|
|||
|
||||
if ("$KC_SCOPE_PERMISSION".equals(key)) {
|
||||
ScopeStore scopeStore = authorization.getStoreFactory().getScopeStore();
|
||||
List<Scope> scopes = entry.getValue().stream().map(scopeName -> {
|
||||
Scope byName = scopeStore.findByName(scopeName, resourceServer.getId());
|
||||
return byName;
|
||||
}).collect(Collectors.toList());
|
||||
List<Scope> scopes = entry.getValue().stream().map(scopeName -> scopeStore.findByName(scopeName, resourceServer.getId())).filter(scope -> Objects.nonNull(scope)).collect(Collectors.toList());
|
||||
return Arrays.asList(new ResourcePermission(null, scopes, resourceServer)).stream();
|
||||
} else {
|
||||
Resource entryResource = storeFactory.getResourceStore().findById(key, resourceServer.getId());
|
||||
|
|
Loading…
Reference in a new issue