cache settings

This commit is contained in:
Bill Burke committed 2014-07-18 11:30:10 -04:00
1 parent 573f7fc1fb
commit f275ecf6d5
17 files changed
+183 -25

No files matched your search

@@ -27,6 +27,10 @@ public class RealmRepresentation {
protected Boolean resetPasswordAllowed;
protected Boolean social;
protected Boolean updateProfileOnInitialSocialLogin;
protected Boolean userCacheEnabled;
protected Boolean realmCacheEnabled;
//--- brute force settings
protected Boolean bruteForceProtected;
protected Integer maxFailureWaitSeconds;
@@ -240,6 +244,22 @@ public class RealmRepresentation {
this.rememberMe = rememberMe;
}
public Boolean isRealmCacheEnabled() {
return realmCacheEnabled;
}
public void setRealmCacheEnabled(Boolean realmCacheEnabled) {
this.realmCacheEnabled = realmCacheEnabled;
}
public Boolean isUserCacheEnabled() {
return userCacheEnabled;
}
public void setUserCacheEnabled(Boolean userCacheEnabled) {
this.userCacheEnabled = userCacheEnabled;
}
public Boolean isVerifyEmail() {
return verifyEmail;
}
@@ -80,7 +80,7 @@
</div>
</fieldset>
<fieldset>
<legend><span class="text">Optional Settings</span></legend>
<legend><span class="text">Theme Settings</span></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="loginTheme">Login Theme</label>
<div class="col-sm-4">
@@ -130,6 +130,21 @@
</div>
</div>
</fieldset>
<fieldset>
<legend><span class="text">Cache Settings</span></legend>
<div class="form-group">
<label class="col-sm-2 control-label" for="enabled">Realm Cache Enabled</label>
<div class="col-sm-4">
<input ng-model="realm.realmCacheEnabled" name="realmCacheEnabled" id="realmCacheEnabled" onoffswitch />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="enabled">User Cache Enabled</label>
<div class="col-sm-4">
<input ng-model="realm.userCacheEnabled" name="userCacheEnabled" id="userCacheEnabled" onoffswitch />
</div>
</div>
</fieldset>
<div class="pull-right form-actions" data-ng-show="createRealm && access.manageRealm">
<button kc-cancel data-ng-click="cancel()">Cancel</button>
@@ -9,6 +9,9 @@ import org.keycloak.models.RealmProvider;
public interface CacheRealmProvider extends RealmProvider {
RealmProvider getDelegate();
boolean isEnabled();
void setEnabled(boolean enabled);
void registerRealmInvalidation(String id);
void registerApplicationInvalidation(String id);
@@ -9,6 +9,7 @@ import org.keycloak.models.UserProvider;
*/
public interface CacheUserProvider extends UserProvider {
UserProvider getDelegate();
boolean isEnabled();
void setEnabled(boolean enabled);
void registerUserInvalidation(RealmModel realm, String id);
}
@@ -41,7 +41,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
protected Map<String, ApplicationModel> managedApplications = new HashMap<String, ApplicationModel>();
protected Map<String, OAuthClientModel> managedClients = new HashMap<String, OAuthClientModel>();
protected Map<String, RoleModel> managedRoles = new HashMap<String, RoleModel>();
protected Map<String, UserModel> managedUsers = new HashMap<String, UserModel>();
protected boolean clearAll;
@@ -52,6 +51,16 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
session.getTransaction().enlistAfterCompletion(getTransaction());
}
@Override
public boolean isEnabled() {
return cache.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
cache.setEnabled(enabled);
}
@Override
public RealmProvider getDelegate() {
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
@@ -142,6 +151,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public RealmModel createRealm(String name) {
RealmModel realm = getDelegate().createRealm(name);
if (!cache.isEnabled()) return realm;
registerRealmInvalidation(realm.getId());
return realm;
}
@@ -149,12 +159,14 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public RealmModel createRealm(String id, String name) {
RealmModel realm = getDelegate().createRealm(id, name);
if (!cache.isEnabled()) return realm;
registerRealmInvalidation(realm.getId());
return realm;
}
@Override
public RealmModel getRealm(String id) {
if (!cache.isEnabled()) return getDelegate().getRealm(id);
CachedRealm cached = cache.getCachedRealm(id);
if (cached == null) {
RealmModel model = getDelegate().getRealm(id);
@@ -174,6 +186,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public RealmModel getRealmByName(String name) {
if (!cache.isEnabled()) return getDelegate().getRealmByName(name);
CachedRealm cached = cache.getCachedRealmByName(name);
if (cached == null) {
RealmModel model = getDelegate().getRealmByName(name);
@@ -199,6 +212,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public boolean removeRealm(String id) {
if (!cache.isEnabled()) return getDelegate().removeRealm(id);
cache.invalidateCachedRealmById(id);
RealmModel realm = getDelegate().getRealm(id);
@@ -227,6 +241,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public RoleModel getRoleById(String id, RealmModel realm) {
if (!cache.isEnabled()) return getDelegate().getRoleById(id, realm);
CachedRole cached = cache.getRole(id);
if (cached == null) {
RoleModel model = getDelegate().getRoleById(id, realm);
@@ -251,6 +266,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public ApplicationModel getApplicationById(String id, RealmModel realm) {
if (!cache.isEnabled()) return getDelegate().getApplicationById(id, realm);
CachedApplication cached = cache.getApplication(id);
if (cached == null) {
ApplicationModel model = getDelegate().getApplicationById(id, realm);
@@ -270,6 +286,7 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
@Override
public OAuthClientModel getOAuthClientById(String id, RealmModel realm) {
if (!cache.isEnabled()) return getDelegate().getOAuthClientById(id, realm);
CachedOAuthClient cached = cache.getOAuthClient(id);
if (cached == null) {
OAuthClientModel model = getDelegate().getOAuthClientById(id, realm);
@@ -40,6 +40,16 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
session.getTransaction().enlistAfterCompletion(getTransaction());
}
@Override
public boolean isEnabled() {
return cache.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
cache.setEnabled(enabled);
}
@Override
public UserProvider getDelegate() {
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
@@ -103,6 +113,7 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
@Override
public UserModel getUserById(String id, RealmModel realm) {
if (!cache.isEnabled()) return getDelegate().getUserById(id, realm);
if (realmInvalidations.contains(realm.getId())) {
return getDelegate().getUserById(id, realm);
}
@@ -127,6 +138,7 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
if (!cache.isEnabled()) return getDelegate().getUserByUsername(username, realm);
if (realmInvalidations.contains(realm.getId())) {
return getDelegate().getUserByUsername(username, realm);
}
@@ -149,6 +161,7 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
if (!cache.isEnabled()) return getDelegate().getUserByEmail(email, realm);
if (realmInvalidations.contains(realm.getId())) {
return getDelegate().getUserByEmail(email, realm);
}
@@ -236,6 +249,7 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
@Override
public boolean removeUser(RealmModel realm, String name) {
if (!cache.isEnabled()) return getDelegate().removeUser(realm, name);
UserModel user = getUserByUsername(name, realm);
if (user == null) return false;
registerUserInvalidation(realm, user.getId());
@@ -8,7 +8,7 @@ import org.keycloak.models.KeycloakSession;
* @version $Revision: 1 $
*/
public class MemoryCacheUserProviderFactory implements CacheUserProviderFactory {
protected UserCache cache = new MemoryUserCache();
protected MemoryUserCache cache;
@Override
public CacheUserProvider create(KeycloakSession session) {
@@ -18,7 +18,9 @@ public class MemoryCacheUserProviderFactory implements CacheUserProviderFactory
@Override
public void init(Config.Scope config) {
config.get("");
cache = new MemoryUserCache();
int size = config.getInt("maxSize", 10000);
cache.setMaxUserCacheSize(size);
}
@Override
@@ -18,6 +18,7 @@ public class MemoryRealmCache implements RealmCache {
protected ConcurrentHashMap<String, CachedApplication> applicationCache = new ConcurrentHashMap<String, CachedApplication>();
protected ConcurrentHashMap<String, CachedOAuthClient> clientCache = new ConcurrentHashMap<String, CachedOAuthClient>();
protected ConcurrentHashMap<String, CachedRole> roleCache = new ConcurrentHashMap<String, CachedRole>();
protected volatile boolean enabled = true;
@Override
public void clear() {
@@ -28,8 +29,21 @@ public class MemoryRealmCache implements RealmCache {
roleCache.clear();
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
clear();
this.enabled = enabled;
clear();
}
@Override
public CachedRealm getCachedRealm(String id) {
if (!enabled) return null;
return realmCache.get(id);
}
@@ -48,6 +62,7 @@ public class MemoryRealmCache implements RealmCache {
@Override
public void addCachedRealm(CachedRealm realm) {
if (!enabled) return;
realmCache.put(realm.getId(), realm);
realmCacheByName.put(realm.getName(), realm);
@@ -55,11 +70,13 @@ public class MemoryRealmCache implements RealmCache {
@Override
public CachedRealm getCachedRealmByName(String name) {
if (!enabled) return null;
return realmCacheByName.get(name);
}
@Override
public CachedApplication getApplication(String id) {
if (!enabled) return null;
return applicationCache.get(id);
}
@@ -70,6 +87,7 @@ public class MemoryRealmCache implements RealmCache {
@Override
public void addCachedApplication(CachedApplication app) {
if (!enabled) return;
applicationCache.put(app.getId(), app);
}
@@ -80,6 +98,7 @@ public class MemoryRealmCache implements RealmCache {
@Override
public CachedOAuthClient getOAuthClient(String id) {
if (!enabled) return null;
return clientCache.get(id);
}
@@ -90,6 +109,7 @@ public class MemoryRealmCache implements RealmCache {
@Override
public void addCachedOAuthClient(CachedOAuthClient client) {
if (!enabled) return;
clientCache.put(client.getId(), client);
}
@@ -100,6 +120,7 @@ public class MemoryRealmCache implements RealmCache {
@Override
public CachedRole getRole(String id) {
if (!enabled) return null;
return roleCache.get(id);
}
@@ -115,6 +136,7 @@ public class MemoryRealmCache implements RealmCache {
@Override
public void addCachedRole(CachedRole role) {
if (!enabled) return;
roleCache.put(role.getId(), role);
}
@@ -14,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class MemoryUserCache implements UserCache {
protected int maxUserCacheSize = 10000;
protected volatile boolean enabled = true;
protected class RealmUsers {
@@ -77,6 +78,18 @@ public class MemoryUserCache implements UserCache {
this.maxUserCacheSize = maxUserCacheSize;
}
@Override
public boolean isEnabled() {
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
clear();
this.enabled = enabled;
clear();
}
@Override
public CachedUser getCachedUser(String realmId, String id) {
if (realmId == null || id == null) return null;
@@ -16,26 +16,25 @@ import java.util.List;
public class NoCacheRealmProvider implements CacheRealmProvider {
protected KeycloakSession session;
protected RealmProvider delegate;
// protected KeycloakTransaction transactionDelegate;
// protected boolean transactionActive;
// protected boolean setRollbackOnly;
public NoCacheRealmProvider(KeycloakSession session) {
this.session = session;
}
@Override
public boolean isEnabled() {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void setEnabled(boolean enabled) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public RealmProvider getDelegate() {
// if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
if (delegate != null) return delegate;
delegate = session.getProvider(RealmProvider.class);
// transactionDelegate = delegate.getTransaction();
// if (!transactionDelegate.isActive()) {
// transactionDelegate.begin();
// if (setRollbackOnly) {
// transactionDelegate.setRollbackOnly();
// }
// }
return delegate;
}
@@ -24,6 +24,15 @@ public class NoCacheUserProvider implements CacheUserProvider {
this.session = session;
}
@Override
public boolean isEnabled() {
return false;
}
@Override
public void setEnabled(boolean enabled) {
}
@Override
public UserProvider getDelegate() {
if (delegate != null) return delegate;
@@ -33,7 +42,6 @@ public class NoCacheUserProvider implements CacheUserProvider {
@Override
public void registerUserInvalidation(RealmModel realm, String id) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
@@ -49,4 +49,7 @@ public interface RealmCache {
void invalidateRoleById(String id);
boolean isEnabled();
void setEnabled(boolean enabled);
}
@@ -22,4 +22,8 @@ public interface UserCache {
void invalidateCachedUserById(String realmId, String id);
void invalidateRealmUsers(String realmId);
boolean isEnabled();
void setEnabled(boolean enabled);
}
@@ -10,16 +10,27 @@
}
},
"model": {
"realm": {
"provider": "jpa"
},
"userSessions": {
"provider" : "mem"
"user": {
"provider": "${keycloak.user.provider:jpa}"
},
"modelCache": {
"provider": "${keycloak.model.cache.provider:}"
"userSessions": {
"provider" : "${keycloak.userSessions.provider:mem}"
},
"realmCache": {
"provider": "${keycloak.realm.cache.provider:mem}"
},
"userCache": {
"provider": "${keycloak.user.cache.provider:mem}",
"mem": {
"maxSize": 20000
}
},
"timer": {
@@ -27,7 +27,10 @@
},
"userCache": {
"provider": "${keycloak.user.cache.provider:mem}"
"provider": "${keycloak.user.cache.provider:mem}",
"mem": {
"maxSize": 20000
}
},
"timer": {
@@ -13,6 +13,8 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.models.cache.CacheRealmProvider;
import org.keycloak.models.cache.CacheUserProvider;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.adapters.action.SessionStats;
@@ -114,7 +116,16 @@ public class RealmAdminResource {
@Produces("application/json")
public RealmRepresentation getRealm() {
if (auth.hasView()) {
return ModelToRepresentation.toRepresentation(realm);
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm);
if (session.realms() instanceof CacheRealmProvider) {
CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled());
}
if (session.users() instanceof CacheUserProvider) {
CacheUserProvider cache = (CacheUserProvider)session.users();
rep.setUserCacheEnabled(cache.isEnabled());
}
return rep;
} else {
auth.requireAny();
@@ -140,6 +151,15 @@ public class RealmAdminResource {
logger.debug("updating realm: " + realm.getName());
try {
RepresentationToModel.updateRealm(rep, realm);
if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) {
CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled());
}
if (rep.isUserCacheEnabled() != null && session.users() instanceof CacheUserProvider) {
CacheUserProvider cache = (CacheUserProvider)session.users();
cache.setEnabled(rep.isUserCacheEnabled());
}
return Response.noContent().build();
} catch (ModelDuplicateException e) {
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
@@ -24,7 +24,10 @@
},
"userCache": {
"provider": "${keycloak.user.cache.provider:mem}"
"provider": "${keycloak.user.cache.provider:mem}",
"mem": {
"maxSize": 20000
}
},
"timer": {