keycloak-uncached
Changes
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/entities/CachedResourceServer.java 5(+2 -3)
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java 59(+43 -16)
Details
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/entities/CachedResourceServer.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/entities/CachedResourceServer.java
index a904bd1..ac07f6e 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/entities/CachedResourceServer.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/entities/CachedResourceServer.java
@@ -27,8 +27,8 @@ import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
*/
public class CachedResourceServer extends AbstractRevisioned {
- private boolean allowRemoteResourceManagement;
- private PolicyEnforcementMode policyEnforcementMode;
+ private final boolean allowRemoteResourceManagement;
+ private final PolicyEnforcementMode policyEnforcementMode;
public CachedResourceServer(Long revision, ResourceServer resourceServer) {
super(revision, resourceServer.getId());
@@ -43,5 +43,4 @@ public class CachedResourceServer extends AbstractRevisioned {
public PolicyEnforcementMode getPolicyEnforcementMode() {
return this.policyEnforcementMode;
}
-
}
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java
index 717d6a2..c2b60c7 100644
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java
@@ -74,6 +74,7 @@ import org.keycloak.models.cache.infinispan.authorization.events.ResourceServerU
import org.keycloak.models.cache.infinispan.authorization.events.ResourceUpdatedEvent;
import org.keycloak.models.cache.infinispan.authorization.events.ScopeRemovedEvent;
import org.keycloak.models.cache.infinispan.authorization.events.ScopeUpdatedEvent;
+import org.keycloak.models.cache.infinispan.entities.NonExistentItem;
import org.keycloak.models.cache.infinispan.events.InvalidationEvent;
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
import org.keycloak.storage.StorageId;
@@ -400,6 +401,15 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
return delegate;
}
+ private void setModelDoesNotExists(String id, Long loaded) {
+ if (! invalidations.contains(id)) {
+ cache.addRevisioned(new NonExistentItem(id, loaded), startupRevision);
+ }
+ }
+
+ private boolean modelMightExist(String id) {
+ return invalidations.contains(id) || cache.get(id, NonExistentItem.class) == null;
+ }
protected class ResourceServerCache implements ResourceServerStore {
@Override
@@ -425,22 +435,25 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
}
- @Override
+ @Override
public ResourceServer findById(String id) {
if (id == null) return null;
CachedResourceServer cached = cache.get(id, CachedResourceServer.class);
if (cached != null) {
logger.tracev("by id cache hit: {0}", cached.getId());
}
- boolean wasCached = false;
+
if (cached == null) {
Long loaded = cache.getCurrentRevision(id);
+ if (! modelMightExist(id)) return null;
ResourceServer model = getResourceServerStoreDelegate().findById(id);
- if (model == null) return null;
+ if (model == null) {
+ setModelDoesNotExists(id, loaded);
+ return null;
+ }
if (invalidations.contains(id)) return model;
cached = new CachedResourceServer(loaded, model);
cache.addRevisioned(cached, startupRevision);
- wasCached =true;
} else if (invalidations.contains(id)) {
return getResourceServerStoreDelegate().findById(id);
} else if (managedResourceServers.containsKey(id)) {
@@ -484,15 +497,17 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
if (cached != null) {
logger.tracev("by id cache hit: {0}", cached.getId());
}
- boolean wasCached = false;
if (cached == null) {
Long loaded = cache.getCurrentRevision(id);
+ if (! modelMightExist(id)) return null;
Scope model = getScopeStoreDelegate().findById(id, resourceServerId);
- if (model == null) return null;
+ if (model == null) {
+ setModelDoesNotExists(id, loaded);
+ return null;
+ }
if (invalidations.contains(id)) return model;
cached = new CachedScope(loaded, model);
cache.addRevisioned(cached, startupRevision);
- wasCached =true;
} else if (invalidations.contains(id)) {
return getScopeStoreDelegate().findById(id, resourceServerId);
} else if (managedScopes.containsKey(id)) {
@@ -552,6 +567,9 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
Resource resource = getResourceStoreDelegate().create(id, name, resourceServer, owner);
Resource cached = findById(resource.getId(), resourceServer.getId());
registerResourceInvalidation(resource.getId(), resource.getName(), resource.getType(), resource.getUris(), resource.getScopes().stream().map(scope -> scope.getId()).collect(Collectors.toSet()), resourceServer.getId(), resource.getOwner());
+ if (cached == null) {
+ cached = findById(resource.getId(), resourceServer.getId());
+ }
return cached;
}
@@ -575,15 +593,17 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
if (cached != null) {
logger.tracev("by id cache hit: {0}", cached.getId());
}
- boolean wasCached = false;
if (cached == null) {
Long loaded = cache.getCurrentRevision(id);
+ if (! modelMightExist(id)) return null;
Resource model = getResourceStoreDelegate().findById(id, resourceServerId);
- if (model == null) return null;
+ if (model == null) {
+ setModelDoesNotExists(id, loaded);
+ return null;
+ }
if (invalidations.contains(id)) return model;
cached = new CachedResource(loaded, model);
cache.addRevisioned(cached, startupRevision);
- wasCached =true;
} else if (invalidations.contains(id)) {
return getResourceStoreDelegate().findById(id, resourceServerId);
} else if (managedResources.containsKey(id)) {
@@ -743,6 +763,9 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
Policy policy = getPolicyStoreDelegate().create(representation, resourceServer);
Policy cached = findById(policy.getId(), resourceServer.getId());
registerPolicyInvalidation(policy.getId(), representation.getName(), representation.getResources(), representation.getScopes(), null, resourceServer.getId());
+ if (cached == null) {
+ cached = findById(policy.getId(), resourceServer.getId());
+ }
return cached;
}
@@ -775,15 +798,17 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
if (cached != null) {
logger.tracev("by id cache hit: {0}", cached.getId());
}
- boolean wasCached = false;
if (cached == null) {
Long loaded = cache.getCurrentRevision(id);
+ if (! modelMightExist(id)) return null;
Policy model = getPolicyStoreDelegate().findById(id, resourceServerId);
- if (model == null) return null;
+ if (model == null) {
+ setModelDoesNotExists(id, loaded);
+ return null;
+ }
if (invalidations.contains(id)) return model;
cached = new CachedPolicy(loaded, model);
cache.addRevisioned(cached, startupRevision);
- wasCached =true;
} else if (invalidations.contains(id)) {
return getPolicyStoreDelegate().findById(id, resourceServerId);
} else if (managedPolicies.containsKey(id)) {
@@ -975,15 +1000,17 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider {
if (cached != null) {
logger.tracev("by id cache hit: {0}", cached.getId());
}
- boolean wasCached = false;
if (cached == null) {
Long loaded = cache.getCurrentRevision(id);
+ if (! modelMightExist(id)) return null;
PermissionTicket model = getPermissionTicketStoreDelegate().findById(id, resourceServerId);
- if (model == null) return null;
+ if (model == null) {
+ setModelDoesNotExists(id, loaded);
+ return null;
+ }
if (invalidations.contains(id)) return model;
cached = new CachedPermissionTicket(loaded, model);
cache.addRevisioned(cached, startupRevision);
- wasCached =true;
} else if (invalidations.contains(id)) {
return getPermissionTicketStoreDelegate().findById(id, resourceServerId);
} else if (managedPermissionTickets.containsKey(id)) {
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java
index 9a0839f..92116b4 100755
--- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/CacheManager.java
@@ -91,7 +91,7 @@ public abstract class CacheManager {
}
- public <T> T get(String id, Class<T> type) {
+ public <T extends Revisioned> T get(String id, Class<T> type) {
Revisioned o = (Revisioned)cache.get(id);
if (o == null) {
return null;
diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/NonExistentItem.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/NonExistentItem.java
new file mode 100644
index 0000000..04d7470
--- /dev/null
+++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/NonExistentItem.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018 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.entities;
+
+/**
+ *
+ * @author hmlnarik
+ */
+public class NonExistentItem implements Revisioned {
+
+ private final String id;
+
+ private Long revision;
+
+ public NonExistentItem(String id) {
+ this.id = id;
+ }
+
+ public NonExistentItem(String id, Long revision) {
+ this.id = id;
+ this.revision = revision;
+ }
+
+ @Override
+ public String getId() {
+ return this.id;
+ }
+
+ @Override
+ public Long getRevision() {
+ return this.revision;
+ }
+
+ @Override
+ public void setRevision(Long revision) {
+ this.revision = revision;
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
index b0994b8..735dd48 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/MgmtPermissions.java
@@ -248,10 +248,10 @@ class MgmtPermissions implements AdminPermissionEvaluator, AdminPermissionManage
@Override
public ResourceServer realmResourceServer() {
if (realmResourceServer != null) return realmResourceServer;
- ResourceServerStore resourceServerStore = authz.getStoreFactory().getResourceServerStore();
ClientModel client = getRealmManagementClient();
if (client == null) return null;
- realmResourceServer = authz.getStoreFactory().getResourceServerStore().findById(client.getId());
+ ResourceServerStore resourceServerStore = authz.getStoreFactory().getResourceServerStore();
+ realmResourceServer = resourceServerStore.findById(client.getId());
return realmResourceServer;
}