Allow invalidating permissions and cache time Patch by brandonwilliams reviewed by aleksey for CASSANDRA-8722
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9caf0457 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9caf0457 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9caf0457 Branch: refs/heads/trunk Commit: 9caf0457ad8920788506f902ce4d9c130c881031 Parents: 1376b8e Author: Brandon Williams <brandonwilli...@apache.org> Authored: Fri Mar 13 10:57:43 2015 -0500 Committer: Brandon Williams <brandonwilli...@apache.org> Committed: Fri Mar 13 10:57:43 2015 -0500 ---------------------------------------------------------------------- CHANGES.txt | 2 +- src/java/org/apache/cassandra/auth/Auth.java | 5 +- .../apache/cassandra/auth/PermissionsCache.java | 69 ++++++++++++++++---- .../cassandra/auth/PermissionsCacheMBean.java | 31 +++++++++ .../org/apache/cassandra/config/Config.java | 4 +- .../cassandra/config/DatabaseDescriptor.java | 10 +++ 6 files changed, 102 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/9caf0457/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index cd29e9d..04861f0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.4 + * Allow invalidating permissions and cache time (CASSANDRA-8722) * Log warning when queries that will require ALLOW FILTERING in Cassandra 3.0 are executed (CASSANDRA-8418) * Fix cassandra-stress so it respects the CL passed in user mode (CASSANDRA-8948) @@ -40,7 +41,6 @@ * Fix Adler32 digest for compressed sstables (CASSANDRA-8778) * Add nodetool statushandoff/statusbackup (CASSANDRA-8912) Merged from 2.0: -2.0.14: * Fix duplicate up/down messages sent to native clients (CASSANDRA-7816) * Expose commit log archive status via JMX (CASSANDRA-8734) * Provide better exceptions for invalid replication strategy parameters http://git-wip-us.apache.org/repos/asf/cassandra/blob/9caf0457/src/java/org/apache/cassandra/auth/Auth.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/Auth.java b/src/java/org/apache/cassandra/auth/Auth.java index 05e5061..dac2af8 100644 --- a/src/java/org/apache/cassandra/auth/Auth.java +++ b/src/java/org/apache/cassandra/auth/Auth.java @@ -57,10 +57,7 @@ public class Auth public static final String USERS_CF = "users"; // User-level permissions cache. - private static final PermissionsCache permissionsCache = new PermissionsCache(DatabaseDescriptor.getPermissionsValidity(), - DatabaseDescriptor.getPermissionsUpdateInterval(), - DatabaseDescriptor.getPermissionsCacheMaxEntries(), - DatabaseDescriptor.getAuthorizer()); + private static final PermissionsCache permissionsCache = new PermissionsCache(DatabaseDescriptor.getAuthorizer()); private static final String USERS_CF_SCHEMA = String.format("CREATE TABLE %s.%s (" + "name text," http://git-wip-us.apache.org/repos/asf/cassandra/blob/9caf0457/src/java/org/apache/cassandra/auth/PermissionsCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/PermissionsCache.java b/src/java/org/apache/cassandra/auth/PermissionsCache.java index 9e0dfa9..bc96d82 100644 --- a/src/java/org/apache/cassandra/auth/PermissionsCache.java +++ b/src/java/org/apache/cassandra/auth/PermissionsCache.java @@ -17,9 +17,11 @@ */ package org.apache.cassandra.auth; +import java.lang.management.ManagementFactory; import java.util.Set; import java.util.concurrent.*; +import org.apache.cassandra.config.DatabaseDescriptor; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -31,19 +33,33 @@ import org.slf4j.LoggerFactory; import org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor; import org.apache.cassandra.utils.Pair; -public class PermissionsCache +import javax.management.MBeanServer; +import javax.management.ObjectName; + +public class PermissionsCache implements PermissionsCacheMBean { private static final Logger logger = LoggerFactory.getLogger(PermissionsCache.class); + private final String MBEAN_NAME = "org.apache.cassandra.auth:type=PermissionsCache"; + private final ThreadPoolExecutor cacheRefreshExecutor = new DebuggableThreadPoolExecutor("PermissionsCacheRefresh", Thread.NORM_PRIORITY); private final IAuthorizer authorizer; - private final LoadingCache<Pair<AuthenticatedUser, IResource>, Set<Permission>> cache; + private volatile LoadingCache<Pair<AuthenticatedUser, IResource>, Set<Permission>> cache; - public PermissionsCache(int validityPeriod, int updateInterval, int maxEntries, IAuthorizer authorizer) + public PermissionsCache(IAuthorizer authorizer) { this.authorizer = authorizer; - 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<Permission> getPermissions(AuthenticatedUser user, IResource resource) @@ -61,20 +77,46 @@ public class PermissionsCache } } - private LoadingCache<Pair<AuthenticatedUser, IResource>, Set<Permission>> initCache(int validityPeriod, - int updateInterval, - int maxEntries) + public void invalidate() + { + cache = initCache(null); + } + + public void setValidity(int validityPeriod) + { + DatabaseDescriptor.setPermissionsValidity(validityPeriod); + cache = initCache(cache); + } + + public int getValidity() + { + return DatabaseDescriptor.getPermissionsValidity(); + } + + public void setUpdateInterval(int updateInterval) + { + DatabaseDescriptor.setPermissionsUpdateInterval(updateInterval); + cache = initCache(cache); + } + + public int getUpdateInterval() + { + return DatabaseDescriptor.getPermissionsUpdateInterval(); + } + + private LoadingCache<Pair<AuthenticatedUser, IResource>, Set<Permission>> initCache( + LoadingCache<Pair<AuthenticatedUser, IResource>, Set<Permission>> existing) { if (authorizer instanceof AllowAllAuthorizer) return null; - if (validityPeriod <= 0) + if (DatabaseDescriptor.getPermissionsValidity() <= 0) return null; - return CacheBuilder.newBuilder() - .refreshAfterWrite(updateInterval, TimeUnit.MILLISECONDS) - .expireAfterWrite(validityPeriod, TimeUnit.MILLISECONDS) - .maximumSize(maxEntries) + LoadingCache<Pair<AuthenticatedUser, IResource>, Set<Permission>> newcache = CacheBuilder.newBuilder() + .refreshAfterWrite(DatabaseDescriptor.getPermissionsUpdateInterval(), TimeUnit.MILLISECONDS) + .expireAfterWrite(DatabaseDescriptor.getPermissionsValidity(), TimeUnit.MILLISECONDS) + .maximumSize(DatabaseDescriptor.getPermissionsCacheMaxEntries()) .build(new CacheLoader<Pair<AuthenticatedUser, IResource>, Set<Permission>>() { public Set<Permission> load(Pair<AuthenticatedUser, IResource> userResource) @@ -104,5 +146,8 @@ public class PermissionsCache return task; } }); + if (existing != null) + newcache.putAll(existing.asMap()); + return newcache; } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/9caf0457/src/java/org/apache/cassandra/auth/PermissionsCacheMBean.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/auth/PermissionsCacheMBean.java b/src/java/org/apache/cassandra/auth/PermissionsCacheMBean.java new file mode 100644 index 0000000..d07c98f --- /dev/null +++ b/src/java/org/apache/cassandra/auth/PermissionsCacheMBean.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 PermissionsCacheMBean +{ + public void invalidate(); + + public void setValidity(int validityPeriod); + + public int getValidity(); + + public void setUpdateInterval(int updateInterval); + + public int getUpdateInterval(); +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/9caf0457/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 c683d7b..ccd4467 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -42,9 +42,9 @@ public class Config public String cluster_name = "Test Cluster"; public String authenticator; public String authorizer; - public int permissions_validity_in_ms = 2000; + public volatile int permissions_validity_in_ms = 2000; public int permissions_cache_max_entries = 1000; - public int permissions_update_interval_in_ms = -1; + public volatile int permissions_update_interval_in_ms = -1; /* Hashing strategy Random or OPHF */ public String partitioner; http://git-wip-us.apache.org/repos/asf/cassandra/blob/9caf0457/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 924ab3c..4426f20 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -714,6 +714,11 @@ public class DatabaseDescriptor return conf.permissions_validity_in_ms; } + public static void setPermissionsValidity(int timeout) + { + conf.permissions_validity_in_ms = timeout; + } + public static int getPermissionsCacheMaxEntries() { return conf.permissions_cache_max_entries; @@ -726,6 +731,11 @@ public class DatabaseDescriptor : conf.permissions_update_interval_in_ms; } + public static void setPermissionsUpdateInterval(int updateInterval) + { + conf.permissions_update_interval_in_ms = updateInterval; + } + public static int getThriftFramedTransportSize() { return conf.thrift_framed_transport_size_in_mb * 1024 * 1024;