This is an automated email from the ASF dual-hosted git repository.

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 0558fa9cc RANGER-4507: refactoring to move security-zone finder to 
RangerSecurityZoneMatcher
0558fa9cc is described below

commit 0558fa9cc63ab3ea17c42b471a7e6b834bc368fa
Author: Madhan Neethiraj <mad...@apache.org>
AuthorDate: Tue Oct 31 13:14:19 2023 -0700

    RANGER-4507: refactoring to move security-zone finder to 
RangerSecurityZoneMatcher
---
 .../ranger/plugin/policyengine/PolicyEngine.java   | 177 ++---------------
 .../policyengine/RangerSecurityZoneMatcher.java    | 209 +++++++++++++++++++++
 .../ranger/plugin/service/RangerAuthContext.java   |  13 +-
 .../plugin/policyengine/TestPolicyEngine.java      |  13 +-
 .../TestRangerSecurityZoneMatcher.java             | 159 ++++++++++++++++
 5 files changed, 397 insertions(+), 174 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
index 063b685d0..858c3f542 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
@@ -24,7 +24,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -37,20 +36,17 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicyDelta;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
-import org.apache.ranger.plugin.model.validation.RangerZoneResourceMatcher;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
-import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher;
 import org.apache.ranger.plugin.service.RangerAuthContext;
-import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerPolicyDeltaUtil;
-import org.apache.ranger.plugin.util.RangerResourceEvaluatorsRetriever;
 import org.apache.ranger.plugin.util.RangerReadWriteLock;
 import org.apache.ranger.plugin.util.RangerRoles;
 import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.apache.ranger.plugin.util.ServicePolicies;
 import org.apache.ranger.plugin.util.StringTokenReplacer;
