diff --git a/model/infinispan/src/main/java/org/keycloak/marshalling/KeycloakModelSchema.java b/model/infinispan/src/main/java/org/keycloak/marshalling/KeycloakModelSchema.java index ba64805f80..9b352798ed 100644 --- a/model/infinispan/src/main/java/org/keycloak/marshalling/KeycloakModelSchema.java +++ b/model/infinispan/src/main/java/org/keycloak/marshalling/KeycloakModelSchema.java @@ -48,6 +48,7 @@ import org.keycloak.models.cache.infinispan.events.GroupAddedEvent; import org.keycloak.models.cache.infinispan.events.GroupMovedEvent; import org.keycloak.models.cache.infinispan.events.GroupRemovedEvent; import org.keycloak.models.cache.infinispan.events.GroupUpdatedEvent; +import org.keycloak.models.cache.infinispan.events.CacheKeyInvalidatedEvent; import org.keycloak.models.cache.infinispan.events.RealmRemovedEvent; import org.keycloak.models.cache.infinispan.events.RealmUpdatedEvent; import org.keycloak.models.cache.infinispan.events.RoleAddedEvent; @@ -158,6 +159,7 @@ import org.keycloak.storage.managers.UserStorageSyncManager; // models.cache.infinispan.events package AuthenticationSessionAuthNoteUpdateEvent.class, + CacheKeyInvalidatedEvent.class, ClientAddedEvent.class, ClientUpdatedEvent.class, ClientRemovedEvent.class, diff --git a/model/infinispan/src/main/java/org/keycloak/marshalling/Marshalling.java b/model/infinispan/src/main/java/org/keycloak/marshalling/Marshalling.java index ada0fd3833..194eb9a52b 100644 --- a/model/infinispan/src/main/java/org/keycloak/marshalling/Marshalling.java +++ b/model/infinispan/src/main/java/org/keycloak/marshalling/Marshalling.java @@ -143,6 +143,9 @@ public final class Marshalling { public static final int SINGLE_USE_OBJECT_VALUE_ENTITY = 65601; public static final int USER_SESSION_ENTITY = 65602; + + public static final int CACHE_KEY_INVALIDATION_EVENT = 65603; + public static void configure(GlobalConfigurationBuilder builder) { builder.serialization() .addContextInitializer(KeycloakModelSchema.INSTANCE); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheManager.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheManager.java index 2e51914aea..94454a04e7 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheManager.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheManager.java @@ -120,6 +120,10 @@ public class RealmCacheManager extends CacheManager { addInvalidations(InClientPredicate.create().client(clientUUID), invalidations); } + public void invalidateCacheKey(String key, Set invalidations) { + invalidations.add(key); + } + @Override protected void addInvalidationsFromEvent(InvalidationEvent event, Set invalidations) { invalidations.add(event.getId()); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java index a0d1dc8a1b..9689d549aa 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java @@ -17,6 +17,7 @@ package org.keycloak.models.cache.infinispan; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -73,6 +74,7 @@ import org.keycloak.models.cache.infinispan.events.GroupMovedEvent; import org.keycloak.models.cache.infinispan.events.GroupRemovedEvent; import org.keycloak.models.cache.infinispan.events.GroupUpdatedEvent; import org.keycloak.models.cache.infinispan.events.InvalidationEvent; +import org.keycloak.models.cache.infinispan.events.CacheKeyInvalidatedEvent; import org.keycloak.models.cache.infinispan.events.RealmRemovedEvent; import org.keycloak.models.cache.infinispan.events.RealmUpdatedEvent; import org.keycloak.models.cache.infinispan.events.RoleAddedEvent; @@ -232,13 +234,8 @@ public class RealmCacheSession implements CacheRealmProvider { @Override public void registerInvalidation(String id) { - invalidations.add(id); - invalidationEvents.add(new InvalidationEvent() { - @Override - public String getId() { - return id; - } - }); + cache.invalidateCacheKey(id, invalidations); + invalidationEvents.add(new CacheKeyInvalidatedEvent(id)); } @Override diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/events/CacheKeyInvalidatedEvent.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/events/CacheKeyInvalidatedEvent.java new file mode 100644 index 0000000000..f708d28dde --- /dev/null +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/events/CacheKeyInvalidatedEvent.java @@ -0,0 +1,39 @@ +/* + * Copyright 2024 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.events; + +import java.util.Set; + +import org.infinispan.protostream.annotations.ProtoFactory; +import org.infinispan.protostream.annotations.ProtoTypeId; +import org.keycloak.marshalling.Marshalling; +import org.keycloak.models.cache.infinispan.RealmCacheManager; + +@ProtoTypeId(Marshalling.CACHE_KEY_INVALIDATION_EVENT) +public class CacheKeyInvalidatedEvent extends InvalidationEvent implements RealmCacheInvalidationEvent { + + @ProtoFactory + public CacheKeyInvalidatedEvent(String id) { + super(id); + } + + @Override + public void addInvalidations(RealmCacheManager realmCache, Set invalidations) { + realmCache.invalidateCacheKey(getId(), invalidations); + } +} diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/organization/InfinispanOrganizationProvider.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/organization/InfinispanOrganizationProvider.java index 0a17163143..e512c9e6ea 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/organization/InfinispanOrganizationProvider.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/organization/InfinispanOrganizationProvider.java @@ -30,6 +30,8 @@ import org.keycloak.organization.OrganizationProvider; public class InfinispanOrganizationProvider implements OrganizationProvider { + private static final String ORG_COUNT_KEY_SUFFIX = ".org.count"; + private final KeycloakSession session; private final OrganizationProvider orgDelegate; private final RealmCacheSession realmCache; @@ -42,7 +44,7 @@ public class InfinispanOrganizationProvider implements OrganizationProvider { } static String cacheKeyOrgCount(RealmModel realm) { - return realm.getId() + ".org.count"; + return realm.getId() + ORG_COUNT_KEY_SUFFIX; } @Override