You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2021/02/27 16:58:01 UTC
[ranger] branch ranger-2.2 updated: RANGER-3192: Use read-write
locks for managing access to policy-engine and tag-repository
This is an automated email from the ASF dual-hosted git repository.
abhay pushed a commit to branch ranger-2.2
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.2 by this push:
new c20d0e0 RANGER-3192: Use read-write locks for managing access to policy-engine and tag-repository
c20d0e0 is described below
commit c20d0e0a65aed8f7fbd8020acfe1612c9b7887f8
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Sat Feb 27 07:08:47 2021 -0800
RANGER-3192: Use read-write locks for managing access to policy-engine and tag-repository
---
.../ranger/admin/client/RangerAdminRESTClient.java | 18 +-
.../plugin/contextenricher/RangerTagEnricher.java | 151 +++++---
.../ranger/plugin/policyengine/PolicyEngine.java | 259 +++++++++-----
.../policyengine/RangerPolicyEngineImpl.java | 397 ++++++++++++++-------
.../policyengine/RangerPolicyRepository.java | 263 ++++++++------
.../org/apache/ranger/plugin/store/TagStore.java | 2 +
.../ranger/plugin/util/RangerCommonConstants.java | 24 +-
.../ranger/plugin/util/RangerReadWriteLock.java | 98 +++++
.../admin/client/RangerAdminJersey2RESTClient.java | 18 +-
.../apache/ranger/biz/RangerPolicyAdminCache.java | 4 +-
.../apache/ranger/biz/RangerPolicyAdminImpl.java | 250 +++++++++----
.../java/org/apache/ranger/biz/ServiceDBStore.java | 9 +-
.../java/org/apache/ranger/biz/TagDBStore.java | 24 +-
.../ranger/common/RangerAdminTagEnricher.java | 12 +
.../java/org/apache/ranger/biz/TestXUserMgr.java | 4 -
15 files changed, 1044 insertions(+), 489 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
index 9d527bf..e0d7a9b 100644
--- a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
+++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java
@@ -53,8 +53,8 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
private String clusterName;
private RangerRESTClient restClient;
private RangerRESTUtils restUtils = new RangerRESTUtils();
- private String supportsPolicyDeltas;
- private String supportsTagDeltas;
+ private boolean supportsPolicyDeltas;
+ private boolean supportsTagDeltas;
private final String pluginCapabilities = Long.toHexString(new RangerPluginCapability().getPluginCapabilities());
public static <T> GenericType<List<T>> getGenericType(final T clazz) {
@@ -97,8 +97,8 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
}
int restClientConnTimeOutMs = config.getInt(propertyPrefix + ".policy.rest.client.connection.timeoutMs", 120 * 1000);
int restClientReadTimeOutMs = config.getInt(propertyPrefix + ".policy.rest.client.read.timeoutMs", 30 * 1000);
- supportsPolicyDeltas = config.get(propertyPrefix + ".policy.rest.supports.policy.deltas", "false");
- supportsTagDeltas = config.get(propertyPrefix + ".tag.rest.supports.tag.deltas", "false");
+ supportsPolicyDeltas = config.getBoolean(propertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
+ supportsTagDeltas = config.getBoolean(propertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
if (!StringUtil.isEmpty(tmpUrl)) {
url = tmpUrl.trim();
@@ -106,12 +106,6 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
if (url.endsWith("/")) {
url = url.substring(0, url.length() - 1);
}
- if (!"true".equalsIgnoreCase(supportsPolicyDeltas)) {
- supportsPolicyDeltas = "false";
- }
- if (!"true".equalsIgnoreCase(supportsTagDeltas)) {
- supportsTagDeltas = "false";
- }
init(url, sslConfigFileName, restClientConnTimeOutMs , restClientReadTimeOutMs, config);
@@ -140,7 +134,7 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME, Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
queryParams.put(RangerRESTUtils.REST_PARAM_CLUSTER_NAME, clusterName);
- queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS, supportsPolicyDeltas);
+ queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS, Boolean.toString(supportsPolicyDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
if (isSecureMode) {
@@ -799,7 +793,7 @@ public class RangerAdminRESTClient extends AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.LAST_KNOWN_TAG_VERSION_PARAM, Long.toString(lastKnownVersion));
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME, Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
- queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS, supportsTagDeltas);
+ queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS, Boolean.toString(supportsTagDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
if (isSecureMode) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index 97b9e2c..f457460 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -26,6 +26,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerServiceResource;
@@ -42,7 +43,9 @@ import org.apache.ranger.plugin.util.DownloadTrigger;
import org.apache.ranger.plugin.util.DownloaderTask;
import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerServiceNotFoundException;
import org.apache.ranger.plugin.util.RangerServiceTagsDeltaUtil;
import org.apache.ranger.plugin.util.ServiceTags;
@@ -87,6 +90,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
private Timer tagDownloadTimer;
private RangerServiceDefHelper serviceDefHelper;
+ private RangerReadWriteLock lock = new RangerReadWriteLock(false);
@Override
public void init() {
@@ -132,6 +136,9 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
cacheFilename = cacheFilename.replace(File.pathSeparatorChar, '_');
String cacheFile = cacheDir == null ? null : (cacheDir + File.separator + cacheFilename);
+
+ createLock();
+
tagRetriever.setServiceName(serviceName);
tagRetriever.setServiceDef(serviceDef);
tagRetriever.setAppId(appId);
@@ -189,21 +196,33 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerTagEnricher.enrich(" + request + ") with dataStore:[" + dataStore + "]");
}
- final EnrichedServiceTags enrichedServiceTags;
- if (dataStore instanceof EnrichedServiceTags) {
- enrichedServiceTags = (EnrichedServiceTags) dataStore;
- } else {
- enrichedServiceTags = this.enrichedServiceTags;
+ final Set<RangerTagForEval> matchedTags;
+
+ try (RangerReadWriteLock.RangerLock readLock = this.lock.getReadLock()) {
- if (dataStore != null) {
- LOG.warn("Incorrect type of dataStore :[" + dataStore.getClass().getName() + "], falling back to original enrich");
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
}
- }
- final Set<RangerTagForEval> matchedTags = enrichedServiceTags == null ? null : findMatchingTags(request, enrichedServiceTags);
+ final EnrichedServiceTags enrichedServiceTags;
- RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(), matchedTags);
+ if (dataStore instanceof EnrichedServiceTags) {
+ enrichedServiceTags = (EnrichedServiceTags) dataStore;
+ } else {
+ enrichedServiceTags = this.enrichedServiceTags;
+
+ if (dataStore != null) {
+ LOG.warn("Incorrect type of dataStore :[" + dataStore.getClass().getName() + "], falling back to original enrich");
+ }
+ }
+
+ matchedTags = enrichedServiceTags == null ? null : findMatchingTags(request, enrichedServiceTags);
+
+ RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(), matchedTags);
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerTagEnricher.enrich(" + request + ") with dataStore:[" + dataStore + "]): tags count=" + (matchedTags == null ? 0 : matchedTags.size()));
@@ -266,48 +285,64 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
LOG.debug("==> RangerTagEnricher.setServiceTags(serviceTags=" + serviceTags + ", rebuildOnlyIndex=" + rebuildOnlyIndex + ")");
}
- if (serviceTags == null) {
- LOG.info("ServiceTags is null for service " + serviceName);
- enrichedServiceTags = null;
- } else {
+ try (RangerReadWriteLock.RangerLock writeLock = this.lock.getWriteLock()) {
+
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_SET_SERVICETAGS_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_SET_SERVICETAGS_LOG, "RangerTagEnricher.setServiceTags(newTagVersion=" + serviceTags.getTagVersion() + ",isDelta=" + serviceTags.getIsDelta() + ")");
}
- if (!serviceTags.getIsDelta()) {
- processServiceTags(serviceTags);
+ if (serviceTags == null) {
+ LOG.info("ServiceTags is null for service " + serviceName);
+ enrichedServiceTags = null;
} else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Received service-tag deltas:" + serviceTags);
- }
-
- ServiceTags oldServiceTags = enrichedServiceTags != null ? enrichedServiceTags.getServiceTags() : new ServiceTags();
- ServiceTags allServiceTags = rebuildOnlyIndex ? oldServiceTags : RangerServiceTagsDeltaUtil.applyDelta(oldServiceTags, serviceTags);
-
- if (serviceTags.getTagsChangeExtent() == ServiceTags.TagsChangeExtent.NONE) {
+ if (!serviceTags.getIsDelta()) {
+ processServiceTags(serviceTags);
+ } else {
if (LOG.isDebugEnabled()) {
- LOG.debug("No change to service-tags other than version change");
+ LOG.debug("Received service-tag deltas:" + serviceTags);
}
- } else {
- if (serviceTags.getTagsChangeExtent() != ServiceTags.TagsChangeExtent.TAGS) {
- processServiceTagDeltas(serviceTags, allServiceTags);
- } else {
+ ServiceTags oldServiceTags = enrichedServiceTags != null ? enrichedServiceTags.getServiceTags() : new ServiceTags();
+ ServiceTags allServiceTags = rebuildOnlyIndex ? oldServiceTags : RangerServiceTagsDeltaUtil.applyDelta(oldServiceTags, serviceTags);
+
+ if (serviceTags.getTagsChangeExtent() == ServiceTags.TagsChangeExtent.NONE) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Delta contains only tag attribute changes");
+ LOG.debug("No change to service-tags other than version change");
+ }
+ } else {
+ if (serviceTags.getTagsChangeExtent() != ServiceTags.TagsChangeExtent.TAGS) {
+ Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> trieMap;
+
+ if (enrichedServiceTags == null) {
+ trieMap = new HashMap<>();
+ } else {
+ trieMap = writeLock.isLockingEnabled() ? enrichedServiceTags.getServiceResourceTrie() : copyServiceResourceTrie();
+ }
+
+ processServiceTagDeltas(serviceTags, allServiceTags, trieMap);
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Delta contains only tag attribute changes");
+ }
+ List<RangerServiceResourceMatcher> resourceMatchers = enrichedServiceTags != null ? enrichedServiceTags.getServiceResourceMatchers() : new ArrayList<>();
+ Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie = enrichedServiceTags != null ? enrichedServiceTags.getServiceResourceTrie() : new HashMap<>();
+ enrichedServiceTags = new EnrichedServiceTags(allServiceTags, resourceMatchers, serviceResourceTrie);
}
- List<RangerServiceResourceMatcher> resourceMatchers = enrichedServiceTags != null ? enrichedServiceTags.getServiceResourceMatchers() : new ArrayList<>();
- Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie = enrichedServiceTags != null ? enrichedServiceTags.getServiceResourceTrie() : new HashMap<>();
- enrichedServiceTags = new EnrichedServiceTags(allServiceTags, resourceMatchers, serviceResourceTrie);
}
}
+
}
+ setEnrichedServiceTagsInPlugin();
+
RangerPerfTracer.logAlways(perf);
}
- setEnrichedServiceTagsInPlugin();
-
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerTagEnricher.setServiceTags(serviceTags=" + serviceTags + ", rebuildOnlyIndex=" + rebuildOnlyIndex + ")");
}
@@ -315,11 +350,13 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
}
protected Long getServiceTagsVersion() {
- return enrichedServiceTags != null ? enrichedServiceTags.getServiceTags().getTagVersion() : -1L;
+ EnrichedServiceTags localEnrichedServiceTags = enrichedServiceTags;
+ return localEnrichedServiceTags != null ? localEnrichedServiceTags.getServiceTags().getTagVersion() : -1L;
}
protected Long getResourceTrieVersion() {
- return enrichedServiceTags != null ? enrichedServiceTags.getResourceTrieVersion() : -1L;
+ EnrichedServiceTags localEnrichedServiceTags = enrichedServiceTags;
+ return localEnrichedServiceTags != null ? localEnrichedServiceTags.getResourceTrieVersion() : -1L;
}
@Override
@@ -359,6 +396,18 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
return enrichedServiceTags;
}
+ protected RangerReadWriteLock createLock() {
+ String propertyPrefix = "ranger.plugin." + serviceDef.getName();
+ RangerPluginConfig config = getPluginConfig();
+ boolean deltasEnabled = config != null && config.getBoolean(propertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
+ boolean inPlaceUpdatesEnabled = config != null && config.getBoolean(propertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT);
+ boolean useReadWriteLock = deltasEnabled && inPlaceUpdatesEnabled;
+
+ LOG.info("Policy-Engine will" + (useReadWriteLock ? " " : " not ") + "use read-write locking to update tags in place when tag-deltas are provided");
+
+ return new RangerReadWriteLock(useReadWriteLock);
+
+ }
private void processServiceTags(ServiceTags serviceTags) {
if (LOG.isDebugEnabled()) {
LOG.debug("Processing all service-tags");
@@ -405,24 +454,18 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
}
}
- private void processServiceTagDeltas(ServiceTags deltas, ServiceTags allServiceTags) {
+ private void processServiceTagDeltas(ServiceTags deltas, ServiceTags allServiceTags, Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie) {
if (LOG.isDebugEnabled()) {
LOG.debug("Delta contains changes other than tag attribute changes, [" + deltas.getTagsChangeExtent() + "]");
}
- boolean isInError = false;
-
- ResourceHierarchies hierarchies = new ResourceHierarchies();
+ boolean isInError = false;
- List<RangerServiceResourceMatcher> resourceMatchers = new ArrayList<>();
- Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie = new HashMap<>();
+ ResourceHierarchies hierarchies = new ResourceHierarchies();
+ List<RangerServiceResourceMatcher> resourceMatchers = new ArrayList<>();
if (enrichedServiceTags != null) {
resourceMatchers.addAll(enrichedServiceTags.getServiceResourceMatchers());
- for (Map.Entry<String, RangerResourceTrie<RangerServiceResourceMatcher>> entry : enrichedServiceTags.getServiceResourceTrie().entrySet()) {
- RangerResourceTrie<RangerServiceResourceMatcher> resourceTrie = new RangerResourceTrie<>(entry.getValue());
- serviceResourceTrie.put(entry.getKey(), resourceTrie);
- }
}
List<RangerServiceResource> changedServiceResources = deltas.getServiceResources();
@@ -810,6 +853,18 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
return ret;
}
+ private Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> copyServiceResourceTrie() {
+ Map<String, RangerResourceTrie<RangerServiceResourceMatcher>> ret = new HashMap<>();
+
+ if (enrichedServiceTags != null) {
+ for (Map.Entry<String, RangerResourceTrie<RangerServiceResourceMatcher>> entry : enrichedServiceTags.getServiceResourceTrie().entrySet()) {
+ RangerResourceTrie<RangerServiceResourceMatcher> resourceTrie = new RangerResourceTrie<>(entry.getValue());
+ ret.put(entry.getKey(), resourceTrie);
+ }
+ }
+ return ret;
+ }
+
static public final class EnrichedServiceTags {
final private ServiceTags serviceTags;
final private List<RangerServiceResourceMatcher> serviceResourceMatchers;
@@ -896,7 +951,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
RangerPerfTracer.log(perf);
} catch (InterruptedException excp) {
- LOG.debug("RangerTagRefresher(" + getName() + ").run(): Interrupted! Exiting thread", excp);
+ LOG.info("RangerTagRefresher(" + getName() + ").run(): Interrupted! Exiting thread", excp);
break;
} finally {
if (trigger != null) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
index 1909ad4..9d79520 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
@@ -46,6 +46,7 @@ import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.RangerPolicyDeltaUtil;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.plugin.util.StringTokenReplacer;
@@ -67,6 +68,16 @@ public class PolicyEngine {
private String[] trustedProxyAddresses;
private final Map<String, StringTokenReplacer> tokenReplacers = new HashMap<>();
+ private final RangerReadWriteLock lock;
+
+ public RangerReadWriteLock.RangerLock getReadLock() {
+ return lock.getReadLock();
+ }
+
+ public RangerReadWriteLock.RangerLock getWriteLock() {
+ return lock.getWriteLock();
+ }
+
public boolean getUseForwardedIPAddress() {
return useForwardedIPAddress;
}
@@ -152,6 +163,8 @@ public class PolicyEngine {
}
sb.append("} ");
+ sb.append(lock.toString());
+
sb.append("}");
return sb;
@@ -167,7 +180,7 @@ public class PolicyEngine {
return resourceZoneTrie;
}
- public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext pluginContext, RangerRoles roles) {
+ public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext pluginContext, RangerRoles roles, boolean isUseReadWriteLock) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> PolicyEngine(" + ", " + servicePolicies + ", " + pluginContext + ")");
}
@@ -184,6 +197,9 @@ public class PolicyEngine {
}
this.pluginContext = pluginContext;
+ this.lock = new RangerReadWriteLock(isUseReadWriteLock);
+
+ LOG.info("Policy engine will" + (isUseReadWriteLock ? " " : " not ") + "perform in place update while processing policy-deltas.");
this.pluginContext.setAuthContext(new RangerAuthContext(null, roles));
@@ -200,8 +216,7 @@ public class PolicyEngine {
if (!options.disableTagPolicyEvaluation
&& tagPolicies != null
&& !StringUtils.isEmpty(tagPolicies.getServiceName())
- && tagPolicies.getServiceDef() != null
- && !CollectionUtils.isEmpty(tagPolicies.getPolicies())) {
+ && tagPolicies.getServiceDef() != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("PolicyEngine : Building tag-policy-repository for tag-service " + tagPolicies.getServiceName());
}
@@ -281,33 +296,46 @@ public class PolicyEngine {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "RangerPolicyEngine.cloneWithDelta()");
}
- RangerServiceDef serviceDef = this.getServiceDef();
- String serviceType = (serviceDef != null) ? serviceDef.getName() : "";
- boolean isValidDeltas = false;
+ try (RangerReadWriteLock.RangerLock writeLock = getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
- if (CollectionUtils.isNotEmpty(servicePolicies.getPolicyDeltas()) || MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
- isValidDeltas = CollectionUtils.isEmpty(servicePolicies.getPolicyDeltas()) || RangerPolicyDeltaUtil.isValidDeltas(servicePolicies.getPolicyDeltas(), serviceType);
+ RangerServiceDef serviceDef = this.getServiceDef();
+ String serviceType = (serviceDef != null) ? serviceDef.getName() : "";
+ boolean isValidDeltas = false;
- if (isValidDeltas) {
- if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
- for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> entry : servicePolicies.getSecurityZones().entrySet()) {
- if (!RangerPolicyDeltaUtil.isValidDeltas(entry.getValue().getPolicyDeltas(), serviceType)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Invalid policy-deltas for security zone:[" + entry.getKey() + "]");
- }
+ if (CollectionUtils.isNotEmpty(servicePolicies.getPolicyDeltas()) || MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
+ isValidDeltas = CollectionUtils.isEmpty(servicePolicies.getPolicyDeltas()) || RangerPolicyDeltaUtil.isValidDeltas(servicePolicies.getPolicyDeltas(), serviceType);
+
+ if (isValidDeltas) {
+ if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
+ for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> entry : servicePolicies.getSecurityZones().entrySet()) {
+ if (!RangerPolicyDeltaUtil.isValidDeltas(entry.getValue().getPolicyDeltas(), serviceType)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Invalid policy-deltas for security zone:[" + entry.getKey() + "]");
+ }
- isValidDeltas = false;
- break;
+ isValidDeltas = false;
+ break;
+ }
}
}
}
}
- }
- if (isValidDeltas) {
- ret = new PolicyEngine(this, servicePolicies);
- } else {
- ret = null;
+ if (isValidDeltas) {
+ if (writeLock.isLockingEnabled()) {
+ updatePolicyEngine(servicePolicies);
+ ret = this;
+ } else {
+ ret = new PolicyEngine(this, servicePolicies);
+ }
+ } else {
+ ret = null;
+ }
}
RangerPerfTracer.log(perf);
@@ -556,83 +584,17 @@ public class PolicyEngine {
return ret;
}
-
private PolicyEngine(final PolicyEngine other, ServicePolicies servicePolicies) {
this.useForwardedIPAddress = other.useForwardedIPAddress;
this.trustedProxyAddresses = other.trustedProxyAddresses;
this.pluginContext = other.pluginContext;
+ this.lock = other.lock;
long policyVersion = servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion() : -1L;
List<RangerPolicyDelta> defaultZoneDeltas = new ArrayList<>();
List<RangerPolicyDelta> defaultZoneDeltasForTagPolicies = new ArrayList<>();
- if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
- buildZoneTrie(servicePolicies);
-
- Map<String, List<RangerPolicyDelta>> zoneDeltasMap = new HashMap<>();
-
- for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone : servicePolicies.getSecurityZones().entrySet()) {
- List<RangerPolicyDelta> deltas = zone.getValue().getPolicyDeltas();
-
- for (RangerPolicyDelta delta : deltas) {
- String zoneName = delta.getZoneName();
-
- if (StringUtils.isNotEmpty(zoneName)) {
- List<RangerPolicyDelta> zoneDeltas = zoneDeltasMap.get(zoneName);
-
- if (zoneDeltas == null) {
- zoneDeltas = new ArrayList<>();
- zoneDeltasMap.put(zoneName, zoneDeltas);
- }
-
- zoneDeltas.add(delta);
- } else {
- LOG.warn("policyDelta : [" + delta + "] does not belong to any zone. Should not have come here.");
- }
- }
- }
-
- for (Map.Entry<String, List<RangerPolicyDelta>> entry : zoneDeltasMap.entrySet()) {
- final String zoneName = entry.getKey();
- final List<RangerPolicyDelta> zoneDeltas = entry.getValue();
- final RangerPolicyRepository otherRepository = other.zonePolicyRepositories.get(zoneName);
- final RangerPolicyRepository policyRepository;
-
- if (CollectionUtils.isNotEmpty(zoneDeltas)) {
- if (otherRepository == null) {
- List<RangerPolicy> policies = new ArrayList<>();
-
- for (RangerPolicyDelta delta : zoneDeltas) {
- if (delta.getChangeType() == RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE) {
- policies.add(delta.getPolicy());
- } else {
- LOG.warn("Expected changeType:[" + RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE + "], found policy-change-delta:[" + delta +"]");
- }
- }
-
- servicePolicies.getSecurityZones().get(zoneName).setPolicies(policies);
-
- policyRepository = new RangerPolicyRepository(servicePolicies, this.pluginContext, zoneName);
- } else {
- policyRepository = new RangerPolicyRepository(otherRepository, zoneDeltas, policyVersion);
- }
- } else {
- policyRepository = shareWith(otherRepository);
- }
-
- zonePolicyRepositories.put(zoneName, policyRepository);
- }
- }
-
- List<RangerPolicyDelta> unzonedDeltas = servicePolicies.getPolicyDeltas();
-
- for (RangerPolicyDelta delta : unzonedDeltas) {
- if (servicePolicies.getServiceDef().getName().equals(delta.getServiceType())) {
- defaultZoneDeltas.add(delta);
- } else {
- defaultZoneDeltasForTagPolicies.add(delta);
- }
- }
+ getDeltasSortedByZones(servicePolicies, defaultZoneDeltas, defaultZoneDeltasForTagPolicies);
if (other.policyRepository != null && CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
this.policyRepository = new RangerPolicyRepository(other.policyRepository, defaultZoneDeltas, policyVersion);
@@ -813,5 +775,122 @@ public class PolicyEngine {
LOG.debug("<== PolicyEngine.cleanup()");
}
}
+
+ void updatePolicyEngine(ServicePolicies servicePolicies) {
+
+ long policyVersion = servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion() : -1L;
+ List<RangerPolicyDelta> defaultZoneDeltas = new ArrayList<>();
+ List<RangerPolicyDelta> defaultZoneDeltasForTagPolicies = new ArrayList<>();
+
+ getDeltasSortedByZones(servicePolicies, defaultZoneDeltas, defaultZoneDeltasForTagPolicies);
+
+ if (this.policyRepository != null && CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
+ this.policyRepository.reinit(defaultZoneDeltas, policyVersion);
+ }
+
+ if (servicePolicies.getTagPolicies() != null && CollectionUtils.isNotEmpty(defaultZoneDeltasForTagPolicies)) {
+ if (this.tagPolicyRepository != null) {
+ this.tagPolicyRepository.reinit(defaultZoneDeltasForTagPolicies, policyVersion);
+ } else {
+ LOG.error("No previous tagPolicyRepository to update! Should not have come here!!");
+ }
+ }
+
+ // Set all repositories to shared
+ if (policyRepository != null) {
+ policyRepository.setShared();
+ }
+ for (RangerPolicyRepository zoneRepository : zonePolicyRepositories.values()) {
+ if (zoneRepository != null) {
+ zoneRepository.setShared();
+ }
+ }
+ if (tagPolicyRepository != null) {
+ tagPolicyRepository.setShared();
+ }
+
+ reorderPolicyEvaluators();
+ }
+
+ private void getDeltasSortedByZones(ServicePolicies servicePolicies, List<RangerPolicyDelta> defaultZoneDeltas, List<RangerPolicyDelta> defaultZoneDeltasForTagPolicies) {
+ long policyVersion = servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion() : -1L;
+
+ if (CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
+ LOG.warn("Emptying out defaultZoneDeltas!");
+ defaultZoneDeltas.clear();
+ }
+ if (CollectionUtils.isNotEmpty(defaultZoneDeltasForTagPolicies)) {
+ LOG.warn("Emptying out defaultZoneDeltasForTagPolicies!");
+ defaultZoneDeltasForTagPolicies.clear();
+ }
+
+ if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
+ buildZoneTrie(servicePolicies);
+
+ Map<String, List<RangerPolicyDelta>> zoneDeltasMap = new HashMap<>();
+
+ for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone : servicePolicies.getSecurityZones().entrySet()) {
+ List<RangerPolicyDelta> deltas = zone.getValue().getPolicyDeltas();
+
+ for (RangerPolicyDelta delta : deltas) {
+ String zoneName = delta.getZoneName();
+
+ if (StringUtils.isNotEmpty(zoneName)) {
+ List<RangerPolicyDelta> zoneDeltas = zoneDeltasMap.get(zoneName);
+
+ if (zoneDeltas == null) {
+ zoneDeltas = new ArrayList<>();
+ zoneDeltasMap.put(zoneName, zoneDeltas);
+ }
+
+ zoneDeltas.add(delta);
+ } else {
+ LOG.warn("policyDelta : [" + delta + "] does not belong to any zone. Should not have come here.");
+ }
+ }
+ }
+
+ for (Map.Entry<String, List<RangerPolicyDelta>> entry : zoneDeltasMap.entrySet()) {
+ final String zoneName = entry.getKey();
+ final List<RangerPolicyDelta> zoneDeltas = entry.getValue();
+ final RangerPolicyRepository otherRepository = this.zonePolicyRepositories.get(zoneName);
+ final RangerPolicyRepository policyRepository;
+
+ if (CollectionUtils.isNotEmpty(zoneDeltas)) {
+ if (otherRepository == null) {
+ List<RangerPolicy> policies = new ArrayList<>();
+
+ for (RangerPolicyDelta delta : zoneDeltas) {
+ if (delta.getChangeType() == RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE) {
+ policies.add(delta.getPolicy());
+ } else {
+ LOG.warn("Expected changeType:[" + RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE + "], found policy-change-delta:[" + delta +"]");
+ }
+ }
+
+ servicePolicies.getSecurityZones().get(zoneName).setPolicies(policies);
+
+ policyRepository = new RangerPolicyRepository(servicePolicies, this.pluginContext, zoneName);
+ } else {
+ policyRepository = new RangerPolicyRepository(otherRepository, zoneDeltas, policyVersion);
+ }
+ } else {
+ policyRepository = shareWith(otherRepository);
+ }
+
+ zonePolicyRepositories.put(zoneName, policyRepository);
+ }
+ }
+
+ List<RangerPolicyDelta> unzonedDeltas = servicePolicies.getPolicyDeltas();
+
+ for (RangerPolicyDelta delta : unzonedDeltas) {
+ if (servicePolicies.getServiceDef().getName().equals(delta.getServiceType())) {
+ defaultZoneDeltas.add(delta);
+ } else {
+ defaultZoneDeltasForTagPolicies.add(delta);
+ }
+ }
+ }
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 4e0c98e..75811b8 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -25,6 +25,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
@@ -36,7 +37,9 @@ import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche
import org.apache.ranger.plugin.service.RangerDefaultRequestProcessor;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.ServicePolicies;
@@ -71,7 +74,11 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
PolicyEngine policyEngine = other.policyEngine.cloneWithDelta(servicePolicies);
if (policyEngine != null) {
- ret = new RangerPolicyEngineImpl(policyEngine, other);
+ if (policyEngine == other.policyEngine) {
+ ret = other;
+ } else {
+ ret = new RangerPolicyEngineImpl(policyEngine, other);
+ }
}
}
@@ -79,7 +86,18 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
public RangerPolicyEngineImpl(ServicePolicies servicePolicies, RangerPluginContext pluginContext, RangerRoles roles) {
- policyEngine = new PolicyEngine(servicePolicies, pluginContext, roles);
+ final boolean isUseReadWriteLock;
+
+ Configuration config = pluginContext != null ? pluginContext.getConfig() : null;
+
+ if (config != null) {
+ boolean isDeltasSupported = config.getBoolean(pluginContext.getConfig().getPropertyPrefix() + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
+ isUseReadWriteLock = isDeltasSupported && config.getBoolean(pluginContext.getConfig().getPropertyPrefix() + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT);
+ } else {
+ isUseReadWriteLock = false;
+ }
+
+ policyEngine = new PolicyEngine(servicePolicies, pluginContext, roles, isUseReadWriteLock);
serviceConfig = new ServiceConfig(servicePolicies.getServiceConfig());
requestProcessor = new RangerDefaultRequestProcessor(policyEngine);
}
@@ -105,22 +123,32 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
LOG.info("RangerPolicyEngineImpl.evaluatePolicies(" + requestHashCode + ", " + request + ")");
}
- requestProcessor.preProcess(request);
+ RangerAccessResult ret;
- RangerAccessResult ret = zoneAwareAccessEvaluationWithNoAudit(request, policyType);
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
- if (resultProcessor != null) {
- RangerPerfTracer perfAuditTracer = null;
+ requestProcessor.preProcess(request);
- if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_AUDIT_LOG)) {
- String requestHashCode = Integer.toHexString(System.identityHashCode(request)) + "_" + policyType;
+ ret = zoneAwareAccessEvaluationWithNoAudit(request, policyType);
- perfAuditTracer = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_AUDIT_LOG, "RangerPolicyEngine.processAudit(requestHashCode=" + requestHashCode + ")");
- }
+ if (resultProcessor != null) {
+ RangerPerfTracer perfAuditTracer = null;
- resultProcessor.processResult(ret);
+ if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_AUDIT_LOG)) {
+ String requestHashCode = Integer.toHexString(System.identityHashCode(request)) + "_" + policyType;
- RangerPerfTracer.log(perfAuditTracer);
+ perfAuditTracer = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_AUDIT_LOG, "RangerPolicyEngine.processAudit(requestHashCode=" + requestHashCode + ")");
+ }
+
+ resultProcessor.processResult(ret);
+
+ RangerPerfTracer.log(perfAuditTracer);
+ }
}
RangerPerfTracer.log(perf);
@@ -140,18 +168,25 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
Collection<RangerAccessResult> ret = new ArrayList<>();
- if (requests != null) {
- for (RangerAccessRequest request : requests) {
- requestProcessor.preProcess(request);
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ if (requests != null) {
+ for (RangerAccessRequest request : requests) {
+ requestProcessor.preProcess(request);
- RangerAccessResult result = zoneAwareAccessEvaluationWithNoAudit(request, policyType);
+ RangerAccessResult result = zoneAwareAccessEvaluationWithNoAudit(request, policyType);
- ret.add(result);
+ ret.add(result);
+ }
}
- }
- if (resultProcessor != null) {
- resultProcessor.processResults(ret);
+ if (resultProcessor != null) {
+ resultProcessor.processResults(ret);
+ }
}
if (LOG.isDebugEnabled()) {
@@ -167,27 +202,35 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
LOG.debug("==> RangerPolicyEngineImpl.evaluateAuditPolicies(result=" + result + ")");
}
- RangerPolicyRepository tagPolicyRepository = policyEngine.getTagPolicyRepository();
- RangerPolicyRepository policyRepository = policyEngine.getPolicyRepository();
- RangerAccessRequest request = result.getAccessRequest();
- boolean savedIsAuditedDetermined = result.getIsAuditedDetermined();
- boolean savedIsAudited = result.getIsAudited();
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
- result.setIsAudited(false);
- result.setIsAuditedDetermined(false);
+ RangerPolicyRepository tagPolicyRepository = policyEngine.getTagPolicyRepository();
+ RangerPolicyRepository policyRepository = policyEngine.getPolicyRepository();
+ RangerAccessRequest request = result.getAccessRequest();
+ boolean savedIsAuditedDetermined = result.getIsAuditedDetermined();
+ boolean savedIsAudited = result.getIsAudited();
- try {
- if (tagPolicyRepository != null) {
- evaluateTagAuditPolicies(request, result, tagPolicyRepository);
- }
+ result.setIsAudited(false);
+ result.setIsAuditedDetermined(false);
- if (!result.getIsAuditedDetermined() && policyRepository != null) {
- evaluateResourceAuditPolicies(request, result, policyRepository);
- }
- } finally {
- if (!result.getIsAuditedDetermined()) {
- result.setIsAudited(savedIsAudited);
- result.setIsAuditedDetermined(savedIsAuditedDetermined);
+ try {
+ if (tagPolicyRepository != null) {
+ evaluateTagAuditPolicies(request, result, tagPolicyRepository);
+ }
+
+ if (!result.getIsAuditedDetermined() && policyRepository != null) {
+ evaluateResourceAuditPolicies(request, result, policyRepository);
+ }
+ } finally {
+ if (!result.getIsAuditedDetermined()) {
+ result.setIsAudited(savedIsAudited);
+ result.setIsAuditedDetermined(savedIsAuditedDetermined);
+ }
}
}
@@ -209,122 +252,130 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_GET_ACLS_LOG, "RangerPolicyEngine.getResourceACLs(requestHashCode=" + request.getResource().getAsString() + ")");
}
- requestProcessor.preProcess(request);
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
- String zoneName = policyEngine.getUniquelyMatchedZoneName(request.getResource().getAsMap());
+ requestProcessor.preProcess(request);
- if (LOG.isDebugEnabled()) {
- LOG.debug("zoneName:[" + zoneName + "]");
- }
- List<RangerPolicyEvaluator> allEvaluators = new ArrayList<>();
- Map<Long, RangerPolicyResourceMatcher.MatchType> tagMatchTypeMap = new HashMap<>();
- Set<Long> policyIdForTemporalTags = new HashSet<>();
+ String zoneName = policyEngine.getUniquelyMatchedZoneName(request.getResource().getAsMap());
- getResourceACLEvaluatorsForZone(request, zoneName, allEvaluators, tagMatchTypeMap, policyIdForTemporalTags);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("zoneName:[" + zoneName + "]");
+ }
+ List<RangerPolicyEvaluator> allEvaluators = new ArrayList<>();
+ Map<Long, RangerPolicyResourceMatcher.MatchType> tagMatchTypeMap = new HashMap<>();
+ Set<Long> policyIdForTemporalTags = new HashSet<>();
- allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
+ getResourceACLEvaluatorsForZone(request, zoneName, allEvaluators, tagMatchTypeMap, policyIdForTemporalTags);
- if (CollectionUtils.isNotEmpty(allEvaluators)) {
- Integer policyPriority = null;
+ allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
- for (RangerPolicyEvaluator evaluator : allEvaluators) {
- if (policyPriority == null) {
- policyPriority = evaluator.getPolicyPriority();
- }
+ if (CollectionUtils.isNotEmpty(allEvaluators)) {
+ Integer policyPriority = null;
- if (policyPriority != evaluator.getPolicyPriority()) {
- ret.finalizeAcls();
+ for (RangerPolicyEvaluator evaluator : allEvaluators) {
+ if (policyPriority == null) {
+ policyPriority = evaluator.getPolicyPriority();
+ }
- policyPriority = evaluator.getPolicyPriority();
- }
+ if (policyPriority != evaluator.getPolicyPriority()) {
+ ret.finalizeAcls();
- RangerPolicyResourceMatcher.MatchType matchType = tagMatchTypeMap.get(evaluator.getId());
+ policyPriority = evaluator.getPolicyPriority();
+ }
- if (matchType == null) {
- matchType = evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), request.getContext());
- }
+ RangerPolicyResourceMatcher.MatchType matchType = tagMatchTypeMap.get(evaluator.getId());
- final boolean isMatched;
+ if (matchType == null) {
+ matchType = evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), request.getContext());
+ }
- if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
- isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
- } else {
- isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
- }
+ final boolean isMatched;
- if (!isMatched) {
- continue;
- }
+ if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+ isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+ } else {
+ isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
+ }
- PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary();
+ if (!isMatched) {
+ continue;
+ }
- if (aclSummary != null) {
- boolean isConditional = policyIdForTemporalTags.contains(evaluator.getId()) || evaluator.getValidityScheduleEvaluatorsCount() != 0;
- Integer accessResult;
+ PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary();
- for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> userAccessInfo : aclSummary.getUsersAccessInfo().entrySet()) {
- final String userName = userAccessInfo.getKey();
+ if (aclSummary != null) {
+ boolean isConditional = policyIdForTemporalTags.contains(evaluator.getId()) || evaluator.getValidityScheduleEvaluatorsCount() != 0;
+ Integer accessResult;
- for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : userAccessInfo.getValue().entrySet()) {
- if (isConditional) {
- accessResult = ACCESS_CONDITIONAL;
- } else {
- accessResult = accessInfo.getValue().getResult();
+ for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> userAccessInfo : aclSummary.getUsersAccessInfo().entrySet()) {
+ final String userName = userAccessInfo.getKey();
+
+ for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : userAccessInfo.getValue().entrySet()) {
+ if (isConditional) {
+ accessResult = ACCESS_CONDITIONAL;
+ } else {
+ accessResult = accessInfo.getValue().getResult();
- if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
- accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+ accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ }
}
- }
- RangerPolicy policy = evaluator.getPolicy();
+ RangerPolicy policy = evaluator.getPolicy();
- ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
+ ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
+ }
}
- }
- for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> groupAccessInfo : aclSummary.getGroupsAccessInfo().entrySet()) {
- final String groupName = groupAccessInfo.getKey();
+ for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> groupAccessInfo : aclSummary.getGroupsAccessInfo().entrySet()) {
+ final String groupName = groupAccessInfo.getKey();
- for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : groupAccessInfo.getValue().entrySet()) {
- if (isConditional) {
- accessResult = ACCESS_CONDITIONAL;
- } else {
- accessResult = accessInfo.getValue().getResult();
+ for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : groupAccessInfo.getValue().entrySet()) {
+ if (isConditional) {
+ accessResult = ACCESS_CONDITIONAL;
+ } else {
+ accessResult = accessInfo.getValue().getResult();
- if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
- accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+ accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ }
}
- }
- RangerPolicy policy = evaluator.getPolicy();
+ RangerPolicy policy = evaluator.getPolicy();
- ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
+ ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
+ }
}
- }
- for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> roleAccessInfo : aclSummary.getRolesAccessInfo().entrySet()) {
- final String roleName = roleAccessInfo.getKey();
+ for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> roleAccessInfo : aclSummary.getRolesAccessInfo().entrySet()) {
+ final String roleName = roleAccessInfo.getKey();
- for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : roleAccessInfo.getValue().entrySet()) {
- if (isConditional) {
- accessResult = ACCESS_CONDITIONAL;
- } else {
- accessResult = accessInfo.getValue().getResult();
+ for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : roleAccessInfo.getValue().entrySet()) {
+ if (isConditional) {
+ accessResult = ACCESS_CONDITIONAL;
+ } else {
+ accessResult = accessInfo.getValue().getResult();
- if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
- accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+ accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+ }
}
- }
- RangerPolicy policy = evaluator.getPolicy();
+ RangerPolicy policy = evaluator.getPolicy();
- ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
+ ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
+ }
}
}
}
- }
- ret.finalizeAcls();
+ ret.finalizeAcls();
+ }
}
RangerPerfTracer.logAlways(perf);
@@ -338,22 +389,56 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
@Override
public void setUseForwardedIPAddress(boolean useForwardedIPAddress) {
- policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
+ try (RangerReadWriteLock.RangerLock writeLock = policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
+ policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
+ }
}
@Override
public void setTrustedProxyAddresses(String[] trustedProxyAddresses) {
- policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
+ try (RangerReadWriteLock.RangerLock writeLock = policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
+ policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
+ }
}
@Override
public RangerServiceDef getServiceDef() {
- return policyEngine.getServiceDef();
+ final RangerServiceDef ret;
+
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getServiceDef();
+ }
+ return ret;
}
@Override
public long getPolicyVersion() {
- return policyEngine.getPolicyVersion();
+ long ret;
+
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getPolicyVersion();
+ }
+ return ret;
}
@Override
@@ -361,12 +446,29 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
@Override
public void setRoles(RangerRoles roles) {
- policyEngine.setRoles(roles);
+ try (RangerReadWriteLock.RangerLock writeLock = policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
+ policyEngine.setRoles(roles);
+ }
+
}
@Override
public Set<String> getRolesFromUserAndGroups(String user, Set<String> groups) {
- return policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user, groups);
+ Set<String> ret;
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user, groups);
+ }
+ return ret;
}
@Override
@@ -375,7 +477,16 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
LOG.debug("==> RangerPolicyEngineImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ")");
}
- String ret = policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ String ret;
+
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ") : " + ret);
@@ -386,21 +497,53 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
@Override
public List<RangerPolicy> getResourcePolicies(String zoneName) {
- return policyEngine.getResourcePolicies(zoneName);
+ List<RangerPolicy> ret;
+
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ List<RangerPolicy> oldPolicies = policyEngine.getResourcePolicies(zoneName);
+ ret = CollectionUtils.isNotEmpty(oldPolicies) ? new ArrayList<>(oldPolicies) : oldPolicies;
+ }
+
+ return ret;
}
@Override
public List<RangerPolicy> getResourcePolicies() {
- RangerPolicyRepository policyRepository = policyEngine.getPolicyRepository();
+ List<RangerPolicy> ret;
- return policyRepository == null ? ListUtils.EMPTY_LIST : policyRepository.getPolicies();
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ RangerPolicyRepository policyRepository = policyEngine.getPolicyRepository();
+ List<RangerPolicy> oldPolicies = policyRepository == null ? ListUtils.EMPTY_LIST : policyRepository.getPolicies();
+ ret = CollectionUtils.isNotEmpty(oldPolicies) ? new ArrayList<>(oldPolicies) : oldPolicies;
+ }
+ return ret;
}
@Override
public List<RangerPolicy> getTagPolicies() {
- RangerPolicyRepository tagPolicyRepository = policyEngine.getTagPolicyRepository();
+ List<RangerPolicy> ret;
- return tagPolicyRepository == null ? ListUtils.EMPTY_LIST : tagPolicyRepository.getPolicies();
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ RangerPolicyRepository tagPolicyRepository = policyEngine.getTagPolicyRepository();
+ List<RangerPolicy> oldPolicies = tagPolicyRepository == null ? ListUtils.EMPTY_LIST : tagPolicyRepository.getPolicies();
+ ret = CollectionUtils.isNotEmpty(oldPolicies) ? new ArrayList<>(oldPolicies) : oldPolicies;
+ }
+ return ret;
}
// This API is used only used by test code
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index b2f3438..4fb0b08 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -73,9 +73,9 @@ public class RangerPolicyRepository {
private final RangerPolicyEngineOptions options;
private final RangerPluginContext pluginContext;
private final RangerServiceDef serviceDef;
- private final List<RangerPolicy> policies;
+ private /*final*/ List<RangerPolicy> policies;
private final long policyVersion;
- private final List<RangerContextEnricher> contextEnrichers;
+ private /*final*/ List<RangerContextEnricher> contextEnrichers;
private final AuditModeEnum auditModeEnum;
private final Map<String, AuditInfo> accessAuditCache;
private final String componentServiceName;
@@ -157,111 +157,12 @@ public class RangerPolicyRepository {
this.accessAuditCache = null;
}
- boolean[] flags = new boolean[RangerPolicy.POLICY_TYPES.length];
-
- for (RangerPolicyDelta delta : deltas) {
- final Integer changeType = delta.getChangeType();
- final String serviceType = delta.getServiceType();
- final Long policyId = delta.getPolicyId();
- final Integer policyType = delta.getPolicyType();
-
- if (!serviceType.equals(this.serviceDef.getName())) {
- continue;
- }
-
- RangerPolicyEvaluator evaluator = null;
-
- switch (changeType) {
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
- if (delta.getPolicy() == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not find policy for policy-id:[" + policyId + "]");
- }
-
- continue;
- }
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
- evaluator = getPolicyEvaluator(policyId);
-
- if (evaluator == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not find evaluator for policy-id:[" + policyId + "]");
- }
- }
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
- evaluator = getPolicyEvaluator(policyId);
- if (evaluator == null) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not find evaluator for policy-id:[" + policyId + "]");
- }
- }
- break;
-
- default:
- LOG.error("Unknown changeType:[" + changeType + "], Ignoring");
- break;
- }
-
- evaluator = update(delta, evaluator);
-
- if (evaluator != null) {
- switch (changeType) {
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
- policyEvaluatorsMap.put(policyId, evaluator);
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
- policyEvaluatorsMap.put(policyId, evaluator);
- break;
-
- case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
- policyEvaluatorsMap.remove(policyId);
- break;
-
- default:
- break;
- }
-
- flags[policyType] = true;
- }
- }
-
- for (int policyType = 0; policyType < flags.length; policyType++) {
- if (flags[policyType]) {
- Map<String, RangerResourceTrie> trie = getTrie(policyType);
-
- if (trie != null) {
- for (Map.Entry<String, RangerResourceTrie> entry : trie.entrySet()) {
- entry.getValue().wrapUpUpdate();
- }
- }
- }
- }
+ final boolean isExistingPolicies = CollectionUtils.isNotEmpty(this.policies);
- if (auditFilterResourceTrie != null) {
- for (Map.Entry<String, RangerResourceTrie> entry : auditFilterResourceTrie.entrySet()) {
- entry.getValue().wrapUpUpdate();
- }
- }
+ List<RangerContextEnricher> newContextEnrichers = updateResourceTrie(deltas, policyVersion);
- if (StringUtils.isEmpty(zoneName)) {
- if (CollectionUtils.isNotEmpty(other.getPolicies())) {
- if (CollectionUtils.isNotEmpty(this.getPolicies())) {
- this.contextEnrichers = shareWith(other);
- } else {
- this.contextEnrichers = null;
- }
- } else {
- if (CollectionUtils.isNotEmpty(this.policies)) {
- this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
- } else {
- this.contextEnrichers = null;
- }
- }
+ if (newContextEnrichers != null && CollectionUtils.isNotEmpty(this.policies)) {
+ this.contextEnrichers = isExistingPolicies ? shareWith(other) : buildContextEnrichers(options);
} else {
this.contextEnrichers = null;
}
@@ -288,9 +189,9 @@ public class RangerPolicyRepository {
this.pluginContext = pluginContext;
if (StringUtils.isEmpty(zoneName)) {
- this.policies = Collections.unmodifiableList(servicePolicies.getPolicies());
+ this.policies = servicePolicies.getPolicies();
} else {
- this.policies = Collections.unmodifiableList(servicePolicies.getSecurityZones().get(zoneName).getPolicies());
+ this.policies = servicePolicies.getSecurityZones().get(zoneName).getPolicies();
}
this.policyVersion = servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion() : -1;
@@ -326,7 +227,7 @@ public class RangerPolicyRepository {
init(options);
if (StringUtils.isEmpty(zoneName)) {
- this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
+ this.contextEnrichers = buildContextEnrichers(options);
this.auditPolicyEvaluators = buildAuditPolicyEvaluators(servicePolicies.getServiceConfig());
} else {
this.contextEnrichers = null;
@@ -358,7 +259,7 @@ public class RangerPolicyRepository {
this.appId = pluginContext.getConfig().getAppId();
this.options = new RangerPolicyEngineOptions(pluginContext.getConfig().getPolicyEngineOptions());
this.pluginContext = pluginContext;
- this.policies = Collections.unmodifiableList(normalizeAndPrunePolicies(tagPolicies.getPolicies(), componentServiceDef.getName()));
+ this.policies = normalizeAndPrunePolicies(tagPolicies.getPolicies(), componentServiceDef.getName());
this.policyVersion = tagPolicies.getPolicyVersion() != null ? tagPolicies.getPolicyVersion() : -1;
String auditMode = tagPolicies.getAuditMode();
@@ -380,7 +281,7 @@ public class RangerPolicyRepository {
init(options);
if (StringUtils.isEmpty(zoneName)) {
- this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
+ this.contextEnrichers = buildContextEnrichers(options);
this.auditPolicyEvaluators = buildAuditPolicyEvaluators(tagPolicies.getServiceConfig());
} else {
this.contextEnrichers = null;
@@ -892,7 +793,7 @@ public class RangerPolicyRepository {
}
}
- return rangerPolicies;
+ return rangerPolicies == null ? new ArrayList<>() : rangerPolicies;
}
private boolean isPolicyNeedsPruning(RangerPolicy policy, final String componentType) {
@@ -1049,13 +950,13 @@ public class RangerPolicyRepository {
}
RangerPolicyEvaluator.PolicyEvalOrderComparator comparator = new RangerPolicyEvaluator.PolicyEvalOrderComparator();
Collections.sort(policyEvaluators, comparator);
- this.policyEvaluators = Collections.unmodifiableList(policyEvaluators);
+ this.policyEvaluators = policyEvaluators;
Collections.sort(dataMaskPolicyEvaluators, comparator);
- this.dataMaskPolicyEvaluators = Collections.unmodifiableList(dataMaskPolicyEvaluators);
+ this.dataMaskPolicyEvaluators = dataMaskPolicyEvaluators;
Collections.sort(rowFilterPolicyEvaluators, comparator);
- this.rowFilterPolicyEvaluators = Collections.unmodifiableList(rowFilterPolicyEvaluators);
+ this.rowFilterPolicyEvaluators = rowFilterPolicyEvaluators;
this.policyEvaluatorsMap = createPolicyEvaluatorsMap();
@@ -1267,8 +1168,6 @@ public class RangerPolicyRepository {
if (CollectionUtils.isNotEmpty(evaluators)) {
ret = new ArrayList<>(evaluators);
Collections.sort(ret, new RangerPolicyEvaluator.PolicyEvalOrderComparator());
-
- ret = Collections.unmodifiableList(ret);
}
return ret;
@@ -1350,7 +1249,7 @@ public class RangerPolicyRepository {
tmpPolicyEvaluatorMap.put(evaluator.getPolicy().getId(), evaluator);
}
- return Collections.unmodifiableMap(tmpPolicyEvaluatorMap);
+ return tmpPolicyEvaluatorMap;
}
@@ -1530,4 +1429,134 @@ public class RangerPolicyRepository {
return isAudited;
}
}
+
+ void reinit(List<RangerPolicyDelta> deltas, long policyVersion) {
+ final boolean isExistingPolicies = CollectionUtils.isNotEmpty(this.policies);
+
+ List<RangerContextEnricher> newContextEnrichers = updateResourceTrie(deltas, policyVersion);
+
+ if (newContextEnrichers != null && CollectionUtils.isNotEmpty(this.policies)) {
+ this.contextEnrichers = isExistingPolicies ? newContextEnrichers : buildContextEnrichers(options);
+ } else {
+ this.contextEnrichers = null;
+ }
+ }
+
+ private List<RangerContextEnricher> updateResourceTrie(List<RangerPolicyDelta> deltas, long policyVersion) {
+
+ final List<RangerContextEnricher> ret;
+
+ final boolean isExistingPolicies = CollectionUtils.isNotEmpty(this.policies);
+
+ boolean[] flags = new boolean[RangerPolicy.POLICY_TYPES.length];
+
+ for (RangerPolicyDelta delta : deltas) {
+ final Integer changeType = delta.getChangeType();
+ final String serviceType = delta.getServiceType();
+ final Long policyId = delta.getPolicyId();
+ final Integer policyType = delta.getPolicyType();
+
+ if (!serviceType.equals(this.serviceDef.getName())) {
+ continue;
+ }
+
+ RangerPolicyEvaluator evaluator = null;
+
+ switch (changeType) {
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
+ if (delta.getPolicy() == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not find policy for policy-id:[" + policyId + "]");
+ }
+
+ continue;
+ }
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
+ evaluator = getPolicyEvaluator(policyId);
+
+ if (evaluator == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not find evaluator for policy-id:[" + policyId + "]");
+ }
+ }
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
+ evaluator = getPolicyEvaluator(policyId);
+ if (evaluator == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not find evaluator for policy-id:[" + policyId + "]");
+ }
+ }
+ break;
+
+ default:
+ LOG.error("Unknown changeType:[" + changeType + "], Ignoring");
+ break;
+ }
+
+ evaluator = update(delta, evaluator);
+
+ if (evaluator != null) {
+ switch (changeType) {
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE:
+ policyEvaluatorsMap.put(policyId, evaluator);
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_UPDATE:
+ policyEvaluatorsMap.put(policyId, evaluator);
+ break;
+
+ case RangerPolicyDelta.CHANGE_TYPE_POLICY_DELETE:
+ policyEvaluatorsMap.remove(policyId);
+ break;
+
+ default:
+ break;
+ }
+
+ flags[policyType] = true;
+ }
+ }
+
+ for (int policyType = 0; policyType < flags.length; policyType++) {
+ if (flags[policyType]) {
+ Map<String, RangerResourceTrie> trie = getTrie(policyType);
+
+ if (trie != null) {
+ for (Map.Entry<String, RangerResourceTrie> entry : trie.entrySet()) {
+ entry.getValue().wrapUpUpdate();
+ }
+ }
+ }
+ }
+
+ if (auditFilterResourceTrie != null) {
+ for (Map.Entry<String, RangerResourceTrie> entry : auditFilterResourceTrie.entrySet()) {
+ entry.getValue().wrapUpUpdate();
+ }
+ }
+
+ if (StringUtils.isEmpty(zoneName)) {
+ if (isExistingPolicies) {
+ if (CollectionUtils.isNotEmpty(this.policies)) {
+ ret = this.contextEnrichers; // Handled by caller
+ } else {
+ ret = null;
+ }
+ } else {
+ if (CollectionUtils.isNotEmpty(this.policies)) {
+ ret = new ArrayList<>(); // Handled by caller
+ } else {
+ ret = null;
+ }
+ }
+ } else {
+ ret = null;
+ }
+
+ return ret;
+ }
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
index 795289b..f9f80c9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/TagStore.java
@@ -139,4 +139,6 @@ public interface TagStore {
void deleteAllTagObjectsForService(String serviceName) throws Exception;
+ boolean isInPlaceTagUpdateSupported();
+
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
index 5ecb280..e0c3f79 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerCommonConstants.java
@@ -21,7 +21,25 @@ package org.apache.ranger.plugin.util;
public class RangerCommonConstants {
- public static final String PROP_COOKIE_NAME = "ranger.admin.cookie.name";
- public static final String DEFAULT_COOKIE_NAME = "RANGERADMINSESSIONID";
+ public static final String PROP_COOKIE_NAME = "ranger.admin.cookie.name";
+ public static final String DEFAULT_COOKIE_NAME = "RANGERADMINSESSIONID";
+ public static final String PLUGIN_CONFIG_SUFFIX_POLICY_DELTA = ".policy.rest.supports.policy.deltas";
+ public static final String PLUGIN_CONFIG_SUFFIX_TAG_DELTA = ".tag.rest.supports.policy.deltas";
+ public static final String PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES = ".supports.in.place.policy.updates";
+ public static final String PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES = ".supports.in.place.tag.updates";
+ public static final String RANGER_ADMIN_SUFFIX_POLICY_DELTA = ".supports.policy.deltas";
+ public static final String RANGER_ADMIN_SUFFIX_TAG_DELTA = ".supports.tag.deltas";
+ public static final String RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES = ".supports.in.place.policy.updates";
+ public static final String RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES = ".supports.in.place.tag.updates";
-}
\ No newline at end of file
+ public static final boolean PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT = false;
+ public static final boolean PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT = false;
+ public static final boolean PLUGIN_CONFIG_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT = false;
+ public static final boolean PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT = false;
+ public static final boolean RANGER_ADMIN_SUFFIX_POLICY_DELTA_DEFAULT = false;
+ public static final boolean RANGER_ADMIN_SUFFIX_TAG_DELTA_DEFAULT = false;
+ public static final boolean RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT = false;
+ public static final boolean RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT = false;
+
+
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerReadWriteLock.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerReadWriteLock.java
new file mode 100644
index 0000000..7f17a52
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerReadWriteLock.java
@@ -0,0 +1,98 @@
+/*
+ * 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.ranger.plugin.util;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+public class RangerReadWriteLock {
+
+ private static final RangerLock NO_OP_LOCK = new RangerLock(null);
+
+ private final ReentrantReadWriteLock lock;
+
+ public RangerReadWriteLock(boolean isUseLock) {
+ lock = isUseLock ? new ReentrantReadWriteLock(true) : null;
+ }
+
+ public RangerLock getReadLock() {
+ final RangerLock ret;
+ if (lock != null) {
+ ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
+ readLock.lock();
+ ret = new RangerLock(readLock);
+ } else {
+ ret = NO_OP_LOCK;
+ }
+ return ret;
+ }
+
+ public RangerLock getWriteLock() {
+ final RangerLock ret;
+ if (lock != null) {
+ boolean isLocked = false;
+ ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+ while (!isLocked) {
+ isLocked = writeLock.tryLock();
+ // Another thread has acquired write lock. Hint to scheduler to schedule some other thread if needed
+ if (!isLocked && lock.getReadLockCount() == 0) {
+ Thread.yield();
+ }
+ }
+ ret = new RangerLock(writeLock);
+ } else {
+ ret = NO_OP_LOCK;
+ }
+ return ret;
+ }
+
+ @Override
+ public String toString() {
+ if (lock != null) {
+ return "ReadWriteLock:[" + lock.toString() + "], ReadLock:[" + lock.readLock().toString() + "], WriteLock:[" + lock.writeLock().toString() + "]";
+ } else {
+ return "ReadWriteLock:[null]";
+ }
+ }
+
+ static final public class RangerLock implements AutoCloseable {
+ private final Lock lock;
+
+ private RangerLock(Lock lock) {
+ this.lock = lock;
+ }
+
+ @Override
+ public void close() {
+ if (lock != null) {
+ lock.unlock();
+ }
+ }
+
+ public boolean isLockingEnabled() {
+ return lock != null;
+ }
+
+ @Override
+ public String toString() {
+ return lock == null ? "null" : lock.toString();
+ }
+ }
+}
diff --git a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
index 1beef86..fa17f5d 100644
--- a/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
+++ b/knox-agent/src/main/java/org/apache/ranger/admin/client/RangerAdminJersey2RESTClient.java
@@ -71,8 +71,8 @@ public class RangerAdminJersey2RESTClient extends AbstractRangerAdminClient {
String _sslConfigFileName = null;
String _serviceName = null;
String _clusterName = null;
- String _supportsPolicyDeltas = null;
- String _supportsTagDeltas = null;
+ boolean _supportsPolicyDeltas = false;
+ boolean _supportsTagDeltas = false;
String _pluginId = null;
int _restClientConnTimeOutMs;
int _restClientReadTimeOutMs;
@@ -99,14 +99,8 @@ public class RangerAdminJersey2RESTClient extends AbstractRangerAdminClient {
if(StringUtil.isEmpty(_clusterName)){
_clusterName =config.get(configPropertyPrefix + ".ambari.cluster.name", "");
}
- _supportsPolicyDeltas = config.get(configPropertyPrefix + ".policy.rest.supports.policy.deltas", "false");
- if (!"true".equalsIgnoreCase(_supportsPolicyDeltas)) {
- _supportsPolicyDeltas = "false";
- }
- _supportsTagDeltas = config.get(configPropertyPrefix + ".tag.rest.supports.tag.deltas", "false");
- if (!"true".equalsIgnoreCase(_supportsTagDeltas)) {
- _supportsTagDeltas = "false";
- }
+ _supportsPolicyDeltas = config.getBoolean(configPropertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_POLICY_DELTA_DEFAULT);
+ _supportsTagDeltas = config.getBoolean(configPropertyPrefix + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA, RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_TAG_DELTA_DEFAULT);
configURLs = StringUtil.getURLs(tmpUrl);
this.lastKnownActiveUrlIndex = new Random().nextInt(configURLs.size());
@@ -141,7 +135,7 @@ public class RangerAdminJersey2RESTClient extends AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME, Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, _pluginId);
queryParams.put(RangerRESTUtils.REST_PARAM_CLUSTER_NAME, _clusterName);
- queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS, _supportsPolicyDeltas);
+ queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_POLICY_DELTAS, Boolean.toString(_supportsPolicyDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
if (isSecureMode) {
@@ -383,7 +377,7 @@ public class RangerAdminJersey2RESTClient extends AbstractRangerAdminClient {
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION, Long.toString(lastKnownVersion));
queryParams.put(RangerRESTUtils.REST_PARAM_LAST_ACTIVATION_TIME, Long.toString(lastActivationTimeInMillis));
queryParams.put(RangerRESTUtils.REST_PARAM_PLUGIN_ID, _pluginId);
- queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS, _supportsTagDeltas);
+ queryParams.put(RangerRESTUtils.REST_PARAM_SUPPORTS_TAG_DELTAS, Boolean.toString(_supportsTagDeltas));
queryParams.put(RangerRESTUtils.REST_PARAM_CAPABILITIES, pluginCapabilities);
String relativeURL = null;
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
index 089bf43..fd5b147 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
@@ -158,11 +158,11 @@ public class RangerPolicyAdminCache {
oldPolicyAdmin.releaseResources(!isPolicyEngineShared);
}
} else {
- LOG.warn("Could not build new policy-engine. Continuing with the old policy-engine, if any");
+ LOG.warn("Could not build new policy-engine.");
}
}
- return ret != null ? ret : oldPolicyAdmin;
+ return ret;
}
private RangerPolicyAdmin addPolicyAdmin(ServicePolicies policies, RangerRoles roles, RangerPolicyEngineOptions options) {
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
index 66835bd..2eef20b 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
@@ -45,6 +45,7 @@ import org.apache.ranger.plugin.service.RangerDefaultRequestProcessor;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.apache.ranger.plugin.util.ServicePolicies;
@@ -81,7 +82,11 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
PolicyEngine policyEngine = other.policyEngine.cloneWithDelta(servicePolicies);
if (policyEngine != null) {
- ret = new RangerPolicyAdminImpl(policyEngine);
+ if (policyEngine == other.policyEngine) {
+ ret = other;
+ } else {
+ ret = new RangerPolicyAdminImpl(policyEngine);
+ }
}
}
@@ -89,7 +94,7 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
}
RangerPolicyAdminImpl(ServicePolicies servicePolicies, RangerPluginContext pluginContext, RangerRoles roles) {
- this.policyEngine = new PolicyEngine(servicePolicies, pluginContext, roles);
+ this.policyEngine = new PolicyEngine(servicePolicies, pluginContext, roles, ServiceDBStore.SUPPORTS_IN_PLACE_POLICY_UPDATES);
this.requestProcessor = new RangerDefaultRequestProcessor(policyEngine);
}
@@ -111,32 +116,41 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(user=" + user + ",accessTypes=" + accessTypes + "resource=" + resource.getAsString() + ")");
}
- final RangerPolicyRepository matchedRepository = policyEngine.getRepositoryForZone(zoneName);
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
- if (matchedRepository != null) {
- Set<String> roles = getRolesFromUserAndGroups(user, userGroups);
- Set<String> requestedAccesses = new HashSet<>(accessTypes);
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+
+ final RangerPolicyRepository matchedRepository = policyEngine.getRepositoryForZone(zoneName);
+
+ if (matchedRepository != null) {
+ Set<String> roles = getRolesFromUserAndGroups(user, userGroups);
+ Set<String> requestedAccesses = new HashSet<>(accessTypes);
- RangerAccessRequestImpl request = new RangerAccessRequestImpl();
- request.setResource(resource);
+ RangerAccessRequestImpl request = new RangerAccessRequestImpl();
+ request.setResource(resource);
- for (RangerPolicyEvaluator evaluator : matchedRepository.getLikelyMatchPolicyEvaluators(request, RangerPolicy.POLICY_TYPE_ACCESS)) {
+ for (RangerPolicyEvaluator evaluator : matchedRepository.getLikelyMatchPolicyEvaluators(request, RangerPolicy.POLICY_TYPE_ACCESS)) {
- Set<String> allowedAccesses = evaluator.getAllowedAccesses(resource, user, userGroups, roles, requestedAccesses);
- if (CollectionUtils.isNotEmpty(allowedAccesses)) {
- requestedAccesses.removeAll(allowedAccesses);
- if (CollectionUtils.isEmpty(requestedAccesses)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Access granted by policy:[" + evaluator.getPolicy() + "]");
+ Set<String> allowedAccesses = evaluator.getAllowedAccesses(resource, user, userGroups, roles, requestedAccesses);
+ if (CollectionUtils.isNotEmpty(allowedAccesses)) {
+ requestedAccesses.removeAll(allowedAccesses);
+ if (CollectionUtils.isEmpty(requestedAccesses)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Access granted by policy:[" + evaluator.getPolicy() + "]");
+ }
+ ret = true;
+ break;
}
- ret = true;
- break;
}
}
+
}
}
-
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
@@ -159,36 +173,46 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.isDelegatedAdminAccessAllowed(user=" + user + "," + userGroups + ", roles=" + roles + ")");
}
- final RangerPolicyRepository matchedRepository = policyEngine.getRepositoryForMatchedZone(policy);
-
- if (matchedRepository != null) {
- // RANGER-3082
- // Convert policy resources to by substituting macros with ASTERISK
- Map<String, RangerPolicyResource> modifiedPolicyResources = getPolicyResourcesWithMacrosReplaced(policy.getResources(), wildcardEvalContext);
- Set<String> accessTypes = getAllAccessTypes(policy, getServiceDef());
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Checking admin-access for the access-types:[" + accessTypes + "]");
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
}
- if (CollectionUtils.isEmpty(accessTypes)) {
- LOG.info("access-types to check for admin-access are empty!! Allowing admin access!!");
- ret = true;
- } else {
- for (RangerPolicyEvaluator evaluator : matchedRepository.getPolicyEvaluators()) {
- Set<String> allowedAccesses = evaluator.getAllowedAccesses(modifiedPolicyResources, user, userGroups, roles, accessTypes, evalContext);
- if (CollectionUtils.isNotEmpty(allowedAccesses)) {
- accessTypes.removeAll(allowedAccesses);
- if (CollectionUtils.isEmpty(accessTypes)) {
- ret = true;
- break;
+ final RangerPolicyRepository matchedRepository = policyEngine.getRepositoryForMatchedZone(policy);
+
+ if (matchedRepository != null) {
+ // RANGER-3082
+ // Convert policy resources to by substituting macros with ASTERISK
+ Map<String, RangerPolicyResource> modifiedPolicyResources = getPolicyResourcesWithMacrosReplaced(policy.getResources(), wildcardEvalContext);
+ Set<String> accessTypes = getAllAccessTypes(policy, getServiceDef());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Checking admin-access for the access-types:[" + accessTypes + "]");
+ }
+
+ if (CollectionUtils.isEmpty(accessTypes)) {
+ LOG.info("access-types to check for admin-access are empty!! Allowing admin access!!");
+ ret = true;
+ } else {
+ for (RangerPolicyEvaluator evaluator : matchedRepository.getPolicyEvaluators()) {
+ Set<String> allowedAccesses = evaluator.getAllowedAccesses(modifiedPolicyResources, user, userGroups, roles, accessTypes, evalContext);
+ if (CollectionUtils.isNotEmpty(allowedAccesses)) {
+ accessTypes.removeAll(allowedAccesses);
+ if (CollectionUtils.isEmpty(accessTypes)) {
+ ret = true;
+ break;
+ }
}
}
- }
- if (CollectionUtils.isNotEmpty(accessTypes)) {
- LOG.info("Accesses : " + accessTypes + " are not authorized for the policy:[" + policy.getId() + "] by any of delegated-admin policies");
+ if (CollectionUtils.isNotEmpty(accessTypes)) {
+ LOG.info("Accesses : " + accessTypes + " are not authorized for the policy:[" + policy.getId() + "] by any of delegated-admin policies");
+ }
}
}
+
}
RangerPerfTracer.log(perf);
@@ -208,18 +232,27 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
List<RangerPolicy> ret = null;
- RangerPolicyRepository policyRepository = policyEngine.getRepositoryForZone(zoneName);
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
- if (policyRepository != null) {
- for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
- if (evaluator.isCompleteMatch(resource, evalContext)) {
- if (ret == null) {
- ret = new ArrayList<>();
- }
+ RangerPolicyRepository policyRepository = policyEngine.getRepositoryForZone(zoneName);
- ret.add(evaluator.getPolicy());
+ if (policyRepository != null) {
+ for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
+ if (evaluator.isCompleteMatch(resource, evalContext)) {
+ if (ret == null) {
+ ret = new ArrayList<>();
+ }
+
+ ret.add(evaluator.getPolicy());
+ }
}
}
+
}
if (LOG.isDebugEnabled()) {
@@ -236,20 +269,31 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
}
List<RangerPolicy> ret = null;
- RangerPolicyRepository policyRepository = policyEngine.getRepositoryForMatchedZone(policy);
- if (policyRepository != null) {
- Map<String, RangerPolicyResource> resources = policy.getResources();
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
- for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
- if (evaluator.isCompleteMatch(resources, evalContext)) {
- if (ret == null) {
- ret = new ArrayList<>();
- }
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+
+ RangerPolicyRepository policyRepository = policyEngine.getRepositoryForMatchedZone(policy);
+
+ if (policyRepository != null) {
+ Map<String, RangerPolicyResource> resources = policy.getResources();
- ret.add(evaluator.getPolicy());
+ for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
+ if (evaluator.isCompleteMatch(resources, evalContext)) {
+ if (ret == null) {
+ ret = new ArrayList<>();
+ }
+
+ ret.add(evaluator.getPolicy());
+ }
}
}
+
}
if (LOG.isDebugEnabled()) {
@@ -264,8 +308,16 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyAdminImpl.getMatchingPolicies(" + resource + ")");
}
+ List<RangerPolicy> ret;
- List<RangerPolicy> ret = getMatchingPolicies(resource, RangerPolicyEngine.ANY_ACCESS);
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = getMatchingPolicies(resource, RangerPolicyEngine.ANY_ACCESS);
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyAdminImpl.getMatchingPolicies(" + resource + ") : " + ret.size());
@@ -275,27 +327,87 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
}
@Override
- public long getPolicyVersion() { return policyEngine.getPolicyVersion(); }
+ public long getPolicyVersion() {
+ long ret;
+
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getPolicyVersion();
+ }
+ return ret;
+ }
@Override
- public long getRoleVersion() { return policyEngine.getRoleVersion(); }
+ public long getRoleVersion() {
+ long ret;
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getRoleVersion();
+ }
+ return ret;
+ }
@Override
- public String getServiceName() { return policyEngine.getServiceName(); }
+ public String getServiceName() {
+ String ret;
+
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getServiceName();
+ }
+ return ret;
+ }
@Override
public RangerServiceDef getServiceDef() {
- return policyEngine.getServiceDef();
+ RangerServiceDef ret;
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getServiceDef();
+ }
+ return ret;
}
@Override
public void setRoles(RangerRoles roles) {
- policyEngine.setRoles(roles);
+ try (RangerReadWriteLock.RangerLock writeLock = policyEngine.getWriteLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (writeLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + writeLock);
+ }
+ }
+ policyEngine.setRoles(roles);
+ }
}
@Override
public Set<String> getRolesFromUserAndGroups(String user, Set<String> groups) {
- return policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user, groups);
+ Set<String> ret;
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user, groups);
+ }
+ return ret;
}
@Override
@@ -303,8 +415,16 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyAdminImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ")");
}
+ String ret;
- String ret = policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ try (RangerReadWriteLock.RangerLock readLock = policyEngine.getReadLock()) {
+ if (LOG.isDebugEnabled()) {
+ if (readLock.isLockingEnabled()) {
+ LOG.debug("Acquired lock - " + readLock);
+ }
+ }
+ ret = policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyAdminImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ") : " + ret);
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 41980d2..ec788af 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -70,6 +70,7 @@ import org.apache.ranger.db.XXGlobalStateDao;
import org.apache.ranger.db.XXPolicyDao;
import org.apache.ranger.entity.XXTagChangeLog;
import org.apache.ranger.plugin.model.RangerSecurityZone;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.ServiceTags;
import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
import org.apache.ranger.plugin.model.validation.RangerValidator;
@@ -240,6 +241,7 @@ public class ServiceDBStore extends AbstractServiceStore {
public static final String SALT = PropertiesUtil.getProperty("ranger.password.salt", PasswordUtils.DEFAULT_SALT);
public static final Integer ITERATION_COUNT = PropertiesUtil.getIntProperty("ranger.password.iteration.count", PasswordUtils.DEFAULT_ITERATION_COUNT);
public static boolean SUPPORTS_POLICY_DELTAS = false;
+ public static boolean SUPPORTS_IN_PLACE_POLICY_UPDATES = false;
public static Integer RETENTION_PERIOD_IN_DAYS = 7;
public static Integer TAG_RETENTION_PERIOD_IN_DAYS = 3;
@@ -377,10 +379,11 @@ public class ServiceDBStore extends AbstractServiceStore {
synchronized(ServiceDBStore.class) {
if(!legacyServiceDefsInitDone) {
- SUPPORTS_POLICY_DELTAS = config.getBoolean("ranger.admin.supports.policy.deltas", false);
+ SUPPORTS_POLICY_DELTAS = config.getBoolean("ranger.admin" + RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA, RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA_DEFAULT);
RETENTION_PERIOD_IN_DAYS = config.getInt("ranger.admin.delta.retention.time.in.days", 7);
TAG_RETENTION_PERIOD_IN_DAYS = config.getInt("ranger.admin.tag.delta.retention.time.in.days", 3);
isRolesDownloadedByService = config.getBoolean("ranger.support.for.service.specific.role.download", false);
+ SUPPORTS_IN_PLACE_POLICY_UPDATES = SUPPORTS_POLICY_DELTAS && config.getBoolean("ranger.admin" + RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES, RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_POLICY_UPDATES_DEFAULT);
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
@@ -2818,7 +2821,7 @@ public class ServiceDBStore extends AbstractServiceStore {
public ServicePolicies getServicePolicyDeltasOrPolicies(String serviceName, Long lastKnownVersion) throws Exception {
boolean getOnlyDeltas = false;
if (LOG.isDebugEnabled()) {
- LOG.debug("Support for incremental policy updates enabled using \"ranger.admin.supports.policy.deltas\" configuation parameter :[" + SUPPORTS_POLICY_DELTAS +"]");
+ LOG.debug("Support for incremental policy updates enabled using \"ranger.admin" + RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA + "\" configuation parameter :[" + SUPPORTS_POLICY_DELTAS +"]");
}
return getServicePolicies(serviceName, lastKnownVersion, getOnlyDeltas, SUPPORTS_POLICY_DELTAS);
}
@@ -2827,7 +2830,7 @@ public class ServiceDBStore extends AbstractServiceStore {
public ServicePolicies getServicePolicyDeltas(String serviceName, Long lastKnownVersion) throws Exception {
boolean getOnlyDeltas = true;
if (LOG.isDebugEnabled()) {
- LOG.debug("Support for incremental policy updates enabled using \"ranger.admin.supports.policy.deltas\" configuation parameter :[" + SUPPORTS_POLICY_DELTAS +"]");
+ LOG.debug("Support for incremental policy updates enabled using \"ranger.admin" + RangerCommonConstants.RANGER_ADMIN_SUFFIX_POLICY_DELTA + "\" configuation parameter :[" + SUPPORTS_POLICY_DELTAS +"]");
}
return getServicePolicies(serviceName, lastKnownVersion, getOnlyDeltas, SUPPORTS_POLICY_DELTAS);
}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
index 581f11a..1bdfce0 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/TagDBStore.java
@@ -49,6 +49,7 @@ import org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
import org.apache.ranger.plugin.store.AbstractTagStore;
import org.apache.ranger.plugin.store.PList;
import org.apache.ranger.plugin.store.RangerServiceResourceSignature;
+import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.RangerServiceNotFoundException;
import org.apache.ranger.plugin.util.RangerServiceTagsDeltaUtil;
@@ -74,6 +75,7 @@ public class TagDBStore extends AbstractTagStore {
private static boolean SUPPORTS_TAG_DELTAS = false;
private static boolean IS_SUPPORTS_TAG_DELTAS_INITIALIZED = false;
+ public static boolean SUPPORTS_IN_PLACE_TAG_UPDATES = false;
@Autowired
RangerTagDefService rangerTagDefService;
@@ -1270,13 +1272,23 @@ public class TagDBStore extends AbstractTagStore {
return ret;
}
- public static boolean isSupportsTagDeltas() {
- if (!IS_SUPPORTS_TAG_DELTAS_INITIALIZED) {
- RangerAdminConfig config = RangerAdminConfig.getInstance();
+ private static void initStatics() {
+ if (!IS_SUPPORTS_TAG_DELTAS_INITIALIZED) {
+ RangerAdminConfig config = RangerAdminConfig.getInstance();
+
+ SUPPORTS_TAG_DELTAS = config.getBoolean("ranger.admin" + RangerCommonConstants.RANGER_ADMIN_SUFFIX_TAG_DELTA, RangerCommonConstants.RANGER_ADMIN_SUFFIX_TAG_DELTA_DEFAULT);
+ SUPPORTS_IN_PLACE_TAG_UPDATES = SUPPORTS_TAG_DELTAS && config.getBoolean("ranger.admin" + RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES, RangerCommonConstants.RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES_DEFAULT);
+ IS_SUPPORTS_TAG_DELTAS_INITIALIZED = true;
+ }
+ }
- SUPPORTS_TAG_DELTAS = config.getBoolean("ranger.admin.supports.tag.deltas", false);
- IS_SUPPORTS_TAG_DELTAS_INITIALIZED = true;
- }
+ public static boolean isSupportsTagDeltas() {
+ initStatics();
return SUPPORTS_TAG_DELTAS;
}
+
+ public boolean isInPlaceTagUpdateSupported() {
+ initStatics();
+ return SUPPORTS_IN_PLACE_TAG_UPDATES;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java b/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
index 09e5c50..c3b70dc 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerAdminTagEnricher.java
@@ -30,6 +30,7 @@ import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.store.ServiceStore;
import org.apache.ranger.plugin.store.TagStore;
+import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.ServiceTags;
public class RangerAdminTagEnricher extends RangerTagEnricher {
@@ -71,9 +72,11 @@ public class RangerAdminTagEnricher extends RangerTagEnricher {
if (tagStore == null || svcStore == null) {
LOG.error("ServiceDBStore/TagDBStore is not initialized!! Internal Error!");
} else {
+ super.init();
try {
RangerService service = svcStore.getServiceByName(serviceName);
serviceId = service.getId();
+ createLock();
} catch (Exception e) {
LOG.error("Cannot find service with name:[" + serviceName + "]", e);
LOG.error("This will cause tag-enricher in Ranger-Admin to fail!!");
@@ -85,6 +88,15 @@ public class RangerAdminTagEnricher extends RangerTagEnricher {
}
@Override
+ protected RangerReadWriteLock createLock() {
+ boolean useReadWriteLock = tagStore != null && tagStore.isInPlaceTagUpdateSupported();
+
+ LOG.info("Policy-Engine will" + (useReadWriteLock ? " " : " not ") + "use read-write locking to update tags in place when tag-deltas are provided");
+
+ return new RangerReadWriteLock(useReadWriteLock);
+ }
+
+ @Override
public void enrich(RangerAccessRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminTagEnricher.enrich(" + request + ")");
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
index cfd66b1..284b9dc 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java
@@ -2029,17 +2029,14 @@ public class TestXUserMgr {
public void test49createServiceConfigUser() {
XXUserDao xxUserDao = Mockito.mock(XXUserDao.class);
XXPortalUserDao userDao = Mockito.mock(XXPortalUserDao.class);
- XXModuleDefDao xXModuleDefDao = Mockito.mock(XXModuleDefDao.class);
VXUser vxUser = vxUser();
XXUser xXUser = xxUser(vxUser);
VXPortalUser userProfile = userProfile();
XXPortalUser xXPortalUser = xxPortalUser(userProfile);
- Collection<String> userRoleList =getRoleList();
VXUserPermission vXUserPermission=vxUserPermission();
XXUserPermission xUserPermissionObj = xxUserPermission();
xUserPermissionObj.setModuleId(vXUserPermission.getModuleId());
xUserPermissionObj.setUserId(vXUserPermission.getUserId());
- List<XXModuleDef> xXModuleDefs = xxModuleDefs();
Mockito.when(daoManager.getXXUser()).thenReturn(xxUserDao);
Mockito.when(xxUserDao.findByUserName(vxUser.getName())).thenReturn(xXUser);
Mockito.when(daoManager.getXXPortalUser()).thenReturn(userDao);
@@ -3194,7 +3191,6 @@ public class TestXUserMgr {
XXUser xXUser = xxUser(vxUser);
VXPortalUser userProfile = userProfile();
XXPortalUser xXPortalUser = xxPortalUser(userProfile);
- Collection<String> userRoleList =getRoleList();
VXUserPermission vXUserPermission=vxUserPermission();
XXUserPermission xUserPermissionObj = xxUserPermission();
xUserPermissionObj.setModuleId(vXUserPermission.getModuleId());