RANGER-2061: Add policy engine support to get summary user and group ACLs  for 
a resource


Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/3b510f8c
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/3b510f8c
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/3b510f8c

Branch: refs/heads/master
Commit: 3b510f8c07271e2e51b5a9151a0d26f7084e3792
Parents: c8f67ce
Author: Abhay Kulkarni <akulka...@hortonworks.com>
Authored: Mon Apr 9 14:29:36 2018 -0700
Committer: Abhay Kulkarni <akulka...@hortonworks.com>
Committed: Mon Apr 9 14:29:36 2018 -0700

----------------------------------------------------------------------
 .../RangerScriptConditionEvaluator.java         |   2 +-
 .../RangerAbstractContextEnricher.java          |   6 +
 .../contextenricher/RangerContextEnricher.java  |   2 +
 .../contextenricher/RangerTagEnricher.java      |  45 +-
 .../policyengine/RangerAccessRequestImpl.java   |   2 +-
 .../plugin/policyengine/RangerPolicyEngine.java |   4 +
 .../policyengine/RangerPolicyEngineImpl.java    | 158 ++++-
 .../policyengine/RangerPolicyEngineOptions.java |   3 +
 .../plugin/policyengine/RangerResourceACLs.java | 233 ++++++++
 .../RangerAbstractPolicyEvaluator.java          |   3 +
 .../RangerAbstractPolicyItemEvaluator.java      |   2 +-
 .../RangerDefaultPolicyEvaluator.java           | 319 +++++++++-
 .../policyevaluator/RangerPolicyEvaluator.java  | 310 +++++++++-
 .../RangerPolicyItemEvaluator.java              |   1 -
 .../plugin/service/RangerAuthContext.java       | 230 ++++++++
 .../service/RangerAuthContextListener.java      |  25 +
 .../ranger/plugin/service/RangerBasePlugin.java |  40 +-
 .../plugin/policyengine/TestPolicyACLs.java     | 211 +++++++
 .../plugin/policyengine/TestPolicyEngine.java   |  15 +-
 agents-common/src/test/resources/log4j.xml      |  16 +-
 .../resources/policyengine/ACLResourceTags.json | 207 +++++++
 .../policyengine/test_aclprovider_default.json  | 586 +++++++++++++++++++
 .../test_policyengine_tag_hive.json             |   2 +-
 23 files changed, 2377 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java
index 5febf95..5b66539 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerScriptConditionEvaluator.java
@@ -117,7 +117,7 @@ public class RangerScriptConditionEvaluator extends 
RangerAbstractConditionEvalu
                                        }
 
                                } catch (NullPointerException nullp) {
-                                       
LOG.error("RangerScriptConditionEvaluator.isMatched(): eval called with NULL 
argument(s)");
+                                       
LOG.error("RangerScriptConditionEvaluator.isMatched(): eval called with NULL 
argument(s)", nullp);
 
                                } catch (ScriptException exception) {
                                        
LOG.error("RangerScriptConditionEvaluator.isMatched(): failed to evaluate 
script," +

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
index f6e462c..a745112 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractContextEnricher.java
@@ -29,6 +29,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 
 
 public abstract class RangerAbstractContextEnricher implements 
RangerContextEnricher {
@@ -71,6 +72,11 @@ public abstract class RangerAbstractContextEnricher 
implements RangerContextEnri
        }
 
        @Override
+       public void enrich(RangerAccessRequest request, Object dataStore) {
+               enrich(request);
+       }
+
+       @Override
        public boolean preCleanup() {
                return true;
        }

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerContextEnricher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerContextEnricher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerContextEnricher.java
index 9d0b985..d39c030 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerContextEnricher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerContextEnricher.java
@@ -37,6 +37,8 @@ public interface RangerContextEnricher {
 
        void enrich(RangerAccessRequest request);
 
+       void enrich(RangerAccessRequest request, Object dataStore);
+
        boolean preCleanup();
 
        void cleanup();

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
----------------------------------------------------------------------
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 d5d14a2..83d1280 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
@@ -36,6 +36,8 @@ import 
org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.service.RangerAuthContext;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerResourceTrie;
@@ -142,15 +144,38 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
                        LOG.debug("==> RangerTagEnricher.enrich(" + request + 
")");
                }
 
-               final Set<RangerTagForEval> matchedTags = enrichedServiceTags 
== null ? null : findMatchingTags(request);
+               enrich(request, null);
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerTagEnricher.enrich(" + request + 
")");
+               }
+       }
+
+       @Override
+       public void enrich(RangerAccessRequest request, Object dataStore) {
+               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;
+
+                       if (dataStore != null) {
+                               LOG.warn("Incorrect type of dataStore :[" + 
dataStore.getClass().getName() + "], falling back to original enrich");
+                       }
+               }
+
+               final Set<RangerTagForEval> matchedTags = enrichedServiceTags 
== null ? null : findMatchingTags(request, enrichedServiceTags);
 
                
RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(), 
matchedTags);
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerTagEnricher.enrich(" + request + 
"): tags count=" + (matchedTags == null ? 0 : matchedTags.size()));
+                       LOG.debug("<== RangerTagEnricher.enrich(" + request + 
") with dataStore:[" + dataStore + "]): tags count=" + (matchedTags == null ? 0 
: matchedTags.size()));
                }
        }
