All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.cassandra.auth.RolesCache Maven / Gradle / Ivy

Go to download

The Apache Cassandra Project develops a highly scalable second-generation distributed database, bringing together Dynamo's fully distributed design and Bigtable's ColumnFamily-based data model.

There is a newer version: 5.0.2
Show newest version
/*
 * 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;

import java.util.Set;
import java.util.concurrent.*;

import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListenableFutureTask;
import com.google.common.util.concurrent.UncheckedExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.utils.MBeanWrapper;

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)
    {
        protected void afterExecute(Runnable r, Throwable t)
        {
            // empty to avoid logging on background updates
        }
    };
    private final IRoleManager roleManager;
    private volatile LoadingCache> cache;

    public RolesCache(IRoleManager roleManager)
    {
        this.roleManager = roleManager;
        this.cache = initCache(null);
        MBeanWrapper.instance.registerMBean(this, MBEAN_NAME);
    }

    public Set getRoles(RoleResource role)
    {
        if (cache == null)
            return roleManager.getRoles(role, true);

        try
        {
            return cache.get(role);
        }
        catch (ExecutionException | UncheckedExecutionException e)
        {
            Throwables.propagateIfInstanceOf(e.getCause(), RuntimeException.class);
            throw Throwables.propagate(e);
        }
    }

    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> initCache(LoadingCache> existing)
    {
        if (!DatabaseDescriptor.getAuthenticator().requireAuthentication())
            return null;

        if (DatabaseDescriptor.getRolesValidity() <= 0)
            return null;

        LoadingCache> newcache = CacheBuilder.newBuilder()
                .refreshAfterWrite(DatabaseDescriptor.getRolesUpdateInterval(), TimeUnit.MILLISECONDS)
                .expireAfterWrite(DatabaseDescriptor.getRolesValidity(), TimeUnit.MILLISECONDS)
                .maximumSize(DatabaseDescriptor.getRolesCacheMaxEntries())
                .build(new CacheLoader>()
                {
                    public Set load(RoleResource primaryRole)
                    {
                        return roleManager.getRoles(primaryRole, true);
                    }

                    public ListenableFuture> reload(final RoleResource primaryRole,
                                                                      final Set oldValue)
                    {
                        ListenableFutureTask> task;
                        task = ListenableFutureTask.create(new Callable>()
                        {
                            public Set call() throws Exception
                            {
                                try
                                {
                                    return roleManager.getRoles(primaryRole, true);
                                } catch (Exception e)
                                {
                                    logger.trace("Error performing async refresh of user roles", e);
                                    throw e;
                                }
                            }
                        });
                        cacheRefreshExecutor.execute(task);
                        return task;
                    }
                });
        if (existing != null)
            newcache.putAll(existing.asMap());
        return newcache;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy