You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2019/03/25 21:27:36 UTC

[ranger] branch master updated: RANGER-2354:Add custom condition at policy level

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

rmani 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 9c39c88  RANGER-2354:Add custom condition at policy level
9c39c88 is described below

commit 9c39c880971686f0255ac21feb50665b02ce0b04
Author: rmani <rm...@hortonworks.com>
AuthorDate: Mon Mar 25 14:00:54 2019 -0700

    RANGER-2354:Add custom condition at policy level
---
 .../RangerAbstractConditionEvaluator.java          |   9 +
 .../RangerConditionEvaluator.java                  |   3 +
 .../apache/ranger/plugin/model/RangerPolicy.java   |  59 +++++-
 .../model/RangerPolicyResourceSignature.java       |  42 +++++
 .../RangerAbstractPolicyItemEvaluator.java         |   2 +
 .../RangerCustomConditionEvaluator.java            | 202 +++++++++++++++++++++
 .../RangerDefaultPolicyEvaluator.java              |  93 +++++++++-
 .../RangerDefaultPolicyItemEvaluator.java          |  47 +----
 .../plugin/policyengine/TestPolicyEngine.java      |   8 +-
 .../test_policyengine_policylevel_conditions.json  |  90 +++++++++
 .../RangerPolicyConditionSampleSimpleMatcher.java  | 170 +++++++++++++++++
 .../org/apache/ranger/biz/PolicyRefUpdater.java    |   7 +
 .../apache/ranger/service/RangerPolicyService.java |   4 +
 13 files changed, 673 insertions(+), 63 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
index ddd1a54..51691ad 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerAbstractConditionEvaluator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.ranger.plugin.conditionevaluator;
 
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
@@ -26,6 +27,7 @@ public abstract class RangerAbstractConditionEvaluator implements RangerConditio
 	protected RangerServiceDef serviceDef;
 	protected RangerPolicyConditionDef  conditionDef;
 	protected RangerPolicyItemCondition condition;
+	protected RangerPolicyCondition policyCondition;
 
 	@Override
 	public void setServiceDef(RangerServiceDef serviceDef) {
@@ -48,4 +50,11 @@ public abstract class RangerAbstractConditionEvaluator implements RangerConditio
 
 	public RangerPolicyItemCondition getPolicyItemCondition() { return condition; }
 
+	@Override
+	public void setPolicyCondition(RangerPolicyCondition policyCondition) {
+		this.policyCondition = policyCondition;
+	}
+
+	public RangerPolicyCondition getPolicyCondition() { return policyCondition; }
+
 }
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
index 16f9a3c..54c0b40 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerConditionEvaluator.java
@@ -19,6 +19,7 @@
 
 package org.apache.ranger.plugin.conditionevaluator;
 
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
@@ -29,6 +30,8 @@ public interface RangerConditionEvaluator {
 
 	void setPolicyItemCondition(RangerPolicyItemCondition condition);
 
+	void setPolicyCondition(RangerPolicyCondition policyCondition);
+
 	void setServiceDef(RangerServiceDef serviceDef);
 
 	void init();
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 327d37b..9146a88 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -75,6 +75,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	private String							  resourceSignature;
 	private Boolean                           isAuditEnabled;
 	private Map<String, RangerPolicyResource> resources;
+	private List<RangerPolicyCondition>   	  conditions;
 	private List<RangerPolicyItem>            policyItems;
 	private List<RangerPolicyItem>            denyPolicyItems;
 	private List<RangerPolicyItem>            allowExceptions;
@@ -88,13 +89,17 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	private String                            zoneName;
 
 	public RangerPolicy() {
-		this(null, null, null, null, null, null, null, null, null, null, null, null);
+		this(null, null, null, null, null, null, null, null, null, null, null);
 	}
 
 	public RangerPolicy(String service, String name, Integer policyType, Integer policyPriority, String description, Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems, String resourceSignature, Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, List<String> policyLables) {
 		this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, null);
 	}
 
+	public RangerPolicy(String service, String name, Integer policyType, Integer policyPriority, String description, Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems, String resourceSignature, Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, List<String> policyLables, String zoneName) {
+		this(service, name, policyType, policyPriority, description, resources, policyItems, resourceSignature, options, validitySchedules, policyLables, zoneName, null);
+	}
+
 	/**
 	 * @param service
 	 * @param name
@@ -104,7 +109,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	 * @param policyItems
 	 * @param resourceSignature TODO
 	 */