-
        /*
         * This class implements a cache of result of look-up of keyset of 
policy-resources for each of the collections of hierarchies
         * for policy types: access, datamask and rowfilter. If a keyset is 
examined for validity in a hierarchy of a policy-type,
@@ -266,6 +291,16 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
                        }
 
                        enrichedServiceTags = new 
EnrichedServiceTags(serviceTags, resourceMatchers, serviceResourceTrie, 
tagsForEmptyResourceAndAnyAccess);
+
+                       Map<String, RangerBasePlugin> servicePluginMap = 
RangerBasePlugin.getServicePluginMap();
+                       RangerBasePlugin plugin = servicePluginMap != null ? 
servicePluginMap.get(getServiceName()) : null;
+                       if (plugin != null) {
+                               RangerAuthContext currentAuthContext = 
plugin.getCurrentRangerAuthContext();
+                               if (currentAuthContext != null) {
+                                       
currentAuthContext.addOrReplaceRequestContextEnricher(this, 
enrichedServiceTags);
+                                       plugin.contextChanged();
+                               }
+                       }
                }
        }
 
@@ -292,13 +327,13 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
                return ret;
        }
 
-       private Set<RangerTagForEval> findMatchingTags(final 
RangerAccessRequest request) {
+       private Set<RangerTagForEval> findMatchingTags(final 
RangerAccessRequest request, EnrichedServiceTags dataStore) {
                if (LOG.isDebugEnabled()) {
                        LOG.debug("==> RangerTagEnricher.findMatchingTags(" + 
request + ")");
                }
 
                // To minimize chance for race condition between Tag-Refresher 
thread and access-evaluation thread
-               final EnrichedServiceTags enrichedServiceTags = 
this.enrichedServiceTags;
+               final EnrichedServiceTags enrichedServiceTags = dataStore != 
null ? dataStore : this.enrichedServiceTags;
 
                Set<RangerTagForEval> ret = null;
 

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
index 3b06f42..5dcdd59 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessRequestImpl.java
@@ -174,7 +174,7 @@ public class RangerAccessRequestImpl implements 
RangerAccessRequest {
        }
 
        public void setAccessTime(Date accessTime) {
-               this.accessTime = (accessTime == null) ? new Date() : 
accessTime;
+               this.accessTime = accessTime;
        }
 
        public void setClientIPAddress(String ipAddress) {

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index 313a8a9..085251a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -57,6 +57,8 @@ public interface RangerPolicyEngine {
 
        Collection<RangerAccessResult> 
evaluatePolicies(Collection<RangerAccessRequest> requests, int policyType, 
RangerAccessResultProcessor resultProcessor);
 
+       RangerResourceACLs getResourceACLs(RangerAccessRequest request);
+
        boolean preCleanup();
 
        void cleanup();
@@ -75,6 +77,8 @@ public interface RangerPolicyEngine {
 
        List<RangerPolicy> getMatchingPolicies(RangerAccessResource resource);
 
+       List<RangerPolicy> getMatchingPolicies(RangerAccessRequest request);
+
        RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest 
request);
 
        List<RangerPolicy> getAllowedPolicies(String user, Set<String> 
userGroups, String accessType);

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
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 5510f6e..5bce47b 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
@@ -31,6 +31,7 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+import 
org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.PolicyACLSummary;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
@@ -41,10 +42,13 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.ACCESS_CONDITIONAL;
+
 public class RangerPolicyEngineImpl implements RangerPolicyEngine {
        private static final Log LOG = 
LogFactory.getLog(RangerPolicyEngineImpl.class);
 
@@ -54,6 +58,7 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
        private static final Log PERF_CONTEXTENRICHER_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("contextenricher.request");
        private static final Log PERF_POLICYENGINE_REBALANCE_LOG = 
RangerPerfTracer.getPerfLogger("policyengine.rebalance");
        private static final Log PERF_POLICYENGINE_USAGE_LOG = 
RangerPerfTracer.getPerfLogger("policyengine.usage");
+       private static final Log PERF_POLICYENGINE_GET_ACLS_LOG = 
RangerPerfTracer.getPerfLogger("policyengine.getResourceACLs");
 
        private static final int MAX_POLICIES_FOR_CACHE_TYPE_EVALUATOR = 100;
 
@@ -326,6 +331,130 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
        }
 
        @Override
+       public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ")");
+               }
+
+               RangerPerfTracer perf = null;
+
+               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_GET_ACLS_LOG)) {
+                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_GET_ACLS_LOG, 
"RangerPolicyEngine.getResourceACLs(requestHashCode=" + 
request.getResource().getAsString() + ")");
+               }
+
+               RangerResourceACLs          ret                      = new 
RangerResourceACLs();
+               Set<RangerTagForEval>       tags                     = 
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+               List<PolicyEvaluatorForTag> tagPolicyEvaluators      = 
tagPolicyRepository == null ? null : 
tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, 
RangerPolicy.POLICY_TYPE_ACCESS, null);
+               List<RangerPolicyEvaluator> resourcePolicyEvaluators = 
policyRepository.getLikelyMatchPolicyEvaluators(request.getResource(), 
RangerPolicy.POLICY_TYPE_ACCESS);
+               List<RangerPolicyEvaluator> allEvaluators;
+               Map<Long, RangerPolicyResourceMatcher.MatchType> 
tagMatchTypeMap            = null;
+               Set<Long>                                        
policyIdForTemporalTags    = null;
+
+               if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
+                       allEvaluators   = new ArrayList<>();
+                       tagMatchTypeMap = new HashMap<>();
+
+                       for (PolicyEvaluatorForTag tagEvaluator : 
tagPolicyEvaluators) {
+                               RangerPolicyEvaluator evaluator = 
tagEvaluator.getEvaluator();
+                               RangerTagForEval      tag       = 
tagEvaluator.getTag();
+
+                               allEvaluators.add(evaluator);
+                               tagMatchTypeMap.put(evaluator.getId(), 
tag.getMatchType());
+
+                               if 
(CollectionUtils.isNotEmpty(tag.getValidityPeriods())) {
+                                       if (policyIdForTemporalTags == null) {
+                                               policyIdForTemporalTags = new 
HashSet<>();
+                                       }
+
+                                       
policyIdForTemporalTags.add(evaluator.getId());
+                               }
+                       }
+
+                       allEvaluators.addAll(resourcePolicyEvaluators);
+                       
allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
+               } else {
+                       allEvaluators = resourcePolicyEvaluators;
+               }
+
+               if (CollectionUtils.isNotEmpty(allEvaluators)) {
+                       Integer policyPriority = null;
+
+                       for (RangerPolicyEvaluator evaluator : allEvaluators) {
+                               if (policyPriority == null) {
+                                       policyPriority = 
evaluator.getPolicyPriority();
+                               }
+
+                               if (policyPriority != 
evaluator.getPolicyPriority()) {
+                                       ret.finalizeAcls();
+
+                                       policyPriority = 
evaluator.getPolicyPriority();
+                               }
+
+                               RangerPolicyResourceMatcher.MatchType matchType 
= tagMatchTypeMap != null ? tagMatchTypeMap.get(evaluator.getId()) : null;
+
+                               if (matchType == null) {
+                                       // This evaluator is not tag evaluator
+                                       matchType = 
evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), 
request.getContext());
+                                       if (matchType == 
RangerPolicyResourceMatcher.MatchType.DESCENDANT) {
+                                               // Need to skip this evaluator, 
if access-type were not ANY, in RangerDefaultPolicyEvaluator this will cause
+                                               // the evaluation to be skipped
+                                               continue;
+                                       }
+                               }
+
+                               PolicyACLSummary aclSummary = 
evaluator.getPolicyACLSummary();
+
+                               if (aclSummary != null) {
+
+                                       boolean isConditional = 
(policyIdForTemporalTags != null && 
policyIdForTemporalTags.contains(evaluator.getId())) || 
evaluator.getValidityScheduleEvaluatorsCount() != 0;
+
+                                       Integer accessResult;
+                                       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;
+                                                               }
+                                                       }
+                                                       
ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult);
+                                               }
+                                       }
+
+                                       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();
+                                                               if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+                                                                       
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
+                                                               }
+                                                       }
+                                                       
ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult);
+                                               }
+                                       }
+                               }
+                       }
+                       ret.finalizeAcls();
+               }
+
+               RangerPerfTracer.logAlways(perf);
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ") : ret=" + ret);
+               }
+
+               return ret;
+       }
+
+       @Override
        public boolean preCleanup() {
 
                boolean ret = true;
@@ -551,12 +680,27 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                        LOG.debug("==> 
RangerPolicyEngineImpl.getMatchingPolicies(" + resource + ")");
                }
 
-               List<RangerPolicy> ret = new ArrayList<>();
-
                RangerAccessRequestImpl request = new 
RangerAccessRequestImpl(resource, RangerPolicyEngine.ANY_ACCESS, null, null);
 
                preProcess(request);
 
+               List<RangerPolicy> ret = getMatchingPolicies(request);
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getMatchingPolicies(" + resource + ") : " + ret.size());
+               }
+
+               return ret;
+       }
+
+       @Override
+       public List<RangerPolicy> getMatchingPolicies(RangerAccessRequest 
request) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getMatchingPolicies(" + request + ")");
+               }
+
+               List<RangerPolicy> ret = new ArrayList<>();
+
                if (hasTagPolicies()) {
                        Set<RangerTagForEval> tags = 
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
 
@@ -568,7 +712,8 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
 
                                        for (RangerPolicyEvaluator evaluator : 
likelyEvaluators) {
                                                RangerPolicyResourceMatcher 
matcher = evaluator.getPolicyResourceMatcher();
-                                               if (matcher != null && 
matcher.isMatch(tagResource, RangerPolicyResourceMatcher.MatchScope.ANY, null)) 
{
+                                               if (matcher != null &&
+                                                               
(request.isAccessTypeAny() ? matcher.isMatch(tagResource, 
RangerPolicyResourceMatcher.MatchScope.ANY, null) : 
matcher.isMatch(tagResource, null))) {
                                                        
ret.add(evaluator.getPolicy());
                                                }
                                        }
@@ -578,11 +723,12 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                }
 
                if (hasResourcePolicies()) {
-                       List<RangerPolicyEvaluator> likelyEvaluators = 
policyRepository.getLikelyMatchPolicyEvaluators(resource);
+                       List<RangerPolicyEvaluator> likelyEvaluators = 
policyRepository.getLikelyMatchPolicyEvaluators(request.getResource());
 
                        for (RangerPolicyEvaluator evaluator : 
likelyEvaluators) {
                                RangerPolicyResourceMatcher matcher = 
evaluator.getPolicyResourceMatcher();
-                               if (matcher != null && 
matcher.isMatch(resource, RangerPolicyResourceMatcher.MatchScope.ANY, null)) {
+                               if (matcher != null &&
+                                               (request.isAccessTypeAny() ? 
matcher.isMatch(request.getResource(), 
RangerPolicyResourceMatcher.MatchScope.ANY, null) : 
matcher.isMatch(request.getResource(), null))) {
                                        ret.add(evaluator.getPolicy());
                                }
                        }
@@ -590,7 +736,7 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                }
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getMatchingPolicies(" + resource + ") : " + ret.size());
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getMatchingPolicies(" + request + ") : " + ret.size());
                }
                return ret;
        }

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
index 2bbdced..b76820c 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
@@ -32,6 +32,7 @@ public class RangerPolicyEngineOptions {
        public boolean cacheAuditResults = true;
        public boolean evaluateDelegateAdminOnly = false;
        public boolean enableTagEnricherWithLocalRefresher = false;
+       public boolean disableAccessEvaluationWithPolicyACLSummary = true;
 
        private RangerServiceDefHelper serviceDefHelper;
 
@@ -48,6 +49,7 @@ public class RangerPolicyEngineOptions {
                }
                evaluateDelegateAdminOnly = false;
                enableTagEnricherWithLocalRefresher = false;
+               disableAccessEvaluationWithPolicyACLSummary = 
conf.getBoolean(propertyPrefix + 
".policyengine.option.disable.access.evaluation.with.policy.acl.summary", true);
        }
 
        public void configureDefaultRangerAdmin(Configuration conf, String 
propertyPrefix) {
@@ -59,6 +61,7 @@ public class RangerPolicyEngineOptions {
                cacheAuditResults = false;
                evaluateDelegateAdminOnly = false;
                enableTagEnricherWithLocalRefresher = false;
+               disableAccessEvaluationWithPolicyACLSummary = 
conf.getBoolean(propertyPrefix + 
".policyengine.option.disable.access.evaluation.with.policy.acl.summary", true);
        }
 
        public void configureDelegateAdmin(Configuration conf, String 
propertyPrefix) {

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
new file mode 100644
index 0000000..34098fa
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceACLs.java
@@ -0,0 +1,233 @@
+/*
+ * 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.policyengine;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.ACCESS_DENIED;
+
+public class RangerResourceACLs {
+       final private Map<String, Map<String, AccessResult>> userACLs  = new 
HashMap<>();
+       final private Map<String, Map<String, AccessResult>> groupACLs = new 
HashMap<>();
+
+       public RangerResourceACLs() {
+       }
+
+       public Map<String, Map<String, AccessResult>> getUserACLs() {
+               return userACLs;
+       }
+
+       public Map<String, Map<String, AccessResult>> getGroupACLs() {
+               return groupACLs;
+       }
+
+       public void finalizeAcls() {
+               Map<String, AccessResult>  publicGroupAccessInfo = 
groupACLs.get(RangerPolicyEngine.GROUP_PUBLIC);
+               if (publicGroupAccessInfo != null) {
+
+                       for (Map.Entry<String, AccessResult> entry : 
publicGroupAccessInfo.entrySet()) {
+                               String accessType = entry.getKey();
+                               AccessResult accessResult = entry.getValue();
+                               int access = accessResult.getResult();
+
+                               if (access == 
RangerPolicyEvaluator.ACCESS_DENIED || access == 
RangerPolicyEvaluator.ACCESS_ALLOWED) {
+                                       for (Map.Entry<String, Map<String, 
AccessResult>> mapEntry : userACLs.entrySet()) {
+                                               Map<String, AccessResult> 
mapValue = mapEntry.getValue();
+                                               AccessResult savedAccessResult 
= mapValue.get(accessType);
+                                               if (savedAccessResult != null 
&& !savedAccessResult.getIsFinal()) {
+                                                       
mapValue.remove(accessType);
+                                               }
+                                       }
+
+                                       for (Map.Entry<String, Map<String, 
AccessResult>> mapEntry : groupACLs.entrySet()) {
+                                               if 
(!StringUtils.equals(mapEntry.getKey(), RangerPolicyEngine.GROUP_PUBLIC)) {
+                                                       Map<String, 
AccessResult> mapValue = mapEntry.getValue();
+                                                       AccessResult 
savedAccessResult = mapValue.get(accessType);
+                                                       if (savedAccessResult 
!= null && !savedAccessResult.getIsFinal()) {
+                                                               
mapValue.remove(accessType);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               finalizeAcls(userACLs);
+               finalizeAcls(groupACLs);
+       }
+
+       public void setUserAccessInfo(String userName, String accessType, 
Integer access) {
+               Map<String, AccessResult> userAccessInfo = 
userACLs.get(userName);
+
+               if (userAccessInfo == null) {
+                       userAccessInfo = new HashMap<>();
+
+                       userACLs.put(userName, userAccessInfo);
+               }
+
+               AccessResult accessResult = userAccessInfo.get(accessType);
+
+               if (accessResult == null) {
+                       accessResult = new AccessResult(access);
+
+                       userAccessInfo.put(accessType, accessResult);
+               } else {
+                       accessResult.setResult(access);
+               }
+       }
+
+       public void setGroupAccessInfo(String groupName, String accessType, 
Integer access) {
+               Map<String, AccessResult> groupAccessInfo = 
groupACLs.get(groupName);
+
+               if (groupAccessInfo == null) {
+                       groupAccessInfo = new HashMap<>();
+
+                       groupACLs.put(groupName, groupAccessInfo);
+               }
+
+               AccessResult accessResult = groupAccessInfo.get(accessType);
+
+               if (accessResult == null) {
+                       accessResult = new AccessResult(access);
+
+                       groupAccessInfo.put(accessType, accessResult);
+               } else {
+                       accessResult.setResult(access);
+               }
+       }
+
+       @Override
+       public String toString() {
+               StringBuffer sb = new StringBuffer();
+
+               sb.append("{");
+               sb.append("UserACLs={");
+               for (Map.Entry<String, Map<String, AccessResult>> entry : 
userACLs.entrySet()) {
+                       sb.append("user=").append(entry.getKey()).append(":");
+                       sb.append("permissions={");
+                       for (Map.Entry<String, AccessResult> permission : 
entry.getValue().entrySet()) {
+                               
sb.append("{Permission=").append(permission.getKey()).append(", 
value=").append(permission.getValue()).append("},");
+                       }
+                       sb.append("},");
+               }
+               sb.append("}");
+               sb.append(", GroupACLs={");
+               for (Map.Entry<String, Map<String, AccessResult>> entry : 
groupACLs.entrySet()) {
+                       sb.append("group=").append(entry.getKey()).append(":");
+                       sb.append("permissions={");
+                       for (Map.Entry<String, AccessResult> permission : 
entry.getValue().entrySet()) {
+                               
sb.append("{Permission=").append(permission.getKey()).append(", 
value=").append(permission.getValue()).append("}, ");
+                       }
+                       sb.append("},");
+               }
+               sb.append("}");
+               sb.append("}");
+
+               return sb.toString();
+       }
+
+       private void finalizeAcls(Map<String, Map<String, AccessResult>> acls) {
+               List<String> keysToRemove = new ArrayList<>();
+               for (Map.Entry<String, Map<String, AccessResult>> entry : 
acls.entrySet()) {
+                       if (entry.getValue().isEmpty()) {
+                               keysToRemove.add(entry.getKey());
+                       } else {
+                               for (Map.Entry<String, AccessResult> permission 
: entry.getValue().entrySet()) {
+                                       permission.getValue().setIsFinal(true);
+                               }
+                       }
+
+               }
+               for (String keyToRemove : keysToRemove) {
+                       acls.remove(keyToRemove);
+               }
+       }
+
+       @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class AccessResult {
+               private int     result;
+               private boolean isFinal;
+
+
+               public AccessResult() {
+                       this(-1);
+               }
+
+               public AccessResult(int result) {
+                       this(result, false);
+               }
+
+               public AccessResult(int result, boolean isFinal) {
+                       setIsFinal(isFinal);
+                       setResult(result);
+               }
+
+               public int getResult() { return result; }
+
+               public void setResult(int result) {
+                       if (!isFinal) {
+                               this.result = result;
+
+                               if (this.result == ACCESS_DENIED) {
+                                       isFinal = true;
+                               }
+                       }
+               }
+
+               public boolean getIsFinal() { return isFinal; }
+
+               public void setIsFinal(boolean isFinal) { this.isFinal = 
isFinal; }
+
+               @Override
+               public boolean equals(Object other) {
+                       if (other == null)
+                               return false;
+                       if (other instanceof AccessResult) {
+                               AccessResult otherObject = (AccessResult)other;
+                               return result == otherObject.result && isFinal 
== otherObject.isFinal;
+                       } else
+                               return false;
+
+               }
+               @Override
+               public String toString() {
+                       if (result == RangerPolicyEvaluator.ACCESS_ALLOWED)
+                               return "ALLOWED, final=" + isFinal;
+                       if (result == RangerPolicyEvaluator.ACCESS_DENIED)
+                               return "NOT_ALLOWED, final=" + isFinal;
+                       return "CONDITIONAL_ALLOWED, final=" + isFinal;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
----------------------------------------------------------------------
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 4e6ca2f..bc459e3 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
@@ -135,6 +135,9 @@ public abstract class RangerAbstractPolicyEvaluator 
implements RangerPolicyEvalu
        }
 
        @Override
+       public PolicyACLSummary getPolicyACLSummary() { return null; }
+
+       @Override
        public String toString( ) {
                StringBuilder sb = new StringBuilder();
 

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index cd7c3c1..f58d514 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
@@ -35,7 +35,7 @@ public abstract class RangerAbstractPolicyItemEvaluator 
implements RangerPolicyI
 
        private static final int RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT = 1000;
 
-       private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_USERSGROUPS       =  25;
+       private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_USERSGROUPS       =  100;
        private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_ACCESS_TYPES      =  25;
        private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_CUSTOM_CONDITIONS =  25;
        private static final int 
RANGER_POLICY_ITEM_EVAL_ORDER_CUSTOM_CONDITION_PENALTY       =   5;

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index c539cc0..63fc468 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -45,6 +45,7 @@ import org.apache.ranger.plugin.model.RangerValiditySchedule;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
 import org.apache.ranger.plugin.policyengine.RangerTagAccessRequest;
@@ -60,6 +61,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private static final Log LOG = 
LogFactory.getLog(RangerDefaultPolicyEvaluator.class);
 
        private static final Log PERF_POLICY_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policy.init");
+       private static final Log PERF_POLICY_INIT_ACLSUMMARY_LOG = 
RangerPerfTracer.getPerfLogger("policy.init.ACLSummary");
        private static final Log PERF_POLICY_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policy.request");
 
        private RangerPolicyResourceMatcher     resourceMatcher;
@@ -71,8 +73,9 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private int                             customConditionsCount;
        private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators;
        private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators;
-
        private String perfTag;
+       private PolicyACLSummary aclSummary                 = null;
+       private boolean          useAclSummaryForEvaluation = false;
 
        protected boolean needsDynamicEval() { return resourceMatcher != null 
&& resourceMatcher.getNeedsDynamicEval(); }
 
@@ -82,6 +85,11 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        }
 
        @Override
+       public int getValidityScheduleEvaluatorsCount() {
+               return validityScheduleEvaluators.size();
+       }
+
+       @Override
        public RangerPolicyResourceMatcher getPolicyResourceMatcher() { return 
resourceMatcher; }
 
        @Override
@@ -121,20 +129,35 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                if(policy != null) {
                        validityScheduleEvaluators = 
createValidityScheduleEvaluators(policy);
-                       allowEvaluators          = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
-                       denyEvaluators           = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
-                       allowExceptionEvaluators = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
-                       denyExceptionEvaluators  = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
-                       dataMaskEvaluators       = 
createDataMaskPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
-                       rowFilterEvaluators      = 
createRowFilterPolicyItemEvaluators(policy, serviceDef, options, 
policy.getRowFilterPolicyItems());
+
+                       if 
(!options.disableAccessEvaluationWithPolicyACLSummary) {
+                               aclSummary = createPolicyACLSummary();
+                       }
+
+                       useAclSummaryForEvaluation = aclSummary != null;
+
+                       if (useAclSummaryForEvaluation) {
+                               allowEvaluators          = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                               denyEvaluators           = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                               allowExceptionEvaluators = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                               denyExceptionEvaluators  = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                       } else {
+                               allowEvaluators          = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
+                               denyEvaluators           = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
+                               allowExceptionEvaluators = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
+                               denyExceptionEvaluators  = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
+                       }
+
+                       dataMaskEvaluators  = 
createDataMaskPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
+                       rowFilterEvaluators = 
createRowFilterPolicyItemEvaluators(policy, serviceDef, options, 
policy.getRowFilterPolicyItems());
                } else {
                        validityScheduleEvaluators = 
Collections.<RangerValidityScheduleEvaluator>emptyList();
-                       allowEvaluators          = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       denyEvaluators           = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       allowExceptionEvaluators = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       denyExceptionEvaluators  = 
Collections.<RangerPolicyItemEvaluator>emptyList();
-                       dataMaskEvaluators       = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
-                       rowFilterEvaluators      = 
Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
+                       allowEvaluators            = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                       denyEvaluators             = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                       allowExceptionEvaluators   = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                       denyExceptionEvaluators    = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                       dataMaskEvaluators         = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
+                       rowFilterEvaluators        = 
Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
                }
 
                RangerPolicyItemEvaluator.EvalOrderComparator comparator = new 
RangerPolicyItemEvaluator.EvalOrderComparator();
@@ -362,7 +385,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
        @Override
        public void getResourceAccessInfo(RangerAccessRequest request, 
RangerResourceAccessInfo result) {
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + result 
+ ")");
                }
                RangerPolicyResourceMatcher.MatchType matchType;
@@ -418,20 +441,156 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        }
                }
 
-               if(LOG.isDebugEnabled()) {
+               if (LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + result 
+ ")");
                }
        }
 
+       /*
+               This API is called by policy-engine to support components which 
need to statically determine Ranger ACLs
+               for a given resource. It will always return a non-null object. 
The accesses that cannot be determined
+               statically will be marked as CONDITIONAL.
+       */
+
+       @Override
+       public PolicyACLSummary getPolicyACLSummary() {
+               if (aclSummary == null) {
+                       boolean forceCreation = true;
+                       aclSummary = createPolicyACLSummary(forceCreation);
+               }
+
+               return aclSummary;
+       }
+
+       void updateAccessResult(RangerAccessResult result, 
RangerPolicyResourceMatcher.MatchType matchType, boolean isAllowed) {
+               if(!isAllowed) {
+                       if(matchType != 
RangerPolicyResourceMatcher.MatchType.DESCENDANT) {
+                               result.setIsAllowed(false);
+                               
result.setPolicyPriority(getPolicy().getPolicyPriority());
+                               result.setPolicyId(getId());
+                               //result.setReason(getComments());
+                       }
+               } else {
+                       if(! result.getIsAllowed()) { // if access is not yet 
allowed by another policy
+                               result.setIsAllowed(true);
+                               
result.setPolicyPriority(getPolicy().getPolicyPriority());
+                               result.setPolicyId(getId());
+                               //result.setReason(getComments());
+                       }
+               }
+       }
+
+       /*
+               This API is only called during initialization of Policy 
Evaluator if policy-engine is configured to use
+               PolicyACLSummary for access evaluation (that is, if 
disableAccessEvaluationWithPolicyACLSummary option
+               is set to false). It may return null object if all accesses for 
all user/groups cannot be determined statically.
+       */
+
+       private PolicyACLSummary createPolicyACLSummary() {
+               boolean forceCreation = false;
+               return createPolicyACLSummary(forceCreation);
+       }
+
+       private PolicyACLSummary createPolicyACLSummary(boolean 
isCreationForced) {
+               PolicyACLSummary ret  = null;
+               RangerPerfTracer perf = null;
+
+               if 
(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_INIT_ACLSUMMARY_LOG)) {
+                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_ACLSUMMARY_LOG, 
"RangerPolicyEvaluator.init.ACLSummary(" + perfTag + ")");
+               }
+
+               final boolean hasNonPublicGroupOrConditionsInAllowExceptions = 
hasNonPublicGroupOrConditions(getPolicy().getAllowExceptions());
+               final boolean hasNonPublicGroupOrConditionsInDenyExceptions  = 
hasNonPublicGroupOrConditions(getPolicy().getDenyExceptions());
+               final boolean hasPublicGroupInAllowAndUsersInAllowExceptions = 
hasPublicGroupAndUserInException(getPolicy().getPolicyItems(), 
getPolicy().getAllowExceptions());
+               final boolean hasPublicGroupInDenyAndUsersInDenyExceptions   = 
hasPublicGroupAndUserInException(getPolicy().getDenyPolicyItems(), 
getPolicy().getDenyExceptions());
+               final boolean hasContextSensitiveSpecification               = 
hasContextSensitiveSpecification();
+               final boolean isUsableForEvaluation                          =  
  !hasNonPublicGroupOrConditionsInAllowExceptions
