caching
This commit is contained in:
parent
1d8e38f0c6
commit
4bf23cc83a
11 changed files with 445 additions and 233 deletions
|
@ -39,14 +39,12 @@ import java.util.Set;
|
|||
public class ClientAdapter implements ClientModel {
|
||||
protected RealmCacheSession cacheSession;
|
||||
protected RealmModel cachedRealm;
|
||||
protected RealmCache cache;
|
||||
|
||||
protected ClientModel updated;
|
||||
protected CachedClient cached;
|
||||
|
||||
public ClientAdapter(RealmModel cachedRealm, CachedClient cached, RealmCacheSession cacheSession, RealmCache cache) {
|
||||
public ClientAdapter(RealmModel cachedRealm, CachedClient cached, RealmCacheSession cacheSession) {
|
||||
this.cachedRealm = cachedRealm;
|
||||
this.cache = cache;
|
||||
this.cacheSession = cacheSession;
|
||||
this.cached = cached;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.*;
|
|||
import org.keycloak.models.cache.CachedRealmModel;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedRealm;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.client.ClientStorageProvider;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -36,7 +37,6 @@ public class RealmAdapter implements CachedRealmModel {
|
|||
protected CachedRealm cached;
|
||||
protected RealmCacheSession cacheSession;
|
||||
protected volatile RealmModel updated;
|
||||
protected RealmCache cache;
|
||||
protected KeycloakSession session;
|
||||
|
||||
public RealmAdapter(KeycloakSession session, CachedRealm cached, RealmCacheSession cacheSession) {
|
||||
|
@ -1323,35 +1323,37 @@ public class RealmAdapter implements CachedRealmModel {
|
|||
@Override
|
||||
public ComponentModel addComponentModel(ComponentModel model) {
|
||||
getDelegateForUpdate();
|
||||
evictUsers(model);
|
||||
executeEvictions(model);
|
||||
return updated.addComponentModel(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentModel importComponentModel(ComponentModel model) {
|
||||
getDelegateForUpdate();
|
||||
evictUsers(model);
|
||||
executeEvictions(model);
|
||||
return updated.importComponentModel(model);
|
||||
}
|
||||
|
||||
public void evictUsers(ComponentModel model) {
|
||||
String parentId = model.getParentId();
|
||||
evictUsers(parentId);
|
||||
}
|
||||
public void executeEvictions(ComponentModel model) {
|
||||
if (model == null) return;
|
||||
// test that this is a realm component
|
||||
if (model.getParentId() != null && !model.getParentId().equals(getId())) return;
|
||||
|
||||
public void evictUsers(String parentId) {
|
||||
if (parentId != null && !parentId.equals(getId())) {
|
||||
ComponentModel parent = getComponent(parentId);
|
||||
if (parent != null && UserStorageProvider.class.getName().equals(parent.getProviderType())) {
|
||||
session.userCache().evict(this);
|
||||
}
|
||||
// invalidate entire user cache if we're dealing with user storage SPI
|
||||
if (UserStorageProvider.class.getName().equals(model.getProviderType())) {
|
||||
session.userCache().evict(this);
|
||||
}
|
||||
// invalidate entire realm if we're dealing with client storage SPI
|
||||
// entire realm because of client roles, client lists, and clients
|
||||
if (ClientStorageProvider.class.getName().equals(model.getProviderType())) {
|
||||
cacheSession.evictRealmOnRemoval(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateComponent(ComponentModel component) {
|
||||
getDelegateForUpdate();
|
||||
evictUsers(component);
|
||||
executeEvictions(component);
|
||||
updated.updateComponent(component);
|
||||
|
||||
}
|
||||
|
@ -1359,7 +1361,7 @@ public class RealmAdapter implements CachedRealmModel {
|
|||
@Override
|
||||
public void removeComponent(ComponentModel component) {
|
||||
getDelegateForUpdate();
|
||||
evictUsers(component);
|
||||
executeEvictions(component);
|
||||
updated.removeComponent(component);
|
||||
|
||||
}
|
||||
|
@ -1367,7 +1369,6 @@ public class RealmAdapter implements CachedRealmModel {
|
|||
@Override
|
||||
public void removeComponents(String parentId) {
|
||||
getDelegateForUpdate();
|
||||
evictUsers(parentId);
|
||||
updated.removeComponents(parentId);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClient;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedClientTemplate;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedGroup;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedRealm;
|
||||
import org.keycloak.models.cache.infinispan.entities.CachedRole;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface RealmCache {
|
||||
void clear();
|
||||
|
||||
CachedRealm getRealm(String id);
|
||||
|
||||
void invalidateRealm(CachedRealm realm);
|
||||
|
||||
void addRealm(CachedRealm realm);
|
||||
|
||||
CachedRealm getRealmByName(String name);
|
||||
|
||||
void invalidateRealmById(String id);
|
||||
|
||||
CachedClient getClient(String id);
|
||||
|
||||
void invalidateClient(CachedClient app);
|
||||
|
||||
void evictClientById(String id);
|
||||
|
||||
void addClient(CachedClient app);
|
||||
|
||||
void invalidateClientById(String id);
|
||||
|
||||
CachedRole getRole(String id);
|
||||
|
||||
void invalidateRole(CachedRole role);
|
||||
|
||||
void evictRoleById(String id);
|
||||
|
||||
void addRole(CachedRole role);
|
||||
|
||||
void invalidateRoleById(String id);
|
||||
|
||||
CachedGroup getGroup(String id);
|
||||
|
||||
void invalidateGroup(CachedGroup role);
|
||||
|
||||
void addGroup(CachedGroup role);
|
||||
|
||||
void invalidateGroupById(String id);
|
||||
|
||||
CachedClientTemplate getClientTemplate(String id);
|
||||
|
||||
void invalidateClientTemplate(CachedClientTemplate app);
|
||||
|
||||
void evictClientTemplateById(String id);
|
||||
|
||||
void addClientTemplate(CachedClientTemplate app);
|
||||
|
||||
void invalidateClientTemplateById(String id);
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@ package org.keycloak.models.cache.infinispan;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.cluster.ClusterProvider;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.migration.MigrationModel;
|
||||
import org.keycloak.models.*;
|
||||
import org.keycloak.models.cache.CacheRealmProvider;
|
||||
|
@ -26,6 +27,9 @@ import org.keycloak.models.cache.CachedRealmModel;
|
|||
import org.keycloak.models.cache.infinispan.entities.*;
|
||||
import org.keycloak.models.cache.infinispan.events.*;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -100,7 +104,7 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
protected boolean setRollbackOnly;
|
||||
|
||||
protected Map<String, RealmAdapter> managedRealms = new HashMap<>();
|
||||
protected Map<String, ClientAdapter> managedApplications = new HashMap<>();
|
||||
protected Map<String, ClientModel> managedApplications = new HashMap<>();
|
||||
protected Map<String, ClientTemplateAdapter> managedClientTemplates = new HashMap<>();
|
||||
protected Map<String, RoleAdapter> managedRoles = new HashMap<>();
|
||||
protected Map<String, GroupAdapter> managedGroups = new HashMap<>();
|
||||
|
@ -173,8 +177,8 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
|
||||
private void invalidateClient(String id) {
|
||||
invalidations.add(id);
|
||||
ClientAdapter adapter = managedApplications.get(id);
|
||||
if (adapter != null) adapter.invalidate();
|
||||
ClientModel adapter = managedApplications.get(id);
|
||||
if (adapter != null && adapter instanceof ClientAdapter) ((ClientAdapter)adapter).invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -204,9 +208,9 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
invalidations.addAll(newInvalidations);
|
||||
// need to make sure that scope and group mapping clients and groups are invalidated
|
||||
for (String id : newInvalidations) {
|
||||
ClientAdapter adapter = managedApplications.get(id);
|
||||
if (adapter != null) {
|
||||
adapter.invalidate();
|
||||
ClientModel adapter = managedApplications.get(id);
|
||||
if (adapter != null && adapter instanceof ClientAdapter){
|
||||
((ClientAdapter)adapter).invalidate();
|
||||
continue;
|
||||
}
|
||||
GroupAdapter group = managedGroups.get(id);
|
||||
|
@ -329,7 +333,6 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
@Override
|
||||
public void commit() {
|
||||
try {
|
||||
if (realmDelegate == null) return;
|
||||
if (clearAll) {
|
||||
cache.clear();
|
||||
}
|
||||
|
@ -470,12 +473,16 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
RealmModel realm = getRealm(id);
|
||||
if (realm == null) return false;
|
||||
|
||||
cache.invalidateObject(id);
|
||||
invalidationEvents.add(RealmRemovedEvent.create(id, realm.getName()));
|
||||
cache.realmRemoval(id, realm.getName(), invalidations);
|
||||
evictRealmOnRemoval(realm);
|
||||
return getRealmDelegate().removeRealm(id);
|
||||
}
|
||||
|
||||
public void evictRealmOnRemoval(RealmModel realm) {
|
||||
cache.invalidateObject(realm.getId());
|
||||
invalidationEvents.add(RealmRemovedEvent.create(realm.getId(), realm.getName()));
|
||||
cache.realmRemoval(realm.getId(), realm.getName(), invalidations);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientModel addClient(RealmModel realm, String clientId) {
|
||||
|
@ -1020,20 +1027,78 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
Long loaded = cache.getCurrentRevision(id);
|
||||
ClientModel model = getClientDelegate().getClientById(id, realm);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(id)) return model;
|
||||
cached = new CachedClient(loaded, realm, model);
|
||||
logger.tracev("adding client by id cache miss: {0}", cached.getClientId());
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
ClientModel adapter = cacheClient(realm, model, loaded);
|
||||
managedApplications.put(id, adapter);
|
||||
return adapter;
|
||||
} else if (invalidations.contains(id)) {
|
||||
return getRealmDelegate().getClientById(id, realm);
|
||||
} else if (managedApplications.containsKey(id)) {
|
||||
return managedApplications.get(id);
|
||||
}
|
||||
ClientAdapter adapter = new ClientAdapter(realm, cached, this, null);
|
||||
ClientModel adapter = validateCache(realm, cached);
|
||||
managedApplications.put(id, adapter);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
protected ClientModel cacheClient(RealmModel realm, ClientModel delegate, Long revision) {
|
||||
if (invalidations.contains(delegate.getId())) return delegate;
|
||||
StorageId storageId = new StorageId(delegate.getId());
|
||||
CachedClient cached = null;
|
||||
ClientAdapter adapter = null;
|
||||
|
||||
if (!storageId.isLocal()) {
|
||||
ComponentModel component = realm.getComponent(storageId.getProviderId());
|
||||
ClientStorageProviderModel model = new ClientStorageProviderModel(component);
|
||||
if (!model.isEnabled()) {
|
||||
return delegate;
|
||||
}
|
||||
ClientStorageProviderModel.CachePolicy policy = model.getCachePolicy();
|
||||
if (policy != null && policy == ClientStorageProviderModel.CachePolicy.NO_CACHE) {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
cached = new CachedClient(revision, realm, delegate);
|
||||
adapter = new ClientAdapter(realm, cached, this);
|
||||
|
||||
long lifespan = model.getLifespan();
|
||||
if (lifespan > 0) {
|
||||
cache.addRevisioned(cached, startupRevision, lifespan);
|
||||
} else {
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
}
|
||||
} else {
|
||||
cached = new CachedClient(revision, realm, delegate);
|
||||
adapter = new ClientAdapter(realm, cached, this);
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
}
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
|
||||
protected ClientModel validateCache(RealmModel realm, CachedClient cached) {
|
||||
if (!realm.getId().equals(cached.getRealm())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StorageId storageId = new StorageId(cached.getId());
|
||||
if (!storageId.isLocal()) {
|
||||
ComponentModel component = realm.getComponent(storageId.getProviderId());
|
||||
ClientStorageProviderModel model = new ClientStorageProviderModel(component);
|
||||
|
||||
// although we do set a timeout, Infinispan has no guarantees when the user will be evicted
|
||||
// its also hard to test stuff
|
||||
if (model.shouldInvalidate(cached)) {
|
||||
registerClientInvalidation(cached.getId(), cached.getClientId(), realm.getId());
|
||||
return getClientDelegate().getClientById(cached.getId(), realm);
|
||||
}
|
||||
}
|
||||
ClientAdapter adapter = new ClientAdapter(realm, cached, this);
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientModel getClientByClientId(String clientId, RealmModel realm) {
|
||||
String cacheKey = getClientByClientIdCacheKey(clientId, realm.getId());
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.models.cache.infinispan;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.cluster.ClusterProvider;
|
||||
import org.keycloak.models.cache.CachedObject;
|
||||
import org.keycloak.models.cache.infinispan.events.InvalidationEvent;
|
||||
import org.keycloak.common.constants.ServiceAccountConstants;
|
||||
import org.keycloak.common.util.Time;
|
||||
|
@ -49,6 +50,7 @@ import org.keycloak.models.cache.infinispan.events.UserFederationLinkUpdatedEven
|
|||
import org.keycloak.models.cache.infinispan.events.UserFullInvalidationEvent;
|
||||
import org.keycloak.models.cache.infinispan.events.UserUpdatedEvent;
|
||||
import org.keycloak.models.utils.ReadOnlyUserModelDelegate;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
|
@ -144,7 +146,6 @@ public class UserCacheSession implements UserCache {
|
|||
|
||||
@Override
|
||||
public void commit() {
|
||||
if (delegate == null) return;
|
||||
runInvalidations();
|
||||
transactionActive = false;
|
||||
}
|
||||
|
@ -296,46 +297,11 @@ public class UserCacheSession implements UserCache {
|
|||
|
||||
if (!storageId.isLocal()) {
|
||||
ComponentModel component = realm.getComponent(storageId.getProviderId());
|
||||
UserStorageProviderModel model = new UserStorageProviderModel(component);
|
||||
CacheableStorageProviderModel model = new CacheableStorageProviderModel(component);
|
||||
|
||||
// although we do set a timeout, Infinispan has no guarantees when the user will be evicted
|
||||
// its also hard to test stuff
|
||||
boolean invalidate = false;
|
||||
if (!model.isEnabled()) {
|
||||
invalidate = true;
|
||||
} else {
|
||||
UserStorageProviderModel.CachePolicy policy = model.getCachePolicy();
|
||||
if (policy != null) {
|
||||
//String currentTime = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(Time.currentTimeMillis()));
|
||||
if (policy == UserStorageProviderModel.CachePolicy.NO_CACHE) {
|
||||
invalidate = true;
|
||||
} else if (cached.getCacheTimestamp() < model.getCacheInvalidBefore()) {
|
||||
invalidate = true;
|
||||
} else if (policy == UserStorageProviderModel.CachePolicy.MAX_LIFESPAN) {
|
||||
if (cached.getCacheTimestamp() + model.getMaxLifespan() < Time.currentTimeMillis()) {
|
||||
invalidate = true;
|
||||
}
|
||||
} else if (policy == UserStorageProviderModel.CachePolicy.EVICT_DAILY) {
|
||||
long dailyTimeout = dailyTimeout(model.getEvictionHour(), model.getEvictionMinute());
|
||||
dailyTimeout = dailyTimeout - (24 * 60 * 60 * 1000);
|
||||
//String timeout = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(dailyTimeout));
|
||||
//String stamp = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(cached.getCacheTimestamp()));
|
||||
if (cached.getCacheTimestamp() <= dailyTimeout) {
|
||||
invalidate = true;
|
||||
}
|
||||
} else if (policy == UserStorageProviderModel.CachePolicy.EVICT_WEEKLY) {
|
||||
int oneWeek = 7 * 24 * 60 * 60 * 1000;
|
||||
long weeklyTimeout = weeklyTimeout(model.getEvictionDay(), model.getEvictionHour(), model.getEvictionMinute());
|
||||
long lastTimeout = weeklyTimeout - oneWeek;
|
||||
//String timeout = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(weeklyTimeout));
|
||||
//String stamp = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(cached.getCacheTimestamp()));
|
||||
if (cached.getCacheTimestamp() <= lastTimeout) {
|
||||
invalidate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (invalidate) {
|
||||
if (model.shouldInvalidate(cached)) {
|
||||
registerUserInvalidation(realm, cached);
|
||||
return getDelegate().getUserById(cached.getId(), realm);
|
||||
}
|
||||
|
@ -371,26 +337,11 @@ public class UserCacheSession implements UserCache {
|
|||
adapter = new UserAdapter(cached, this, session, realm);
|
||||
onCache(realm, adapter, delegate);
|
||||
|
||||
if (policy == null || policy == UserStorageProviderModel.CachePolicy.DEFAULT) {
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
long lifespan = model.getLifespan();
|
||||
if (lifespan > 0) {
|
||||
cache.addRevisioned(cached, startupRevision, lifespan);
|
||||
} else {
|
||||
long lifespan = -1;
|
||||
if (policy == UserStorageProviderModel.CachePolicy.EVICT_DAILY) {
|
||||
if (model.getEvictionHour() > -1 && model.getEvictionMinute() > -1) {
|
||||
lifespan = dailyTimeout(model.getEvictionHour(), model.getEvictionMinute()) - Time.currentTimeMillis();
|
||||
}
|
||||
} else if (policy == UserStorageProviderModel.CachePolicy.EVICT_WEEKLY) {
|
||||
if (model.getEvictionDay() > 0 && model.getEvictionHour() > -1 && model.getEvictionMinute() > -1) {
|
||||
lifespan = weeklyTimeout(model.getEvictionDay(), model.getEvictionHour(), model.getEvictionMinute()) - Time.currentTimeMillis();
|
||||
}
|
||||
} else if (policy == UserStorageProviderModel.CachePolicy.MAX_LIFESPAN) {
|
||||
lifespan = model.getMaxLifespan();
|
||||
}
|
||||
if (lifespan > 0) {
|
||||
cache.addRevisioned(cached, startupRevision, lifespan);
|
||||
} else {
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
}
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
}
|
||||
} else {
|
||||
cached = new CachedUser(revision, realm, delegate, notBefore);
|
||||
|
@ -402,39 +353,6 @@ public class UserCacheSession implements UserCache {
|
|||
return adapter;
|
||||
}
|
||||
|
||||
|
||||
public static long dailyTimeout(int hour, int minute) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Calendar cal2 = Calendar.getInstance();
|
||||
cal.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.set(Calendar.HOUR_OF_DAY, hour);
|
||||
cal2.set(Calendar.MINUTE, minute);
|
||||
if (cal2.getTimeInMillis() < cal.getTimeInMillis()) {
|
||||
int add = (24 * 60 * 60 * 1000);
|
||||
cal.add(Calendar.MILLISECOND, add);
|
||||
} else {
|
||||
cal.add(Calendar.MILLISECOND, (int)(cal2.getTimeInMillis() - cal.getTimeInMillis()));
|
||||
}
|
||||
return cal.getTimeInMillis();
|
||||
}
|
||||
|
||||
public static long weeklyTimeout(int day, int hour, int minute) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Calendar cal2 = Calendar.getInstance();
|
||||
cal.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.set(Calendar.HOUR_OF_DAY, hour);
|
||||
cal2.set(Calendar.MINUTE, minute);
|
||||
cal2.set(Calendar.DAY_OF_WEEK, day);
|
||||
if (cal2.getTimeInMillis() < cal.getTimeInMillis()) {
|
||||
int add = (7 * 24 * 60 * 60 * 1000);
|
||||
cal2.add(Calendar.MILLISECOND, add);
|
||||
}
|
||||
|
||||
return cal2.getTimeInMillis();
|
||||
}
|
||||
|
||||
private void onCache(RealmModel realm, UserAdapter adapter, UserModel delegate) {
|
||||
((OnUserCache)getDelegate()).onCache(realm, adapter, delegate);
|
||||
((OnUserCache)session.userCredentialManager()).onCache(realm, adapter, delegate);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.keycloak.models.cache.infinispan.entities;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.cache.CachedObject;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -8,7 +9,7 @@ import java.io.Serializable;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class AbstractRevisioned implements Revisioned, Serializable {
|
||||
public class AbstractRevisioned implements Revisioned, Serializable, CachedObject {
|
||||
private String id;
|
||||
private Long revision;
|
||||
private final long cacheTimestamp = Time.currentTimeMillis();
|
||||
|
@ -38,6 +39,7 @@ public class AbstractRevisioned implements Revisioned, Serializable {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public long getCacheTimestamp() {
|
||||
return cacheTimestamp;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.keycloak.models.sessions.infinispan.initializer;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.models.cache.infinispan.UserCacheSession;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Calendar;
|
||||
|
@ -65,13 +66,13 @@ public class InitializerStateTest {
|
|||
|
||||
@Test
|
||||
public void testDailyTimeout() throws Exception {
|
||||
Date date = new Date(UserCacheSession.dailyTimeout(10, 30));
|
||||
Date date = new Date(CacheableStorageProviderModel.dailyTimeout(10, 30));
|
||||
System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date));
|
||||
date = new Date(UserCacheSession.dailyTimeout(17, 45));
|
||||
date = new Date(CacheableStorageProviderModel.dailyTimeout(17, 45));
|
||||
System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date));
|
||||
date = new Date(UserCacheSession.weeklyTimeout(Calendar.MONDAY, 13, 45));
|
||||
date = new Date(CacheableStorageProviderModel.weeklyTimeout(Calendar.MONDAY, 13, 45));
|
||||
System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date));
|
||||
date = new Date(UserCacheSession.weeklyTimeout(Calendar.THURSDAY, 13, 45));
|
||||
date = new Date(CacheableStorageProviderModel.weeklyTimeout(Calendar.THURSDAY, 13, 45));
|
||||
System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date));
|
||||
System.out.println("----");
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
@ -80,7 +81,7 @@ public class InitializerStateTest {
|
|||
int min = cal.get(Calendar.MINUTE);
|
||||
date = new Date(cal.getTimeInMillis());
|
||||
System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date));
|
||||
date = new Date(UserCacheSession.dailyTimeout(hour, min));
|
||||
date = new Date(CacheableStorageProviderModel.dailyTimeout(hour, min));
|
||||
System.out.println(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(date));
|
||||
cal = Calendar.getInstance();
|
||||
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||
|
|
25
server-spi/src/main/java/org/keycloak/models/cache/CachedObject.java
vendored
Normal file
25
server-spi/src/main/java/org/keycloak/models/cache/CachedObject.java
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface CachedObject {
|
||||
long getCacheTimestamp();
|
||||
}
|
|
@ -16,8 +16,12 @@
|
|||
*/
|
||||
package org.keycloak.storage;
|
||||
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.component.PrioritizedComponentModel;
|
||||
import org.keycloak.models.cache.CachedObject;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -30,6 +34,7 @@ public class CacheableStorageProviderModel extends PrioritizedComponentModel {
|
|||
public static final String EVICTION_MINUTE = "evictionMinute";
|
||||
public static final String EVICTION_DAY = "evictionDay";
|
||||
public static final String CACHE_INVALID_BEFORE = "cacheInvalidBefore";
|
||||
public static final String ENABLED = "enabled";
|
||||
|
||||
private transient CachePolicy cachePolicy;
|
||||
private transient long maxLifespan = -1;
|
||||
|
@ -37,6 +42,7 @@ public class CacheableStorageProviderModel extends PrioritizedComponentModel {
|
|||
private transient int evictionMinute = -1;
|
||||
private transient int evictionDay = -1;
|
||||
private transient long cacheInvalidBefore = -1;
|
||||
private transient Boolean enabled;
|
||||
|
||||
public CacheableStorageProviderModel() {
|
||||
}
|
||||
|
@ -137,6 +143,117 @@ public class CacheableStorageProviderModel extends PrioritizedComponentModel {
|
|||
getConfig().putSingle(CACHE_INVALID_BEFORE, Long.toString(cacheInvalidBefore));
|
||||
}
|
||||
|
||||
public void setEnabled(boolean flag) {
|
||||
enabled = flag;
|
||||
getConfig().putSingle(ENABLED, Boolean.toString(flag));
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
if (enabled == null) {
|
||||
String val = getConfig().getFirst(ENABLED);
|
||||
if (val == null) {
|
||||
enabled = true;
|
||||
} else {
|
||||
enabled = Boolean.valueOf(val);
|
||||
}
|
||||
}
|
||||
return enabled;
|
||||
|
||||
}
|
||||
|
||||
public long getLifespan() {
|
||||
UserStorageProviderModel.CachePolicy policy = getCachePolicy();
|
||||
long lifespan = -1;
|
||||
if (policy == null || policy == UserStorageProviderModel.CachePolicy.DEFAULT) {
|
||||
lifespan = -1;
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.EVICT_DAILY) {
|
||||
if (getEvictionHour() > -1 && getEvictionMinute() > -1) {
|
||||
lifespan = dailyTimeout(getEvictionHour(), getEvictionMinute()) - Time.currentTimeMillis();
|
||||
}
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.EVICT_WEEKLY) {
|
||||
if (getEvictionDay() > 0 && getEvictionHour() > -1 && getEvictionMinute() > -1) {
|
||||
lifespan = weeklyTimeout(getEvictionDay(), getEvictionHour(), getEvictionMinute()) - Time.currentTimeMillis();
|
||||
}
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.MAX_LIFESPAN) {
|
||||
lifespan = getMaxLifespan();
|
||||
}
|
||||
return lifespan;
|
||||
}
|
||||
|
||||
public boolean shouldInvalidate(CachedObject cached) {
|
||||
boolean invalidate = false;
|
||||
if (!isEnabled()) {
|
||||
invalidate = true;
|
||||
} else {
|
||||
CacheableStorageProviderModel.CachePolicy policy = getCachePolicy();
|
||||
if (policy != null) {
|
||||
//String currentTime = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(Time.currentTimeMillis()));
|
||||
if (policy == CacheableStorageProviderModel.CachePolicy.NO_CACHE) {
|
||||
invalidate = true;
|
||||
} else if (cached.getCacheTimestamp() < getCacheInvalidBefore()) {
|
||||
invalidate = true;
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.MAX_LIFESPAN) {
|
||||
if (cached.getCacheTimestamp() + getMaxLifespan() < Time.currentTimeMillis()) {
|
||||
invalidate = true;
|
||||
}
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.EVICT_DAILY) {
|
||||
long dailyTimeout = dailyTimeout(getEvictionHour(), getEvictionMinute());
|
||||
dailyTimeout = dailyTimeout - (24 * 60 * 60 * 1000);
|
||||
//String timeout = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(dailyTimeout));
|
||||
//String stamp = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(cached.getCacheTimestamp()));
|
||||
if (cached.getCacheTimestamp() <= dailyTimeout) {
|
||||
invalidate = true;
|
||||
}
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.EVICT_WEEKLY) {
|
||||
int oneWeek = 7 * 24 * 60 * 60 * 1000;
|
||||
long weeklyTimeout = weeklyTimeout(getEvictionDay(), getEvictionHour(), getEvictionMinute());
|
||||
long lastTimeout = weeklyTimeout - oneWeek;
|
||||
//String timeout = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(weeklyTimeout));
|
||||
//String stamp = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(cached.getCacheTimestamp()));
|
||||
if (cached.getCacheTimestamp() <= lastTimeout) {
|
||||
invalidate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return invalidate;
|
||||
}
|
||||
|
||||
|
||||
public static long dailyTimeout(int hour, int minute) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Calendar cal2 = Calendar.getInstance();
|
||||
cal.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.set(Calendar.HOUR_OF_DAY, hour);
|
||||
cal2.set(Calendar.MINUTE, minute);
|
||||
if (cal2.getTimeInMillis() < cal.getTimeInMillis()) {
|
||||
int add = (24 * 60 * 60 * 1000);
|
||||
cal.add(Calendar.MILLISECOND, add);
|
||||
} else {
|
||||
cal.add(Calendar.MILLISECOND, (int)(cal2.getTimeInMillis() - cal.getTimeInMillis()));
|
||||
}
|
||||
return cal.getTimeInMillis();
|
||||
}
|
||||
|
||||
public static long weeklyTimeout(int day, int hour, int minute) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Calendar cal2 = Calendar.getInstance();
|
||||
cal.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.setTimeInMillis(Time.currentTimeMillis());
|
||||
cal2.set(Calendar.HOUR_OF_DAY, hour);
|
||||
cal2.set(Calendar.MINUTE, minute);
|
||||
cal2.set(Calendar.DAY_OF_WEEK, day);
|
||||
if (cal2.getTimeInMillis() < cal.getTimeInMillis()) {
|
||||
int add = (7 * 24 * 60 * 60 * 1000);
|
||||
cal2.add(Calendar.MILLISECOND, add);
|
||||
}
|
||||
|
||||
return cal2.getTimeInMillis();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public enum CachePolicy {
|
||||
NO_CACHE,
|
||||
DEFAULT,
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
package org.keycloak.storage;
|
||||
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.component.PrioritizedComponentModel;
|
||||
|
||||
/**
|
||||
* Stored configuration of a User Storage provider instance.
|
||||
|
@ -32,7 +31,6 @@ public class UserStorageProviderModel extends CacheableStorageProviderModel {
|
|||
public static final String FULL_SYNC_PERIOD = "fullSyncPeriod";
|
||||
public static final String CHANGED_SYNC_PERIOD = "changedSyncPeriod";
|
||||
public static final String LAST_SYNC = "lastSync";
|
||||
public static final String ENABLED = "enabled";
|
||||
|
||||
public UserStorageProviderModel() {
|
||||
setProviderType(UserStorageProvider.class.getName());
|
||||
|
@ -46,7 +44,6 @@ public class UserStorageProviderModel extends CacheableStorageProviderModel {
|
|||
private transient Integer changedSyncPeriod;
|
||||
private transient Integer lastSync;
|
||||
private transient Boolean importEnabled;
|
||||
private transient Boolean enabled;
|
||||
|
||||
public boolean isImportEnabled() {
|
||||
if (importEnabled == null) {
|
||||
|
@ -66,24 +63,6 @@ public class UserStorageProviderModel extends CacheableStorageProviderModel {
|
|||
getConfig().putSingle(IMPORT_ENABLED, Boolean.toString(flag));
|
||||
}
|
||||
|
||||
public void setEnabled(boolean flag) {
|
||||
enabled = flag;
|
||||
getConfig().putSingle(ENABLED, Boolean.toString(flag));
|
||||
}
|
||||
|
||||
|
||||
public boolean isEnabled() {
|
||||
if (enabled == null) {
|
||||
String val = getConfig().getFirst(ENABLED);
|
||||
if (val == null) {
|
||||
enabled = true;
|
||||
} else {
|
||||
enabled = Boolean.valueOf(val);
|
||||
}
|
||||
}
|
||||
return enabled;
|
||||
|
||||
}
|
||||
|
||||
public int getFullSyncPeriod() {
|
||||
if (fullSyncPeriod == null) {
|
||||
|
|
|
@ -30,17 +30,21 @@ import org.keycloak.admin.client.resource.ClientsResource;
|
|||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.authentication.authenticators.browser.UsernamePasswordFormFactory;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowBindings;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.cache.infinispan.ClientAdapter;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.client.ClientStorageProvider;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
|
@ -66,9 +70,18 @@ import javax.ws.rs.core.Response;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Calendar.DAY_OF_WEEK;
|
||||
import static java.util.Calendar.HOUR_OF_DAY;
|
||||
import static java.util.Calendar.MINUTE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.keycloak.storage.CacheableStorageProviderModel.CACHE_POLICY;
|
||||
import static org.keycloak.storage.CacheableStorageProviderModel.EVICTION_DAY;
|
||||
import static org.keycloak.storage.CacheableStorageProviderModel.EVICTION_HOUR;
|
||||
import static org.keycloak.storage.CacheableStorageProviderModel.EVICTION_MINUTE;
|
||||
import static org.keycloak.storage.CacheableStorageProviderModel.MAX_LIFESPAN;
|
||||
|
||||
/**
|
||||
* Test that clients can override auth flows
|
||||
|
@ -92,6 +105,8 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest {
|
|||
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||
}
|
||||
|
||||
protected String providerId;
|
||||
|
||||
@Deployment
|
||||
public static WebArchive deploy() {
|
||||
return RunOnServerDeployment.create(UserResource.class)
|
||||
|
@ -116,7 +131,7 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest {
|
|||
provider.getConfig().putSingle(HardcodedClientStorageProviderFactory.CLIENT_ID, "hardcoded-client");
|
||||
provider.getConfig().putSingle(HardcodedClientStorageProviderFactory.REDIRECT_URI, oauth.getRedirectUri());
|
||||
|
||||
String providerId = addComponent(provider);
|
||||
providerId = addComponent(provider);
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,4 +227,176 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest {
|
|||
httpClient.close();
|
||||
events.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@Test
|
||||
public void testDailyEviction() {
|
||||
|
||||
// set eviction to 1 hour from now
|
||||
Calendar eviction = Calendar.getInstance();
|
||||
eviction.add(Calendar.HOUR, 1);
|
||||
ComponentRepresentation propProviderRW = testRealmResource().components().component(propProviderRWId).toRepresentation();
|
||||
propProviderRW.getConfig().putSingle(CACHE_POLICY, CacheableStorageProviderModel.CachePolicy.EVICT_DAILY.name());
|
||||
propProviderRW.getConfig().putSingle(EVICTION_HOUR, Integer.toString(eviction.get(HOUR_OF_DAY)));
|
||||
propProviderRW.getConfig().putSingle(EVICTION_MINUTE, Integer.toString(eviction.get(MINUTE)));
|
||||
testRealmResource().components().component(propProviderRWId).update(propProviderRW);
|
||||
|
||||
// now
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("thor", realm);
|
||||
});
|
||||
|
||||
// run twice to make sure its in cache.
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("thor", realm);
|
||||
System.out.println("User class: " + user.getClass());
|
||||
Assert.assertTrue(user instanceof CachedUserModel); // should still be cached
|
||||
});
|
||||
|
||||
setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
UserModel user = session.users().getUserByUsername("thor", realm);
|
||||
System.out.println("User class: " + user.getClass());
|
||||
Assert.assertFalse(user instanceof CachedUserModel); // should be evicted
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@Test
|
||||
public void testDailyEviction() {
|
||||
testIsCached();
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientStorageProviderModel model = realm.getClientStorageProviders().get(0);
|
||||
Calendar eviction = Calendar.getInstance();
|
||||
eviction.add(Calendar.HOUR, 1);
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.EVICT_DAILY);
|
||||
model.setEvictionHour(eviction.get(HOUR_OF_DAY));
|
||||
model.setEvictionMinute(eviction.get(MINUTE));
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
testIsCached();
|
||||
setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
testNotCached();
|
||||
testIsCached();
|
||||
|
||||
setDefaultCachePolicy();
|
||||
testIsCached();
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testWeeklyEviction() {
|
||||
testIsCached();
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientStorageProviderModel model = realm.getClientStorageProviders().get(0);
|
||||
Calendar eviction = Calendar.getInstance();
|
||||
eviction.add(Calendar.HOUR, 4 * 24);
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.EVICT_WEEKLY);
|
||||
model.setEvictionDay(eviction.get(DAY_OF_WEEK));
|
||||
model.setEvictionHour(eviction.get(HOUR_OF_DAY));
|
||||
model.setEvictionMinute(eviction.get(MINUTE));
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
testIsCached();
|
||||
setTimeOffset(2 * 24 * 60 * 60); // 2 days in future
|
||||
testIsCached();
|
||||
setTimeOffset(5 * 24 * 60 * 60); // 5 days in future
|
||||
testNotCached();
|
||||
testIsCached();
|
||||
|
||||
setDefaultCachePolicy();
|
||||
testIsCached();
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testMaxLifespan() {
|
||||
testIsCached();
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientStorageProviderModel model = realm.getClientStorageProviders().get(0);
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.MAX_LIFESPAN);
|
||||
model.setMaxLifespan(1 * 60 * 60 * 1000);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
testIsCached();
|
||||
|
||||
setTimeOffset(1/2 * 60 * 60); // 1/2 hour in future
|
||||
|
||||
testIsCached();
|
||||
|
||||
setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
|
||||
testNotCached();
|
||||
testIsCached();
|
||||
|
||||
setDefaultCachePolicy();
|
||||
testIsCached();
|
||||
|
||||
}
|
||||
|
||||
private void testNotCached() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientModel hardcoded = realm.getClientByClientId("hardcoded-client");
|
||||
Assert.assertNotNull(hardcoded);
|
||||
Assert.assertFalse(hardcoded instanceof ClientAdapter);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIsCached() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientModel hardcoded = realm.getClientByClientId("hardcoded-client");
|
||||
Assert.assertNotNull(hardcoded);
|
||||
Assert.assertTrue(hardcoded instanceof org.keycloak.models.cache.infinispan.ClientAdapter);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoCache() {
|
||||
testIsCached();
|
||||
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientStorageProviderModel model = realm.getClientStorageProviders().get(0);
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
|
||||
testNotCached();
|
||||
|
||||
// test twice because updating component should evict
|
||||
testNotCached();
|
||||
|
||||
// set it back
|
||||
setDefaultCachePolicy();
|
||||
testIsCached();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void setDefaultCachePolicy() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
ClientStorageProviderModel model = realm.getClientStorageProviders().get(0);
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.DEFAULT);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue