This is an automated email from the ASF dual-hosted git repository.
abhay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 7aa065860 RANGER-4922: Reduce time to find tags associated with
multi-level resource
7aa065860 is described below
commit 7aa06586039a53c58d0d9b07572168b0fd6ae0fa
Author: Abhay Kulkarni <[email protected]>
AuthorDate: Thu Sep 5 14:34:31 2024 -0700
RANGER-4922: Reduce time to find tags associated with multi-level resource
---
.../RangerServiceResourceMatcher.java | 12 +-
.../plugin/contextenricher/RangerTagEnricher.java | 145 ++++++++++++++++++---
.../validation/RangerZoneResourceMatcher.java | 4 +
.../plugin/policyengine/RangerResourceTrie.java | 103 ++++++++++-----
.../gds/GdsSharedResourceEvaluator.java | 3 +
.../RangerAbstractPolicyEvaluator.java | 4 +
.../RangerResourceEvaluator.java | 2 +
.../util/RangerResourceEvaluatorsRetriever.java | 16 ++-
.../apache/ranger/plugin/util/ServiceDefUtil.java | 28 +++-
.../plugin/contextenricher/TestTagEnricher.java | 1 +
.../plugin/policyengine/TestPathResourceTrie.java | 3 +
distro/src/main/assembly/ranger-tools.xml | 4 +
ranger-tools/conf/logback-mem-sizing.xml | 21 +++
ranger-tools/pom.xml | 20 +++
.../org/apache/ranger/sizing/RangerMemSizing.java | 1 +
15 files changed, 312 insertions(+), 55 deletions(-)
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
index e696db518..44cf3dcdf 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
@@ -19,8 +19,9 @@
package org.apache.ranger.plugin.contextenricher;
+import org.apache.commons.lang.StringUtils;
import org.apache.ranger.plugin.model.RangerPolicy;
-import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceResource;
import
org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -38,12 +39,12 @@ public class RangerServiceResourceMatcher implements
RangerResourceEvaluator {
private final RangerServiceResource serviceResource;
private final RangerPolicyResourceMatcher policyResourceMatcher;
- private RangerServiceDef.RangerResourceDef leafResourceDef;
+ private final RangerResourceDef leafResourceDef;
public RangerServiceResourceMatcher(final RangerServiceResource
serviceResource, RangerPolicyResourceMatcher policyResourceMatcher) {
this.serviceResource = serviceResource;
this.policyResourceMatcher = policyResourceMatcher;
- this.leafResourceDef =
ServiceDefUtil.getLeafResourceDef(policyResourceMatcher.getServiceDef(),
getPolicyResource());
+ this.leafResourceDef =
ServiceDefUtil.getLeafResourceDef(policyResourceMatcher.getServiceDef(),
getPolicyResource(), true);
}
public RangerServiceResource getServiceResource() { return
serviceResource; }
@@ -67,7 +68,7 @@ public class RangerServiceResourceMatcher implements
RangerResourceEvaluator {
}
@Override
- public boolean isAncestorOf(RangerServiceDef.RangerResourceDef
resourceDef) {
+ public boolean isAncestorOf(RangerResourceDef resourceDef) {
return
ServiceDefUtil.isAncestorOf(policyResourceMatcher.getServiceDef(),
leafResourceDef, resourceDef);
}
@@ -86,4 +87,7 @@ public class RangerServiceResourceMatcher implements
RangerResourceEvaluator {
public String toString() {
return String.valueOf(getId());
}
+
+ @Override
+ public boolean isLeaf(String resourceName) { return
StringUtils.equals(resourceName, leafResourceDef.getName()); }
}
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 a8fbc0215..92d2a7848 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
@@ -21,17 +21,28 @@ package org.apache.ranger.plugin.contextenricher;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
+import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.model.RangerServiceResource;
import org.apache.ranger.plugin.model.RangerTag;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
-import org.apache.ranger.plugin.policyengine.*;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import
org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
+import
org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceMatchingScope;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
+import org.apache.ranger.plugin.policyengine.RangerPluginContext;
+import org.apache.ranger.plugin.policyengine.RangerResourceTrie;
import
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
import
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
import org.apache.ranger.plugin.util.DownloadTrigger;
import org.apache.ranger.plugin.util.DownloaderTask;
import org.apache.ranger.plugin.service.RangerAuthContext;
@@ -42,6 +53,7 @@ import org.apache.ranger.plugin.util.RangerReadWriteLock;
import org.apache.ranger.plugin.util.RangerResourceEvaluatorsRetriever;
import org.apache.ranger.plugin.util.RangerServiceNotFoundException;
import org.apache.ranger.plugin.util.RangerServiceTagsDeltaUtil;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.apache.ranger.plugin.util.ServiceTags;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,12 +95,13 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
private EnrichedServiceTags enrichedServiceTags;
private boolean
disableCacheIfServiceNotFound = true;
private boolean dedupStrings
= true;
+ private Timer tagDownloadTimer;
+ private RangerServiceDefHelper serviceDefHelper;
private final BlockingQueue<DownloadTrigger> tagDownloadQueue = new
LinkedBlockingQueue<>();
- private Timer tagDownloadTimer;
+ private final RangerReadWriteLock lock = new
RangerReadWriteLock(false);
+ private final CachedResourceEvaluators cache = new
CachedResourceEvaluators();
- private RangerServiceDefHelper serviceDefHelper;
- private RangerReadWriteLock lock = new
RangerReadWriteLock(false);
@Override
public void init() {
@@ -347,6 +360,8 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
}
setEnrichedServiceTagsInPlugin();
+ cache.clearCache();
+
RangerPerfTracer.logAlways(perf);
}
@@ -451,7 +466,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
if (!disableTrieLookupPrefilter) {
serviceResourceTrie = new HashMap<>();
- for (RangerServiceDef.RangerResourceDef
resourceDef : serviceDef.getResources()) {
+ for (RangerResourceDef resourceDef :
serviceDef.getResources()) {
serviceResourceTrie.put(resourceDef.getName(), new
RangerResourceTrie(resourceDef, resourceMatchers,
getPolicyEngineOptions().optimizeTagTrieForRetrieval,
getPolicyEngineOptions().optimizeTagTrieForSpace, null));
}
}
@@ -483,8 +498,8 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
RangerServiceResourceMatcher
resourceMatcher = createRangerServiceResourceMatcher(serviceResource,
serviceDefHelper, hierarchies, getPluginContext());
if (resourceMatcher != null) {
- for
(RangerServiceDef.RangerResourceDef resourceDef : serviceDef.getResources()) {
-
RangerPolicy.RangerPolicyResource policyResource =
serviceResource.getResourceElements().get(resourceDef.getName());
+ for (RangerResourceDef
resourceDef : serviceDef.getResources()) {
+ RangerPolicyResource
policyResource =
serviceResource.getResourceElements().get(resourceDef.getName());
RangerResourceTrie<RangerServiceResourceMatcher> trie =
serviceResourceTrie.get(resourceDef.getName());
if
(LOG.isDebugEnabled()) {
@@ -543,7 +558,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
RangerAccessResourceImpl accessResource = new
RangerAccessResourceImpl();
- for (Map.Entry<String,
RangerPolicy.RangerPolicyResource> entry :
serviceResource.getResourceElements().entrySet()) {
+ for (Map.Entry<String, RangerPolicyResource> entry :
serviceResource.getResourceElements().entrySet()) {
accessResource.setValue(entry.getKey(),
entry.getValue().getValues());
}
@@ -583,7 +598,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
}
for (RangerServiceResourceMatcher matcher :
oldMatchers) {
- for (RangerServiceDef.RangerResourceDef
resourceDef : serviceDef.getResources()) {
+ for (RangerResourceDef resourceDef :
serviceDef.getResources()) {
String
resourceDefName = resourceDef.getName();
RangerResourceTrie<RangerServiceResourceMatcher> trie =
resourceTries.get(resourceDefName);
@@ -624,7 +639,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
if (isValidHierarchy == null) { // hierarchy not yet
validated
isValidHierarchy = Boolean.FALSE;
- for (List<RangerServiceDef.RangerResourceDef>
hierarchy : serviceDefHelper.getResourceHierarchies(policyType)) {
+ for (List<RangerResourceDef> hierarchy :
serviceDefHelper.getResourceHierarchies(policyType)) {
if
(serviceDefHelper.hierarchyHasAllResources(hierarchy, resourceKeys)) {
isValidHierarchy = Boolean.TRUE;
@@ -716,7 +731,7 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
if (request.isAccessTypeAny()) {
isMatched = matchType !=
RangerPolicyResourceMatcher.MatchType.NONE;
- } else if
(request.getResourceMatchingScope() ==
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+ } else if
(request.getResourceMatchingScope() ==
ResourceMatchingScope.SELF_OR_DESCENDANTS) {
isMatched = matchType !=
RangerPolicyResourceMatcher.MatchType.NONE;
} else {
isMatched = matchType ==
RangerPolicyResourceMatcher.MatchType.SELF || matchType ==
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS || matchType ==
RangerPolicyResourceMatcher.MatchType.ANCESTOR;
@@ -752,14 +767,42 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
return ret;
}
+ private static class CachedResourceEvaluators {
+ private final Map<String, Map<Map<String,
ResourceElementMatchingScope>, Collection<RangerServiceResourceMatcher>>> cache
= new HashMap<>();
+ private final RangerReadWriteLock
cacheLock = new
RangerReadWriteLock(true);
+
+ CachedResourceEvaluators() {}
+
+ Collection<RangerServiceResourceMatcher> getEvaluators(String
resourceKey, Map<String, ResourceElementMatchingScope> scopes) {
+ Collection<RangerServiceResourceMatcher> ret;
+
+ try (RangerReadWriteLock.RangerLock ignored =
cacheLock.getReadLock()) {
+ ret = cache.getOrDefault(resourceKey,
Collections.emptyMap()).get(scopes);
+ }
+
+ return ret;
+ }
+
+ void cacheEvaluators(String resource, Map<String,
ResourceElementMatchingScope> scopes, Collection<RangerServiceResourceMatcher>
evaluators) {
+ try (RangerReadWriteLock.RangerLock ignored =
cacheLock.getWriteLock()) {
+ cache.computeIfAbsent(resource, k -> new
HashMap<>()).put(scopes, evaluators);
+ }
+ }
+
+ void clearCache() {
+ try (RangerReadWriteLock.RangerLock ignored =
cacheLock.getWriteLock()) {
+ cache.clear();
+ }
+ }
+ }
+
private Collection<RangerServiceResourceMatcher>
getEvaluators(RangerAccessRequest request, EnrichedServiceTags
enrichedServiceTags) {
if(LOG.isDebugEnabled()) {
LOG.debug("==>
RangerTagEnricher.getEvaluators(request=" + request + ")");
}
- Collection<RangerServiceResourceMatcher> ret;
-
- RangerAccessResource resource =
request.getResource();
+ Collection<RangerServiceResourceMatcher>
ret = null;
+ final RangerAccessResource
resource = request.getResource();
final Map<String,
RangerResourceTrie<RangerServiceResourceMatcher>> serviceResourceTrie =
enrichedServiceTags.getServiceResourceTrie();
if (resource == null || resource.getKeys() == null ||
resource.getKeys().isEmpty() || serviceResourceTrie == null) {
@@ -771,7 +814,27 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
perf =
RangerPerfTracer.getPerfTracer(PERF_TRIE_OP_LOG,
"RangerTagEnricher.getEvaluators(resource=" + resource.getAsString() + ")");
}
- ret =
RangerResourceEvaluatorsRetriever.getEvaluators(serviceResourceTrie,
resource.getAsMap(), request.getResourceElementMatchingScopes());
+ final Predicate predicate =
excludeDescendantMatches(request) ? new
SelfOrAncestorPredicate(serviceDefHelper.getResourceDef(resource.getLeafName()))
: null;
+
+ if (predicate != null) {
+ ret =
cache.getEvaluators(resource.getCacheKey(),
request.getResourceElementMatchingScopes());
+ }
+
+ if (ret == null) {
+ ret =
RangerResourceEvaluatorsRetriever.getEvaluators(serviceResourceTrie,
resource.getAsMap(), request.getResourceElementMatchingScopes(), predicate);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found [" + ret.size() + "]
service-resource-matchers for service-resource [" + resource.getAsString() +
"]");
+ }
+
+ if (predicate != null) {
+
cache.cacheEvaluators(resource.getCacheKey(),
request.getResourceElementMatchingScopes(), ret);
+ }
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Found [" + ret.size() + "]
service-resource-matchers for service-resource [" + resource.getAsString() + "]
in the cache");
+ }
+ }
RangerPerfTracer.logAlways(perf);
}
@@ -786,6 +849,39 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
return ret;
}
+ private boolean excludeDescendantMatches(RangerAccessRequest request) {
+ final boolean ret;
+
+ if (request.isAccessTypeAny() ||
RangerAccessRequestUtil.getIsAnyAccessInContext(request.getContext())) {
+ ret = false;
+ } else {
+ RangerAccessResource resource = request.getResource();
+ String leafName = resource.getLeafName();
+
+ if (StringUtils.isNotEmpty(leafName)) {
+ RangerServiceDefHelper helper = new
RangerServiceDefHelper(getServiceDef());
+ Set<List<RangerResourceDef>> hierarchies =
helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS,
resource.getKeys());
+
+ // skip caching if the leaf of accessed
resource is the deepest in the only applicable hierarchy
+ if (hierarchies.size() == 1) {
+ List<RangerResourceDef> theHierarchy
= hierarchies.iterator().next();
+ RangerResourceDef leafOfHierarchy
= theHierarchy.get(theHierarchy.size() - 1);
+
+ if
(StringUtils.equals(leafOfHierarchy.getName(), leafName)) {
+ ret = false;
+ } else {
+ ret = true;
+ }
+ } else {
+ ret = true;
+ }
+ } else {
+ ret = false;
+ }
+ }
+ return ret;
+ }
+
private static Set<RangerTagForEval> getTagsForServiceResource(Date
accessTime, final ServiceTags serviceTags, final RangerServiceResource
serviceResource, final RangerPolicyResourceMatcher.MatchType matchType) {
Set<RangerTagForEval> ret = new HashSet<>();
@@ -1141,4 +1237,23 @@ public class RangerTagEnricher extends
RangerAbstractContextEnricher {
}
}
}
+
+ private static class SelfOrAncestorPredicate implements Predicate {
+ private final RangerServiceDef.RangerResourceDef
leafResourceDef;
+
+ public
SelfOrAncestorPredicate(RangerServiceDef.RangerResourceDef leafResourceDef) {
+ this.leafResourceDef = leafResourceDef;
+ }
+
+ @Override
+ public boolean evaluate(Object o) {
+ if (o instanceof RangerResourceEvaluator) {
+ RangerResourceEvaluator evaluator =
(RangerResourceEvaluator) o;
+
+ return
evaluator.isLeaf(leafResourceDef.getName()) ||
evaluator.isAncestorOf(leafResourceDef);
+ }
+
+ return false;
+ }
+ }
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerZoneResourceMatcher.java
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerZoneResourceMatcher.java
index 1a8a867a0..27ed49b0b 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerZoneResourceMatcher.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerZoneResourceMatcher.java
@@ -19,6 +19,7 @@
package org.apache.ranger.plugin.model.validation;
+import org.apache.commons.lang.StringUtils;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.RangerPluginContext;
@@ -109,6 +110,9 @@ public class RangerZoneResourceMatcher implements
RangerResourceEvaluator {
return
ServiceDefUtil.isAncestorOf(policyResourceMatcher.getServiceDef(),
leafResourceDef, resourceDef);
}
+ @Override
+ public boolean isLeaf(String resourceName) { return
StringUtils.equals(resourceName, leafResourceDef.getName()); }
+
@Override
public String toString() {
return "{security-zone-name:[" + securityZoneName + "],
policyResource=[" + policyResource +"]}";
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
index abfc8f0aa..3a3a80e53 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceTrie.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.policyengine;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
@@ -36,15 +37,7 @@ import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
+import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -194,7 +187,11 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
public Set<T> getEvaluatorsForResource(Object resource,
ResourceElementMatchingScope scope) {
- EvalCollector<T> ret = new EvalCollector<>();
+ return getEvaluatorsForResource(resource, scope, (Predicate) null);
+ }
+
+ public Set<T> getEvaluatorsForResource(Object resource,
ResourceElementMatchingScope scope, Predicate predicate) {
+ EvalCollector<T> ret = new EvalCollector<>(predicate);
traverse(resource, scope, ret);
@@ -202,7 +199,11 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
public Set<T> getEvaluatorsForResource(Object resource,
ResourceElementMatchingScope scope, Set<T> filter) {
- EvalSubsetCollector<T> ret = new EvalSubsetCollector<>(filter);
+ return getEvaluatorsForResource(resource, scope, filter, null);
+ }
+
+ public Set<T> getEvaluatorsForResource(Object resource,
ResourceElementMatchingScope scope, Set<T> filter, Predicate predicate) {
+ EvalSubsetCollector<T> ret = new EvalSubsetCollector<>(filter,
predicate);
traverse(resource, scope, ret);
@@ -210,7 +211,11 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
public int getEvaluatorsCountForResource(Object resource,
ResourceElementMatchingScope scope) {
- EvalCountCollector<T> ret = new EvalCountCollector<>();
+ return getEvaluatorsCountForResource(resource, scope, null);
+ }
+
+ public int getEvaluatorsCountForResource(Object resource,
ResourceElementMatchingScope scope, Predicate predicate) {
+ EvalCountCollector<T> ret = new EvalCountCollector<>(predicate);
traverse(resource, scope, ret);
@@ -1321,18 +1326,20 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
}
- public interface TraverseMatchHandler<T> {
+ public interface TraverseMatchHandler<T extends RangerResourceEvaluator> {
// return: true - stop traverse, processing is complete
// false - continue traverse, processing is not complete yet
boolean process(Set<T> evaluators);
}
- public static class EvalCollector<T> implements TraverseMatchHandler<T> {
- private Set<T> result;
- private boolean isOwnedResult = false;
+ public static class EvalCollector<T extends RangerResourceEvaluator>
implements TraverseMatchHandler<T> {
+ private final Predicate predicate;
+ private Set<T> result;
+ private boolean isOwnedResult = false;
- public EvalCollector() {
- this.result = null;
+ public EvalCollector(Predicate predicate) {
+ this.predicate = predicate;
+ this.result = null;
}
public Set<T> getResult() {
@@ -1343,7 +1350,18 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
public boolean process(Set<T> evaluators) {
if (evaluators != null && !evaluators.isEmpty()) {
if (result == null) {
- result = evaluators;
+ if (predicate == null) {
+ result = evaluators;
+ } else {
+ result = new HashSet<>();
+ isOwnedResult = true;
+
+ for (T evaluator : evaluators) {
+ if (predicate.evaluate(evaluator)) {
+ result.add(evaluator);
+ }
+ }
+ }
} else {
if (!isOwnedResult) {
result = new HashSet<>(result);
@@ -1351,7 +1369,15 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
isOwnedResult = true;
}
- result.addAll(evaluators);
+ if (predicate == null) {
+ result.addAll(evaluators);
+ } else {
+ for (T evaluator : evaluators) {
+ if (predicate.evaluate(evaluator)) {
+ result.add(evaluator);
+ }
+ }
+ }
}
}
@@ -1359,13 +1385,15 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
}
- public static class EvalSubsetCollector<T> implements
TraverseMatchHandler<T> {
- private final Set<T> filter;
- private Set<T> result;
+ public static class EvalSubsetCollector<T extends RangerResourceEvaluator>
implements TraverseMatchHandler<T> {
+ private final Predicate predicate;
+ private final Set<T> filter;
+ private Set<T> result;
- public EvalSubsetCollector(Set<T> filter) {
- this.filter = filter == null ? Collections.emptySet() : filter;
- this.result = null;
+ public EvalSubsetCollector(Set<T> filter, Predicate predicate) {
+ this.predicate = predicate;
+ this.filter = filter == null ? Collections.emptySet() : filter;
+ this.result = null;
}
public Set<T> getResult() {
@@ -1380,6 +1408,10 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
intersect(filter, evaluators, result);
+
+ if (predicate != null) {
+ result.removeIf(evaluator ->
!predicate.evaluate(evaluator));
+ }
}
return result != null && (filter.size() == result.size()); // stop
traverse once the result includes all entries in the filter
@@ -1393,8 +1425,13 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
}
}
- public static class EvalCountCollector<T> implements
TraverseMatchHandler<T> {
- private int result = 0;
+ public static class EvalCountCollector<T extends RangerResourceEvaluator>
implements TraverseMatchHandler<T> {
+ private final Predicate predicate;
+ private int result = 0;
+
+ public EvalCountCollector(Predicate predicate) {
+ this.predicate = predicate;
+ }
public int getResult() {
return result;
@@ -1403,7 +1440,15 @@ public class RangerResourceTrie<T extends
RangerResourceEvaluator> {
@Override
public boolean process(Set<T> evaluators) {
if (evaluators != null) {
- result += evaluators.size();
+ if (predicate == null) {
+ result += evaluators.size();
+ } else {
+ for (T evaluator : evaluators) {
+ if (predicate.evaluate(evaluator)) {
+ result++;
+ }
+ }
+ }
}
return false; // continue traverse
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
index c2773c9e0..309181344 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/gds/GdsSharedResourceEvaluator.java
@@ -105,6 +105,9 @@ public class GdsSharedResourceEvaluator implements
RangerResourceEvaluator {
return
ServiceDefUtil.isAncestorOf(policyResourceMatcher.getServiceDef(),
leafResourceDef, resourceDef);
}
+ @Override
+ public boolean isLeaf(String resourceName) { return
StringUtils.equals(leafResourceDef.getName(), resourceName); }
+
public Collection<String> getResourceKeys() {
return resource != null && resource.getResource() != null ?
resource.getResource().keySet() : Collections.emptySet();
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
index 549dc8f5a..006ceefc3 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
@@ -20,6 +20,7 @@
package org.apache.ranger.plugin.policyevaluator;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
import org.apache.ranger.plugin.model.RangerPolicy;
import
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
@@ -609,5 +610,8 @@ public abstract class RangerAbstractPolicyEvaluator
implements RangerPolicyEvalu
return ServiceDefUtil.isAncestorOf(serviceDef,
leafResourceDef, resourceDef);
}
}
+
+ @Override
+ public boolean isLeaf(String resourceName) { return
StringUtils.equals(resourceName, leafResourceDef.getName()); }
}
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerResourceEvaluator.java
b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerResourceEvaluator.java
index 014bdd528..7544f1bdd 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerResourceEvaluator.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerResourceEvaluator.java
@@ -36,4 +36,6 @@ public interface RangerResourceEvaluator {
RangerResourceMatcher getResourceMatcher(String resourceName);
boolean isAncestorOf(RangerServiceDef.RangerResourceDef resourceDef);
+
+ boolean isLeaf(String resourceName);
}
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
index 69cb4417d..7f39dc2a2 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerResourceEvaluatorsRetriever.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.util;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
+import org.apache.commons.collections.Predicate;
import
org.apache.ranger.plugin.policyengine.RangerAccessRequest.ResourceElementMatchingScope;
import org.apache.ranger.plugin.policyengine.RangerResourceTrie;
import org.apache.ranger.plugin.policyresourcematcher.RangerResourceEvaluator;
@@ -40,6 +41,10 @@ public class RangerResourceEvaluatorsRetriever {
}
public static <T extends RangerResourceEvaluator> Collection<T>
getEvaluators(Map<String, RangerResourceTrie<T>> resourceTrie, Map<String, ?>
resource, Map<String, ResourceElementMatchingScope> scopes) {
+ return getEvaluators(resourceTrie, resource, scopes, null);
+ }
+
+ public static <T extends RangerResourceEvaluator> Collection<T>
getEvaluators(Map<String, RangerResourceTrie<T>> resourceTrie, Map<String, ?>
resource, Map<String, ResourceElementMatchingScope> scopes, Predicate
predicate) {
if (LOG.isDebugEnabled()) {
LOG.debug("==>
RangerPolicyResourceEvaluatorsRetriever.getEvaluators(" + resource + ")");
}
@@ -65,13 +70,18 @@ public class RangerResourceEvaluatorsRetriever {
Object resourceValues = resource.get(resourceDefName);
- int evalCount =
trie.getEvaluatorsCountForResource(resourceValues, scopes.get(resourceDefName));
+ int evalCount =
trie.getEvaluatorsCountForResource(resourceValues, scopes.get(resourceDefName),
predicate);
if (resourceWithMinEvals == null || (evalCount <
minEvalCount)) {
resourceWithMinEvals = resourceDefName;
minEvalCount = evalCount;
}
}
+
+ if (minEvalCount == 0) {
+ resourceWithMinEvals = null;
+ ret = Collections.emptySet();
+ }
} else if (resourceKeys.size() == 1) { // skip
getEvaluatorsCountForResource() when there is only one resource
String resourceKey =
resourceKeys.iterator().next();
RangerResourceTrie<T> trie =
resourceTrie.get(resourceKey);
@@ -84,7 +94,7 @@ public class RangerResourceEvaluatorsRetriever {
if (resourceWithMinEvals != null) {
RangerResourceTrie<T> trie =
resourceTrie.get(resourceWithMinEvals);
- ret =
trie.getEvaluatorsForResource(resource.get(resourceWithMinEvals),
scopes.get(resourceWithMinEvals));
+ ret =
trie.getEvaluatorsForResource(resource.get(resourceWithMinEvals),
scopes.get(resourceWithMinEvals), predicate);
for (String resourceDefName : resourceKeys) {
if (resourceWithMinEvals.equals(resourceDefName)) {
@@ -97,7 +107,7 @@ public class RangerResourceEvaluatorsRetriever {
continue;
}
- Set<T> evaluators =
trie.getEvaluatorsForResource(resource.get(resourceDefName),
scopes.get(resourceDefName), ret);
+ Set<T> evaluators =
trie.getEvaluatorsForResource(resource.get(resourceDefName),
scopes.get(resourceDefName), ret, predicate);
if (CollectionUtils.isEmpty(evaluators)) {
ret = Collections.emptySet();
diff --git
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index ed1ab5bda..2bb667e31 100644
---
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -43,6 +43,7 @@ import
org.apache.ranger.plugin.model.RangerServiceDef.RangerDataMaskTypeDef;
import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
import org.apache.ranger.plugin.policyengine.RangerPluginContext;
import org.apache.ranger.plugin.policyengine.RangerRequestScriptEvaluator;
+import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher;
import org.apache.ranger.plugin.store.AbstractServiceStore;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.ServicePolicies.SecurityZoneInfo;
@@ -188,6 +189,10 @@ public class ServiceDefUtil {
}
public static RangerResourceDef getLeafResourceDef(RangerServiceDef
serviceDef, Map<String, RangerPolicyResource> policyResource) {
+ return getLeafResourceDef(serviceDef, policyResource, false);
+ }
+
+ public static RangerResourceDef getLeafResourceDef(RangerServiceDef
serviceDef, Map<String, RangerPolicyResource> policyResource, boolean
excludeWildcardLeaves) {
RangerResourceDef ret = null;
if(serviceDef != null && policyResource != null) {
@@ -197,10 +202,12 @@ public class ServiceDefUtil {
RangerResourceDef resourceDef =
ServiceDefUtil.getResourceDef(serviceDef, resource);
if (resourceDef != null && resourceDef.getLevel() != null)
{
- if (ret == null) {
- ret = resourceDef;
- } else if(ret.getLevel() < resourceDef.getLevel()) {
- ret = resourceDef;
+ if (ret == null || ret.getLevel() <
resourceDef.getLevel()) {
+ if (StringUtils.isEmpty(resourceDef.getParent())) {
+ ret = resourceDef;
+ } else if (!excludeWildcardLeaves ||
!hasWildcardValue(entry.getValue().getValues())) {
+ ret = resourceDef;
+ }
}
}
}
@@ -210,6 +217,19 @@ public class ServiceDefUtil {
return ret;
}
+ private static boolean hasWildcardValue(List<String> values) {
+ boolean ret = false;
+
+ for (String strValue : values) {
+ ret = StringUtils.equals(strValue,
RangerAbstractResourceMatcher.WILDCARD_ASTERISK);
+ if (ret) {
+ break;
+ }
+ }
+
+ return ret;
+ }
+
public static boolean isAncestorOf(RangerServiceDef serviceDef,
RangerResourceDef ancestor, RangerResourceDef descendant) {
boolean ret = false;
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
index 86985177a..3e0812a0f 100644
---
a/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/contextenricher/TestTagEnricher.java
@@ -128,6 +128,7 @@ public class TestTagEnricher {
for (TestData test : testCase.tests) {
RangerAccessRequestImpl request = new
RangerAccessRequestImpl(test.resource, test.accessType, "testUser", null, null);
+
((RangerMutableResource)request.getResource()).setServiceDef(testCase.serviceDef);
tagEnricher.enrich(request);
List<RangerTag> expected = test.result;
diff --git
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
index d23509f86..24e1a80cc 100644
---
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
+++
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPathResourceTrie.java
@@ -191,6 +191,9 @@ public class TestPathResourceTrie {
return false;
}
+ @Override
+ public boolean isLeaf(String resourceName) { return true; }
+
@Override
public String toString() {
return "id=" + id + ", resource=" + policyResource;
diff --git a/distro/src/main/assembly/ranger-tools.xml
b/distro/src/main/assembly/ranger-tools.xml
index 6893366d3..f12159ff9 100644
--- a/distro/src/main/assembly/ranger-tools.xml
+++ b/distro/src/main/assembly/ranger-tools.xml
@@ -72,6 +72,10 @@
<include>net.java.dev.jna:jna-platform:jar:${jna-platform.version}</include>
<include>org.slf4j:slf4j-api</include>
<include>org.apache.hadoop.thirdparty:hadoop-shaded-guava:jar:${hadoop-shaded-guava.version}</include>
+
<include>org.slf4j:log4j-over-slf4j:jar:${slf4j.version}</include>
+
<include>ch.qos.logback:logback-classic:jar:${logback.version}</include>
+
<include>ch.qos.logback:logback-core:jar:${logback.version}</include>
+ <include>com.google.code.gson:gson:jar:${gson.version}</include>
</includes>
</dependencySet>
</dependencySets>
diff --git a/ranger-tools/conf/logback-mem-sizing.xml
b/ranger-tools/conf/logback-mem-sizing.xml
index c3b601451..700fcb538 100644
--- a/ranger-tools/conf/logback-mem-sizing.xml
+++ b/ranger-tools/conf/logback-mem-sizing.xml
@@ -39,6 +39,27 @@
<level>INFO</level>
</filter>
</appender>
+ <appender name="perf_appender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <!--See http://logback.qos.ch/manual/appenders.html#RollingFileAppender-->
+ <!--and
http://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy-->
+ <!--for further documentation-->
+ <file>./ranger-mem-sizing-perf.log</file>
+ <append>true</append>
+ <encoder>
+ <pattern>%d [%t] %msg%n</pattern>
+ </encoder>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
<fileNamePattern>./ranger-mem-sizing-perf.log.%d{yyyy-MM-dd}</fileNamePattern>
+ <maxHistory>15</maxHistory>
+ <cleanHistoryOnStart>true</cleanHistoryOnStart>
+ </rollingPolicy>
+ </appender>
+ <logger name="org.apache.ranger.perf.tagenricher.tags.retrieval"
additivity="false" level="info">
+ <appender-ref ref="perf_appender"/>
+ </logger>
+ <logger name="org.apache.ranger.perf.policyresourcematcher.gethierarchy"
additivity="false" level="info">
+ <appender-ref ref="perf_appender"/>
+ </logger>
<root level="INFO">
<appender-ref ref="file"/>
</root>
diff --git a/ranger-tools/pom.xml b/ranger-tools/pom.xml
index 440f3711e..150924505 100644
--- a/ranger-tools/pom.xml
+++ b/ranger-tools/pom.xml
@@ -60,6 +60,26 @@
<artifactId>chart</artifactId>
<version>2.2.0</version>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>log4j-over-slf4j</artifactId>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>${logback.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <version>${logback.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>${gson.version}</version>
+ </dependency>
<!-- Test -->
<dependency>
diff --git
a/ranger-tools/src/main/java/org/apache/ranger/sizing/RangerMemSizing.java
b/ranger-tools/src/main/java/org/apache/ranger/sizing/RangerMemSizing.java
index 4cb15c099..6272388e3 100644
--- a/ranger-tools/src/main/java/org/apache/ranger/sizing/RangerMemSizing.java
+++ b/ranger-tools/src/main/java/org/apache/ranger/sizing/RangerMemSizing.java
@@ -619,6 +619,7 @@ public class RangerMemSizing {
ret.disablePolicyRefresher = true;
ret.disableTagRetriever = true;
ret.disableUserStoreRetriever = true;
+ ret.disableGdsInfoRetriever = true;
ret.optimizeTrieForSpace = optimizationMode.equals(OPT_MODE_SPACE);
ret.optimizeTrieForRetrieval = !ret.optimizeTrieForSpace;
ret.optimizeTagTrieForSpace = ret.optimizeTrieForSpace;