+                                                                              
&& !hasNonPublicGroupOrConditionsInDenyExceptions
+                                                                              
&& !hasPublicGroupInAllowAndUsersInAllowExceptions
+                                                                              
&& !hasPublicGroupInDenyAndUsersInDenyExceptions
+                                                                              
&& !hasContextSensitiveSpecification;
+
+               if (isUsableForEvaluation || isCreationForced) {
+                       ret = new PolicyACLSummary();
+
+                       for (RangerPolicyItem policyItem : 
getPolicy().getDenyPolicyItems()) {
+                               ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, 
hasNonPublicGroupOrConditionsInDenyExceptions || 
hasPublicGroupInDenyAndUsersInDenyExceptions);
+                       }
+
+                       if (!hasNonPublicGroupOrConditionsInDenyExceptions && 
!hasPublicGroupInDenyAndUsersInDenyExceptions) {
+                               for (RangerPolicyItem policyItem : 
getPolicy().getDenyExceptions()) {
+                                       ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false);
+                               }
+                       }
+
+                       for (RangerPolicyItem policyItem : 
getPolicy().getPolicyItems()) {
+                               ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, 
hasNonPublicGroupOrConditionsInAllowExceptions || 
hasPublicGroupInAllowAndUsersInAllowExceptions);
+                       }
+
+                       if (!hasNonPublicGroupOrConditionsInAllowExceptions && 
!hasPublicGroupInAllowAndUsersInAllowExceptions) {
+                               for (RangerPolicyItem policyItem : 
getPolicy().getAllowExceptions()) {
+                                       ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false);
+                               }
+                       }
+
+                       ret.finalizeAcls();
+               }
+
+               RangerPerfTracer.logAlways(perf);
+
+               return ret;
+       }
+
+       private boolean hasPublicGroupAndUserInException(List<RangerPolicyItem> 
grants, List<RangerPolicyItem> exceptionItems) {
+               boolean ret = false;
+
+               if (CollectionUtils.isNotEmpty(exceptionItems)) {
+                       boolean hasPublicGroupInGrant = false;
+
+                       for (RangerPolicyItem policyItem : grants) {
+                               if 
(policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC) || 
policyItem.getUsers().contains(RangerPolicyEngine.USER_CURRENT)) {
+                                       hasPublicGroupInGrant = true;
+                                       break;
+                               }
+                       }
+
+                       if (hasPublicGroupInGrant) {
+                               boolean hasPublicGroupInException = false;
+
+                               for (RangerPolicyItem policyItem : 
exceptionItems) {
+                                       if 
(policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC) || 
policyItem.getUsers().contains(RangerPolicyEngine.USER_CURRENT)) {
+                                               hasPublicGroupInException = 
true;
+                                               break;
+                                       }
+                               }
+
+                               if (!hasPublicGroupInException) {
+                                       ret = true;
+                               }
+                       }
+               }
+
+               return ret;
+       }
+
        protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerPolicyResourceMatcher.MatchType matchType, RangerAccessResult result) {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + matchType + ")");
                }
+               if (useAclSummaryForEvaluation && (getPolicy().getPolicyType() 
== null || getPolicy().getPolicyType() == RangerPolicy.POLICY_TYPE_ACCESS)) {
+                       LOG.info("Using ACL Summary for access evaluation. 
PolicyId=[" + getId() +"]");
+                       Integer accessResult = 
lookupPolicyACLSummary(request.getUser(), request.getUserGroups(), 
request.getAccessType());
+                       if (accessResult != null) {
+                               updateAccessResult(result, matchType, 
accessResult.equals(RangerPolicyEvaluator.ACCESS_ALLOWED));
+                       }
+               } else {
+                       LOG.info("Using policyItemEvaluators for access 
evaluation. PolicyId=[" + getId() +"]");
 
-               RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, result);
+                       RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, result);
 
-               if(matchedPolicyItem != null) {
-                       matchedPolicyItem.updateAccessResult(result, matchType, 
getPolicy());
+                       if (matchedPolicyItem != null) {
+                               matchedPolicyItem.updateAccessResult(result, 
matchType, getPolicy());
+                       }
                }
 
                if(LOG.isDebugEnabled()) {
@@ -439,6 +598,96 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                }
        }
 
+       private Integer lookupPolicyACLSummary(String user, Set<String> 
userGroups, String accessType) {
+               Integer accessResult = null;
+
+               Map<String, PolicyACLSummary.AccessResult> accesses = 
aclSummary.getUsersAccessInfo().get(user);
+
+               accessResult = lookupAccess(user, accessType, accesses);
+
+               if (accessResult == null) {
+
+                       Set<String> groups = new HashSet<>();
+                       groups.add(RangerPolicyEngine.GROUP_PUBLIC);
+                       groups.addAll(userGroups);
+
+                       for (String userGroup : groups) {
+                               accesses = 
aclSummary.getGroupsAccessInfo().get(userGroup);
+                               accessResult = lookupAccess(userGroup, 
accessType, accesses);
+                               if (accessResult != null) {
+                                       break;
+                               }
+                       }
+               }
+
+               return accessResult;
+       }
+
+       private Integer lookupAccess(String userOrGroup, String accessType, 
Map<String, PolicyACLSummary.AccessResult> accesses) {
+               Integer ret = null;
+               if (accesses != null) {
+                       if (accessType.equals(RangerPolicyEngine.ANY_ACCESS)) {
+                               ret = getAccessResultForAnyAccess(accesses);
+                       } else {
+                               PolicyACLSummary.AccessResult accessResult = 
accesses.get(accessType);
+                               if (accessResult != null) {
+                                       if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_CONDITIONAL) {
+                                               LOG.error("Access should not be 
conditional at this point! user=[" + userOrGroup + "], " + "accessType=[" + 
accessType + "]");
+                                       } else {
+                                               ret = accessResult.getResult();
+                                       }
+                               }
+                       }
+               }
+               return ret;
+       }
+
+       private Integer getAccessResultForAnyAccess(Map<String, 
PolicyACLSummary.AccessResult> accessses) {
+               Integer ret = null;
+
+               int allowedAccessCount = 0;
+               int deniedAccessCount = 0;
+               int deniedWithException = 0;
+               int undeterminedAccessCount = 0;
+               int accessesSize = 0;
+
+               for (Map.Entry<String, PolicyACLSummary.AccessResult> entry : 
accessses.entrySet()) {
+                       if (StringUtils.equals(entry.getKey(), 
RangerPolicyEngine.ADMIN_ACCESS)) {
+                               // Dont count admin access if present
+                               continue;
+                       }
+                       PolicyACLSummary.AccessResult accessResult = 
entry.getValue();
+                       if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_ALLOWED) {
+                               allowedAccessCount++;
+                       } else if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_DENIED) {
+                               deniedAccessCount++;
+                       } else if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_UNDETERMINED) {
+                               if (accessResult.getHasSeenDeny()) {
+                                       deniedWithException++;
+                               } else {
+                                       undeterminedAccessCount++;
+                               }
+                       }
+                       accessesSize++;
+               }
+
+               int accessTypeCount = getServiceDef().getAccessTypes().size();
+
+               if (accessTypeCount == accessesSize) {
+                       // All permissions are represented
+                       if (deniedAccessCount > 0 || undeterminedAccessCount == 
accessTypeCount) {
+                               // at least one is denied or all are 
undetermined
+                               ret = RangerPolicyEvaluator.ACCESS_DENIED;
+                       }
+               }
+               if (ret == null) {
+                       if (allowedAccessCount > 0 || undeterminedAccessCount > 
0) {
+                               ret = RangerPolicyEvaluator.ACCESS_ALLOWED;
+                       }
+               }
+               return ret;
+       }
+
        protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String 