+import org.apache.ranger.plugin.util.RangerUserStore;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -66,8 +62,7 @@ public class PolicyEngine {
     private final List<RangerContextEnricher>         allContextEnrichers;
     private final RangerPluginContext                 pluginContext;
     private final Map<String, RangerPolicyRepository> zonePolicyRepositories = 
new HashMap<>();
-    private final Map<String, RangerResourceTrie<RangerZoneResourceMatcher>>   
  resourceZoneTrie = new HashMap<>();
-    private final Map<String, String>                 zoneTagServiceMap = new 
HashMap<>();
+    private final RangerSecurityZoneMatcher           zoneMatcher;
     private       boolean                             useForwardedIPAddress;
     private       String[]                            trustedProxyAddresses;
     private final Map<String, StringTokenReplacer>    tokenReplacers = new 
HashMap<>();
@@ -189,8 +184,8 @@ public class PolicyEngine {
         return zoneResourceRepository == null ? Collections.emptyList() : 
zoneResourceRepository.getPolicies();
     }
 
-    Map<String, RangerResourceTrie<RangerZoneResourceMatcher>> 
getResourceZoneTrie() {
-        return resourceZoneTrie;
+    RangerSecurityZoneMatcher getZoneMatcher() {
+        return zoneMatcher;
     }
 
     public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext 
pluginContext, RangerRoles roles, boolean isUseReadWriteLock) {
@@ -213,6 +208,7 @@ public class PolicyEngine {
 
         this.pluginContext = pluginContext;
         this.lock          = new RangerReadWriteLock(isUseReadWriteLock);
+        this.zoneMatcher   = new 
RangerSecurityZoneMatcher(servicePolicies.getSecurityZones(), 
servicePolicies.getServiceDef(), pluginContext);
 
         Boolean                  hasPolicyDeltas      = 
RangerPolicyDeltaUtil.hasPolicyDeltas(servicePolicies);
 
@@ -224,7 +220,11 @@ public class PolicyEngine {
             }
         }
 
-        this.pluginContext.setAuthContext(new RangerAuthContext(null, roles));
+        RangerAuthContext currAuthContext = pluginContext.getAuthContext();
+        RangerUserStore   userStore       = currAuthContext != null ? 
currAuthContext.getUserStoreUtil().getUserStore() : null;
+        RangerAuthContext authContext     = new RangerAuthContext(null, 
zoneMatcher, roles, userStore);
+
+        this.pluginContext.setAuthContext(authContext);
 
         RangerPolicyEngineOptions options = 
pluginContext.getConfig().getPolicyEngineOptions();
 
@@ -271,8 +271,6 @@ public class PolicyEngine {
         this.allContextEnrichers = tmpList;
 
         if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
-            buildZoneTrie(servicePolicies);
-
             for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone : 
servicePolicies.getSecurityZones().entrySet()) {
                 RangerPolicyRepository policyRepository = new 
RangerPolicyRepository(servicePolicies, this.pluginContext, zone.getKey());
 
@@ -386,29 +384,27 @@ public class PolicyEngine {
     }
 
     public Set<String> getMatchedZonesForResourceAndChildren(Map<String, ?> 
resource) {
-        return 
getMatchedZonesForResourceAndChildren(convertToAccessResource(resource));
-    }
+        Set<String> ret = zoneMatcher.getZonesForResourceAndChildren(resource);
 
-    public Set<String> 
getMatchedZonesForResourceAndChildren(RangerAccessResource accessResource) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + accessResource + ")");
+            LOG.debug("getMatchedZonesForResourceAndChildren(resource={}): 
ret={}", resource, ret);
         }
 
-        Set<String> ret = null;
+        return ret;
+    }
 
-        if (MapUtils.isNotEmpty(this.resourceZoneTrie)) {
-            ret = 
getMatchedZonesForResourceAndChildren(accessResource.getAsMap(), 
accessResource);
-        }
+    public Set<String> 
getMatchedZonesForResourceAndChildren(RangerAccessResource resource) {
+        Set<String> ret = zoneMatcher.getZonesForResourceAndChildren(resource);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + accessResource + ") : " 
+ ret);
+            LOG.debug("getMatchedZonesForResourceAndChildren(resource={}): 
ret={}", resource, ret);
         }
 
         return ret;
     }
 
     public String getUniquelyMatchedZoneName(Map<String, ?> resourceAsMap) {
-        Set<String> matchedZones = 
getMatchedZonesForResourceAndChildren(resourceAsMap, 
convertToAccessResource(resourceAsMap));
+        Set<String> matchedZones = 
zoneMatcher.getZonesForResourceAndChildren(resourceAsMap);
         String      ret          = (matchedZones != null && 
matchedZones.size() == 1) ? matchedZones.iterator().next() : null;
 
         if (LOG.isDebugEnabled()) {
@@ -449,7 +445,7 @@ public class PolicyEngine {
     public boolean isResourceZoneAssociatedWithTagService(String 
resourceZoneName) {
         final boolean ret;
 
-        if (StringUtils.isNotEmpty(resourceZoneName) && tagPolicyRepository != 
null && zoneTagServiceMap.get(resourceZoneName) != null) {
+        if (StringUtils.isNotEmpty(resourceZoneName) && tagPolicyRepository != 
null && zoneMatcher.hasTagService(resourceZoneName)) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Accessed resource is in a zone:[" + 
resourceZoneName + "] which is associated with the tag-service:[" + 
tagPolicyRepository.getServiceName() + "]");
             }
@@ -512,76 +508,13 @@ public class PolicyEngine {
         }
     }
 
-    private Set<String> getMatchedZonesForResourceAndChildren(Map<String, ?> 
resource, RangerAccessResource accessResource) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("==> 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + resource + ", " + 
accessResource + ")");
-        }
-
-        Set<String> ret = null;
-
-        if (MapUtils.isNotEmpty(this.resourceZoneTrie)) {
-
-            Collection<RangerZoneResourceMatcher> smallestList = 
RangerResourceEvaluatorsRetriever.getEvaluators(resourceZoneTrie, resource);
-
-            if (CollectionUtils.isNotEmpty(smallestList)) {
-
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Resource:[" + resource + "], matched-zones:[" + 
smallestList + "]");
-                }
-
-                ret = new HashSet<>();
-
-                for (RangerZoneResourceMatcher zoneMatcher : smallestList) {
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("Trying to match resource:[" + 
accessResource + "] using zoneMatcher:[" + zoneMatcher + "]");
-                    }
-
-                    // These are potential matches. Try to really match them
-                    if 
(zoneMatcher.getPolicyResourceMatcher().isMatch(accessResource, 
RangerPolicyResourceMatcher.MatchScope.ANY, null)) {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("Matched resource:[" + accessResource + 
"] using zoneMatcher:[" + zoneMatcher + "]");
-                        }
-
-                        // Actual match happened
-                        ret.add(zoneMatcher.getSecurityZoneName());
-                    } else {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("Did not match resource:[" + 
accessResource + "] using zoneMatcher:[" + zoneMatcher + "]");
-                        }
-                    }
-                }
-
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("The following zone-names matched resource:[" + 
accessResource + "]: " + ret);
-                }
-            }
-        }
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("<== 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + resource + ", " + 
accessResource + ") : " + ret);
-        }
-
-        return ret;
-    }
-
-    private RangerAccessResource convertToAccessResource(Map<String, ?> 
resource) {
-        RangerAccessResourceImpl ret = new RangerAccessResourceImpl();
-
-        ret.setServiceDef(getServiceDef());
-
-        for (Map.Entry<String, ?> entry : resource.entrySet()) {
-            ret.setValue(entry.getKey(), entry.getValue());
-        }
-
-        return ret;
-    }
-
     private PolicyEngine(final PolicyEngine other, ServicePolicies 
servicePolicies) {
         this.useForwardedIPAddress = other.useForwardedIPAddress;
         this.trustedProxyAddresses = other.trustedProxyAddresses;
         this.serviceDefHelper      = other.serviceDefHelper;
         this.pluginContext         = other.pluginContext;
         this.lock                  = other.lock;
+        this.zoneMatcher           = new 
RangerSecurityZoneMatcher(servicePolicies.getSecurityZones(), 
servicePolicies.getServiceDef(), pluginContext);
 
         long                    policyVersion                   = 
servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion() 
: -1L;
         List<RangerPolicyDelta> defaultZoneDeltas               = new 
ArrayList<>();
@@ -666,74 +599,6 @@ public class PolicyEngine {
         reorderPolicyEvaluators();
     }
 
-    private void buildZoneTrie(ServicePolicies servicePolicies) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("==> PolicyEngine.buildZoneTrie()");
-        }
-
-        Map<String, ServicePolicies.SecurityZoneInfo> securityZones = 
servicePolicies.getSecurityZones();
-
-        if (MapUtils.isNotEmpty(securityZones)) {
-            RangerServiceDef                serviceDef = 
servicePolicies.getServiceDef();
-            List<RangerZoneResourceMatcher> matchers   = new ArrayList<>();
-
-            for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> 
securityZone : securityZones.entrySet()) {
-                String                           zoneName    = 
securityZone.getKey();
-                ServicePolicies.SecurityZoneInfo zoneDetails = 
securityZone.getValue();
-
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Building matchers for zone:[" + zoneName +"]");
-                }
-
-                for (Map<String, List<String>> resource : 
zoneDetails.getResources()) {
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("Building matcher for resource:[" + resource 
+ "] in zone:[" + zoneName +"]");
-                    }
-
-                    Map<String, RangerPolicy.RangerPolicyResource> 
policyResources = new HashMap<>();
-
-                    for (Map.Entry<String, List<String>> entry : 
resource.entrySet()) {
-                        String                            resourceDefName = 
entry.getKey();
-                        List<String>                      resourceValues  = 
entry.getValue();
-                        RangerPolicy.RangerPolicyResource policyResource  = 
new RangerPolicy.RangerPolicyResource();
-                        policyResource.setIsExcludes(false);
-                        
policyResource.setIsRecursive(EmbeddedServiceDefsUtil.isRecursiveEnabled(serviceDef,
 resourceDefName));
-                        policyResource.setValues(resourceValues);
-                        policyResources.put(resourceDefName, policyResource);
-                    }
-
-                    matchers.add(new RangerZoneResourceMatcher(zoneName, 
policyResources, serviceDef));
-
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("Built matcher for resource:[" + resource 
+"] in zone:[" + zoneName + "]");
-                    }
-                }
-
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Built all matchers for zone:[" + zoneName +"]");
-                }
-
-                if (zoneDetails.getContainsAssociatedTagService()) {
-                    zoneTagServiceMap.put(zoneName, zoneName);
-                }
-            }
-
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Built matchers for all Zones");
-            }
-
-            RangerPolicyEngineOptions options = 
pluginContext.getConfig().getPolicyEngineOptions();
-
-            for (RangerServiceDef.RangerResourceDef resourceDef : 
serviceDef.getResources()) {
-                resourceZoneTrie.put(resourceDef.getName(), new 
RangerResourceTrie<>(resourceDef, matchers, options.optimizeTrieForSpace, 
options.optimizeTrieForRetrieval, pluginContext));
-            }
-        }
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("<== PolicyEngine.buildZoneTrie()");
-        }
-    }
-
     private RangerPolicyRepository shareWith(RangerPolicyRepository other) {
         if (other != null) {
             other.setShared();
@@ -839,8 +704,6 @@ public class PolicyEngine {
         }
 
         if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
-            buildZoneTrie(servicePolicies);
-
             Map<String, List<RangerPolicyDelta>> zoneDeltasMap = new 
HashMap<>();
 
             for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone : 
servicePolicies.getSecurityZones().entrySet()) {
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerSecurityZoneMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerSecurityZoneMatcher.java
new file mode 100644
index 000000000..a36eda0b8
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerSecurityZoneMatcher.java
@@ -0,0 +1,209 @@
+/*
+ * 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.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.validation.RangerZoneResourceMatcher;
+import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.plugin.util.RangerResourceEvaluatorsRetriever;
+import org.apache.ranger.plugin.util.ServicePolicies.SecurityZoneInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class RangerSecurityZoneMatcher {
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerSecurityZoneMatcher.class);
+
+    private final Map<String, RangerResourceTrie<RangerZoneResourceMatcher>> 
resourceZoneTrie;
+    private final Set<String>                                                
zonesWithTagService;
+    private final RangerServiceDef                                           
serviceDef;
+
+    public RangerSecurityZoneMatcher(Map<String, SecurityZoneInfo> 
securityZones, RangerServiceDef serviceDef, RangerPluginContext pluginContext) {
+        this.resourceZoneTrie    = new HashMap<>();
+        this.zonesWithTagService = new HashSet<>();
+        this.serviceDef          = serviceDef;
+
+        buildZoneTrie(securityZones, serviceDef, pluginContext);
+    }
+
+    public boolean hasTagService(String zoneName) {
+        return zonesWithTagService.contains(zoneName);
+    }
+
+    public Set<String> getZonesForResourceAndChildren(Map<String, ?> resource) 
{
+        return getZonesForResourceAndChildren(resource, 
convertToAccessResource(resource));
+    }
+
+    public Set<String> getZonesForResourceAndChildren(RangerAccessResource 
resource) {
+        return getZonesForResourceAndChildren(resource.getAsMap(), resource);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        } else if (obj == null || !getClass().equals(obj.getClass())) {
+            return false;
+        }
+
+        RangerSecurityZoneMatcher other = (RangerSecurityZoneMatcher) obj;
+
+        return Objects.equals(resourceZoneTrie, other.resourceZoneTrie) &&
+               Objects.equals(zonesWithTagService, other.zonesWithTagService);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(resourceZoneTrie, zonesWithTagService);
+    }
+
+    private Set<String> getZonesForResourceAndChildren(Map<String, ?> 
resource, RangerAccessResource accessResource) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> 
RangerSecurityZoneMatcher.getZonesForResourceAndChildren({})", accessResource);
+        }
+
+        Set<String> ret = null;
+
+        if (MapUtils.isNotEmpty(this.resourceZoneTrie)) {
+            Collection<RangerZoneResourceMatcher> matchers = 
RangerResourceEvaluatorsRetriever.getEvaluators(resourceZoneTrie, resource);
+
+            if (CollectionUtils.isNotEmpty(matchers)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Resource:[{}], matchers:[{}]", resource, 
matchers);
+                }
+
+                ret = new HashSet<>(matchers.size());
+
+                // These are potential matches. Try to really match them
+                for (RangerZoneResourceMatcher matcher : matchers) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Trying to match resource:[{}] using 
matcher:[{}]", accessResource, matcher);
+                    }
+
+                    if 
(matcher.getPolicyResourceMatcher().isMatch(accessResource, 
RangerPolicyResourceMatcher.MatchScope.ANY, null)) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Matched resource:[{}] using 
matcher:[{}]", accessResource, matcher);
+                        }
+
+                        // Actual match happened
+                        ret.add(matcher.getSecurityZoneName());
+                    } else {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Did not match resource:[{}] using 
matcher:[{}]", accessResource, matcher);
+                        }
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("zone-names matched resource:[{}]: {}", 
accessResource, ret);
+                }
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== 
RangerSecurityZoneMatcher.getZonesForResourceAndChildren({}): ret={}", 
accessResource, ret);
+        }
+
+        return ret;
+    }
+
+    private void buildZoneTrie(Map<String, SecurityZoneInfo> securityZones, 
RangerServiceDef serviceDef, RangerPluginContext pluginContext) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerSecurityZoneMatcher.buildZoneTrie()");
+        }
+
+        Map<String, Boolean> resourceIsRecursive = new HashMap<>();
+
+        if (MapUtils.isNotEmpty(securityZones)) {
+            List<RangerZoneResourceMatcher> matchers = new ArrayList<>();
+
+            for (Map.Entry<String, SecurityZoneInfo> securityZone : 
securityZones.entrySet()) {
+                String           zoneName    = securityZone.getKey();
+                SecurityZoneInfo zoneDetails = securityZone.getValue();
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Building matchers for zone:[{}]", zoneName);
+                }
+
+                for (Map<String, List<String>> resource : 
zoneDetails.getResources()) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Building matcher for resource:[{}] in 
zone:[{}]", resource, zoneName);
+                    }
+
+                    Map<String, RangerPolicyResource> policyResources = new 
HashMap<>();
+
+                    for (Map.Entry<String, List<String>> entry : 
resource.entrySet()) {
+                        String       resourceDefName = entry.getKey();
+                        List<String> resourceValues  = entry.getValue();
+                        Boolean      isRecursive     = 
resourceIsRecursive.computeIfAbsent(resourceDefName, f -> 
EmbeddedServiceDefsUtil.isRecursiveEnabled(serviceDef, resourceDefName));
+
+                        policyResources.put(resourceDefName, new 
RangerPolicyResource(resourceValues, false, isRecursive));
+                    }
+
+                    matchers.add(new RangerZoneResourceMatcher(zoneName, 
policyResources, serviceDef));
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Built matcher for resource:[{}] in 
zone:[{}]", resource, zoneName);
+                    }
+                }
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Built all matchers for zone:[{}]", zoneName);
+                }
+
+                if 
(Boolean.TRUE.equals(zoneDetails.getContainsAssociatedTagService())) {
+                    zonesWithTagService.add(zoneName);
+                }
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Built matchers for all Zones");
+            }
+
+            RangerPolicyEngineOptions options = 
pluginContext.getConfig().getPolicyEngineOptions();
+
+            for (RangerResourceDef resourceDef : serviceDef.getResources()) {
+                resourceZoneTrie.put(resourceDef.getName(), new 
RangerResourceTrie<>(resourceDef, matchers, options.optimizeTrieForSpace, 
options.optimizeTrieForRetrieval, pluginContext));
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerSecurityZoneMatcher.buildZoneTrie()");
+        }
+    }
+
+    private RangerAccessResource convertToAccessResource(Map<String, ?> 
resource) {
+        RangerAccessResourceImpl ret = new RangerAccessResourceImpl();
+
+        ret.setServiceDef(serviceDef);
+
+        for (Map.Entry<String, ?> entry : resource.entrySet()) {
+            ret.setValue(entry.getKey(), entry.getValue());
+        }
+
+        return ret;
+    }
+}
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
index 56e4d782d..f3da19fe5 100644
--- 
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
@@ -24,6 +24,7 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerSecurityZoneMatcher;
 import org.apache.ranger.plugin.util.RangerRoles;
 import org.apache.ranger.plugin.util.RangerRolesUtil;
 import org.apache.ranger.plugin.util.RangerUserStore;
@@ -36,15 +37,13 @@ import java.util.concurrent.ConcurrentHashMap;
 
 public class RangerAuthContext {
     private final Map<RangerContextEnricher, Object> requestContextEnrichers;
+    private final RangerSecurityZoneMatcher          zoneMatcher;
     private       RangerRolesUtil                    rolesUtil;
     private       RangerUserStoreUtil                userStoreUtil;
 
-    public RangerAuthContext(Map<RangerContextEnricher, Object> 
requestContextEnrichers, RangerRoles roles) {
-        this(requestContextEnrichers, roles, null);
-    }
-
-    public RangerAuthContext(Map<RangerContextEnricher, Object> 
requestContextEnrichers, RangerRoles roles, RangerUserStore userStore) {
+    public RangerAuthContext(Map<RangerContextEnricher, Object> 
requestContextEnrichers, RangerSecurityZoneMatcher zoneMatcher, RangerRoles 
roles, RangerUserStore userStore) {
         this.requestContextEnrichers = requestContextEnrichers != null ? 
requestContextEnrichers : new ConcurrentHashMap<>();
+        this.zoneMatcher             = zoneMatcher;;
 
         setRoles(roles);
         setUserStore(userStore);
@@ -54,6 +53,10 @@ public class RangerAuthContext {
         return requestContextEnrichers;
     }
 
+    public RangerSecurityZoneMatcher getZoneMatcher() {
+        return zoneMatcher;
+    }
+
     public void addOrReplaceRequestContextEnricher(RangerContextEnricher 
enricher, Object database) {
         // concurrentHashMap does not allow null to be inserted into it, so 
insert a dummy which is checked
         // when enrich() is called
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index ba2e6439e..fc24ca752 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -44,7 +44,6 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceResource;
 import org.apache.ranger.plugin.model.RangerValiditySchedule;
 import 
org.apache.ranger.plugin.model.validation.RangerValidityScheduleValidator;
-import org.apache.ranger.plugin.model.validation.RangerZoneResourceMatcher;
 import org.apache.ranger.plugin.model.validation.ValidationFailureDetails;
 import 
org.apache.ranger.plugin.policyengine.TestPolicyEngine.PolicyEngineTestCase.TestData;
 import 
org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.RangerPolicyResourceEvaluator;
@@ -986,17 +985,7 @@ public class TestPolicyEngine {
                }
 
                if (ret) {
-                       ret = Objects.equals(me.getResourceZoneTrie().keySet(), 
other.getResourceZoneTrie().keySet());
-
-                       if (ret) {
-                               for (Map.Entry<String, 
RangerResourceTrie<RangerZoneResourceMatcher>> entry : 
me.getResourceZoneTrie().entrySet()) {
-                                       ret = compareSubtree(entry.getValue(), 
other.getResourceZoneTrie().get(entry.getKey()));
-
-                                       if (!ret) {
-                                               break;
-                                       }
-                               }
-                       }
+                       ret = Objects.equals(me.getZoneMatcher(), 
other.getZoneMatcher());
                }
 
                if (ret) {
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerSecurityZoneMatcher.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerSecurityZoneMatcher.java
new file mode 100644
index 000000000..254184403
--- /dev/null
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerSecurityZoneMatcher.java
@@ -0,0 +1,159 @@
+/*
+ * 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.ranger.authorization.hadoop.config.RangerPluginConfig;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.util.ServicePolicies.SecurityZoneInfo;
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+public class TestRangerSecurityZoneMatcher {
+    final RangerPluginContext           pluginContext = new 
RangerPluginContext(new RangerPluginConfig("hive", null, "hive", "cl1", 
"on-prem", null));
+    final Map<String, SecurityZoneInfo> securityZones = createSecurityZones();
+    final RangerServiceDef              serviceDef    = createServiceDef();
+
+    @Test
+    public void testZoneMatcher() {
+        RangerSecurityZoneMatcher zoneMatcher = new 
RangerSecurityZoneMatcher(securityZones, serviceDef, pluginContext);
+
+        RangerAccessResource res;
+        Set<String>          zones;
+
+        res   = createResource("database", "db1", "table", "tbl1");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z1"), zones);
+
+        res   = createResource("database", "db2", "table", "tbl1");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z2"), zones);
+
+        res   = createResource("database", "db3", "table", "test_1");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z3"), zones);
+
+        res   = createResource("database", "db3", "table", "test_2");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z3"), zones);
+
+        res   = createResource("database", "db3", "table", "orders");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertNull(zones);
+
+        res   = createResource("database", "db3", "table", "user_1");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z4"), zones);
+
+        res   = createResource("database", "db3", "table", "user_2");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z4"), zones);
+
+        res   = createResource("database", "db3");
+        zones = zoneMatcher.getZonesForResourceAndChildren(res);
+        assertEquals(createSet("z3", "z4"), zones);
+    }
+
+    private Map<String, SecurityZoneInfo> createSecurityZones() {
+        HashMap<String, List<String>> db1     = new HashMap<String, 
List<String>>() {{ put("database", Arrays.asList("db1")); }};
+        HashMap<String, List<String>> db2     = new HashMap<String, 
List<String>>() {{ put("database", Arrays.asList("db2")); }};
+        HashMap<String, List<String>> db3Test = new HashMap<String, 
List<String>>() {{ put("database", Arrays.asList("db3")); put("table", 
Arrays.asList("test_*")); }};
+        HashMap<String, List<String>> db4User = new HashMap<String, 
List<String>>() {{ put("database", Arrays.asList("db3")); put("table", 
Arrays.asList("user_*")); }};
+
+        SecurityZoneInfo z1 = new SecurityZoneInfo();
+        SecurityZoneInfo z2 = new SecurityZoneInfo();
+        SecurityZoneInfo z3 = new SecurityZoneInfo();
+        SecurityZoneInfo z4 = new SecurityZoneInfo();
+
+        z1.setZoneName("z1");
+        z1.setResources(Arrays.asList(db1));
+
+        z2.setZoneName("z2");
+        z2.setResources(Arrays.asList(db2));
+
+        z3.setZoneName("z3");
+        z3.setResources(Arrays.asList(db3Test));
+
+        z4.setZoneName("z4");
+        z4.setResources(Arrays.asList(db4User));
+
+        Map<String, SecurityZoneInfo> ret = new HashMap<>();
+
+        ret.put(z1.getZoneName(), z1);
+        ret.put(z2.getZoneName(), z2);
+        ret.put(z3.getZoneName(), z3);
+        ret.put(z4.getZoneName(), z4);
+
+        return ret;
+    }
+
+    private RangerServiceDef createServiceDef() {
+        RangerServiceDef ret = new RangerServiceDef();
+
+        ret.setName("hive");
+        ret.setResources(createResourceDefs());
+
+        return ret;
+    }
+
+    private List<RangerResourceDef> createResourceDefs() {
+        List<RangerResourceDef> ret = new ArrayList<>();
+
+        ret.add(createResourceDef("database", null));
+        ret.add(createResourceDef("table",    "database"));
+        ret.add(createResourceDef("column",   "table"));
+
+        return ret;
+    }
+
+    private RangerResourceDef createResourceDef(String name, String parent) {
+        RangerResourceDef ret = new RangerResourceDef();
+
+        ret.setName(name);
+        ret.setType("string");
+        ret.setParent(parent);
+
+        return ret;
+    }
+
+    private RangerAccessResource createResource(String...args) {
+        RangerAccessResourceImpl ret = new RangerAccessResourceImpl();
+
+        for (int i = 1; i < args.length; i += 2) {
+            ret.setValue(args[i - 1], args[i]);
+        }
+
+        return ret;
+    }
+
+    private Set<String> createSet(String...args) {
+        Set<String> ret = new HashSet<>();
+
+        for (String arg : args) {
+            ret.add(arg);
+        }
+
+        return ret;
+    }
+}


Reply via email to