Repository: cassandra Updated Branches: refs/heads/trunk 9ba900dcf -> e379f978b
Allow roles cache to be invalidated Patch by brandonwilliams, reviewed by beobal for CASSANDRA-8967 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e379f978 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e379f978 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e379f978 Branch: refs/heads/trunk Commit: e379f978b6b00f4dc7c2b37a8bda6cdc52d32b8a Parents: 9ba900d Author: Brandon Williams <brandonwilli...@apache.org> Authored: Wed May 13 10:29:58 2015 -0500 Committer: Brandon Williams <brandonwilli...@apache.org> Committed: Wed May 13 10:29:58 2015 -0500 ---------------------------------------------------------------------- CHANGES.txt | 1 + src/java/org/apache/cassandra/auth/Roles.java | 5 +- .../org/apache/cassandra/auth/RolesCache.java | 126 ++++++++++++------- .../apache/cassandra/auth/RolesCacheMBean.java | 31 +++++ .../org/apache/cassandra/config/Config.java | 4 +- .../cassandra/config/DatabaseDescriptor.java | 10 ++ 6 files changed, 129 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/e379f978/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 4a700aa..94f5fcd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.0 + * Allow roles cache to be invalidated (CASSANDRA-8967) * Upgrade Snappy (CASSANDRA-9063) * Don't start Thrift rpc by default (CASSANDRA-9319) * Only stream from unrepaired sstables with incremental repair (CASSANDRA-8267) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e379f978/src/java/org/apache/cassandra/auth/Roles.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/Roles.java b/src/java/org/apache/cassandra/auth/Roles.java index c73f882..da6804b 100644 --- a/src/java/org/apache/cassandra/auth/Roles.java +++ b/src/java/org/apache/cassandra/auth/Roles.java @@ -23,10 +23,7 @@ import org.apache.cassandra.config.DatabaseDescriptor; public class Roles { - private static final RolesCache cache = new RolesCache(DatabaseDescriptor.getRolesValidity(), - DatabaseDescriptor.getRolesUpdateInterval(), - DatabaseDescriptor.getRolesCacheMaxEntries(), - DatabaseDescriptor.getRoleManager()); + private static final RolesCache cache = new RolesCache(DatabaseDescriptor.getRoleManager()); /** * Get all roles granted to the supplied Role, including both directly granted http://git-wip-us.apache.org/repos/asf/cassandra/blob/e379f978/src/java/org/apache/cassandra/auth/RolesCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/RolesCache.java b/src/java/org/apache/cassandra/auth/RolesCache.java index 0e9e134..58aa739 100644 --- a/src/java/org/apache/cassandra/auth/RolesCache.java +++ b/src/java/org/apache/cassandra/auth/RolesCache.java @@ -17,6 +17,7 @@ */ package org.apache.cassandra.auth; +import java.lang.management.ManagementFactory; import java.util.Set; import java.util.concurrent.*; @@ -31,19 +32,32 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor; import org.apache.cassandra.config.DatabaseDescriptor; -public class RolesCache +import javax.management.MBeanServer; +import javax.management.ObjectName; + +public class RolesCache implements RolesCacheMBean { private static final Logger logger = LoggerFactory.getLogger(RolesCache.class); + private final String MBEAN_NAME = "org.apache.cassandra.auth:type=RolesCache"; private final ThreadPoolExecutor cacheRefreshExecutor = new DebuggableThreadPoolExecutor("RolesCacheRefresh", Thread.NORM_PRIORITY); private final IRoleManager roleManager; - private final LoadingCache<RoleResource, Set<RoleResource>> cache; + private volatile LoadingCache<RoleResource, Set<RoleResource>> cache; - public RolesCache(int validityPeriod, int updateInterval, int maxEntries, IRoleManager roleManager) + public RolesCache(IRoleManager roleManager) { this.roleManager = roleManager; - this.cache = initCache(validityPeriod, updateInterval, maxEntries); + this.cache = initCache(null); + try + { + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + mbs.registerMBean(this, new ObjectName(MBEAN_NAME)); + } + catch (Exception e) + { + throw new RuntimeException(e); + } } public Set<RoleResource> getRoles(RoleResource role) @@ -61,49 +75,77 @@ public class RolesCache } } - private LoadingCache<RoleResource, Set<RoleResource>> initCache(int validityPeriod, - int updateInterval, - int maxEntries) + public void invalidate() + { + cache = initCache(null); + } + + public void setValidity(int validityPeriod) + { + DatabaseDescriptor.setRolesValidity(validityPeriod); + cache = initCache(cache); + } + + public int getValidity() + { + return DatabaseDescriptor.getRolesValidity(); + } + + public void setUpdateInterval(int updateInterval) + { + DatabaseDescriptor.setRolesUpdateInterval(updateInterval); + cache = initCache(cache); + } + + public int getUpdateInterval() + { + return DatabaseDescriptor.getRolesUpdateInterval(); + } + + + private LoadingCache<RoleResource, Set<RoleResource>> initCache(LoadingCache<RoleResource, Set<RoleResource>> existing) { if (DatabaseDescriptor.getAuthenticator() instanceof AllowAllAuthenticator) return null; - if (validityPeriod <= 0) + if (DatabaseDescriptor.getRolesValidity() <= 0) return null; - return CacheBuilder.newBuilder() - .refreshAfterWrite(updateInterval, TimeUnit.MILLISECONDS) - .expireAfterWrite(validityPeriod, TimeUnit.MILLISECONDS) - .maximumSize(maxEntries) - .build(new CacheLoader<RoleResource, Set<RoleResource>>() - { - public Set<RoleResource> load(RoleResource primaryRole) - { - return roleManager.getRoles(primaryRole, true); - } - - public ListenableFuture<Set<RoleResource>> reload(final RoleResource primaryRole, - final Set<RoleResource> oldValue) - { - ListenableFutureTask<Set<RoleResource>> task; - task = ListenableFutureTask.create(new Callable<Set<RoleResource>>() - { - public Set<RoleResource> call() throws Exception - { - try - { - return roleManager.getRoles(primaryRole, true); - } - catch (Exception e) - { - logger.debug("Error performing async refresh of user roles", e); - throw e; - } - } - }); - cacheRefreshExecutor.execute(task); - return task; - } - }); + LoadingCache<RoleResource, Set<RoleResource>> newcache = CacheBuilder.newBuilder() + .refreshAfterWrite(DatabaseDescriptor.getRolesUpdateInterval(), TimeUnit.MILLISECONDS) + .expireAfterWrite(DatabaseDescriptor.getRolesValidity(), TimeUnit.MILLISECONDS) + .maximumSize(DatabaseDescriptor.getRolesCacheMaxEntries()) + .build(new CacheLoader<RoleResource, Set<RoleResource>>() + { + public Set<RoleResource> load(RoleResource primaryRole) + { + return roleManager.getRoles(primaryRole, true); + } + + public ListenableFuture<Set<RoleResource>> reload(final RoleResource primaryRole, + final Set<RoleResource> oldValue) + { + ListenableFutureTask<Set<RoleResource>> task; + task = ListenableFutureTask.create(new Callable<Set<RoleResource>>() + { + public Set<RoleResource> call() throws Exception + { + try + { + return roleManager.getRoles(primaryRole, true); + } catch (Exception e) + { + logger.debug("Error performing async refresh of user roles", e); + throw e; + } + } + }); + cacheRefreshExecutor.execute(task); + return task; + } + }); + if (existing != null) + newcache.putAll(existing.asMap()); + return newcache; } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/e379f978/src/java/org/apache/cassandra/auth/RolesCacheMBean.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/RolesCacheMBean.java b/src/java/org/apache/cassandra/auth/RolesCacheMBean.java new file mode 100644 index 0000000..cf270e6 --- /dev/null +++ b/src/java/org/apache/cassandra/auth/RolesCacheMBean.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cassandra.auth; + +public interface RolesCacheMBean +{ + public void invalidate(); + + public void setValidity(int validityPeriod); + + public int getValidity(); + + public void setUpdateInterval(int updateInterval); + + public int getUpdateInterval(); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cassandra/blob/e379f978/src/java/org/apache/cassandra/config/Config.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java index 7d7ef01..421794e 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -51,9 +51,9 @@ public class Config public volatile int permissions_validity_in_ms = 2000; public int permissions_cache_max_entries = 1000; public volatile int permissions_update_interval_in_ms = -1; - public int roles_validity_in_ms = 2000; + public volatile int roles_validity_in_ms = 2000; public int roles_cache_max_entries = 1000; - public int roles_update_interval_in_ms = -1; + public volatile int roles_update_interval_in_ms = -1; /* Hashing strategy Random or OPHF */ public String partitioner; http://git-wip-us.apache.org/repos/asf/cassandra/blob/e379f978/src/java/org/apache/cassandra/config/DatabaseDescriptor.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 7da9066..ec90be2 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -674,6 +674,11 @@ public class DatabaseDescriptor return conf.roles_validity_in_ms; } + public static void setRolesValidity(int validity) + { + conf.roles_validity_in_ms = validity; + } + public static int getRolesCacheMaxEntries() { return conf.roles_cache_max_entries; @@ -686,6 +691,11 @@ public class DatabaseDescriptor : conf.roles_update_interval_in_ms; } + public static void setRolesUpdateInterval(int interval) + { + conf.roles_update_interval_in_ms = interval; + } + public static void setPermissionsUpdateInterval(int updateInterval) { conf.permissions_update_interval_in_ms = updateInterval;