You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ranger.apache.org by Abhay Kulkarni <ak...@hortonworks.com> on 2015/03/14 05:12:34 UTC

Re: incubator-ranger git commit: RANGER-307: Policy evaluation optimization: reorder policies and short-circuit evaluation

Thanks, Madhan!

On 3/13/15, 7:50 PM, "madhan@apache.org" <ma...@apache.org> wrote:

>Repository: incubator-ranger
>Updated Branches:
>  refs/heads/master d4f2eb20f -> 2e0be82df
>
>
>RANGER-307: Policy evaluation optimization: reorder policies and
>short-circuit evaluation
>
>
>Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
>Commit: 
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/2e0be82d
>Tree: 
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/2e0be82d
>Diff: 
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/2e0be82d
>
>Branch: refs/heads/master
>Commit: 2e0be82df973a6f37e766b7e9fff2b41431d0db1
>Parents: d4f2eb2
>Author: Abhay Kulkarni <ak...@hortonworks.com>
>Authored: Fri Mar 13 19:50:19 2015 -0700
>Committer: Madhan Neethiraj <ma...@apache.org>
>Committed: Fri Mar 13 19:50:19 2015 -0700
>
>----------------------------------------------------------------------
> .../ranger/plugin/policyengine/CacheMap.java    |  40 +++
> .../plugin/policyengine/RangerAccessData.java   |  39 +++
> .../plugin/policyengine/RangerAccessResult.java |  32 ++-
> .../policyengine/RangerPolicyEngineImpl.java    | 149 ++---------
> .../RangerPolicyEvaluatorFacade.java            | 128 ++++++++++
> .../policyengine/RangerPolicyRepository.java    | 231 +++++++++++++++++
> .../RangerDefaultPolicyEvaluator.java           | 223 ++++++++++-------
> .../RangerOptimizedPolicyEvaluator.java         | 247 +++++++++++++++++++
> .../RangerDefaultPolicyEvaluatorTest.java       |   8 +-
> .../policyengine/test_policyengine_hdfs.json    |   2 +-
> pom.xml                                         |   2 +-
> src/main/assembly/ranger-src.xml                |  83 ++++---
> 12 files changed, 913 insertions(+), 271 deletions(-)
>----------------------------------------------------------------------
>
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyengine/CacheMap.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/CacheM
>ap
>.java 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/CacheM
>ap
>.java
>new file mode 100644
>index 0000000..0a1566c
>--- /dev/null
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/CacheM
>ap
>.java
>@@ -0,0 +1,40 @@
>+/*
>+ * 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 java.util.LinkedHashMap;
>+import java.util.Map;
>+
>+
>+public class CacheMap<K, V> extends LinkedHashMap<K, V> {
>+    private static final float RANGER_CACHE_DEFAULT_LOAD_FACTOR = 0.75f;
>+
>+    protected int maxCapacity;
>+
>+    public CacheMap(int maxCapacity) {
>+        super(maxCapacity, CacheMap.RANGER_CACHE_DEFAULT_LOAD_FACTOR,
>true); // true for access-order
>+
>+        this.maxCapacity = maxCapacity;
>+    }
>+
>+    @Override
>+    protected boolean removeEldestEntry(Map.Entry eldest) {
>+        return size() > maxCapacity;
>+    }
>+}
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessD
>at
>a.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessData.java 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessData.java
>new file mode 100644
>index 0000000..34f7428
>--- /dev/null
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessData.java
>@@ -0,0 +1,39 @@
>+/*
>+ * 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;
>+
>+
>+public class RangerAccessData<T> {
>+    private String accessFDN    = null;
>+    private T accessDetails    = null;
>+
>+    public RangerAccessData(String accessFDN) {
>+        this.accessFDN = accessFDN;
>+    }
>+    public String getAccessFDN() {
>+        return accessFDN;
>+    }
>+    public T getAccessDetails() {
>+        return accessDetails;
>+    }
>+    public void setAccessDetails(T accessDetails) {
>+        this.accessDetails = accessDetails;
>+    }
>+}
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessR
>es
>ult.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessResult.java 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessResult.java
>index 2eaec16..3a1fa1d 100644
>--- 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessResult.java
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Ac
>cessResult.java
>@@ -27,23 +27,23 @@ public class RangerAccessResult {
> 	private RangerServiceDef    serviceDef  = null;
> 	private RangerAccessRequest request     = null;
> 
>+	private boolean isAccessDetermined = false;
> 	private boolean  isAllowed = false;
>+	private boolean isAuditedDetermined = false;
> 	private boolean  isAudited = false;
> 	private long     policyId  = -1;
> 	private String   reason    = null;
> 
> 	public RangerAccessResult(String serviceName, RangerServiceDef
>serviceDef, RangerAccessRequest request) {
>-		this(serviceName, serviceDef, request, false, false, -1, null);
>-	}
>-
>-	public RangerAccessResult(String serviceName, RangerServiceDef
>serviceDef, RangerAccessRequest request, boolean isAllowed, boolean
>isAudited, long policyId, String reason) {
> 		this.serviceName = serviceName;
> 		this.serviceDef  = serviceDef;
> 		this.request     = request;
>-		this.isAllowed   = isAllowed;
>-		this.isAudited   = isAudited;
>-		this.policyId    = policyId;
>-		this.reason      = reason;
>+		this.isAccessDetermined = false;
>+		this.isAllowed   = false;
>+		this.isAuditedDetermined = false;
>+		this.isAudited   = false;
>+		this.policyId    = -1;
>+		this.reason      = null;
> 	}
> 
> 	/**
>@@ -67,6 +67,10 @@ public class RangerAccessResult {
> 		return request;
> 	}
> 
>+	public boolean getIsAccessDetermined() { return isAccessDetermined; }
>+
>+	private void setIsAccessDetermined(boolean value) { isAccessDetermined =
>value; }
>+
> 	/**
> 	 * @return the isAllowed
> 	 */
>@@ -78,6 +82,7 @@ public class RangerAccessResult {
> 	 * @param isAllowed the isAllowed to set
> 	 */
> 	public void setIsAllowed(boolean isAllowed) {
>+		setIsAccessDetermined(true);
> 		this.isAllowed = isAllowed;
> 	}
> 
>@@ -87,6 +92,10 @@ public class RangerAccessResult {
> 	public void setReason(String reason) {
> 		this.reason = reason;
> 	}
>+
>+	public boolean getIsAuditedDetermined() { return isAuditedDetermined; }
>+
>+	private void setIsAuditedDetermined(boolean value) { isAuditedDetermined
>= value; }
> 	
> 	/**
> 	 * @return the isAudited
>@@ -95,10 +104,13 @@ public class RangerAccessResult {
> 		return isAudited;
> 	}
> 
>+
>+
> 	/**
> 	 * @param isAudited the isAudited to set
> 	 */
> 	public void setIsAudited(boolean isAudited) {
>+		setIsAuditedDetermined(true);
> 		this.isAudited = isAudited;
> 	}
> 
>@@ -145,8 +157,10 @@ public class RangerAccessResult {
> 	public StringBuilder toString(StringBuilder sb) {
> 		sb.append("RangerAccessResult={");
> 
>+        
>sb.append("isAccessDetermined={").append(isAccessDetermined).append("} ");
> 		sb.append("isAllowed={").append(isAllowed).append("} ");
>-		sb.append("isAudited={").append(isAudited).append("} ");
>+        
>sb.append("isAuditedDetermined={").append(isAuditedDetermined).append("}
>");
>+        sb.append("isAudited={").append(isAudited).append("} ");
> 		sb.append("policyId={").append(policyId).append("} ");
> 		sb.append("reason={").append(reason).append("} ");
> 
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyE
>ng
>ineImpl.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEngineImpl.java
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEngineImpl.java
>index 51787ac..abae1fe 100644
>--- 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEngineImpl.java
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEngineImpl.java
>@@ -19,31 +19,25 @@
> 
> package org.apache.ranger.plugin.policyengine;
> 
>-import java.util.ArrayList;
>-import java.util.Collection;
>-import java.util.List;
>-
>-import org.apache.commons.collections.CollectionUtils;
>-import org.apache.commons.lang.StringUtils;
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> import org.apache.ranger.plugin.audit.RangerAuditHandler;
> 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.model.RangerServiceDef.RangerContextEnricherDef;
>-import 
>org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluator;
> import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
> 
>+import java.util.ArrayList;
>+import java.util.Collection;
>+import java.util.List;
>+
> 
> public class RangerPolicyEngineImpl implements RangerPolicyEngine {
> 	private static final Log LOG =
>LogFactory.getLog(RangerPolicyEngineImpl.class);
> 
>-	private String                      serviceName         = null;
>-	private RangerServiceDef            serviceDef          = null;
>-	private List<RangerContextEnricher> contextEnrichers    = null;
>-	private List<RangerPolicyEvaluator> policyEvaluators    = null;
>-	private RangerAuditHandler          defaultAuditHandler = null;
>+	private String                 serviceName         = null;
>+	private RangerPolicyRepository policyRepository    = null;
>+	private RangerAuditHandler     defaultAuditHandler = null;
> 
> 
> 	public RangerPolicyEngineImpl() {
>@@ -63,12 +57,13 @@ public class RangerPolicyEngineImpl implements
>RangerPolicyEngine {
> 
> 	@Override
> 	public RangerServiceDef getServiceDef() {
>-		return serviceDef;
>+		return policyRepository == null ? null :
>policyRepository.getServiceDef();
> 	}
> 
> 	@Override
> 	public List<RangerContextEnricher> getContextEnrichers() {
>-		return contextEnrichers;
>+
>+		return policyRepository == null ? null : getContextEnrichers();
> 	}
> 
> 	@Override
>@@ -77,51 +72,12 @@ public class RangerPolicyEngineImpl implements
>RangerPolicyEngine {
> 			LOG.debug("==> RangerPolicyEngineImpl.setPolicies(" + serviceName + ",
>" + serviceDef + ", policies.count=" + (policies == null ? 0 :
>policies.size()) + ")");
> 		}
> 
>-		if(serviceName != null && serviceDef != null && policies != null) {
>-			List<RangerContextEnricher> contextEnrichers = new
>ArrayList<RangerContextEnricher>();
>-
>-			if(!CollectionUtils.isEmpty(serviceDef.getContextEnrichers())) {
>-				for(RangerContextEnricherDef enricherDef :
>serviceDef.getContextEnrichers()) {
>-					if(enricherDef == null) {
>-						continue;
>-					}
>-					
>-					RangerContextEnricher contextEnricher =
>getContextEnricher(enricherDef);
>-					
>-					contextEnrichers.add(contextEnricher);
>-				}
>-			}
>-
>-			List<RangerPolicyEvaluator> evaluators = new
>ArrayList<RangerPolicyEvaluator>();
>-
>-			for(RangerPolicy policy : policies) {
>-				if(! policy.getIsEnabled()) {
>-					continue;
>-				}
>-
>-				RangerPolicyEvaluator evaluator = getPolicyEvaluator(policy,
>serviceDef);
>-
>-				if(evaluator != null) {
>-					evaluators.add(evaluator);
>-				}
>-			}
>-
>-			/* TODO:
>-			 *  sort evaluators list for faster completion of isAccessAllowed()
>method
>-			 *   1. Global policies: the policies that cover for any resource (for
>example: database=*; table=*; column=*)
>-			 *   2. Policies that cover all resources under level-1 (for example:
>every thing in one or more databases)
>-			 *   3. Policies that cover all resources under level-2 (for example:
>every thing in one or more tables)
>-			 *   ...
>-			 *   4. Policies that cover all resources under level-n (for example:
>one or more columns)
>-			 * 
>-			 */
>-
>-			this.serviceName      = serviceName;
>-			this.serviceDef       = serviceDef;
>-			this.contextEnrichers = contextEnrichers;
>-			this.policyEvaluators = evaluators;
>+		if (serviceName != null && serviceDef != null && policies != null) {
>+			policyRepository = new RangerPolicyRepository(serviceName);
>+			policyRepository.init(serviceDef, policies);
>+			this.serviceName = serviceName;
> 		} else {
>-			LOG.error("RangerPolicyEngineImpl.setPolicies(): invalid arguments -
>null serviceDef/policies");
>+			LOG.error("RangerPolicyEngineImpl.setPolicies ->Invalid arguments:
>serviceName, serviceDef, or policies is null");
> 		}
> 
> 		if(LOG.isDebugEnabled()) {
>@@ -141,7 +97,7 @@ public class RangerPolicyEngineImpl implements
>RangerPolicyEngine {
> 
> 	@Override
> 	public RangerAccessResult createAccessResult(RangerAccessRequest
>request)
>{
>-		return new RangerAccessResult(serviceName, serviceDef, request);	
>+		return policyRepository == null ? null : new
>RangerAccessResult(serviceName, policyRepository.getServiceDef(),
>request);
> 	}
> 
> 	@Override
>@@ -207,73 +163,26 @@ public class RangerPolicyEngineImpl implements
>RangerPolicyEngine {
> 
> 		RangerAccessResult ret = createAccessResult(request);
> 
>-		if(request != null) {
>-			List<RangerPolicyEvaluator> evaluators = policyEvaluators;
>+		if(policyRepository != null && ret != null && request != null) {
>+			List<RangerPolicyEvaluatorFacade> evaluators =
>policyRepository.getPolicyEvaluators();
> 
> 			if(evaluators != null) {
>+				policyRepository.retrieveAuditEnabled(request, ret);
> 				for(RangerPolicyEvaluator evaluator : evaluators) {
> 					evaluator.evaluate(request, ret);
> 
>-					// stop once allowed=true && audited==true
>-					if(ret.getIsAllowed() && ret.getIsAudited()) {
>+					// stop once allowed==true && auditedDetermined==true
>+					if(ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
> 						break;
> 					}
> 				}
>-			}
>-		}
>+				policyRepository.storeAuditEnabled(request, ret);
> 
>-		if(LOG.isDebugEnabled()) {
>-			LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowedNoAudit(" +
>request + "): " + ret);
>-		}
>-
>-		return ret;
>-	}
>-
>-	private RangerContextEnricher
>getContextEnricher(RangerContextEnricherDef
>enricherDef) {
>-		if(LOG.isDebugEnabled()) {
>-			LOG.debug("==> RangerPolicyEngineImpl.getContextEnricher(" +
>enricherDef + ")");
>-		}
>-
>-		RangerContextEnricher ret = null;
>-
>-		String name    = enricherDef != null ? enricherDef.getName()     :
>null;
>-		String clsName = enricherDef != null ? enricherDef.getEnricher() :
>null;
>-
>-		if(! StringUtils.isEmpty(clsName)) {
>-			try {
>-				@SuppressWarnings("unchecked")
>-				Class<RangerContextEnricher> enricherClass =
>(Class<RangerContextEnricher>)Class.forName(clsName);
>-
>-				ret = enricherClass.newInstance();
>-			} catch(Exception excp) {
>-				LOG.error("failed to instantiate context enricher '" + clsName + "'
>for '" + name + "'", excp);
> 			}
> 		}
> 
>-		if(ret != null) {
>-			ret.init(enricherDef);
>-		}
>-
> 		if(LOG.isDebugEnabled()) {
>-			LOG.debug("<== RangerPolicyEngineImpl.getContextEnricher(" +
>enricherDef + "): " + ret);
>-		}
>-
>-		return ret;
>-	}
>-
>-	private RangerPolicyEvaluator getPolicyEvaluator(RangerPolicy policy,
>RangerServiceDef serviceDef) {
>-		if(LOG.isDebugEnabled()) {
>-			LOG.debug("==> RangerPolicyEngineImpl.getPolicyEvaluator(" + policy +
>"," + serviceDef + ")");
>-		}
>-
>-		RangerPolicyEvaluator ret = null;
>-
>-		ret = new RangerDefaultPolicyEvaluator(); // TODO: configurable
>evaluator class?
>-
>-		ret.init(policy, serviceDef);
>-
>-		if(LOG.isDebugEnabled()) {
>-			LOG.debug("<== RangerPolicyEngineImpl.getPolicyEvaluator(" + policy +
>"," + serviceDef + "): " + ret);
>+			LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowedNoAudit(" +
>request + "): " + ret);
> 		}
> 
> 		return ret;
>@@ -292,17 +201,7 @@ public class RangerPolicyEngineImpl implements
>RangerPolicyEngine {
> 		sb.append("RangerPolicyEngineImpl={");
> 
> 		sb.append("serviceName={").append(serviceName).append("} ");
>-		sb.append("serviceDef={").append(serviceDef).append("} ");
>-
>-		sb.append("policyEvaluators={");
>-		if(policyEvaluators != null) {
>-			for(RangerPolicyEvaluator policyEvaluator : policyEvaluators) {
>-				if(policyEvaluator != null) {
>-					sb.append(policyEvaluator).append(" ");
>-				}
>-			}
>-		}
>-		sb.append("} ");
>+		sb.append(policyRepository);
> 
> 		sb.append("}");
> 
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyE
>va
>luatorFacade.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEvaluatorFacade.java
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEvaluatorFacade.java
>new file mode 100644
>index 0000000..5c30df3
>--- /dev/null
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyEvaluatorFacade.java
>@@ -0,0 +1,128 @@
>+/*
>+ * 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.logging.Log;
>+import org.apache.commons.logging.LogFactory;
>+import 
>org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
>+import org.apache.ranger.plugin.model.RangerPolicy;
>+import org.apache.ranger.plugin.model.RangerServiceDef;
>+import 
>org.apache.ranger.plugin.policyevaluator.RangerDefaultPolicyEvaluator;
>+import 
>org.apache.ranger.plugin.policyevaluator.RangerOptimizedPolicyEvaluator;
>+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
>+
>+import java.util.Map;
>+
>+public class RangerPolicyEvaluatorFacade implements
>RangerPolicyEvaluator,
>Comparable<RangerPolicyEvaluatorFacade> {
>+    private static final Log LOG =
>LogFactory.getLog(RangerPolicyEvaluatorFacade.class);
>+
>+    RangerDefaultPolicyEvaluator delegate  =   null;
>+    int computedPriority            =   0;
>+    boolean useCachePolicyEngine         = false;
>+
>+    RangerPolicyEvaluatorFacade(boolean useCachePolicyEngine) {
>+        super();
>+        this.useCachePolicyEngine = useCachePolicyEngine;
>+        delegate = new RangerOptimizedPolicyEvaluator();
>+    }
>+
>+    RangerPolicyEvaluator getPolicyEvaluator() {
>+        return delegate;
>+    }
>+
>+    @Override
>+    public void init(RangerPolicy policy, RangerServiceDef serviceDef) {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerPolicyEvaluatorFacade.init(),
>useCachePolicyEngine:" + useCachePolicyEngine);
>+        }
>+        delegate.init(policy, serviceDef);
>+        computedPriority = computePriority();
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerPolicyEvaluatorFacade.init(),
>useCachePolicyEngine:" + useCachePolicyEngine);
>+        }
>+    }
>+
>+    @Override
>+    public RangerPolicy getPolicy() {
>+        return delegate.getPolicy();
>+    }
>+
>+    @Override
>+    public RangerServiceDef getServiceDef() {
>+        return delegate.getServiceDef();
>+    }
>+
>+    @Override
>+    public void evaluate(RangerAccessRequest request, RangerAccessResult
>result) {
>+        delegate.evaluate(request, result);
>+    }
>+
>+    @Override
>+    public boolean isMatch(RangerResource resource) {
>+        return false;
>+    }
>+
>+    @Override
>+    public boolean isSingleAndExactMatch(RangerResource resource) {
>+        return false;
>+    }
>+
>+    @Override
>+    public int compareTo(RangerPolicyEvaluatorFacade other) {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerPolicyEvaluatorFacade.compareTo()");
>+        }
>+        int result;
>+
>+        if (this.getComputedPriority() == other.getComputedPriority()) {
>+            Map<String, RangerConditionEvaluator> myConditionEvaluators =
>this.delegate.getConditionEvaluators();
>+            Map<String, RangerConditionEvaluator>
>otherConditionEvaluators
>= other.delegate.getConditionEvaluators();
>+
>+            int myConditionEvaluatorCount = myConditionEvaluators == null
>? 0 : myConditionEvaluators.size();
>+            int otherConditionEvaluatorCount = otherConditionEvaluators
>==
>null ? 0 : otherConditionEvaluators.size();
>+
>+            result = Integer.compare(myConditionEvaluatorCount,
>otherConditionEvaluatorCount);
>+        } else {
>+            int myComputedPriority = this.getComputedPriority();
>+            int otherComputedPriority = other.getComputedPriority();
>+            result = Integer.compare(myComputedPriority,
>otherComputedPriority);
>+        }
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerPolicyEvaluatorFacade.compareTo(),
>result:" + result);
>+        }
>+
>+        return result;
>+    }
>+
>+    private int getComputedPriority() {
>+        return computedPriority;
>+    }
>+
>+    private int computePriority() {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==>
>RangerPolicyEvaluatorFacade.computePriority()");
>+        }
>+        int result = delegate.computePriority();
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<==RangerPolicyEvaluatorFacade.computePriority(),
>result:" + result);
>+        }
>+        return result;
>+    }
>+}
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyR
>ep
>ository.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyRepository.java
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyRepository.java
>new file mode 100644
>index 0000000..700b3ad
>--- /dev/null
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/Ranger
>Po
>licyRepository.java
>@@ -0,0 +1,231 @@
>+/*
>+ * 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.lang.StringUtils;
>+import org.apache.commons.logging.Log;
>+import org.apache.commons.logging.LogFactory;
>+import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
>+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.policyevaluator.RangerPolicyEvaluator;
>+
>+import java.util.ArrayList;
>+import java.util.Collections;
>+import java.util.List;
>+import java.util.Map;
>+
>+public class RangerPolicyRepository {
>+    private static final Log LOG =
>LogFactory.getLog(RangerPolicyRepository.class);
>+
>+    private String serviceName                               = null;
>+    private List<RangerPolicyEvaluatorFacade> policyEvaluators  = null;
>+    private List<RangerContextEnricher> contextEnrichers        = null;
>+    private RangerServiceDef serviceDef                         = null;
>+    // Not used at this time
>+    private boolean useCachePolicyEngine                                =
>false;
>+    private Map<String, RangerAccessData<Boolean>> accessAuditCache     =
>null;
>+
>+    private static int RANGER_POLICYENGINE_AUDITRESULT_CACHE_SIZE =
>64*1024;
>+
>+    RangerPolicyRepository(String serviceName) {
>+        super();
>+        this.serviceName = serviceName;
>+    }
>+    String getRepositoryName() {
>+        return serviceName;
>+    }
>+    List<RangerPolicyEvaluatorFacade> getPolicyEvaluators() {
>+        return policyEvaluators;
>+    }
>+    List<RangerContextEnricher> getContextEnrichers() {
>+        return contextEnrichers;
>+    }
>+    RangerServiceDef getServiceDef() {
>+        return serviceDef;
>+    }
>+
>+    void init(RangerServiceDef serviceDef, List<RangerPolicy> policies) {
>+
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerPolicyRepository.init(" + serviceDef +
>",
>policies.count=" + (policies == null ? 0 : policies.size()) + ")");
>+        }
>+
>+        this.serviceDef = serviceDef;
>+
>+        contextEnrichers = new ArrayList<RangerContextEnricher>();
>+
>+        if (!CollectionUtils.isEmpty(serviceDef.getContextEnrichers())) {
>+            for (RangerServiceDef.RangerContextEnricherDef enricherDef :
>serviceDef.getContextEnrichers()) {
>+                if (enricherDef == null) {
>+                    continue;
>+                }
>+
>+                RangerContextEnricher contextEnricher =
>buildContextEnricher(enricherDef);
>+
>+                contextEnrichers.add(contextEnricher);
>+            }
>+        }
>+
>+        policyEvaluators = new ArrayList<RangerPolicyEvaluatorFacade>();
>+
>+        for (RangerPolicy policy : policies) {
>+            if (!policy.getIsEnabled()) {
>+                continue;
>+            }
>+
>+            RangerPolicyEvaluatorFacade evaluator =
>buildPolicyEvaluator(policy, serviceDef);
>+
>+            if (evaluator != null) {
>+                policyEvaluators.add(evaluator);
>+            }
>+
>+            Collections.sort(policyEvaluators);
>+
>+        }
>+
>+        String propertyName = "ranger.plugin." + serviceName +
>".policyengine.auditcachesize";
>+
>+        int auditResultCacheSize =
>RangerConfiguration.getInstance().getInt(propertyName,
>RANGER_POLICYENGINE_AUDITRESULT_CACHE_SIZE);
>+
>+        accessAuditCache = new CacheMap<String,
>RangerAccessData<Boolean>>(auditResultCacheSize);
>+
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerPolicyRepository.init(" + serviceDef +
>",
>policies.count=" + (policies == null ? 0 : policies.size()) + ")");
>+        }
>+    }
>+
>+    private RangerContextEnricher
>buildContextEnricher(RangerServiceDef.RangerContextEnricherDef
>enricherDef)
>{
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerPolicyRepository.buildContextEnricher("
>+
>enricherDef + ")");
>+        }
>+
>+        RangerContextEnricher ret = null;
>+
>+        String name    = enricherDef != null ? enricherDef.getName()
>:
>null;
>+        String clsName = enricherDef != null ? enricherDef.getEnricher()
>:
>null;
>+
>+        if(! StringUtils.isEmpty(clsName)) {
>+            try {
>+                @SuppressWarnings("unchecked")
>+                Class<RangerContextEnricher> enricherClass =
>(Class<RangerContextEnricher>)Class.forName(clsName);
>+
>+                ret = enricherClass.newInstance();
>+            } catch(Exception excp) {
>+                LOG.error("failed to instantiate context enricher '" +
>clsName + "' for '" + name + "'", excp);
>+            }
>+        }
>+
>+        if(ret != null) {
>+            ret.init(enricherDef);
>+        }
>+
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerPolicyRepository.buildContextEnricher("
>+
>enricherDef + "): " + ret);
>+        }
>+        return ret;
>+    }
>+
>+    private RangerPolicyEvaluatorFacade buildPolicyEvaluator(RangerPolicy
>policy, RangerServiceDef serviceDef) {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerPolicyRepository.buildPolicyEvaluator("
>+
>policy + "," + serviceDef + ")");
>+        }
>+
>+        RangerPolicyEvaluatorFacade ret = null;
>+
>+        ret = new RangerPolicyEvaluatorFacade(useCachePolicyEngine);
>+        ret.init(policy, serviceDef);
>+
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerPolicyRepository.buildPolicyEvaluator("
>+
>policy + "," + serviceDef + "): " + ret);
>+        }
>+        return ret;
>+    }
>+
>+    synchronized void retrieveAuditEnabled(RangerAccessRequest request,
>RangerAccessResult ret) {
>+        if (LOG.isDebugEnabled()) {
>+            LOG.debug("==>
>RangerPolicyRepository.retrieveAuditEnabled()");
>+        }
>+        RangerAccessData<Boolean> value =
>accessAuditCache.get(request.getResource().toString());
>+        if ((value != null)) {
>+            ret.setIsAudited(value.getAccessDetails());
>+        }
>+
>+        if (LOG.isDebugEnabled()) {
>+            LOG.debug("<==
>RangerPolicyRepository.retrieveAuditEnabled()");
>+        }
>+    }
>+
>+    synchronized void storeAuditEnabled(RangerAccessRequest request,
>RangerAccessResult ret) {
>+        if (LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerPolicyRepository.storeAuditEnabled()");
>+        }
>+        RangerAccessData<Boolean> lookup =
>accessAuditCache.get(request.getResource().toString());
>+        if ((lookup == null && ret.getIsAuditedDetermined() == true)) {
>+            RangerAccessData<Boolean> value = new
>RangerAccessData<Boolean>(request.toString());
>+            value.setAccessDetails(ret.getIsAudited());
>+            accessAuditCache.put(request.getResource().toString(),
>value);
>+        }
>+
>+        if (LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerPolicyRepository.storeAuditEnabled()");
>+        }
>+    }
>+
>+    @Override
>+    public String toString( ) {
>+        StringBuilder sb = new StringBuilder();
>+
>+        toString(sb);
>+
>+        return sb.toString();
>+    }
>+
>+    public StringBuilder toString(StringBuilder sb) {
>+
>+        sb.append("RangerPolicyRepository={");
>+
>+        sb.append("serviceName={").append(serviceName).append("} ");
>+        sb.append("serviceDef={").append(serviceDef).append("} ");
>+        sb.append("policyEvaluators={");
>+        if (policyEvaluators != null) {
>+            for (RangerPolicyEvaluator policyEvaluator : 
>policyEvaluators) 
>{
>+                if (policyEvaluator != null) {
>+                    sb.append(policyEvaluator).append(" ");
>+                }
>+            }
>+        }
>+        if (contextEnrichers != null) {
>+            for (RangerContextEnricher contextEnricher : 
>contextEnrichers) 
>{
>+                if (contextEnricher != null) {
>+                    sb.append(contextEnricher).append(" ");
>+                }
>+            }
>+        }
>+        
>sb.append("useCachePolicyEngine={").append(useCachePolicyEngine).append("}
> 
>");
>+
>+        sb.append("} ");
>+
>+        return sb;
>+    }
>+
>+}
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefa
>ul
>tPolicyEvaluator.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluator.java 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluator.java
>index 0ac5eed..30b36fa 100644
>--- 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluator.java
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluator.java
>@@ -19,13 +19,7 @@
> 
> package org.apache.ranger.plugin.policyevaluator;
> 
>-import java.util.Collection;
>-import java.util.Collections;
>-import java.util.HashMap;
>-import java.util.HashSet;
>-import java.util.Iterator;
>-import java.util.Map;
>-
>+import com.google.common.base.Strings;
> import org.apache.commons.collections.CollectionUtils;
> import org.apache.commons.lang.StringUtils;
> import org.apache.commons.logging.Log;
>@@ -47,7 +41,7 @@ import 
>org.apache.ranger.plugin.policyengine.RangerResource;
> import 
>org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher;
> import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
> 
>-import com.google.common.base.Strings;
>+import java.util.*;
> 
> 
> public class RangerDefaultPolicyEvaluator extends 
>RangerAbstractPolicyEvaluator {
>@@ -92,7 +86,13 @@ public class RangerDefaultPolicyEvaluator extends 
>RangerAbstractPolicyEvaluator
> 		}
> 	}
> 
>-	/**
>+    public Map<String, RangerConditionEvaluator> 
>getConditionEvaluators() 
>{
>+        return conditionEvaluators;
>+    }
>+    public int computePriority() { return 0;}
>+
>+
>+    /**
> 	 * Non-private only for testability.
> 	 * @param policy
> 	 * @param serviceDef
>@@ -129,7 +129,7 @@ public class RangerDefaultPolicyEvaluator extends 
>RangerAbstractPolicyEvaluator
> 							if (Strings.isNullOrEmpty(evaluatorClassName)) {
> 								LOG.error("initializeConditionEvaluators: Serious Configuration 
>error: Couldn't get condition evaluator class name for condition[" + 
>conditionName + "]!  Disabling all checks for this condition.");
> 							} else {
>-								RangerConditionEvaluator anEvaluator = 
>newConditionEvauator(evaluatorClassName);
>+								RangerConditionEvaluator anEvaluator = 
>newConditionEvaluator(evaluatorClassName);
> 								if (anEvaluator == null) {
> 									LOG.error("initializeConditionEvaluators: Serious Configuration 
>error: Couldn't instantiate condition evaluator for class[" + 
>evaluatorClassName + "].  All checks for condition[" + conditionName + "] 
>disabled.");
> 								} else {
>@@ -179,9 +179,9 @@ public class RangerDefaultPolicyEvaluator extends 
>RangerAbstractPolicyEvaluator
> 		return result;
> 	}
> 
>-	RangerConditionEvaluator newConditionEvauator(String className) {
>+	RangerConditionEvaluator newConditionEvaluator(String className) {
> 		if(LOG.isDebugEnabled()) {
>-			LOG.debug(String.format("==> 
>RangerDefaultPolicyEvaluator.newConditionEvauator(%s)", className));
>+			LOG.debug(String.format("==> 
>RangerDefaultPolicyEvaluator.newConditionEvaluator(%s)", className));
> 		}
> 
> 		RangerConditionEvaluator evaluator = null;
>@@ -195,92 +195,135 @@ public class RangerDefaultPolicyEvaluator extends 
>RangerAbstractPolicyEvaluator
> 		}
> 	
> 		if(LOG.isDebugEnabled()) {
>-			LOG.debug(String.format("<== 
>RangerDefaultPolicyEvaluator.newConditionEvauator(%s)", evaluator == null 
>? 
>null : evaluator.toString()));
>+			LOG.debug(String.format("<== 
>RangerDefaultPolicyEvaluator.newConditionEvaluator(%s)", evaluator == 
>null ? 
>null : evaluator.toString()));
> 		}
> 		return evaluator;
> 	}
> 
> 	@Override
>-	public void evaluate(RangerAccessRequest request, RangerAccessResult 
>result) {
>-		if(LOG.isDebugEnabled()) {
>-			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", 
>" 
>+ result + ")");
>-		}
>-
>-		RangerPolicy policy = getPolicy();
>-
>-		if(policy != null && request != null && result != null) {
>-			boolean isResourceMatch     = isMatch(request.getResource());
>-			boolean isResourceHeadMatch = isResourceMatch || 
>matchResourceHead(request.getResource());
>-			String  accessType          = request.getAccessType();
>-
>-			if(StringUtils.isEmpty(accessType)) {
>-				accessType = RangerPolicyEngine.ANY_ACCESS;
>-			}
>-
>-			boolean isAnyAccess   = StringUtils.equals(accessType, 
>RangerPolicyEngine.ANY_ACCESS);
>-			boolean isAdminAccess = StringUtils.equals(accessType, 
>RangerPolicyEngine.ADMIN_ACCESS);
>-
>-			if(isResourceMatch || (isResourceHeadMatch && isAnyAccess)) {
>-				if(policy.getIsAuditEnabled()) {
>-					result.setIsAudited(true);
>-				}
>-
>-				for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
>-					if(isAdminAccess) {
>-						if(policyItem.getDelegateAdmin()) {
>-							result.setIsAllowed(true);
>-							result.setPolicyId(policy.getId());
>-							break;
>-						}
>-
>-						continue;
>-					}
>-
>-					if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
>-						continue;
>-					}
>-
>-					boolean isUserGroupMatch = matchUserGroup(policyItem, 
>request.getUser(), request.getUserGroups());
>-
>-					if(! isUserGroupMatch) {
>-						continue;
>-					}
>-
>-					boolean isCustomConditionsMatch = matchCustomConditions(policyItem, 
>request, conditionEvaluators);
>-
>-					if(! isCustomConditionsMatch) {
>-						continue;
>-					}
>-
>-					if(isAnyAccess) {
>-						for(RangerPolicyItemAccess access : policyItem.getAccesses()) {
>-							if(access.getIsAllowed()) {
>-								result.setIsAllowed(true);
>-								result.setPolicyId(policy.getId());
>-								break;
>-							}
>-						}
>-					} else {
>-						RangerPolicyItemAccess access = getAccess(policyItem, accessType);
>-
>-						if(access != null && access.getIsAllowed()) {
>-							result.setIsAllowed(true);
>-							result.setPolicyId(policy.getId());
>-						}
>-					}
>-
>-					if(result.getIsAllowed()) {
>-						break;
>-					}
>-				}
>-			}
>-		}
>-
>-		if(LOG.isDebugEnabled()) {
>+    public void evaluate(RangerAccessRequest request, RangerAccessResult 
>result) {
>+        if (LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + 
>request + ", " + result + ")");
>+        }
>+        RangerPolicy policy = getPolicy();
>+
>+        if (policy != null && request != null && result != null) {
>+
>+            String accessType = request.getAccessType();
>+            if (StringUtils.isEmpty(accessType)) {
>+                accessType = RangerPolicyEngine.ANY_ACCESS;
>+            }
>+            boolean isAnyAccess = StringUtils.equals(accessType, 
>RangerPolicyEngine.ANY_ACCESS);
>+
>+            boolean isMatchAttempted = false;
>+            boolean matchResult = false;
>+            boolean headMatchResult = false;
>+
>+            if (!result.getIsAuditedDetermined()) {
>+                // Need to match request.resource first. If it matches 
>(or 
>head matches), then only more progress can be made
>+                matchResult = isMatch(request.getResource());
>+                isMatchAttempted = true;
>+
>+                if (matchResult) {
>+                    // Do all stuff.
>+                    if (policy.getIsAuditEnabled()) {
>+                        result.setIsAudited(true);
>+                    }
>+                }
>+            }
>+
>+            if (!result.getIsAccessDetermined()) {
>+                if (!isMatchAttempted) {
>+                    // Need to match request.resource first. If it 
>matches 
>(or head matches), then only more progress can be made
>+                    matchResult = isMatch(request.getResource());
>+                    isMatchAttempted = true;
>+                }
>+
>+                // Try head match only if it is useful
>+                if (isAnyAccess) {
>+                    headMatchResult = matchResult || 
>matchResourceHead(request.getResource());
>+                }
>+
>+                if (matchResult || (isAnyAccess && headMatchResult)) {
>+                    // A match was found earlier
>+                    evaluatePolicyItemsForAccess(request, result);
>+                }
>+            }
>+        }
>+
>+        if(LOG.isDebugEnabled()) {
> 			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", 
>" 
>+ result + ")");
> 		}
> 	}
> 
>+    protected void evaluatePolicyItemsForAccess(RangerAccessRequest 
>request, RangerAccessResult result) {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> 
>RangerDefaultPolicyEvaluator.evaluatePolicyItemsForAccess()");
>+        }
>+        String accessType = request.getAccessType();
>+        if (StringUtils.isEmpty(accessType)) {
>+            accessType = RangerPolicyEngine.ANY_ACCESS;
>+        }
>+        boolean isAnyAccess = StringUtils.equals(accessType, 
>RangerPolicyEngine.ANY_ACCESS);
>+        boolean isAdminAccess = StringUtils.equals(accessType, 
>RangerPolicyEngine.ADMIN_ACCESS);
>+
>+        for (RangerPolicy.RangerPolicyItem policyItem : 
>getPolicy().getPolicyItems()) {
>+
>+            boolean isUserGroupMatch = matchUserGroup(policyItem, 
>request.getUser(), request.getUserGroups());
>+
>+            if (!isUserGroupMatch) {
>+                continue;
>+            }
>+            // This is only for Grant and Revoke access requests sent by 
>the component. For those cases
>+            // Our plugin will fill in the accessType as ADMIN_ACCESS.
>+
>+            if (isAdminAccess) {
>+                if (policyItem.getDelegateAdmin()) {
>+                    result.setIsAllowed(true);
>+                    result.setPolicyId(getPolicy().getId());
>+                    break;
>+                }
>+                continue;
>+            }
>+
>+            if (CollectionUtils.isEmpty(policyItem.getAccesses())) {
>+                continue;
>+            }
>+
>+            boolean accessAllowed = false;
>+            if (isAnyAccess) {
>+                for (RangerPolicy.RangerPolicyItemAccess access : 
>policyItem.getAccesses()) {
>+                    if (access.getIsAllowed()) {
>+                        accessAllowed = true;
>+                        break;
>+                    }
>+                }
>+            } else {
>+                RangerPolicy.RangerPolicyItemAccess access = 
>getAccess(policyItem, accessType);
>+
>+                if (access != null && access.getIsAllowed()) {
>+                    accessAllowed = true;
>+                }
>+            }
>+            if (accessAllowed == false) {
>+                continue;
>+            }
>+
>+            boolean isCustomConditionsMatch = 
>matchCustomConditions(policyItem, request, getConditionEvaluators());
>+
>+            if (!isCustomConditionsMatch) {
>+                continue;
>+            }
>+
>+            result.setIsAllowed(true);
>+            result.setPolicyId(getPolicy().getId());
>+            break;
>+        }
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== 
>RangerDefaultPolicyEvaluator.evaluatePolicyItemsForAccess()");
>+        }
>+    }
>+
> 	@Override
> 	public boolean isMatch(RangerResource resource) {
> 		if(LOG.isDebugEnabled()) {
>@@ -554,7 +597,7 @@ public class RangerDefaultPolicyEvaluator extends 
>RangerAbstractPolicyEvaluator
> 		}
> 
> 		if(LOG.isDebugEnabled()) {
>-			LOG.debug("==> RangerDefaultPolicyEvaluator.createResourceMatcher(" + 
>resourceDef + ", " + resource + "): " + ret);
>+			LOG.debug("<== RangerDefaultPolicyEvaluator.createResourceMatcher(" + 
>resourceDef + ", " + resource + "): " + ret);
> 		}
> 
> 		return ret;
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOpti
>mi
>zedPolicyEvaluator.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rOptimizedPolicyEvaluator.java 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rOptimizedPolicyEvaluator.java
>new file mode 100644
>index 0000000..59fb87c
>--- /dev/null
>+++ 
>b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rOptimizedPolicyEvaluator.java
>@@ -0,0 +1,247 @@
>+/*
>+ * 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.policyevaluator;
>+
>+import org.apache.commons.collections.CollectionUtils;
>+import org.apache.commons.lang.StringUtils;
>+import org.apache.commons.logging.Log;
>+import org.apache.commons.logging.LogFactory;
>+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.RangerAccessResult;
>+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
>+
>+import java.util.*;
>+import java.lang.Math;
>+
>+public class RangerOptimizedPolicyEvaluator extends 
>RangerDefaultPolicyEvaluator {
>+    private static final Log LOG = 
>LogFactory.getLog(RangerOptimizedPolicyEvaluator.class);
>+
>+    private Set<String> groups         = null;
>+    private Set<String> users          = null;
>+    private Set<String> accessPerms    = null;
>+    private boolean     delegateAdmin  = false;
>+    private boolean     hasAllPerms    = false;
>+    private boolean     hasPublicGroup = false;
>+
>+
>+    // For computation of priority
>+    private static final String 
>RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING                   = "*";
>+    private static final String 
>RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING                 = "?";
>+    private static final int 
>RANGER_POLICY_EVAL_MATCH_ANY_WILDCARD_PREMIUM                    
>= 25;
>+    private static final int 
>RANGER_POLICY_EVAL_CONTAINS_MATCH_ANY_WILDCARD_PREMIUM           = 10;
>+    private static final int 
>RANGER_POLICY_EVAL_CONTAINS_MATCH_ONE_CHARACTER_WILDCARD_PREMIUM = 10;
>+    private static final int RANGER_POLICY_EVAL_HAS_EXCLUDES_PREMIUM     
>                     
>= 25;
>+    private static final int RANGER_POLICY_EVAL_IS_RECURSIVE_PREMIUM     
>                     
>= 25;
>+    private static final int 
>RANGER_POLICY_EVAL_PUBLIC_GROUP_ACCESS_PREMIUM                   = 25;
>+    private static final int RANGER_POLICY_EVAL_ALL_ACCESS_TYPES_PREMIUM 
>                     
>= 25;
>+    private static final int RANGER_POLICY_EVAL_RESERVED_SLOTS_NUMBER    
>                     
>= 10000;
>+    private static final int 
>RANGER_POLICY_EVAL_RESERVED_SLOTS_PER_LEVEL_NUMBER               = 1000;
>+
>+    @Override
>+    public void init(RangerPolicy policy, RangerServiceDef serviceDef) {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> RangerOptimizedPolicyEvaluator.init()");
>+        }
>+
>+        super.init(policy, serviceDef);
>+
>+        accessPerms = new HashSet<String>();
>+        groups = new HashSet<String>();
>+        users = new HashSet<String>();
>+
>+        for (RangerPolicy.RangerPolicyItem item : 
>policy.getPolicyItems()) 
>{
>+            delegateAdmin = delegateAdmin || item.getDelegateAdmin();
>+
>+            List<RangerPolicy.RangerPolicyItemAccess> policyItemAccesses 
>= 
>item.getAccesses();
>+            for(RangerPolicy.RangerPolicyItemAccess policyItemAccess : 
>policyItemAccesses) {
>+
>+                if (policyItemAccess.getIsAllowed()) {
>+                    String accessType = policyItemAccess.getType();
>+                    accessPerms.add(accessType);
>+                }
>+            }
>+
>+            groups.addAll(item.getGroups());
>+            users.addAll(item.getUsers());
>+        }
>+
>+        hasAllPerms = checkIfHasAllPerms();
>+
>+        for (String group : groups) {
>+            if (group.equalsIgnoreCase(RangerPolicyEngine.GROUP_PUBLIC)) 
>{
>+                hasPublicGroup = true;
>+            }
>+        }
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== RangerOptimizedPolicyEvaluator.init()");
>+        }
>+    }
>+
>+    @Override
>+    public int computePriority() {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> 
>RangerOptimizedPolicyEvaluator.computePriority()");
>+        }
>+        RangerServiceDef serviceDef = getServiceDef();
>+        RangerPolicy policy = getPolicy();
>+
>+        class LevelResourceNames implements 
>Comparable<LevelResourceNames> 
>{
>+            int level;
>+            RangerPolicy.RangerPolicyResource policyResource;
>+
>+            @Override
>+            public int compareTo(LevelResourceNames other) {
>+                // Sort in ascending order of level numbers
>+                return Integer.compare(this.level, other.level);
>+            }
>+        }
>+        List<LevelResourceNames> tmpList = new 
>ArrayList<LevelResourceNames>();
>+
>+        List<RangerServiceDef.RangerResourceDef> resourceDefs = 
>serviceDef.getResources();
>+
>+        for (Map.Entry<String, RangerPolicy.RangerPolicyResource> 
>keyValuePair : policy.getResources().entrySet()) {
>+            String serviceDefResourceName = keyValuePair.getKey();
>+            RangerPolicy.RangerPolicyResource policyResource = 
>keyValuePair.getValue();
>+            List<String> policyResourceNames = 
>policyResource.getValues();
>+
>+            RangerServiceDef.RangerResourceDef found = null;
>+            for (RangerServiceDef.RangerResourceDef resourceDef : 
>resourceDefs) {
>+                if 
>(serviceDefResourceName.equals(resourceDef.getName())) 
>{
>+                    found = resourceDef;
>+                    break;
>+                }
>+            }
>+            if (found != null) {
>+                int level = found.getLevel();
>+                if (policyResourceNames != null) {
>+                    LevelResourceNames item = new LevelResourceNames();
>+                    item.level = level;
>+                    item.policyResource = policyResource;
>+                    tmpList.add(item);
>+                }
>+
>+            }
>+
>+        }
>+        Collections.sort(tmpList); // Sort in ascending order of levels
>+
>+        CharSequence matchesAnySeq = 
>RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING.subSequence(0, 1);
>+        CharSequence matchesSingleCharacterSeq = 
>RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING.subSequence(0, 1);
>+
>+        int priorityLevel = RANGER_POLICY_EVAL_RESERVED_SLOTS_NUMBER;
>+        boolean seenFirstMatchAny = false;
>+
>+        for (LevelResourceNames item : tmpList) {
>+            // Expect lowest level first
>+            List<String> resourceNames = item.policyResource.getValues();
>+            boolean foundStarWildcard = false;
>+            boolean foundQuestionWildcard = false;
>+            boolean foundMatchAny = false;
>+
>+            for (String resourceName : resourceNames) {
>+                if (resourceName.isEmpty() 
>||resourceName.equals(RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING)) {
>+                    foundMatchAny = true;
>+                    break;
>+                }
>+                if (resourceName.contains(matchesAnySeq))
>+                    foundStarWildcard = true;
>+                else if 
>(resourceName.contains(matchesSingleCharacterSeq))
>+                    foundQuestionWildcard = true;
>+            }
>+            if (foundMatchAny) {
>+                if (seenFirstMatchAny)
>+                    priorityLevel -= 
>RANGER_POLICY_EVAL_MATCH_ANY_WILDCARD_PREMIUM;
>+                else {
>+                    seenFirstMatchAny = true;
>+                }
>+            } else {
>+                priorityLevel +=  
>RANGER_POLICY_EVAL_RESERVED_SLOTS_PER_LEVEL_NUMBER;
>+                if (foundStarWildcard) priorityLevel -= 
>RANGER_POLICY_EVAL_CONTAINS_MATCH_ANY_WILDCARD_PREMIUM;
>+                else if (foundQuestionWildcard) priorityLevel -= 
>RANGER_POLICY_EVAL_CONTAINS_MATCH_ONE_CHARACTER_WILDCARD_PREMIUM;
>+
>+                RangerPolicy.RangerPolicyResource resource = 
>item.policyResource;
>+                if (resource.getIsExcludes()) priorityLevel -= 
>RANGER_POLICY_EVAL_HAS_EXCLUDES_PREMIUM;
>+                if (resource.getIsRecursive()) priorityLevel -= 
>RANGER_POLICY_EVAL_IS_RECURSIVE_PREMIUM;
>+            }
>+        }
>+
>+        if (hasPublicGroup) {
>+            priorityLevel -= 
>RANGER_POLICY_EVAL_PUBLIC_GROUP_ACCESS_PREMIUM;
>+        } else {
>+            priorityLevel -= groups.size();
>+        }
>+        priorityLevel -= users.size();
>+
>+        priorityLevel -= 
>Math.round(((float)RANGER_POLICY_EVAL_ALL_ACCESS_TYPES_PREMIUM * 
>accessPerms.size()) / serviceDef.getAccessTypes().size());
>+
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== 
>RangerOptimizedPolicyEvaluator.computePriority(), policyName:" + 
>policy.getName() + ", priority:" + priorityLevel);
>+        }
>+        return priorityLevel;
>+    }
>+    @Override
>+    protected void evaluatePolicyItemsForAccess(RangerAccessRequest 
>request, RangerAccessResult result) {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> 
>RangerOptimizedPolicyEvaluator.evaluatePolicyItemsForAccess()");
>+        }
>+        String accessType = request.getAccessType();
>+        if (StringUtils.isEmpty(accessType)) {
>+            accessType = RangerPolicyEngine.ANY_ACCESS;
>+        }
>+        boolean isAnyAccess = StringUtils.equals(accessType, 
>RangerPolicyEngine.ANY_ACCESS);
>+        boolean isAdminAccess = StringUtils.equals(accessType, 
>RangerPolicyEngine.ADMIN_ACCESS);
>+
>+        if (hasPublicGroup || users.contains(request.getUser()) || 
>CollectionUtils.containsAny(groups, request.getUserGroups())) {
>+            // No need to reject based on users and groups
>+
>+            if (isAnyAccess || (isAdminAccess && delegateAdmin) || 
>hasAllPerms || accessPerms.contains(accessType)) {
>+                // No need to reject based on aggregated access 
>permissions
>+                super.evaluatePolicyItemsForAccess(request, result);
>+            }
>+        }
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("<== 
>RangerOptimizedPolicyEvaluator.evaluatePolicyItemsForAccess()");
>+        }
>+
>+    }
>+    private boolean checkIfHasAllPerms() {
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> 
>RangerOptimizedPolicyEvaluator.checkIfHasAllPerms()");
>+        }
>+
>+        boolean result = true;
>+
>+        List<RangerServiceDef.RangerAccessTypeDef> serviceAccessTypes = 
>getServiceDef().getAccessTypes();
>+        for (RangerServiceDef.RangerAccessTypeDef serviceAccessType : 
>serviceAccessTypes) {
>+            if(! accessPerms.contains(serviceAccessType.getName())) {
>+                return false;
>+            }
>+        }
>+
>+        if(LOG.isDebugEnabled()) {
>+            LOG.debug("==> 
>RangerOptimizedPolicyEvaluator.checkIfHasAllPerms(), " + result);
>+        }
>+
>+        return result;
>+    }
>+
>+}
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/test/java/org/apache/ranger/plugin/policyevaluator/RangerDefa
>ul
>tPolicyEvaluatorTest.java
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluatorTest.java 
>b/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluatorTest.java
>index 9256995..9efbcaf 100644
>--- 
>a/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluatorTest.java
>+++ 
>b/agents-common/src/test/java/org/apache/ranger/plugin/policyevaluator/Ran
>ge
>rDefaultPolicyEvaluatorTest.java
>@@ -59,15 +59,15 @@ public class RangerDefaultPolicyEvaluatorTest {
> 	}
> 
> 	@Test
>-	public void test_newConditionEvauator() {
>+	public void test_newConditionEvaulator() {
> 		RangerDefaultPolicyEvaluator evaluator = new 
>RangerDefaultPolicyEvaluator();
>-		RangerConditionEvaluator ipMatcher = 
>evaluator.newConditionEvauator("org.apache.ranger.plugin.conditionevaluato
>r.
>RangerIpMatcher");
>+		RangerConditionEvaluator ipMatcher = 
>evaluator.newConditionEvaluator("org.apache.ranger.plugin.conditionevaluat
>or
>.RangerIpMatcher");
> 		assertTrue(ipMatcher.getClass().equals(RangerIpMatcher.class));
> 		
> 		// bogus value will lead to null object from coming back
>-		ipMatcher = 
>evaluator.newConditionEvauator("org.apache.ranger.plugin.conditionevaluato
>r.
>RangerIpMatcha");
>+		ipMatcher = 
>evaluator.newConditionEvaluator("org.apache.ranger.plugin.conditionevaluat
>or
>.RangerIpMatcha");
> 		assertNull(ipMatcher);
>-		ipMatcher = evaluator.newConditionEvauator("RangerIpMatcher");
>+		ipMatcher = evaluator.newConditionEvaluator("RangerIpMatcher");
> 		assertNull(ipMatcher);
> 	}
> 	
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/agen
>t
>s-common/src/test/resources/policyengine/test_policyengine_hdfs.json
>----------------------------------------------------------------------
>diff --git 
>a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.jso
>n 
>b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.jso
>n
>index 943fe80..2acf868 100644
>--- 
>a/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.jso
>n
>+++ 
>b/agents-common/src/test/resources/policyengine/test_policyengine_hdfs.jso
>n
>@@ -23,7 +23,7 @@
>     }
>     ,
>     {"id":2,"name":"allow-read-to-all under 
>/public/","isEnabled":true,"isAuditEnabled":false,
>-     "resources":{"path":{"values":["/public/"],"isRecursive":true}},
>+     "resources":{"path":{"values":["/public/*"],"isRecursive":true}},
>      "policyItems":[
>        
>{"accesses":[{"type":"read","isAllowed":true},{"type":"execute","isAllowed
>":
>true}],"users":[],"groups":["public"],"delegateAdmin":false}
>      ]
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/pom.
>x
>ml
>----------------------------------------------------------------------
>diff --git a/pom.xml b/pom.xml
>index 7df033d..fe340c4 100644
>--- a/pom.xml
>+++ b/pom.xml
>@@ -333,9 +333,9 @@
>              <descriptor>src/main/assembly/plugin-yarn.xml</descriptor>
>              <descriptor>src/main/assembly/admin-web.xml</descriptor>
>              <descriptor>src/main/assembly/usersync.xml</descriptor>
>-             <descriptor>src/main/assembly/ranger-src.xml</descriptor>
>              
><descriptor>src/main/assembly/migration-util.xml</descriptor>
>              <descriptor>src/main/assembly/kms.xml</descriptor>
>+             <descriptor>src/main/assembly/ranger-src.xml</descriptor>
>            </descriptors>
>          </configuration>
>       </plugin>
>
>http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2e0be82d/src/
>m
>ain/assembly/ranger-src.xml
>----------------------------------------------------------------------
>diff --git a/src/main/assembly/ranger-src.xml 
>b/src/main/assembly/ranger-src.xml
>index cf6b1da..077fa42 100644
>--- a/src/main/assembly/ranger-src.xml
>+++ b/src/main/assembly/ranger-src.xml
>@@ -16,45 +16,46 @@
>   limitations under the License.
> -->
> <assembly>
>-  <id>src</id>
>-  <formats>
>-     <format>tar.gz</format>
>-     <format>zip</format>
>-  </formats>
>-  <baseDirectory>${project.name}-${project.version}-src</baseDirectory>
>-  <includeBaseDirectory>true</includeBaseDirectory>
>-  <fileSets>
>-    <fileSet>
>-      <directory>.</directory>
>-      <includes>
>-        <include>LICENCE.txt</include>
>-        <include>README.txt</include>
>-        <include>NOTICE.txt</include>
>-	<include>DISCLAIMER.txt</include>
>-      </includes>
>-    </fileSet>
>-    <fileSet>
>-      <directory>.</directory>
>-      <useDefaultExcludes>true</useDefaultExcludes>
>-      <excludes>
>-        <exclude>.git/**</exclude>
>-        <exclude>**/.gitignore</exclude>
>-        <exclude>**/.svn</exclude>
>-        <exclude>**/*.iws</exclude>
>-        <exclude>**/*.ipr</exclude>
>-        <exclude>**/*.iml</exclude>
>-        <exclude>**/.classpath</exclude>
>-        <exclude>**/.project</exclude>
>-        <exclude>**/.settings</exclude>
>-        <exclude>**/target/**</exclude>
>-        <!-- until the code that does this is fixed -->
>-        <exclude>**/*.log</exclude>
>-        <exclude>**/build/**</exclude>
>-        <exclude>**/file:/**</exclude>
>-	<exclude>**/debugfiles.list</exclude>
>-	<exclude>**/debuglinks.list</exclude>
>-	<exclude>**/debugsources.list</exclude>
>-      </excludes>
>-    </fileSet>
>-  </fileSets>
>+    <id>src</id>
>+    <formats>
>+        <format>tar.gz</format>
>+        <format>zip</format>
>+    </formats>
>+    <baseDirectory>${project.name}-${project.version}-src</baseDirectory>
>+    <includeBaseDirectory>true</includeBaseDirectory>
>+    <fileSets>
>+        <fileSet>
>+            <directory>.</directory>
>+            <includes>
>+                <include>LICENCE.txt</include>
>+                <include>README.txt</include>
>+                <include>NOTICE.txt</include>
>+                <include>DISCLAIMER.txt</include>
>+            </includes>
>+            <useDefaultExcludes>true</useDefaultExcludes>
>+        </fileSet>
>+        <fileSet>
>+            <directory>.</directory>
>+            <excludes>
>+                <exclude>.git/**</exclude>
>+                <exclude>**/.gitignore</exclude>
>+                <exclude>**/.svn</exclude>
>+                <exclude>**/*.iws</exclude>
>+                <exclude>**/*.ipr</exclude>
>+                <exclude>**/*.iml</exclude>
>+                <exclude>**/.classpath</exclude>
>+                <exclude>**/.project</exclude>
>+                <exclude>**/.settings</exclude>
>+                <exclude>**/target/**</exclude>
>+                <exclude>.idea/**</exclude>
>+                <!-- until the code that does this is fixed -->
>+                <exclude>**/*.log</exclude>
>+                <exclude>**/build/**</exclude>
>+                <exclude>**/file:/**</exclude>
>+                <exclude>**/debugfiles.list</exclude>
>+                <exclude>**/debuglinks.list</exclude>
>+                <exclude>**/debugsources.list</exclude>
>+            </excludes>
>+        </fileSet>
>+    </fileSets>
> </assembly>
>
>
>