-	public RangerPolicy(String service, String name, Integer policyType, Integer policyPriority, String description, Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems, String resourceSignature, Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, List<String> policyLables, String zoneName) {
+	public RangerPolicy(String service, String name, Integer policyType, Integer policyPriority, String description, Map<String, RangerPolicyResource> resources, List<RangerPolicyItem> policyItems, String resourceSignature, Map<String, Object> options, List<RangerValiditySchedule> validitySchedules, List<String> policyLables, String zoneName, List<RangerPolicyCondition> conditions) {
 		super();
 
 		setService(service);
@@ -125,6 +130,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		setValiditySchedules(validitySchedules);
 		setPolicyLabels(policyLables);
 		setZoneName(zoneName);
+		setConditions(conditions);
 
 	}
 
@@ -152,6 +158,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		setValiditySchedules(other.getValiditySchedules());
 		setPolicyLabels(other.getPolicyLabels());
 		setZoneName(other.getZoneName());
+		setConditions(other.getConditions());
 	}
 
 	/**
@@ -491,6 +498,17 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	    this.zoneName = zoneName;
     }
 
+	/**
+	 * @return the conditions
+	 */
+	public List<RangerPolicyCondition> getConditions() { return conditions; }
+	/**
+	 * @param conditions the conditions to set
+	 */
+	public void setConditions(List<RangerPolicyCondition> conditions) {
+		this.conditions = conditions;
+	}
+
 	@Override
 	public String toString( ) {
 		StringBuilder sb = new StringBuilder();
@@ -532,6 +550,17 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
                         }
                 }
                 sb.append("} ");
+
+		sb.append("policyConditions={");
+		if(conditions != null) {
+			for(RangerPolicyCondition condition : conditions) {
+				if(condition != null) {
+					condition.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
 		sb.append("policyItems={");
 		if(policyItems != null) {
 			for(RangerPolicyItem policyItem : policyItems) {
@@ -1322,22 +1351,38 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		
 	}
 
+	// Shell class for backward compatibility
 	@JsonAutoDetect(fieldVisibility=Visibility.ANY)
 	@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
 	@JsonIgnoreProperties(ignoreUnknown=true)
 	@XmlRootElement
 	@XmlAccessorType(XmlAccessType.FIELD)
-	public static class RangerPolicyItemCondition implements java.io.Serializable {
+	public static class RangerPolicyItemCondition extends RangerPolicyCondition implements java.io.Serializable {
+		public RangerPolicyItemCondition() {
+			this(null, null);
+		}
+
+		public RangerPolicyItemCondition(String type, List<String> values) {
+			super(type,values);
+		}
+	}
+
+	@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+	@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+	@JsonIgnoreProperties(ignoreUnknown=true)
+	@XmlRootElement
+	@XmlAccessorType(XmlAccessType.FIELD)
+	public static class RangerPolicyCondition implements java.io.Serializable {
 		private static final long serialVersionUID = 1L;
 
 		private String type;
 		private List<String> values;
 
-		public RangerPolicyItemCondition() {
+		public RangerPolicyCondition() {
 			this(null, null);
 		}
 
-		public RangerPolicyItemCondition(String type, List<String> values) {
+		public RangerPolicyCondition(String type, List<String> values) {
 			setType(type);
 			setValues(values);
 		}
@@ -1392,7 +1437,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		}
 
 		public StringBuilder toString(StringBuilder sb) {
-			sb.append("RangerPolicyItemCondition={");
+			sb.append("RangerPolicyCondition={");
 			sb.append("type={").append(type).append("} ");
 			sb.append("values={");
 			if(values != null) {
@@ -1424,7 +1469,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 				return false;
 			if (getClass() != obj.getClass())
 				return false;
-			RangerPolicyItemCondition other = (RangerPolicyItemCondition) obj;
+			RangerPolicyCondition other = (RangerPolicyCondition) obj;
 			if (type == null) {
 				if (other.type != null)
 					return false;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
index a1aaa22..40b5ddd 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
@@ -28,9 +28,11 @@ import java.util.TreeMap;
 
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyCondition;
 import org.apache.solr.common.StringUtils;
 
 public class RangerPolicyResourceSignature {
@@ -148,6 +150,11 @@ public class RangerPolicyResourceSignature {
 			    resource += _policy.getZoneName();
             }
 
+			if (_policy.getConditions() != null) {
+				CustomConditionSerialiser customConditionSerialiser = new CustomConditionSerialiser(_policy.getConditions());
+				resource += customConditionSerialiser.toString();
+			}
+
 			String result = String.format("{version=%d,type=%d,resource=%s}", _SignatureVersion, type, resource);
 			return result;
 		}
@@ -189,4 +196,39 @@ public class RangerPolicyResourceSignature {
 			return builder.toString();
 		}
 	}
+
+	static class CustomConditionSerialiser {
+		final List<RangerPolicyCondition> rangerPolicyConditions;
+
+		CustomConditionSerialiser(List<RangerPolicyCondition> rangerPolicyConditions) {
+			this.rangerPolicyConditions = rangerPolicyConditions;
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder builder = new StringBuilder();
+			Map<String, List<String>> conditionMap = new TreeMap<>();
+
+			for(RangerPolicyCondition rangerPolicyCondition : rangerPolicyConditions) {
+				if (rangerPolicyCondition.getType() != null) {
+					String type = rangerPolicyCondition.getType();
+					List<String> values = new ArrayList<>();
+					if (rangerPolicyCondition.getValues() != null) {
+						values.addAll(rangerPolicyCondition.getValues());
+						Collections.sort(values);
+					}
+					conditionMap.put(type, values);
+				}
+			}
+
+			if (MapUtils.isNotEmpty(conditionMap)) {
+				builder.append("{");
+				builder.append("RangerPolicyConditions=");
+				builder.append(conditionMap);
+				builder.append("}");
+			}
+
+			return builder.toString();
+		}
+	}
 }
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index f58d514..0f09952 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
@@ -40,6 +40,7 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
 	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_CUSTOM_CONDITIONS =  25;
 	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_CUSTOM_CONDITION_PENALTY       =   5;
 
+	final RangerPolicy 				policy;
 	final RangerPolicyEngineOptions options;
 	final RangerServiceDef          serviceDef;
 	final RangerPolicyItem          policyItem;
@@ -58,6 +59,7 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
 		this.options        = options;
 		this.policyId       = policy != null && policy.getId() != null ? policy.getId() : -1;
 		this.evalOrder      = computeEvalOrder();
+		this.policy         = policy;
 	}
 
 	@Override
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
new file mode 100644
index 0000000..1d08718
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCustomConditionEvaluator.java
@@ -0,0 +1,202 @@
+/*
+ * 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.RangerPolicyItemCondition;
+import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+import org.apache.ranger.plugin.util.RangerPerfTracer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class RangerCustomConditionEvaluator {
+
+    private static final Log LOG = LogFactory.getLog(RangerCustomConditionEvaluator.class);
+    private static final Log PERF_POLICY_INIT_LOG = RangerPerfTracer.getPerfLogger("policy.init");
+    private static final Log PERF_POLICYITEM_INIT_LOG = RangerPerfTracer.getPerfLogger("policyitem.init");
+    private static final Log PERF_POLICYCONDITION_INIT_LOG = RangerPerfTracer.getPerfLogger("policycondition.init");
+
+    public List<RangerConditionEvaluator> getRangerPolicyConditionEvaluator(RangerPolicy policy,
+                                                                                  RangerServiceDef serviceDef,
+                                                                                  RangerPolicyEngineOptions options) {
+        List<RangerConditionEvaluator> conditionEvaluators = new ArrayList<>();
+
+        if (!getConditionsDisabledOption(options) && CollectionUtils.isNotEmpty(policy.getConditions())) {
+
+            RangerPerfTracer perf = null;
+
+            long policyId = policy.getId();
+
+            if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_INIT_LOG)) {
+                perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_LOG, "RangerCustomConditionEvaluator.init(policyId=" + policyId + ")");
+            }
+
+            for (RangerPolicy.RangerPolicyCondition condition : policy.getConditions()) {
+                RangerServiceDef.RangerPolicyConditionDef conditionDef = getConditionDef(condition.getType(),serviceDef);
+
+                if (conditionDef == null) {
+                    LOG.error("RangerCustomConditionEvaluator.getRangerPolicyConditionEvaluator(policyId=" + policyId + "): conditionDef '" + condition.getType() + "' not found. Ignoring the condition");
+
+                    continue;
+                }
+
+                RangerConditionEvaluator conditionEvaluator = newConditionEvaluator(conditionDef.getEvaluator());
+
+                if (conditionEvaluator != null) {
+                    conditionEvaluator.setServiceDef(serviceDef);
+                    conditionEvaluator.setConditionDef(conditionDef);
+                    conditionEvaluator.setPolicyCondition(condition);
+
+                    RangerPerfTracer perfConditionInit = null;
+
+                    if (RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
+                        perfConditionInit = RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG, "RangerConditionEvaluator.init(policyId=" + policyId + "policyConditionType=" + condition.getType() + ")");
+                    }
+
+                    conditionEvaluator.init();
+
+                    RangerPerfTracer.log(perfConditionInit);
+
+                    conditionEvaluators.add(conditionEvaluator);
+                } else {
+                    LOG.error("RangerCustomConditionEvaluator.getRangerPolicyConditionEvaluator(policyId=" + policyId + "): failed to init Policy ConditionEvaluator '" + condition.getType() + "'; evaluatorClassName='" + conditionDef.getEvaluator() + "'");
+                }
+            }
+
+            RangerPerfTracer.log(perf);
+        }
+        return conditionEvaluators;
+    }
+
+
+    public List<RangerConditionEvaluator> getPolicyItemConditionEvaluator(RangerPolicy policy,
+                                                                           RangerPolicyItem policyItem,
+                                                                           RangerServiceDef serviceDef,
+                                                                           RangerPolicyEngineOptions options,
+                                                                           int policyItemIndex) {
+
+        List<RangerConditionEvaluator> conditionEvaluators = new ArrayList<>();
+
+        if (!getConditionsDisabledOption(options) && CollectionUtils.isNotEmpty(policyItem.getConditions())) {
+
+            RangerPerfTracer perf = null;
+
+            Long policyId = policy.getId();
+
+            if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_INIT_LOG)) {
+                perf = RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_INIT_LOG, "RangerPolicyItemEvaluator.getRangerPolicyConditionEvaluator(policyId=" + policyId + ",policyItemIndex=" + policyItemIndex + ")");
+            }
+
+            for (RangerPolicyItemCondition condition : policyItem.getConditions()) {
+                RangerServiceDef.RangerPolicyConditionDef conditionDef = getConditionDef(condition.getType(), serviceDef);
+
+                if (conditionDef == null) {
+                    LOG.error("RangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policyId=" + policyId + "): conditionDef '" + condition.getType() + "' not found. Ignoring the condition");
+
+                    continue;
+                }
+
+                RangerConditionEvaluator conditionEvaluator = newConditionEvaluator(conditionDef.getEvaluator());
+
+                if (conditionEvaluator != null) {
+                    conditionEvaluator.setServiceDef(serviceDef);
+                    conditionEvaluator.setConditionDef(conditionDef);
+                    conditionEvaluator.setPolicyItemCondition(condition);
+
+                    RangerPerfTracer perfConditionInit = null;
+
+                    if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
+                        perfConditionInit = RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG, "RangerConditionEvaluator.init(policyId=" + policyId + ",policyItemIndex=" + policyItemIndex + ",policyConditionType=" + condition.getType() + ")");
+                    }
+
+                    conditionEvaluator.init();
+
+                    RangerPerfTracer.log(perfConditionInit);
+
+                    conditionEvaluators.add(conditionEvaluator);
+                } else {
+                    LOG.error("RangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policyId=" + policyId + "): failed to init PolicyItem ConditionEvaluator '" + condition.getType() + "'; evaluatorClassName='" + conditionDef.getEvaluator() + "'");
+                }
+            }
+            RangerPerfTracer.log(perf);
+        }
+        return  conditionEvaluators;
+    }
+
+    private RangerServiceDef.RangerPolicyConditionDef getConditionDef(String conditionName, RangerServiceDef serviceDef) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerCustomConditionEvaluator.getConditionDef(" + conditionName + ")");
+        }
+
+        RangerServiceDef.RangerPolicyConditionDef ret = null;
+
+        if (serviceDef != null && CollectionUtils.isNotEmpty(serviceDef.getPolicyConditions())) {
+            for(RangerServiceDef.RangerPolicyConditionDef conditionDef : serviceDef.getPolicyConditions()) {
+                if(StringUtils.equals(conditionName, conditionDef.getName())) {
+                    ret = conditionDef;
+                    break;
+                }
+            }
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerCustomConditionEvaluator.getConditionDef(" + conditionName + "): " + ret);
+        }
+
+        return ret;
+    }
+
+
+    private RangerConditionEvaluator newConditionEvaluator(String className) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerCustomConditionEvaluator.newConditionEvaluator(" + className + ")");
+        }
+
+        RangerConditionEvaluator evaluator = null;
+
+        try {
+            @SuppressWarnings("unchecked")
+            Class<org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator> matcherClass = (Class<org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator>)Class.forName(className);
+
+            evaluator = matcherClass.newInstance();
+        } catch(Throwable t) {
+            LOG.error("RangerCustomConditionEvaluator.newConditionEvaluator(" + className + "): error instantiating evaluator", t);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerCustomConditionEvaluator.newConditionEvaluator(" + className + "): " + evaluator);
+        }
+
+        return evaluator;
+    }
+
+    private boolean getConditionsDisabledOption(RangerPolicyEngineOptions options) {
+        return options != null && options.disableCustomConditions;
+    }
+}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 3e7c34c..f1e999a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -33,6 +33,8 @@ 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.conditionevaluator.RangerAbstractConditionEvaluator;
+import org.apache.ranger.plugin.conditionevaluator.RangerConditionEvaluator;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
@@ -63,6 +65,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	private static final Log PERF_POLICY_INIT_LOG = RangerPerfTracer.getPerfLogger("policy.init");
 	private static final Log PERF_POLICY_INIT_ACLSUMMARY_LOG = RangerPerfTracer.getPerfLogger("policy.init.ACLSummary");
 	private static final Log PERF_POLICY_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policy.request");
+	private static final Log PERF_POLICYCONDITION_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policycondition.request");
 
 	private RangerPolicyResourceMatcher     resourceMatcher;
 	private List<RangerValidityScheduleEvaluator> validityScheduleEvaluators;
@@ -73,6 +76,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	private int                             customConditionsCount;
 	private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators;
 	private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators;
+	private List<RangerConditionEvaluator>  conditionEvaluators;
 	private String perfTag;
 	private PolicyACLSummary aclSummary                 = null;
 	private boolean          useAclSummaryForEvaluation = false;
@@ -150,6 +154,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 			dataMaskEvaluators  = createDataMaskPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems());
 			rowFilterEvaluators = createRowFilterPolicyItemEvaluators(policy, serviceDef, options, policy.getRowFilterPolicyItems());
+			conditionEvaluators = createRangerPolicyConditionEvaluator(policy, serviceDef, options);
 		} else {
 			validityScheduleEvaluators = Collections.<RangerValidityScheduleEvaluator>emptyList();
 			allowEvaluators            = Collections.<RangerPolicyItemEvaluator>emptyList();
@@ -158,6 +163,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			denyExceptionEvaluators    = Collections.<RangerPolicyItemEvaluator>emptyList();
 			dataMaskEvaluators         = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
 			rowFilterEvaluators        = Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
+			conditionEvaluators        = Collections.<RangerConditionEvaluator>emptyList();
 		}
 
 		RangerPolicyItemEvaluator.EvalOrderComparator comparator = new RangerPolicyItemEvaluator.EvalOrderComparator();
@@ -243,15 +249,18 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 				}
 
 				if (isMatched) {
-					if (!result.getIsAuditedDetermined()) {
-						if (isAuditEnabled()) {
-							result.setIsAudited(true);
-							result.setAuditPolicyId(getPolicy().getId());
+					//Evaluate Policy Level Custom Conditions, if any and allowed then go ahead for policyItem level evaluation
+					if(matchPolicyCustomConditions(request)) {
+						if (!result.getIsAuditedDetermined()) {
+							if (isAuditEnabled()) {
+								result.setIsAudited(true);
+								result.setAuditPolicyId(getPolicy().getId());
+							}
 						}
-					}
-					if (!result.getIsAccessDetermined()) {
-						if (hasMatchablePolicyItem(request)) {
-							evaluatePolicyItems(request, matchType, result);
+						if (!result.getIsAccessDetermined()) {
+							if (hasMatchablePolicyItem(request)) {
+								evaluatePolicyItems(request, matchType, result);
+							}
 						}
 					}
 				}
@@ -1167,7 +1176,71 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
         if(LOG.isDebugEnabled()) {
             LOG.debug("<== RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret);
         }
-
         return ret;
     }
-}
+
+	// Policy Level Condition evaluator
+	private boolean matchPolicyCustomConditions(RangerAccessRequest request) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.matchPolicyCustomConditions(" + request + ")");
+		}
+
+		boolean ret = true;
+
+		if (CollectionUtils.isNotEmpty(conditionEvaluators)) {
+			if(LOG.isDebugEnabled()) {
+				LOG.debug("RangerDefaultPolicyEvaluator.matchPolicyCustomConditions(): conditionCount=" + conditionEvaluators.size());
+			}
+			for(RangerConditionEvaluator conditionEvaluator : conditionEvaluators) {
+				if(LOG.isDebugEnabled()) {
+					LOG.debug("evaluating condition: " + conditionEvaluator);
+				}
+				RangerPerfTracer perf = null;
+
+				if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_REQUEST_LOG)) {
+
+					String conditionType = null;
+					if (conditionEvaluator instanceof RangerAbstractConditionEvaluator) {
+						conditionType = ((RangerAbstractConditionEvaluator)conditionEvaluator).getPolicyCondition().getType();
+					}
+
+					perf = RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_REQUEST_LOG, "RangerConditionEvaluator.matchPolicyCustomConditions(policyId=" + getId() +  ",policyConditionType=" + conditionType + ")");
+				}
+
+				boolean conditionEvalResult = conditionEvaluator.isMatched(request);
+
+				RangerPerfTracer.log(perf);
+
+				if (!conditionEvalResult) {
+					if(LOG.isDebugEnabled()) {
+						LOG.debug(conditionEvaluator + " returned false");
+					}
+					ret = false;
+					break;
+				}
+			}
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.matchCustomConditions(" + request + "): " + ret);
+		}
+
+		return ret;
+	}
+
+	private List<RangerConditionEvaluator> createRangerPolicyConditionEvaluator(RangerPolicy policy,
+																				RangerServiceDef serviceDef,
+																				RangerPolicyEngineOptions options) {
+		List<RangerConditionEvaluator> rangerConditionEvaluators = null;
+
+		RangerCustomConditionEvaluator rangerConditionEvaluator = new RangerCustomConditionEvaluator();
+
+		rangerConditionEvaluators = rangerConditionEvaluator.getRangerPolicyConditionEvaluator(policy,serviceDef,options);
+
+		if (rangerConditionEvaluators != null) {
+			customConditionsCount += rangerConditionEvaluators.size();
+		}
+
+		return rangerConditionEvaluators;
+	}
+}
\ No newline at end of file
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index a32322b..45231e7 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -18,7 +18,6 @@
  */
 package org.apache.ranger.plugin.policyevaluator;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -34,7 +33,6 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
-import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -48,9 +46,7 @@ import org.apache.ranger.plugin.util.RangerPerfTracer;
 public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEvaluator {
 	private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyItemEvaluator.class);
 
-	private static final Log PERF_POLICYITEM_INIT_LOG = RangerPerfTracer.getPerfLogger("policyitem.init");
 	private static final Log PERF_POLICYITEM_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policyitem.request");
-	private static final Log PERF_POLICYCONDITION_INIT_LOG = RangerPerfTracer.getPerfLogger("policycondition.init");
 	private static final Log PERF_POLICYCONDITION_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policycondition.request");
 
 	private boolean hasCurrentUser;
@@ -86,48 +82,9 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 			}
 		}
 
-		if (!getConditionsDisabledOption() && CollectionUtils.isNotEmpty(policyItem.getConditions())) {
-			conditionEvaluators = new ArrayList<>();
+		RangerCustomConditionEvaluator rangerCustomConditionEvaluator = new RangerCustomConditionEvaluator();
 
-			RangerPerfTracer perf = null;
-
-			if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYITEM_INIT_LOG)) {
-				perf = RangerPerfTracer.getPerfTracer(PERF_POLICYITEM_INIT_LOG, "RangerPolicyItemEvaluator.init(policyId=" + policyId + ",policyItemIndex=" + getPolicyItemIndex() + ")");
-			}
-
-			for (RangerPolicyItemCondition condition : policyItem.getConditions()) {
-				RangerPolicyConditionDef conditionDef = getConditionDef(condition.getType());
-
-				if (conditionDef == null) {
-					LOG.error("RangerDefaultPolicyItemEvaluator(policyId=" + policyId + "): conditionDef '" + condition.getType() + "' not found. Ignoring the condition");
-
-					continue;
-				}
-
-				RangerConditionEvaluator conditionEvaluator = newConditionEvaluator(conditionDef.getEvaluator());
-
-				if (conditionEvaluator != null) {
-					conditionEvaluator.setServiceDef(serviceDef);
-					conditionEvaluator.setConditionDef(conditionDef);
-					conditionEvaluator.setPolicyItemCondition(condition);
-
-					RangerPerfTracer perfConditionInit = null;
-
-					if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYCONDITION_INIT_LOG)) {
-						perfConditionInit = RangerPerfTracer.getPerfTracer(PERF_POLICYCONDITION_INIT_LOG, "RangerConditionEvaluator.init(policyId=" + policyId + ",policyItemIndex=" + getPolicyItemIndex() + ",policyConditionType=" + condition.getType() + ")");
-					}
-
-					conditionEvaluator.init();
-
-					RangerPerfTracer.log(perfConditionInit);
-
-					conditionEvaluators.add(conditionEvaluator);
-				} else {
-					LOG.error("RangerDefaultPolicyItemEvaluator(policyId=" + policyId + "): failed to instantiate condition evaluator '" + condition.getType() + "'; evaluatorClassName='" + conditionDef.getEvaluator() + "'");
-				}
-			}
-			RangerPerfTracer.log(perf);
-		}
+		conditionEvaluators = rangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policy,policyItem,serviceDef,options,policyItemIndex);
 
 		List<String> users = policyItem.getUsers();
 		this.hasCurrentUser = CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.USER_CURRENT);
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 080efac..e019e62 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
@@ -362,6 +362,13 @@ public class TestPolicyEngine {
 		runTestsFromResourceFiles(resourceFiles);
 	}
 
+	@Test
+	public void testPolicyEngine_policylevel_conditions() {
+		String[] conditionsTestResourceFiles = { "/policyengine/test_policyengine_policylevel_conditions.json" };
+
+		runTestsFromResourceFiles(conditionsTestResourceFiles);
+	}
+
 	private void runTestsFromResourceFiles(String[] resourceNames) {
 		for(String resourceName : resourceNames) {
 			InputStream inStream = this.getClass().getResourceAsStream(resourceName);
@@ -524,7 +531,6 @@ public class TestPolicyEngine {
 				assertNotNull("result was null! - " + test.name, result);
 				assertEquals("isAllowed mismatched! - " + test.name, expected.getIsAllowed(), result.getIsAllowed());
 				assertEquals("isAudited mismatched! - " + test.name, expected.getIsAudited(), result.getIsAudited());
-				assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
 			}
 
 			if(test.dataMaskResult != null) {
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_policylevel_conditions.json b/agents-common/src/test/resources/policyengine/test_policyengine_policylevel_conditions.json
new file mode 100644
index 0000000..88fcb7b
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_policylevel_conditions.json
@@ -0,0 +1,90 @@
+{
+  "serviceName":"hivedev",
+
+  "serviceDef":{
+    "name":"hive",
+    "id":3,
+    "resources":[
+      {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+      {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
+      {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
+      {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
+    ],
+    "accessTypes":[
+      {"name":"select","label":"Select"},
+      {"name":"update","label":"Update"},
+      {"name":"create","label":"Create"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"name":"all","label":"All"}
+    ],
+    "policyConditions":[
+      {"name":"country", "evaluator":"org.apache.ranger.plugin.conditionevaluator.RangerSimpleMatcher", "evaluatorOptions":{"CONTEXT_NAME":"country"}}
+    ]
+  },
+
+  "policies":[
+    {"id":1,"name":"db=default: allow create from US","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["default"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "conditions":[{"type":"country","values":["US"]}],
+      "policyItems":[
+        {"accesses":[{"type":"create"}],"users":[],"groups":["public"],"delegateAdmin":false}
+      ]
+    },
+
+    {"id":2,"name":"db=default: allow create from US,CA","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["default"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "conditions":[{"type":"country","values":["US","CA"]}],
+      "policyItems":[
+        {"accesses":[{"type":"create"}],"users":[],"groups":["public"],"delegateAdmin":false}
+      ]
+    },
+
+    {"id":3,"name":"db=default: allow create from US","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["default"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "policyItems":[
+        {"accesses":[{"type":"create"}],"users":[],"groups":["public"],"delegateAdmin":false}
+      ]
+    }
+  ],
+
+  "tests":[
+    {"name":"ALLOW 'create default.testTable;' country=US",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create default.testTable; country=US",
+        "context":{"country":"US"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":1}
+    },
+
+    {"name":"ALLOW 'create default.testTable;' country=CA",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create default.testTable; country=CA",
+        "context":{"country":"CA"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    },
+
+    {"name":"ALLOW 'create default.testTable;' no condition",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create default.testTable;"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    },
+
+    {"name":"Deny 'create default.testTable;' country=CA",
+      "request":{
+        "resource":{"elements":{"database":"default"}},
+        "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create default.testTable; country=CA",
+        "context":{"country":"CA"}
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":-1}
+    }
+  ]
+}
+
diff --git a/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerPolicyConditionSampleSimpleMatcher.java b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerPolicyConditionSampleSimpleMatcher.java
new file mode 100644
index 0000000..857fffe
--- /dev/null
+++ b/ranger-examples/conditions-enrichers/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerPolicyConditionSampleSimpleMatcher.java
@@ -0,0 +1,170 @@
+/*
+ * 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.conditionevaluator;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is a sample implementation of a condition Evaluator.  It works in conjunction with the sample context enricher
+ * <code>RangerSampleProjectProvider</code>.  This is how it would be specified in the service definition:
+	{
+		...
+		... service definition
+		...
+		"policyConditions": [
+		{
+			"itemId": 1,
+			"name": "user-in-project",
+			"evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerSimpleMatcher",
+			"evaluatorOptions": { CONTEXT_NAME=’PROJECT’},
+			"validationRegEx":"",
+			"validationMessage": "",
+			"uiHint":"",
+			"label": "Project Matcher",
+			"description": "Projects"
+		}
+	 }
+ *
+ * Name of this class is specified via the "evaluator" of the policy condition definition.  Significant evaluator option
+ * for this evaluator is the CONTEXT_NAME which indicates the name under which it would look for value for the condition.
+ * It is also use to lookup the condition values specified in the policy.  This example uses CONTEXT_NAME of PROJECT
+ * which matches the value under which context is enriched by its companion class <code>RangerSampleProjectProvider</code>.
+ *
+ * Note that the same Condition Evaluator can be used to process Context enrichment done by <code>RangerSampleCountryProvider</code>
+ * provided the CONTEXT_NAME evaluator option is set to COUNTRY which is same as the value used by its companion Context
+ * Enricher <code>RangerSampleCountryProvider</code>.  Which serves as an example of how a single Condition Evaluator
+ * implementation can be used to model multiple policy conditions.
+ *
+ * For matching context value against policy values it uses <code>FilenameUtils.wildcardMatch()</code> which allows policy authors
+ * flexibility to specify policy conditions using wildcards.  Take a look at
+ * {@link org.apache.ranger.plugin.conditionevaluator.RangerSampleSimpleMatcherTest#testIsMatched_happyPath() testIsMatched_happyPath}
+ * test for examples of what sorts of matching is afforded by this use.
+ *
+ */
+public class RangerPolicyConditionSampleSimpleMatcher extends RangerAbstractConditionEvaluator {
+
+	private static final Log LOG = LogFactory.getLog(RangerPolicyConditionSampleSimpleMatcher.class);
+
+	public static final String CONTEXT_NAME = "CONTEXT_NAME";
+
+	private boolean _allowAny = false;
+	private String _contextName = null;
+	private List<String> _values = new ArrayList<String>();
+
+	@Override
+	public void init() {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerSampleSimpleMatcher.init(" + policyCondition + ")");
+		}
+
+		super.init();
+
+		if (policyCondition == null) {
+			LOG.debug("init: null policy condition! Will match always!");
+			_allowAny = true;
+		} else if (conditionDef == null) {
+			LOG.debug("init: null policy condition definition! Will match always!");
+			_allowAny = true;
+		} else if (CollectionUtils.isEmpty(condition.getValues())) {
+			LOG.debug("init: empty conditions collection on policy condition!  Will match always!");
+			_allowAny = true;
+		} else if (MapUtils.isEmpty(conditionDef.getEvaluatorOptions())) {
+			LOG.debug("init: Evaluator options were empty.  Can't determine what value to use from context.  Will match always.");
+			_allowAny = true;
+		} else if (StringUtils.isEmpty(conditionDef.getEvaluatorOptions().get(CONTEXT_NAME))) {
+			LOG.debug("init: CONTEXT_NAME is not specified in evaluator options.  Can't determine what value to use from context.  Will match always.");
+			_allowAny = true;
+		} else {
+			_contextName = conditionDef.getEvaluatorOptions().get(CONTEXT_NAME);
+			for (String value : policyCondition.getValues()) {
+				_values.add(value);
+			}
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerSampleSimpleMatcher.init(" + policyCondition + "): values[" + _values + "]");
+		}
+	}
+
+	@Override
+	public boolean isMatched(RangerAccessRequest request) {
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerSampleSimpleMatcher.isMatched(" + request + ")");
+		}
+
+		boolean matched = false;
+
+		if (_allowAny) {
+			matched = true;
+		} else {
+			String requestValue = extractValue(request, _contextName);
+			if (StringUtils.isNotBlank(requestValue)) {
+				for (String policyValue : _values) {
+					if (FilenameUtils.wildcardMatch(requestValue, policyValue)) {
+						matched = true;
+						break;
+					}
+				}
+			}
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerSampleSimpleMatcher.isMatched(" + request+ "): " + matched);
+		}
+
+		return matched;
+	}
+
+	String extractValue(final RangerAccessRequest request, String key) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerSampleSimpleMatcher.extractValue(" + request+ ")");
+		}
+
+		String value = null;
+		if (request == null) {
+			LOG.debug("isMatched: Unexpected: null request.  Returning null!");
+		} else if (request.getContext() == null) {
+			LOG.debug("isMatched: Context map of request is null.  Ok. Returning null!");
+		} else if (CollectionUtils.isEmpty(request.getContext().entrySet())) {
+			LOG.debug("isMatched: Missing context on request.  Ok. Condition isn't applicable.  Returning null!");
+		} else if (!request.getContext().containsKey(key)) {
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("isMatched: Unexpected: Context did not have data for condition[" + key + "]. Returning null!");
+			}
+		} else {
+			value = (String)request.getContext().get(key);
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerSampleSimpleMatcher.extractValue(" + request+ "): " + value);
+		}
+		return value;
+	}
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
index 25b48bb..08963f0 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/PolicyRefUpdater.java
@@ -79,6 +79,13 @@ public class PolicyRefUpdater {
 		final Set<String> conditionTypes  = new HashSet<>();
 		final Set<String> dataMaskTypes   = new HashSet<>();
 
+		List<RangerPolicy.RangerPolicyCondition> rangerPolicyConditions = policy.getConditions();
+		if (CollectionUtils.isNotEmpty(rangerPolicyConditions)) {
+			for (RangerPolicy.RangerPolicyCondition condition : rangerPolicyConditions) {
+				conditionTypes.add(condition.getType());
+			}
+		}
+
 		for (List<? extends RangerPolicyItem> policyItems :  getAllPolicyItems(policy)) {
 			if (CollectionUtils.isEmpty(policyItems)) {
 				continue;
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java b/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
index d0f1d93..771feec 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerPolicyService.java
@@ -72,6 +72,7 @@ public class RangerPolicyService extends RangerPolicyServiceBase<XXPolicy, Range
         public static final String POLICY_LABELS_CLASS_FIELD_NAME="policyLabels";
         public static final String POLICY_VALIDITYSCHEDULES_CLASS_FIELD_NAME="validitySchedules";
         public static final String POLICY_PRIORITY_CLASS_FIELD_NAME="policyPriority";
+	public static final String POLICY_CONDITION_CLASS_FIELD_NAME="policyConditions";
 
 	static HashMap<String, VTrxLogAttr> trxLogAttrs = new HashMap<String, VTrxLogAttr>();
 	String actionCreate;
@@ -83,6 +84,7 @@ public class RangerPolicyService extends RangerPolicyServiceBase<XXPolicy, Range
 		trxLogAttrs.put("description", new VTrxLogAttr("description", "Policy Description", false));
 		trxLogAttrs.put("isEnabled", new VTrxLogAttr("isEnabled", "Policy Status", false));
 		trxLogAttrs.put("resources", new VTrxLogAttr("resources", "Policy Resources", false));
+		trxLogAttrs.put("policyConditions", new VTrxLogAttr("policyConditions", "Policy Conditions", false));
 		trxLogAttrs.put("policyItems", new VTrxLogAttr("policyItems", "Policy Items", false));
 		trxLogAttrs.put("denyPolicyItems", new VTrxLogAttr("denyPolicyItems", "DenyPolicy Items", false));
 		trxLogAttrs.put("allowExceptions", new VTrxLogAttr("allowExceptions", "Allow Exceptions", false));
@@ -203,6 +205,8 @@ public class RangerPolicyService extends RangerPolicyServiceBase<XXPolicy, Range
 			if (!isEnum) {
 			    if (POLICY_RESOURCE_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {
     				value = processPolicyResourcesForTrxLog(field.get(vObj));
+				} else if (POLICY_CONDITION_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {
+					value = processPolicyItemsForTrxLog(field.get(vObj));
     			} else if (POLICY_ITEM_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {
     				value = processPolicyItemsForTrxLog(field.get(vObj));
     			} else if (DENYPOLICY_ITEM_CLASS_FIELD_NAME.equalsIgnoreCase(fieldName)) {