user, Set<String> userGroups, String accessType) {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + 
userGroups + ", " + accessType + ")");
@@ -528,10 +777,21 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.isAccessAllowed(hashCode=" + 
Integer.toHexString(System.identityHashCode(this)) + "," + perfTag + ")");
                }
 
-               RangerPolicyItemEvaluator item = 
this.getDeterminingPolicyItem(user, userGroups, accessType);
+               if (useAclSummaryForEvaluation && (getPolicy().getPolicyType() 
== null || getPolicy().getPolicyType() == RangerPolicy.POLICY_TYPE_ACCESS)) {
+                       LOG.info("Using ACL Summary for checking if access is 
allowed. PolicyId=[" + getId() +"]");
 
-               if(item != null && item.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW) {
-                       ret = true;
+                       Integer accessResult = lookupPolicyACLSummary(user, 
userGroups, accessType);
+                       if (accessResult != null && 
accessResult.equals(RangerPolicyEvaluator.ACCESS_ALLOWED)) {
+                               ret = true;
+                       }
+               } else {
+                       LOG.info("Using policyItemEvaluators for checking if 
access is allowed. PolicyId=[" + getId() +"]");
+
+                       RangerPolicyItemEvaluator item = 
this.getDeterminingPolicyItem(user, userGroups, accessType);
+
+                       if (item != null && item.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW) {
+                               ret = true;
+                       }
                }
 
                RangerPerfTracer.log(perf);
@@ -774,6 +1034,22 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
+       private static boolean 
hasNonPublicGroupOrConditions(List<RangerPolicyItem> policyItems) {
+               boolean ret = false;
+               for (RangerPolicyItem policyItem : policyItems) {
+                       if 
(CollectionUtils.isNotEmpty(policyItem.getConditions())) {
+                               ret = true;
+                               break;
+                       }
+                       List<String> allGroups = policyItem.getGroups();
+                       if (CollectionUtils.isNotEmpty(allGroups) && 
!allGroups.contains(RangerPolicyEngine.GROUP_PUBLIC)) {
+                               ret = true;
+                               break;
+                       }
+               }
+               return ret;
+       }
+
        protected RangerPolicyItemEvaluator 
getMatchingPolicyItem(RangerAccessRequest request, RangerAccessResult result) {
                RangerPolicyItemEvaluator ret = null;
 
@@ -887,5 +1163,4 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
         return ret;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index 613a001..e3cd154 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -21,27 +21,45 @@ package org.apache.ranger.plugin.policyevaluator;
 
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+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.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceEvaluator;
 
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW;
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS;
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY;
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS;
 
 public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
        Comparator<RangerPolicyEvaluator> EVAL_ORDER_COMPARATOR = new 
RangerPolicyEvaluator.PolicyEvalOrderComparator();
        Comparator<RangerPolicyEvaluator> NAME_COMPARATOR       = new 
RangerPolicyEvaluator.PolicyNameComparator();
 
-       String EVALUATOR_TYPE_AUTO   = "auto";
+       // computation of PolicyACLSummary rely on following specific values
+       Integer ACCESS_DENIED       = -1;
+       Integer ACCESS_UNDETERMINED = 0;
+       Integer ACCESS_ALLOWED      = 1;
+       Integer ACCESS_CONDITIONAL  = 2;
+
+       String EVALUATOR_TYPE_AUTO      = "auto";
        String EVALUATOR_TYPE_OPTIMIZED = "optimized";
        String EVALUATOR_TYPE_CACHED    = "cached";
 
@@ -71,6 +89,8 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
 
        int getCustomConditionsCount();
 
+       int getValidityScheduleEvaluatorsCount();
+
        boolean isAuditEnabled();
 
        void evaluate(RangerAccessRequest request, RangerAccessResult result);
@@ -89,6 +109,38 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
 
        void getResourceAccessInfo(RangerAccessRequest request, 
RangerResourceAccessInfo result);
 
+       PolicyACLSummary getPolicyACLSummary();
+
+       default boolean hasContextSensitiveSpecification() {
+               RangerPolicy policy = getPolicy();
+
+               for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
+                       if (hasContextSensitiveSpecification(policyItem)) {
+                               return true;
+                       }
+               }
+               for (RangerPolicyItem policyItem : policy.getDenyPolicyItems()) 
{
+                       if (hasContextSensitiveSpecification(policyItem)) {
+                               return true;
+                       }
+               }
+               for (RangerPolicyItem policyItem : policy.getAllowExceptions()) 
{
+                       if (hasContextSensitiveSpecification(policyItem)) {
+                               return true;
+                       }
+               }
+               for (RangerPolicyItem policyItem : policy.getDenyExceptions()) {
+                       if (hasContextSensitiveSpecification(policyItem)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       static boolean hasContextSensitiveSpecification(RangerPolicyItem 
policyItem) {
+               return  CollectionUtils.isNotEmpty(policyItem.getConditions()) 
|| policyItem.getUsers().contains(RangerPolicyEngine.RESOURCE_OWNER); /* || 
policyItem.getGroups().contains(RangerPolicyEngine.RESOURCE_GROUP_OWNER) */
+       }
+
        class PolicyEvalOrderComparator implements 
Comparator<RangerPolicyEvaluator>, Serializable {
                @Override
                public int compare(RangerPolicyEvaluator me, 
RangerPolicyEvaluator other) {
@@ -139,4 +191,260 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
                }
        }
 
+       class PolicyACLSummary {
+               private final Map<String, Map<String, AccessResult>> 
usersAccessInfo = new HashMap<>();
+               private final Map<String, Map<String, AccessResult>> 
groupsAccessInfo = new HashMap<>();
+
+               private enum AccessorType { USER, GROUP }
+
+               public static class AccessResult {
+                       private int result;
+                       private final boolean hasSeenDeny;
+
+                       public AccessResult(int result) {
+                               this(result, false);
+                       }
+
+                       public AccessResult(int result, boolean hasSeenDeny) {
+                               this.hasSeenDeny = hasSeenDeny;
+                               setResult(result);
+                       }
+
+                       public int getResult() {
+                               return result;
+                       }
+
+                       public void setResult(int result) {
+                               this.result = result;
+                       }
+
+                       public boolean getHasSeenDeny() {
+                               return hasSeenDeny;
+                       }
+                       @Override
+                       public String toString() {
+                               if (result == 
RangerPolicyEvaluator.ACCESS_ALLOWED)
+                                       return "ALLOWED, hasSeenDeny=" + 
hasSeenDeny;
+                               if (result == 
RangerPolicyEvaluator.ACCESS_DENIED)
+                                       return "NOT_ALLOWED, hasSeenDeny=" + 
hasSeenDeny;
+                               if (result == 
RangerPolicyEvaluator.ACCESS_CONDITIONAL)
+                                       return "CONDITIONAL_ALLOWED, 
hasSeenDeny=" + hasSeenDeny;
+                               return "NOT_DETERMINED, hasSeenDeny=" + 
hasSeenDeny;
+                       }
+               }
+
+               PolicyACLSummary() {
+               }
+
+               public Map<String, Map<String, AccessResult>> 
getUsersAccessInfo() {
+                       return usersAccessInfo;
+               }
+
+               public Map<String, Map<String, AccessResult>> 
getGroupsAccessInfo() {
+                       return groupsAccessInfo;
+               }
+
+               void processPolicyItem(RangerPolicyItem policyItem, int 
policyItemType, boolean isConditional) {
+                       final Integer result;
+                       final boolean hasContextSensitiveSpecification = 
RangerPolicyEvaluator.hasContextSensitiveSpecification(policyItem);
+
+                       switch (policyItemType) {
+                               case POLICY_ITEM_TYPE_ALLOW:
+                                       result = 
(hasContextSensitiveSpecification || isConditional) ? ACCESS_CONDITIONAL : 
ACCESS_ALLOWED;
+                                       break;
+
+                               case POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS:
+                                       result = 
(hasContextSensitiveSpecification || isConditional) ? null : ACCESS_DENIED;
+                                       break;
+
+                               case POLICY_ITEM_TYPE_DENY:
+                                       result = 
(hasContextSensitiveSpecification || isConditional) ? ACCESS_CONDITIONAL : 
ACCESS_DENIED;
+                                       break;
+
+                               case POLICY_ITEM_TYPE_DENY_EXCEPTIONS:
+                                       result = 
(hasContextSensitiveSpecification || isConditional) ? null : ACCESS_ALLOWED;
+                                       break;
+
+                               default:
+                                       result = null;
+                                       break;
+                       }
+
+                       if (result != null) {
+                               final List<RangerPolicyItemAccess> accesses;
+
+                               if (policyItem.getDelegateAdmin()) {
+                                       accesses = new ArrayList<>();
+
+                                       accesses.add(new 
RangerPolicyItemAccess(RangerPolicyEngine.ADMIN_ACCESS, 
policyItem.getDelegateAdmin()));
+                                       
accesses.addAll(policyItem.getAccesses());
+                               } else {
+                                       accesses = policyItem.getAccesses();
+                               }
+
+                               final List<String> groups         = 
policyItem.getGroups();
+                               final List<String> users          = 
policyItem.getUsers();
+                               boolean            hasPublicGroup = false;
+
+                               for (RangerPolicyItemAccess access : accesses) {
+                                       for (String user : users) {
+                                               if (StringUtils.equals(user, 
RangerPolicyEngine.USER_CURRENT)) {
+                                                       hasPublicGroup = true;
+                                                       continue;
+                                               } else if 
(StringUtils.isBlank(user)) {
+                                                       continue;
+                                               }
+
+                                               addAccess(user, 
AccessorType.USER, access.getType(), result, policyItemType);
+                                       }
+
+                                       for (String group : groups) {
+                                               if (StringUtils.equals(group, 
RangerPolicyEngine.GROUP_PUBLIC)) {
+                                                       hasPublicGroup = true;
+                                                       continue;
+                                               }
+
+                                               addAccess(group, 
AccessorType.GROUP, access.getType(), result, policyItemType);
+                                       }
+
+                                       if (hasPublicGroup) {
+                                               
addAccess(RangerPolicyEngine.GROUP_PUBLIC, AccessorType.GROUP, 
access.getType(), result, policyItemType);
+                                       }
+                               }
+                       }
+               }
+
+               void finalizeAcls() {
+                       Map<String, AccessResult>  publicGroupAccessInfo = 
groupsAccessInfo.get(RangerPolicyEngine.GROUP_PUBLIC);
+
+                       if (publicGroupAccessInfo != null) {
+                               // For each accessType in public, retrieve 
access
+                               for (Map.Entry<String, AccessResult> entry : 
publicGroupAccessInfo.entrySet()) {
+                                       final String       accessType   = 
entry.getKey();
+                                       final AccessResult accessResult = 
entry.getValue();
+                                       final int          access       = 
accessResult.getResult();
+
+                                       if (access == ACCESS_DENIED || access 
== ACCESS_ALLOWED) {
+                                               List<String> keysToRemove = 
null;
+
+                                               for (Map.Entry<String, 
Map<String, AccessResult>> mapEntry : usersAccessInfo.entrySet()) {
+                                                       Map<String, 
AccessResult> mapValue = mapEntry.getValue();
+
+                                                       
mapValue.remove(accessType);
+
+                                                       if (mapValue.isEmpty()) 
{
+                                                               if 
(keysToRemove == null) {
+                                                                       
keysToRemove = new ArrayList<>();
+                                                               }
+
+                                                               
keysToRemove.add(mapEntry.getKey());
+                                                       }
+                                               }
+
+                                               if (keysToRemove != null) {
+                                                       for (String keyToRemove 
: keysToRemove) {
+                                                               
usersAccessInfo.remove(keyToRemove);
+                                                       }
+
+                                                       keysToRemove.clear();
+                                               }
+
+                                               for (Map.Entry<String, 
Map<String, AccessResult>> mapEntry : groupsAccessInfo.entrySet()) {
+                                                       if 
(!StringUtils.equals(mapEntry.getKey(), RangerPolicyEngine.GROUP_PUBLIC)) {
+                                                               Map<String, 
AccessResult> mapValue = mapEntry.getValue();
+
+                                                               
mapValue.remove(accessType);
+
+                                                               if 
(mapValue.isEmpty()) {
+                                                                       if 
(keysToRemove == null) {
+                                                                               
keysToRemove = new ArrayList<>();
+                                                                       }
+
+                                                                       
keysToRemove.add(mapEntry.getKey());
+                                                               }
+                                                       }
+                                               }
+
+
+                                               if (keysToRemove != null) {
+                                                       for (String keyToRemove 
: keysToRemove) {
+                                                               
groupsAccessInfo.remove(keyToRemove);
+                                                       }
+
+                                                       keysToRemove.clear();
+                                               }
+                                       }
+                               }
+
+                       }
+               }
+
+               private void addAccess(String accessorName, AccessorType 
accessorType, String accessType, Integer access, int policyItemType) {
+                       final Map<String, Map<String, AccessResult>> 
accessorsAccessInfo;
+
+                       switch (accessorType) {
+                               case USER:
+                                       accessorsAccessInfo = usersAccessInfo;
+                                       break;
+
+                               case GROUP:
+                                       accessorsAccessInfo = groupsAccessInfo;
+                                       break;
+
+                               default:
+                                       return;
+                       }
+
+                       final Map<String, AccessResult> accessorAccessInfo = 
accessorsAccessInfo.computeIfAbsent(accessorName, k -> new HashMap<>());
+                       final AccessResult              currentAccess      = 
accessorAccessInfo.get(accessType);
+
+                       if (currentAccess == null) {
+                               if (policyItemType == POLICY_ITEM_TYPE_ALLOW || 
policyItemType == POLICY_ITEM_TYPE_DENY) {
+                                       accessorAccessInfo.put(accessType, new 
AccessResult(access, policyItemType == POLICY_ITEM_TYPE_DENY));
+                               }
+                       } else {
+                               if 
(access.equals(RangerPolicyEvaluator.ACCESS_DENIED)) {
+                                       if (currentAccess.getResult() == 
ACCESS_CONDITIONAL) {
+                                               currentAccess.setResult(access);
+                                       } else {
+                                               int updatedAccessValue = 
currentAccess.getResult() + access;
+
+                                               if (policyItemType == 
POLICY_ITEM_TYPE_DENY) {
+                                                       updatedAccessValue = 
(updatedAccessValue < ACCESS_DENIED) ? ACCESS_DENIED : updatedAccessValue;
+                                               } else {
+                                                       updatedAccessValue = 
(updatedAccessValue < ACCESS_UNDETERMINED) ? ACCESS_UNDETERMINED : 
updatedAccessValue;
+                                               }
+
+                                               
currentAccess.setResult(updatedAccessValue);
+                                       }
+                               } else if 
(access.equals(RangerPolicyEvaluator.ACCESS_ALLOWED)) {
+                                       if (currentAccess.getResult() == 
ACCESS_CONDITIONAL) {
+                                               if (policyItemType == 
POLICY_ITEM_TYPE_ALLOW) {
+                                                       
currentAccess.setResult(access);
+                                               }
+                                       } else {
+                                               int     updatedAccessValue = 
currentAccess.getResult() + access;
+                                               boolean replaceValue       = 
false;
+
+                                               if (policyItemType == 
POLICY_ITEM_TYPE_ALLOW) {
+                                                       updatedAccessValue = 
(updatedAccessValue > ACCESS_ALLOWED) ? ACCESS_ALLOWED : updatedAccessValue;
+                                                       replaceValue       = 
true;            // Forget earlier stashed hasSeenDeny
+                                               } else {
+                                                       updatedAccessValue = 
(updatedAccessValue > ACCESS_UNDETERMINED) ? ACCESS_UNDETERMINED : 
updatedAccessValue;
+                                               }
+
+                                               if (replaceValue) {
+                                                       
accessorAccessInfo.put(accessType, new AccessResult(updatedAccessValue));
+                                               } else {
+                                                       
currentAccess.setResult(updatedAccessValue);
+                                               }
+                                       }
+                               } else {
+                                       if (currentAccess.getResult() == 
ACCESS_UNDETERMINED) {
+                                               currentAccess.setResult(access);
+                                       }
+                               }
+                       }
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index bd61cfd..be0ab7d 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -67,5 +67,4 @@ public interface RangerPolicyItemEvaluator {
                }
        }
        void updateAccessResult(RangerAccessResult result, 
RangerPolicyResourceMatcher.MatchType matchType, RangerPolicy policy);
-
 }

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
new file mode 100644
index 0000000..ef7194f
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContext.java
@@ -0,0 +1,230 @@
+/*
+ * 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.service;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerAccessResultProcessor;
+import org.apache.ranger.plugin.policyengine.RangerMutableResource;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
+import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class RangerAuthContext implements RangerPolicyEngine {
+    private RangerPolicyEngine policyEngine;
+    private Map<RangerContextEnricher, Object> requestContextEnrichers;
+
+    protected RangerAuthContext() {
+        this(null, null);
+    }
+
+    RangerAuthContext(RangerPolicyEngine policyEngine, 
Map<RangerContextEnricher, Object> requestContextEnrichers) {
+        this.policyEngine = policyEngine;
+        this.requestContextEnrichers = requestContextEnrichers;
+    }
+
+    RangerAuthContext(RangerAuthContext other) {
+       if (other != null) {
+                   this.policyEngine = other.getPolicyEngine();
+                   Map<RangerContextEnricher, Object> localReference = 
other.requestContextEnrichers;
+                   if (MapUtils.isNotEmpty(localReference)) {
+                           this.requestContextEnrichers = new 
HashMap<>(localReference);
+                   }
+           }
+    }
+    public RangerPolicyEngine getPolicyEngine() {
+        return policyEngine;
+    }
+
+    void setPolicyEngine(RangerPolicyEngine policyEngine) { this.policyEngine 
= policyEngine; }
+
+    public Map<RangerContextEnricher, Object> getRequestContextEnrichers() {
+        return requestContextEnrichers;
+    }
+
+    public void addOrReplaceRequestContextEnricher(RangerContextEnricher 
enricher, Object database) {
+        if (requestContextEnrichers == null) {
+            requestContextEnrichers = new HashMap<>();
+        }
+
+        requestContextEnrichers.put(enricher, database);
+    }
+
+    @Override
+    public void setUseForwardedIPAddress(boolean useForwardedIPAddress) {
+        policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
+    }
+
+    @Override
+    public void setTrustedProxyAddresses(String[] trustedProxyAddresses) {
+        policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
+    }
+
+    @Override
+    public RangerServiceDef getServiceDef() {
+        return policyEngine.getServiceDef();
+    }
+
+    @Override
+    public long getPolicyVersion() {
+        return policyEngine.getPolicyVersion();
+    }
+
+    public Collection<RangerAccessResult> 
isAccessAllowed(Collection<RangerAccessRequest> requests, 
RangerAccessResultProcessor resultProcessor) {
+        preProcess(requests);
+        return policyEngine.evaluatePolicies(requests, 
RangerPolicy.POLICY_TYPE_ACCESS, resultProcessor);
+    }
+
+    public RangerAccessResult isAccessAllowed(RangerAccessRequest request, 
RangerAccessResultProcessor resultProcessor) {
+        preProcess(request);
+        return policyEngine.evaluatePolicies(request, 
RangerPolicy.POLICY_TYPE_ACCESS, resultProcessor);
+    }
+
+    public RangerAccessResult evalDataMaskPolicies(RangerAccessRequest 
request, RangerAccessResultProcessor resultProcessor) {
+        preProcess(request);
+        return policyEngine.evaluatePolicies(request, 
RangerPolicy.POLICY_TYPE_DATAMASK, resultProcessor);
+    }
+
+    public RangerAccessResult evalRowFilterPolicies(RangerAccessRequest 
request, RangerAccessResultProcessor resultProcessor) {
+        preProcess(request);
+        return policyEngine.evaluatePolicies(request, 
RangerPolicy.POLICY_TYPE_ROWFILTER, resultProcessor);
+    }
+
+    @Override
+    public void preProcess(RangerAccessRequest request) {
+
+        RangerAccessResource resource = request.getResource();
+        if (resource.getServiceDef() == null) {
+               if (resource instanceof RangerMutableResource) {
+                       RangerMutableResource mutable = (RangerMutableResource) 
resource;
+                       mutable.setServiceDef(getServiceDef());
+               }
+        }
+
+           if (MapUtils.isNotEmpty(requestContextEnrichers)) {
+            for (Map.Entry<RangerContextEnricher, Object> entry : 
requestContextEnrichers.entrySet()) {
+                entry.getKey().enrich(request);
+            }
+        }
+    }
+
+    @Override
+    public void preProcess(Collection<RangerAccessRequest> requests) {
+        if (CollectionUtils.isNotEmpty(requests)) {
+            for (RangerAccessRequest request : requests) {
+                preProcess(request);
+            }
+        }
+    }
+
+    @Override
+    public RangerAccessResult evaluatePolicies(RangerAccessRequest request, 
int policyType, RangerAccessResultProcessor resultProcessor) {
+        return policyEngine.evaluatePolicies(request, policyType, 
resultProcessor);
+    }
+
+    @Override
+    public Collection<RangerAccessResult> 
evaluatePolicies(Collection<RangerAccessRequest> requests, int policyType, 
RangerAccessResultProcessor resultProcessor) {
+        return policyEngine.evaluatePolicies(requests, policyType, 
resultProcessor);
+    }
+
+       @Override
+       public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+               preProcess(request);
+               return policyEngine.getResourceACLs(request);
+       }
+
+    @Override
+    public boolean preCleanup() {
+        return policyEngine.preCleanup();
+    }
+
+    @Override
+    public void cleanup() {
+        policyEngine.cleanup();
+    }
+
+    @Override
+    public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest 
request) {
+        preProcess(request);
+        return policyEngine.getResourceAccessInfo(request);
+    }
+
+    @Override
+    public List<RangerPolicy> getMatchingPolicies(RangerAccessResource 
resource) {
+        RangerAccessRequestImpl request = new 
RangerAccessRequestImpl(resource, RangerPolicyEngine.ANY_ACCESS, null, null);
+        preProcess(request);
+        return getMatchingPolicies(request);
+    }
+
+    @Override
+    public List<RangerPolicy> getMatchingPolicies(RangerAccessRequest request) 
{
+        return policyEngine.getMatchingPolicies(request);
+    }
+
+    /* This API is called for a long running policy-engine. Not needed here */
+    @Override
+    public void reorderPolicyEvaluators() {
+    }
+
+    /* The following APIs are used only by ranger-admin. Providing dummy 
implementation */
+    @Override
+    public boolean isAccessAllowed(RangerAccessResource resource, String user, 
Set<String> userGroups, String accessType) {
+        return false;
+    }
+
+    @Override
+       public boolean isAccessAllowed(RangerPolicy policy, String user, 
Set<String> userGroups, String accessType) {
+       return false;
+    }
+
+       @Override
+    public boolean isAccessAllowed(Map<String, 
RangerPolicy.RangerPolicyResource> resources, String user, Set<String> 
userGroups, String accessType) {
+        return false;
+    }
+
+    @Override
+    public List<RangerPolicy> getExactMatchPolicies(Map<String, 
RangerPolicy.RangerPolicyResource> resources, Map<String, Object> evalContext) {
+        return null;
+    }
+
+    @Override
+    public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource 
resource, Map<String, Object> evalContext) {
+        return null;
+    }
+
+    @Override
+    public List<RangerPolicy> getAllowedPolicies(String user, Set<String> 
userGroups, String accessType) {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContextListener.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContextListener.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContextListener.java
new file mode 100644
index 0000000..b980552
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerAuthContextListener.java
@@ -0,0 +1,25 @@
+/*
+ * 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.service;
+
+
+public interface RangerAuthContextListener {
+    void contextChanged();
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/3b510f8c/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index 725ed74..e40d223 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -25,6 +25,7 @@ import java.util.Hashtable;
 import java.util.Map;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -55,6 +56,8 @@ public class RangerBasePlugin {
 
        public static final char 
RANGER_TRUSTED_PROXY_IPADDRESSES_SEPARATOR_CHAR = ',';
 
+       private static Map<String, RangerBasePlugin> servicePluginMap = new 
ConcurrentHashMap<>();
+
        private String                    serviceType;
        private String                    appId;
        private String                    serviceName;
@@ -62,16 +65,24 @@ public class RangerBasePlugin {
        private PolicyRefresher           refresher;
        private RangerPolicyEngine        policyEngine;
        private RangerPolicyEngineOptions policyEngineOptions = new 
RangerPolicyEngineOptions();
+       private RangerAuthContext         currentAuthContext;
+       private RangerAuthContext         readOnlyAuthContext;
        private RangerAccessResultProcessor resultProcessor;
        private boolean                   useForwardedIPAddress;
        private String[]                  trustedProxyAddresses;
        private Timer                     policyEngineRefreshTimer;
+       private RangerAuthContextListener authContextListener;
+
 
        Map<String, LogHistory> logHistoryList = new Hashtable<String, 
RangerBasePlugin.LogHistory>();
        int logInterval = 30000; // 30 seconds
 
+       public static Map<String, RangerBasePlugin> getServicePluginMap() {
+               return servicePluginMap;
+       }
 
        public RangerBasePlugin(String serviceType, String appId) {
+
                this.serviceType = serviceType;
                this.appId       = appId;
        }
@@ -84,6 +95,12 @@ public class RangerBasePlugin {
                return clusterName;
        }
 
+       public RangerAuthContext createRangerAuthContext() {
+               return new RangerAuthContext(readOnlyAuthContext);
+       }
+
+       public RangerAuthContext getCurrentRangerAuthContext() { return 
currentAuthContext; }
+
        public void setClusterName(String clusterName) {
                this.clusterName = clusterName;
        }
@@ -144,6 +161,8 @@ public class RangerBasePlugin {
 
                LOG.info(policyEngineOptions);
 
+               servicePluginMap.put(serviceName, this);
+
                RangerAdminClient admin = createAdminClient(serviceName, appId, 
propertyPrefix);
 
                refresher = new PolicyRefresher(this, serviceType, appId, 
serviceName, admin, pollingIntervalMs, cacheDir);
@@ -187,13 +206,17 @@ public class RangerBasePlugin {
                        }
                        if (policies == null) {
                                this.policyEngine = null;
+                               readOnlyAuthContext = null;
                        } else {
+                               currentAuthContext = new RangerAuthContext();
                                RangerPolicyEngine policyEngine = new 
RangerPolicyEngineImpl(appId, policies, policyEngineOptions);
                                
policyEngine.setUseForwardedIPAddress(useForwardedIPAddress);
                                
policyEngine.setTrustedProxyAddresses(trustedProxyAddresses);
-
                                this.policyEngine = policyEngine;
+                               
currentAuthContext.setPolicyEngine(this.policyEngine);
+                               readOnlyAuthContext = new 
RangerAuthContext(currentAuthContext);
                        }
+                       contextChanged();
 
                        if (oldPolicyEngine != null && 
!oldPolicyEngine.preCleanup()) {
                                LOG.error("preCleanup() failed on the previous 
policy engine instance !!");
@@ -203,6 +226,14 @@ public class RangerBasePlugin {
                }
        }
 
+       public void contextChanged() {
+               RangerAuthContextListener authContextListener = 
this.authContextListener;
+
+               if (authContextListener != null) {
+                       authContextListener.contextChanged();
+               }
+       }
+
        public void cleanup() {
 
                PolicyRefresher refresher = this.refresher;
@@ -358,6 +389,13 @@ public class RangerBasePlugin {
                }
        }
 
+       public void registerAuthContextEventListener(RangerAuthContextListener 
authContextListener) {
+               this.authContextListener = authContextListener;
+       }
+       public void 
unregisterAuthContextEventListener(RangerAuthContextListener 
authContextListener) {
+               this.authContextListener = null;
+       }
+
        public static RangerAdminClient createAdminClient(String 
rangerServiceName, String applicationId, String propertyPrefix) {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> RangerBasePlugin.createAdminClient(" + 
rangerServiceName + ", " + applicationId + ", " + propertyPrefix + ")");

Reply via email to