org.apache.cassandra.auth.CIDRGroupsMappingCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cassandra-all Show documentation
Show all versions of cassandra-all Show documentation
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.
/*
* 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.net.InetAddress;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Preconditions;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.apache.cassandra.concurrent.ImmediateExecutor;
import org.apache.cassandra.concurrent.ScheduledExecutors;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.metrics.CIDRAuthorizerMetrics;
import org.apache.cassandra.utils.MonotonicClock;
/**
* CIDR groups mapping cache. Periodically reloads the cache with the latest entries
* in the table {@link AuthKeyspace#CIDR_GROUPS}
*/
public class CIDRGroupsMappingCache
{
// References to the latest mapping, changes everytime cache is reloaded
private volatile CIDRGroupsMappingLoader currentCidrGroupsMappingLoader = null;
// IP to CIDR groups cache, to reuse CIDR groups lookup result for an IP
private LoadingCache> ipToCidrGroupsCache;
private volatile boolean cacheInitialized = false;
private CIDRGroupsMappingManager cidrGroupsMappingManager;
private final CIDRAuthorizerMetrics cidrAuthorizerMetrics;
public CIDRGroupsMappingCache(CIDRGroupsMappingManager cidrGroupsMappingManager,
CIDRAuthorizerMetrics cidrAuthorizerMetrics)
{
this.cidrGroupsMappingManager = cidrGroupsMappingManager;
this.cidrAuthorizerMetrics = cidrAuthorizerMetrics;
// IP to CIDR groups cache
ipToCidrGroupsCache = Caffeine.newBuilder()
.maximumSize(DatabaseDescriptor.getIpCacheMaxSize())
.executor(ImmediateExecutor.INSTANCE)
.build(this::lookupCidrGroupsCacheForIp);
// Interval to reload the cache periodically
int cidrGroupsCacheRefreshInterval = DatabaseDescriptor.getCidrGroupsCacheRefreshInterval();
// Schedule a task to reload cache periodically
ScheduledExecutors.scheduledTasks.scheduleWithFixedDelay(this::reloadCidrGroupsCache,
cidrGroupsCacheRefreshInterval,
cidrGroupsCacheRefreshInterval,
TimeUnit.MINUTES);
}
/**
* Builds CIDR groups cache from entries in the table {@link AuthKeyspace#CIDR_GROUPS}
* and points to the latest cache
*/
private void loadCidrGroupsCacheInternal()
{
long startTimeNanos = MonotonicClock.Global.approxTime.now();
currentCidrGroupsMappingLoader = new CIDRGroupsMappingLoader(this.cidrGroupsMappingManager);
// Clear IP to CIDR groups cache entries as we reloaded CIDR groups cache
ipToCidrGroupsCache.invalidateAll();
cidrAuthorizerMetrics.cacheReloadCount.inc();
cidrAuthorizerMetrics.cacheReloadLatency.update(MonotonicClock.Global.approxTime.now() - startTimeNanos,
TimeUnit.NANOSECONDS);
}
/**
* Reload CIDR groups cache with the latest state of the table {@link AuthKeyspace#CIDR_GROUPS}
*/
private void reloadCidrGroupsCache()
{
// Wait until CIDR authorizer calls init cache during the setup
// Otherwise scheduled task may trigger this before startup is complete
// and fails to find system tables
if (cacheInitialized)
loadCidrGroupsCacheInternal();
}
/**
* Builds CIDR groups cache the first time. Should be called before
* auth starts sending lookup IP requests
*/
public void loadCidrGroupsCache()
{
loadCidrGroupsCacheInternal();
cacheInitialized = true;
}
private Set lookupCidrGroupsCacheForIp(InetAddress ipAddr)
{
long startTimeNanos = MonotonicClock.Global.approxTime.now();
Preconditions.checkNotNull(currentCidrGroupsMappingLoader);
Set cidrGroups = currentCidrGroupsMappingLoader.lookupCidrGroupsCacheForIp(ipAddr);
cidrAuthorizerMetrics.lookupCidrGroupsForIpLatency.update(MonotonicClock.Global.approxTime.now() - startTimeNanos,
TimeUnit.NANOSECONDS);
return cidrGroups;
}
/**
* Lookup best matching CIDR group for the given IP
* @param ipAddr IP address
* @return returns set of CIDR group(s)
*/
public Set lookupCidrGroupsForIp(InetAddress ipAddr)
{
Preconditions.checkState(cacheInitialized, "CIDR groups cache not inited");
return ipToCidrGroupsCache.get(ipAddr);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy