You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2015/05/13 17:30:36 UTC

cassandra git commit: Allow roles cache to be invalidated

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 <br...@apache.org>
Authored: Wed May 13 10:29:58 2015 -0500
Committer: Brandon Williams <br...@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;