ranger-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mad...@apache.org
Subject [2/2] incubator-ranger git commit: RANGER-606: policy updated to support for policyItems for deny/allowExceptions/denyExceptions (in addition to existing allow)
Date Wed, 09 Sep 2015 01:31:05 GMT
RANGER-606: policy updated to support for policyItems for deny/allowExceptions/denyExceptions (in addition to existing allow)


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

Branch: refs/heads/tag-policy
Commit: c18f8bf7407809e2917abd7f00406043281a7e27
Parents: e8ceab4
Author: Madhan Neethiraj <madhan@apache.org>
Authored: Sun Sep 6 02:00:40 2015 -0700
Committer: Madhan Neethiraj <madhan@apache.org>
Committed: Tue Sep 8 15:47:33 2015 -0700

----------------------------------------------------------------------
 .../ranger/plugin/model/RangerPolicy.java       | 158 +++++++++----
 .../model/validation/RangerPolicyValidator.java |  28 ++-
 .../plugin/policyengine/RangerAccessResult.java |   7 +-
 .../policyengine/RangerPolicyEngineImpl.java    |  70 ++++--
 .../policyengine/RangerPolicyRepository.java    | 106 +++++----
 .../RangerAbstractPolicyEvaluator.java          |   9 +
 .../RangerAbstractPolicyItemEvaluator.java      |  26 ++-
 .../RangerDefaultPolicyEvaluator.java           | 225 ++++++++++++++-----
 .../RangerDefaultPolicyItemEvaluator.java       |   4 +-
 .../RangerOptimizedPolicyEvaluator.java         |  63 +++---
 .../policyevaluator/RangerPolicyEvaluator.java  |   4 +
 .../RangerPolicyItemEvaluator.java              |   6 +
 .../plugin/store/AbstractPredicateUtil.java     |  38 +++-
 .../policyengine/test_policyengine_hbase.json   |   8 +
 ...test_policyengine_hive_mutex_conditions.json |  73 +++---
 .../test_policyengine_tag_hdfs.json             |  72 +++---
 .../test_policyengine_tag_hive.json             |  35 +--
 .../org/apache/ranger/biz/ServiceDBStore.java   |  28 ++-
 .../org/apache/ranger/rest/ServiceREST.java     |  31 ++-
 .../ranger/service/RangerPolicyService.java     |   3 +-
 .../ranger/service/RangerPolicyServiceBase.java |  26 ++-
 .../RangerPolicyWithAssignedIdService.java      |   3 +-
 .../main/webapp/scripts/models/RangerPolicy.js  |   7 -
 .../scripts/modules/globalize/message/en.js     |   1 -
 .../src/main/webapp/scripts/utils/XAUtils.js    |  13 +-
 .../scripts/views/policies/PermissionList.js    |  28 +--
 .../scripts/views/policies/RangerPolicyForm.js  |  84 +++++--
 .../scripts/views/policies/RangerPolicyRO.js    |   1 -
 .../views/policies/RangerPolicyTableLayout.js   |  11 -
 .../views/reports/PlugableServiceDiffDetail.js  |  16 --
 .../scripts/views/reports/UserAccessLayout.js   |  11 -
 .../templates/policies/PermissionItem.html      |   3 -
 .../templates/policies/PermissionList.html      |  15 +-
 .../policies/RangerPolicyForm_tmpl.html         |  54 ++++-
 .../templates/policies/RangerPolicyRO_tmpl.html |   3 -
 .../PlugableServicePolicyDeleteDiff_tmpl.html   |   1 -
 .../reports/PlugableServicePolicyDiff_tmpl.html |   1 -
 .../PlugableServicePolicyUpdateDiff_tmpl.html   |   2 -
 .../ranger/service/TestRangerPolicyService.java |   6 +-
 39 files changed, 864 insertions(+), 416 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
----------------------------------------------------------------------
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 19c2b50..6486429 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
@@ -28,7 +28,6 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.apache.commons.collections.CollectionUtils;
 import org.codehaus.jackson.annotate.JsonAutoDetect;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
@@ -45,26 +44,24 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	// For future use
 	private static final long serialVersionUID = 1L;
 
-	public static final int POLICY_TYPE_ALLOW           = 0;
-	public static final int POLICY_TYPE_DENY            = 1;
-	public static final int POLICY_ITEM_TYPE_DEFAULT    = 0;
-	public static final int POLICY_ITEM_TYPE_ABSTAIN    = 1;
-
 	private String                            service        	= null;
 	private String                            name           	= null;
-	private Integer                           policyType     	= POLICY_TYPE_ALLOW;
+	private Integer                           policyType     	= null;
 	private String                            description    	= null;
 	private String							  resourceSignature = null;
 	private Boolean                           isAuditEnabled 	= null;
 	private Map<String, RangerPolicyResource> resources      	= null;
 	private List<RangerPolicyItem>            policyItems    	= null;
+	private List<RangerPolicyItem>            denyPolicyItems	= null;
+	private List<RangerPolicyItem>            allowExceptions	= null;
+	private List<RangerPolicyItem>            denyExceptions	= null;
 
 
 	/**
 	 * @param
 	 */
 	public RangerPolicy() {
-		this(null, null, POLICY_TYPE_ALLOW, null, null, null, null);
+		this(null, null, null, null, null, null, null);
 	}
 
 	/**
@@ -87,6 +84,9 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		setIsAuditEnabled(null);
 		setResources(resources);
 		setPolicyItems(policyItems);
+		setDenyPolicyItems(null);
+		setAllowExceptions(null);
+		setDenyExceptions(null);
 	}
 
 	/**
@@ -103,6 +103,9 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		setIsAuditEnabled(other.getIsAuditEnabled());
 		setResources(other.getResources());
 		setPolicyItems(other.getPolicyItems());
+		setDenyPolicyItems(other.getDenyPolicyItems());
+		setAllowExceptions(other.getAllowExceptions());
+		setDenyExceptions(other.getDenyExceptions());
 	}
 
 	/**
@@ -245,16 +248,88 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		}
 	}
 
-	final public boolean isPolicyTypeAllow() {
-		boolean ret = this.policyType == null || this.policyType == POLICY_TYPE_ALLOW;
+	/**
+	 * @return the denyPolicyItems
+	 */
+	public List<RangerPolicyItem> getDenyPolicyItems() {
+		return denyPolicyItems;
+	}
+
+	/**
+	 * @param denyPolicyItems the denyPolicyItems to set
+	 */
+	public void setDenyPolicyItems(List<RangerPolicyItem> denyPolicyItems) {
+		if(this.denyPolicyItems == null) {
+			this.denyPolicyItems = new ArrayList<RangerPolicyItem>();
+		}
 
-		return ret;
+		if(this.denyPolicyItems == denyPolicyItems) {
+			return;
+		}
+
+		this.denyPolicyItems.clear();
+
+		if(denyPolicyItems != null) {
+			for(RangerPolicyItem policyItem : denyPolicyItems) {
+				this.denyPolicyItems.add(policyItem);
+			}
+		}
 	}
 
-	final public boolean isPolicyTypeDeny() {
-		boolean ret = this.policyType != null && this.policyType == POLICY_TYPE_DENY;
+	/**
+	 * @return the allowExceptions
+	 */
+	public List<RangerPolicyItem> getAllowExceptions() {
+		return allowExceptions;
+	}
+
+	/**
+	 * @param allowExceptions the allowExceptions to set
+	 */
+	public void setAllowExceptions(List<RangerPolicyItem> allowExceptions) {
+		if(this.allowExceptions == null) {
+			this.allowExceptions = new ArrayList<RangerPolicyItem>();
+		}
+
+		if(this.allowExceptions == allowExceptions) {
+			return;
+		}
+
+		this.allowExceptions.clear();
 
-		return ret;
+		if(allowExceptions != null) {
+			for(RangerPolicyItem policyItem : allowExceptions) {
+				this.allowExceptions.add(policyItem);
+			}
+		}
+	}
+
+	/**
+	 * @return the denyExceptions
+	 */
+	public List<RangerPolicyItem> getDenyExceptions() {
+		return denyExceptions;
+	}
+
+	/**
+	 * @param denyExceptions the denyExceptions to set
+	 */
+	public void setDenyExceptions(List<RangerPolicyItem> denyExceptions) {
+		if(this.denyExceptions == null) {
+			this.denyExceptions = new ArrayList<RangerPolicyItem>();
+		}
+
+		if(this.denyExceptions == denyExceptions) {
+			return;
+		}
+
+		this.denyExceptions.clear();
+
+		if(denyExceptions != null) {
+			for(RangerPolicyItem policyItem : denyExceptions) {
+				this.denyExceptions.add(policyItem);
+			}
+		}
 	}
 
 	@Override
@@ -298,6 +373,36 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		}
 		sb.append("} ");
 
+		sb.append("denyPolicyItems={");
+		if(denyPolicyItems != null) {
+			for(RangerPolicyItem policyItem : denyPolicyItems) {
+				if(policyItem != null) {
+					policyItem.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
+		sb.append("allowExceptions={");
+		if(denyExceptions != null) {
+			for(RangerPolicyItem policyItem : allowExceptions) {
+				if(policyItem != null) {
+					policyItem.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
+		sb.append("denyExceptions={");
+		if(denyExceptions != null) {
+			for(RangerPolicyItem policyItem : denyExceptions) {
+				if(policyItem != null) {
+					policyItem.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
 		sb.append("}");
 
 		return sb;
@@ -478,7 +583,6 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		private List<String>                    groups        = null;
 		private List<RangerPolicyItemCondition> conditions    = null;
 		private Boolean                         delegateAdmin = null;
-		private Integer                         itemType      = POLICY_ITEM_TYPE_DEFAULT;
 
 		public RangerPolicyItem() {
 			this(null, null, null, null, null);
@@ -490,7 +594,6 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 			setGroups(groups);
 			setConditions(conditions);
 			setDelegateAdmin(delegateAdmin);
-			setItemType(null);
 		}
 
 		/**
@@ -604,20 +707,6 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 			this.delegateAdmin = delegateAdmin == null ? Boolean.FALSE : delegateAdmin;
 		}
 
-		/**
-		 * @return the itemType
-		 */
-		public Integer getItemType() {
-			return itemType;
-		}
-
-		/**
-		 * @param itemType the itemType to set
-		 */
-		public void setItemType(Integer itemType) {
-			this.itemType = itemType == null ? POLICY_ITEM_TYPE_DEFAULT : itemType;
-		}
-
 		@Override
 		public String toString( ) {
 			StringBuilder sb = new StringBuilder();
@@ -671,7 +760,6 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 			sb.append("} ");
 
 			sb.append("delegateAdmin={").append(delegateAdmin).append("} ");
-			sb.append("itemType={").append(itemType).append("} ");
 			sb.append("}");
 
 			return sb;
@@ -690,7 +778,6 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 			result = prime * result
 					+ ((groups == null) ? 0 : groups.hashCode());
 			result = prime * result + ((users == null) ? 0 : users.hashCode());
-			result = prime * result + ((itemType == null) ? 0 : itemType.hashCode());
 			return result;
 		}
 
@@ -718,11 +805,6 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 					return false;
 			} else if (!delegateAdmin.equals(other.delegateAdmin))
 				return false;
-			if (itemType == null) {
-				if (other.itemType != null)
-					return false;
-			} else if (!itemType.equals(other.itemType))
-				return false;
 			if (groups == null) {
 				if (other.groups != null)
 					return false;
@@ -877,7 +959,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		 * @param values the value to set
 		 */
 		public void setValues(List<String> values) {
-			if (CollectionUtils.isEmpty(values)) {
+			if (values == null) {
 				this.values = new ArrayList<String>();
 			}
 			else {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
index da817c6..a5837ce 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
@@ -212,11 +212,21 @@ public class RangerPolicyValidator extends RangerValidator {
 					serviceNameValid = true;
 				}
 			}
-			List<RangerPolicyItem> policyItems = policy.getPolicyItems();
-			boolean isAuditEnabled = getIsAuditEnabled(policy);
-			RangerServiceDef serviceDef = null;
-			String serviceDefName = null;
-			if (CollectionUtils.isEmpty(policyItems) && !isAuditEnabled) {
+
+			boolean          isAuditEnabled   = getIsAuditEnabled(policy);
+			String           serviceDefName   = null;
+			RangerServiceDef serviceDef       = null;
+			int              policyItemsCount = 0;
+
+			if(CollectionUtils.isNotEmpty(policy.getPolicyItems())) {
+				policyItemsCount += policy.getPolicyItems().size();
+			}
+
+			if(CollectionUtils.isNotEmpty(policy.getDenyPolicyItems())) {
+				policyItemsCount += policy.getDenyPolicyItems().size();
+			}
+
+			if (policyItemsCount == 0 && !isAuditEnabled) {
 				ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_POLICY_ITEMS;
 				failures.add(new ValidationFailureDetailsBuilder()
 					.field("policy items")
@@ -227,7 +237,7 @@ public class RangerPolicyValidator extends RangerValidator {
 				valid = false;
 			} else if (service != null) {
 				serviceDefName = service.getType();
-				serviceDef = getServiceDef(serviceDefName);
+				serviceDef     = getServiceDef(serviceDefName);
 				if (serviceDef == null) {
 					ValidationErrorCode error = ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_SERVICE_DEF;
 					failures.add(new ValidationFailureDetailsBuilder()
@@ -238,9 +248,13 @@ public class RangerPolicyValidator extends RangerValidator {
 						.build());
 					valid = false;
 				} else {
-					valid = isValidPolicyItems(policyItems, failures, serviceDef) && valid;
+					valid = isValidPolicyItems(policy.getPolicyItems(), failures, serviceDef) && valid;
+					valid = isValidPolicyItems(policy.getDenyPolicyItems(), failures, serviceDef) && valid;
+					valid = isValidPolicyItems(policy.getAllowExceptions(), failures, serviceDef) && valid;
+					valid = isValidPolicyItems(policy.getDenyExceptions(), failures, serviceDef) && valid;
 				}
 			}
+
 			if (serviceNameValid) { // resource checks can't be done meaningfully otherwise
 				valid = isValidResources(policy, failures, action, isAdmin, serviceDef) && valid;
 			}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
index 9bc43c7..49d32b2 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
@@ -81,7 +81,7 @@ public class RangerAccessResult {
 
 	public boolean getIsAccessDetermined() { return isAccessDetermined; }
 
-	private void setIsAccessDetermined(boolean value) { isAccessDetermined = value; }
+	public void setIsAccessDetermined(boolean value) { isAccessDetermined = value; }
 
 	/**
 	 * @return the isAllowed
@@ -94,7 +94,10 @@ public class RangerAccessResult {
 	 * @param isAllowed the isAllowed to set
 	 */
 	public void setIsAllowed(boolean isAllowed) {
-		setIsAccessDetermined(true);
+		if(! isAllowed) {
+			setIsAccessDetermined(true);
+		}
+
 		this.isAllowed = isAllowed;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index c7d2a28..3cccde0 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -288,6 +288,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 
 		List<RangerPolicy> ret = new ArrayList<RangerPolicy>();
 
+		// TODO: run through evaluator in tagPolicyRepository as well
 		for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
 			RangerPolicy policy = evaluator.getPolicy();
 
@@ -313,34 +314,43 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		RangerAccessResult ret = createAccessResult(request);
 
 		if (ret != null && request != null) {
-			if (tagPolicyRepository != null && CollectionUtils.isNotEmpty(tagPolicyRepository.getPolicies())) {
-				RangerAccessResult tagAccessResult = isAccessAllowedForTagPolicies(request);
+			if (hasTagPolicies()) {
+				isAccessAllowedForTagPolicies(request, ret);
 
 				if (LOG.isDebugEnabled()) {
-					if (tagAccessResult.getIsAccessDetermined() && tagAccessResult.getIsAuditedDetermined()) {
-						LOG.debug("RangerPolicyEngineImpl.isAccessAllowedNoAudit() - access and audit determined by tag policy. No resource policies will be evaluated, request=" + request + ", result=" + tagAccessResult);
+					if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
+						LOG.debug("RangerPolicyEngineImpl.isAccessAllowedNoAudit() - access and audit determined by tag policy. No resource policies will be evaluated, request=" + request + ", result=" + ret);
 					}
 				}
-
-				ret.setAccessResultFrom(tagAccessResult);
-				ret.setAuditResultFrom(tagAccessResult);
 			}
 
 			if (!ret.getIsAccessDetermined() || !ret.getIsAuditedDetermined()) {
-				List<RangerPolicyEvaluator> evaluators = policyRepository.getPolicyEvaluators();
-
-				if (CollectionUtils.isNotEmpty(evaluators)) {
+				if (hasResourcePolicies()) {
 					boolean foundInCache = policyRepository.setAuditEnabledFromCache(request, ret);
+					RangerPolicyEvaluator allowedEvaluator = null;
 
+					List<RangerPolicyEvaluator> evaluators = policyRepository.getPolicyEvaluators();
 					for (RangerPolicyEvaluator evaluator : evaluators) {
 						evaluator.evaluate(request, ret);
 
+						if(allowedEvaluator == null && ret.getIsAllowed()) {
+							allowedEvaluator = evaluator;
+						}
+
 						// stop once isAccessDetermined==true && isAuditedDetermined==true
-						if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
-							break;
+						if(ret.getIsAuditedDetermined()) {
+							if(ret.getIsAccessDetermined() || (allowedEvaluator != null && !evaluator.hasDeny())) {
+								break;			// Break out of policy-evaluation loop for this tag
+							}
 						}
 					}
 
+					if(!ret.getIsAccessDetermined() && allowedEvaluator != null) {
+						ret.setIsAllowed(true);
+						ret.setPolicyId(allowedEvaluator.getPolicy().getId());
+						ret.setIsAccessDetermined(true);
+					}
+
 					if (!foundInCache) {
 						policyRepository.storeAuditEnabledInCache(request, ret);
 					}
@@ -355,12 +365,11 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		return ret;
 	}
 
-	protected RangerAccessResult isAccessAllowedForTagPolicies(final RangerAccessRequest request) {
+	protected RangerAccessResult isAccessAllowedForTagPolicies(final RangerAccessRequest request, RangerAccessResult result) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowedForTagPolicies(" + request + ")");
 		}
 
-		RangerAccessResult          result     = createAccessResult(request);
 		List<RangerPolicyEvaluator> evaluators = tagPolicyRepository.getPolicyEvaluators();
 
 		if (CollectionUtils.isNotEmpty(evaluators)) {
@@ -376,20 +385,33 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 						LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: Evaluating policies for tag (" + tag.getType() + ")");
 					}
 
-					RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
-					RangerAccessResult  tagEvalResult  = createAccessResult(tagEvalRequest);
+					RangerAccessRequest   tagEvalRequest   = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
+					RangerAccessResult    tagEvalResult    = createAccessResult(tagEvalRequest);
+					RangerPolicyEvaluator allowedEvaluator = null;
 
 					for (RangerPolicyEvaluator evaluator : evaluators) {
 						evaluator.evaluate(tagEvalRequest, tagEvalResult);
 
-						if (tagEvalResult.getIsAccessDetermined() && tagEvalResult.getIsAuditedDetermined()) {
-							if (LOG.isDebugEnabled()) {
-								LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: concluding eval of tag (" + tag.getType() + ") with authorization=" + tagEvalResult.getIsAllowed());
+						if(allowedEvaluator == null && tagEvalResult.getIsAllowed()) {
+							allowedEvaluator = evaluator;
+						}
+
+						if(tagEvalResult.getIsAuditedDetermined()) {
+							if(tagEvalResult.getIsAccessDetermined() || (allowedEvaluator != null && !evaluator.hasDeny())) {
+								if (LOG.isDebugEnabled()) {
+									LOG.debug("RangerPolicyEngineImpl.isAccessAllowedForTagPolicies: concluding eval of tag (" + tag.getType() + ") with authorization=" + tagEvalResult.getIsAllowed());
+								}
+								break;			// Break out of policy-evaluation loop for this tag
 							}
-							break;			// Break out of policy-evaluation loop for this tag
 						}
 					}
 
+					if(!tagEvalResult.getIsAccessDetermined() && allowedEvaluator != null) {
+						tagEvalResult.setIsAllowed(true);
+						tagEvalResult.setPolicyId(allowedEvaluator.getPolicy().getId());
+						tagEvalResult.setIsAccessDetermined(true);
+					}
+
 					if (tagEvalResult.getIsAuditedDetermined()) {
 						someTagAllowedAudit = true;
 						// And generate an audit event
@@ -453,6 +475,14 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		}
 	}
 
+	private boolean hasTagPolicies() {
+		return tagPolicyRepository != null && CollectionUtils.isNotEmpty(tagPolicyRepository.getPolicies());
+	}
+
+	private boolean hasResourcePolicies() {
+		return policyRepository != null && CollectionUtils.isNotEmpty(policyRepository.getPolicies());
+	}
+
 	@Override
 	public String toString( ) {
 		StringBuilder sb = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index 96fddde..8519860 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -92,7 +92,7 @@ public class RangerPolicyRepository {
 
         this.appId = appId;
 
-        this.policies = Collections.unmodifiableList(normalizePolicyItemAccesses(tagPolicies.getPolicies(), componentServiceDef.getName()));
+        this.policies = Collections.unmodifiableList(normalizeAndPrunePolicies(tagPolicies.getPolicies(), componentServiceDef.getName()));
         this.policyVersion = tagPolicies.getPolicyVersion() != null ? tagPolicies.getPolicyVersion() : -1;
         this.accessAuditCache = null;
 
@@ -134,7 +134,7 @@ public class RangerPolicyRepository {
 
                 String prefix = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
 
-                List<RangerServiceDef.RangerAccessTypeDef> unneededAccessTypeDefs = new ArrayList<RangerServiceDef.RangerAccessTypeDef>();
+                List<RangerServiceDef.RangerAccessTypeDef> unneededAccessTypeDefs = null;
 
                 for (RangerServiceDef.RangerAccessTypeDef accessTypeDef : accessTypeDefs) {
 
@@ -169,72 +169,102 @@ public class RangerPolicyRepository {
 
                         }
                     } else if (StringUtils.contains(accessType, AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
+                        if(unneededAccessTypeDefs == null) {
+                            unneededAccessTypeDefs = new ArrayList<RangerServiceDef.RangerAccessTypeDef>();
+                        }
+
                         unneededAccessTypeDefs.add(accessTypeDef);
                     }
                 }
-                accessTypeDefs.removeAll(unneededAccessTypeDefs);
+
+                if(unneededAccessTypeDefs != null) {
+                    accessTypeDefs.removeAll(unneededAccessTypeDefs);
+                }
             }
         }
 
         return serviceDef;
     }
 
-    private List<RangerPolicy> normalizePolicyItemAccesses(List<RangerPolicy> rangerPolicies, final String componentType) {
-
+    private List<RangerPolicy> normalizeAndPrunePolicies(List<RangerPolicy> rangerPolicies, final String componentType) {
         if (CollectionUtils.isNotEmpty(rangerPolicies) && StringUtils.isNotBlank(componentType)) {
-
-            String prefix = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
-
-            List<RangerPolicy> unneededPolicies = new ArrayList<>();
+            List<RangerPolicy> policiesToPrune = null;
 
             for (RangerPolicy policy : rangerPolicies) {
+                normalizeAndPrunePolicyItems(policy.getPolicyItems(), componentType);
+                normalizeAndPrunePolicyItems(policy.getDenyPolicyItems(), componentType);
+                normalizeAndPrunePolicyItems(policy.getAllowExceptions(), componentType);
+                normalizeAndPrunePolicyItems(policy.getDenyExceptions(), componentType);
+
+                if (!policy.getIsAuditEnabled() &&
+                    CollectionUtils.isEmpty(policy.getPolicyItems()) &&
+                    CollectionUtils.isEmpty(policy.getDenyPolicyItems()) &&
+                    CollectionUtils.isEmpty(policy.getAllowExceptions()) &&
+                    CollectionUtils.isEmpty(policy.getDenyExceptions())) {
+
+                    if(policiesToPrune == null) {
+                        policiesToPrune = new ArrayList<RangerPolicy>();
+                    }
 
-                List<RangerPolicy.RangerPolicyItem> policyItems = policy.getPolicyItems();
-
-                if (CollectionUtils.isNotEmpty(policyItems)) {
-
-                    List<RangerPolicy.RangerPolicyItem> unneededPolicyItems = new ArrayList< RangerPolicy.RangerPolicyItem>();
-
-                    for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
-
-                        List<RangerPolicy.RangerPolicyItemAccess> policyItemAccesses = policyItem.getAccesses();
+                    policiesToPrune.add(policy);
+                }
+            }
 
-                        if (CollectionUtils.isNotEmpty(policyItemAccesses)) {
+            if(policiesToPrune != null) {
+	            rangerPolicies.removeAll(policiesToPrune);
+            }
+        }
 
-                            List<RangerPolicy.RangerPolicyItemAccess> unneededItemAccesses = new ArrayList<RangerPolicy.RangerPolicyItemAccess>();
+        return rangerPolicies;
+    }
 
-                            for (RangerPolicy.RangerPolicyItemAccess access : policyItemAccesses) {
+    private List<RangerPolicy.RangerPolicyItem> normalizeAndPrunePolicyItems(List<RangerPolicy.RangerPolicyItem> policyItems, final String componentType) {
+        if(CollectionUtils.isNotEmpty(policyItems)) {
+            final String                        prefix       = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
+            List<RangerPolicy.RangerPolicyItem> itemsToPrune = null;
 
-                                String accessType = access.getType();
+            for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
+                List<RangerPolicy.RangerPolicyItemAccess> policyItemAccesses = policyItem.getAccesses();
 
-                                if (StringUtils.startsWith(accessType, prefix)) {
+                if (CollectionUtils.isNotEmpty(policyItemAccesses)) {
+                    List<RangerPolicy.RangerPolicyItemAccess> accessesToPrune = null;
 
-                                    String newAccessType = StringUtils.removeStart(accessType, prefix);
+                    for (RangerPolicy.RangerPolicyItemAccess access : policyItemAccesses) {
+                        String accessType = access.getType();
 
-                                    access.setType(newAccessType);
+                        if (StringUtils.startsWith(accessType, prefix)) {
+                            String newAccessType = StringUtils.removeStart(accessType, prefix);
 
-                                } else if (accessType.contains(AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
-                                    unneededItemAccesses.add(access);
-                                }
+                            access.setType(newAccessType);
+                        } else if (accessType.contains(AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR)) {
+                            if(accessesToPrune == null) {
+                                accessesToPrune = new ArrayList<RangerPolicy.RangerPolicyItemAccess>();
                             }
-                            policyItemAccesses.removeAll(unneededItemAccesses);
 
-                            if (policyItemAccesses.isEmpty() && !policyItem.getDelegateAdmin()) {
-                                unneededPolicyItems.add(policyItem);
-                            }
+                            accessesToPrune.add(access);
                         }
                     }
 
-                    policyItems.removeAll(unneededPolicyItems);
-                }
-                if (CollectionUtils.isEmpty(policyItems) && !policy.getIsAuditEnabled()) {
-                    unneededPolicies.add(policy);
+                    if(accessesToPrune != null) {
+	                    policyItemAccesses.removeAll(accessesToPrune);
+                    }
+
+                    if (policyItemAccesses.isEmpty() && !policyItem.getDelegateAdmin()) {
+                        if(itemsToPrune != null) {
+                            itemsToPrune = new ArrayList< RangerPolicy.RangerPolicyItem>();
+                        }
+
+                        itemsToPrune.add(policyItem);
+                    }
                 }
             }
-            rangerPolicies.removeAll(unneededPolicies);
+
+            if(itemsToPrune != null) {
+	            policyItems.removeAll(itemsToPrune);
+            }
         }
 
-        return rangerPolicies;
+        return policyItems;
     }
 
     private void init(RangerPolicyEngineOptions options) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
index 1308e63..fa35f1c 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.policyevaluator;
 
 
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerPolicy;
@@ -60,6 +61,14 @@ public abstract class RangerAbstractPolicyEvaluator implements RangerPolicyEvalu
 		return serviceDef;
 	}
 
+	public boolean hasAllow() {
+		return policy != null && CollectionUtils.isNotEmpty(policy.getPolicyItems());
+	}
+
+	public boolean hasDeny() {
+		return policy != null && CollectionUtils.isNotEmpty(policy.getDenyPolicyItems());
+	}
+
 	@Override
 	public int getEvalOrder() {
 		return evalOrder;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index 45fce94..450f766 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
@@ -36,8 +36,7 @@ import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyItemEvaluator {
 	private static final Log LOG = LogFactory.getLog(RangerAbstractPolicyItemEvaluator.class);
 
-	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT          = 1000;
-	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_DISCOUNT_ABSTAIN =  500;
+	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT = 1000;
 
 	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_USERSGROUPS       =  25;
 	private static final int RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_ACCESS_TYPES      =  25;
@@ -47,17 +46,19 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
 	final RangerPolicyEngineOptions options;
 	final RangerServiceDef          serviceDef;
 	final RangerPolicyItem          policyItem;
+	final int                       policyItemType;
 	final long                      policyId;
 	final int                       evalOrder;
 
 	List<RangerConditionEvaluator> conditionEvaluators = Collections.<RangerConditionEvaluator>emptyList();
 
-	RangerAbstractPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, RangerPolicyEngineOptions options) {
-		this.serviceDef = serviceDef;
-		this.policyItem = policyItem;
-		this.options    = options;
-		this.policyId   = policy != null && policy.getId() != null ? policy.getId() : -1;
-		this.evalOrder  = computeEvalOrder();
+	RangerAbstractPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, RangerPolicyEngineOptions options) {
+		this.serviceDef     = serviceDef;
+		this.policyItem     = policyItem;
+		this.policyItemType = policyItemType;
+		this.options        = options;
+		this.policyId       = policy != null && policy.getId() != null ? policy.getId() : -1;
+		this.evalOrder      = computeEvalOrder();
 	}
 
 	@Override
@@ -76,6 +77,11 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
 	}
 
 	@Override
+	public int getPolicyItemType() {
+		return policyItemType;
+	}
+
+	@Override
 	public int compareTo(RangerPolicyItemEvaluator other) {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerAbstractPolicyItemEvaluator.compareTo()");
@@ -102,10 +108,6 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
 		int evalOrder = RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT;
 
 		if(policyItem != null) {
-			if(policyItem.getItemType() == RangerPolicy.POLICY_ITEM_TYPE_ABSTAIN) {
-				evalOrder -= RANGER_POLICY_ITEM_EVAL_ORDER_DISCOUNT_ABSTAIN;
-			}
-
 			if(CollectionUtils.isNotEmpty(policyItem.getGroups()) && policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC)) {
 				evalOrder -= RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_USERSGROUPS;
 			} else {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 9c63089..a6285d9 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
@@ -49,9 +49,12 @@ import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche
 public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator {
 	private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyEvaluator.class);
 
-	private RangerPolicyResourceMatcher     resourceMatcher       = null;
-	private List<RangerPolicyItemEvaluator> policyItemEvaluators  = null;
-	private int                             customConditionsCount = 0;
+	private RangerPolicyResourceMatcher     resourceMatcher          = null;
+	private List<RangerPolicyItemEvaluator> allowEvaluators          = null;
+	private List<RangerPolicyItemEvaluator> denyEvaluators           = null;
+	private List<RangerPolicyItemEvaluator> allowExceptionEvaluators = null;
+	private List<RangerPolicyItemEvaluator> denyExceptionEvaluators  = null;
+	private int                             customConditionsCount    = 0;
 
 	@Override
 	public int getCustomConditionsCount() {
@@ -64,35 +67,32 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			LOG.debug("==> RangerDefaultPolicyEvaluator.init()");
 		}
 
-		preprocessPolicy(policy, serviceDef);
-
 		super.init(policy, serviceDef, options);
 
+		preprocessPolicy(policy, serviceDef);
+
 		resourceMatcher = new RangerDefaultPolicyResourceMatcher();
 
 		resourceMatcher.setServiceDef(serviceDef);
 		resourceMatcher.setPolicyResources(policy == null ? null : policy.getResources());
 		resourceMatcher.init();
-		
-		if(policy != null && CollectionUtils.isNotEmpty(policy.getPolicyItems())) {
-			policyItemEvaluators = new ArrayList<RangerPolicyItemEvaluator>();
-
-			for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
-				RangerPolicyItemEvaluator itemEvaluator = new RangerDefaultPolicyItemEvaluator(serviceDef, policy, policyItem, options);
 
-				itemEvaluator.init();
-
-				policyItemEvaluators.add(itemEvaluator);
-				
-				if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
-					customConditionsCount += itemEvaluator.getConditionEvaluators().size();
-				}
-			}
+		if(policy != null) {
+			allowEvaluators          = createPolicyItemEvaluators(policy, serviceDef, options, policy.getPolicyItems(), RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
+			denyEvaluators           = createPolicyItemEvaluators(policy, serviceDef, options, policy.getDenyPolicyItems(), RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
+			allowExceptionEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, policy.getAllowExceptions(), RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
+			denyExceptionEvaluators  = createPolicyItemEvaluators(policy, serviceDef, options, policy.getDenyExceptions(), RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
 		} else {
-			policyItemEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
+			allowEvaluators          = Collections.<RangerPolicyItemEvaluator>emptyList();
+			denyEvaluators           = Collections.<RangerPolicyItemEvaluator>emptyList();
+			allowExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
+			denyExceptionEvaluators  = Collections.<RangerPolicyItemEvaluator>emptyList();
 		}
 
-		Collections.sort(policyItemEvaluators);
+		Collections.sort(allowEvaluators);
+		Collections.sort(denyEvaluators);
+		Collections.sort(allowExceptionEvaluators);
+		Collections.sort(denyExceptionEvaluators);
 
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("<== RangerDefaultPolicyEvaluator.init()");
@@ -152,15 +152,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
                 }
                 // Go further to evaluate access only if match or head match was found at this point
                 if (isResourceMatch || isResourceHeadMatch) {
-                    boolean isPolicyItemsMatch = isPolicyItemsMatch(request);
+                    RangerPolicyItemEvaluator matchedPolicyItem = getDeterminingPolicyItem(request);
 
-                    RangerPolicy policy = getPolicy();
+                    if(matchedPolicyItem != null) {
+                        RangerPolicy policy = getPolicy();
 
-                    if(isPolicyItemsMatch) {
-                        if(policy.isPolicyTypeDeny()) {
+                        if(matchedPolicyItem.getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
                             if(isResourceMatch) {
-                                result.setIsAllowed(false);
-                                result.setPolicyId(policy.getId());
+	                            result.setIsAllowed(false);
+	                            result.setPolicyId(policy.getId());
                             }
 	                    } else {
 	                        result.setIsAllowed(true);
@@ -176,28 +176,49 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
         }
     }
 
-    protected boolean isPolicyItemsMatch(RangerAccessRequest request) {
+    protected RangerPolicyItemEvaluator getDeterminingPolicyItem(RangerAccessRequest request) {
         if(LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerDefaultPolicyEvaluator.isPolicyItemsMatch(" + request + ")");
+            LOG.debug("==> RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + request + ")");
         }
 
-        boolean ret = false;
+        RangerPolicyItemEvaluator ret = null;
 
-        if(CollectionUtils.isNotEmpty(policyItemEvaluators)) {
-            for (RangerPolicyItemEvaluator policyItemEvaluator : policyItemEvaluators) {
-                ret = policyItemEvaluator.isMatch(request);
+        /*
+         *  1. if a deny matches without hitting any deny-exception, return that
+         *  2. if an allow matches without hitting any allow-exception, return that
+         */
+        ret = getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators);
 
-                if(ret) {
-                    if(policyItemEvaluator.getPolicyItem().getItemType() == RangerPolicy.POLICY_ITEM_TYPE_ABSTAIN) {
-                        ret = false;
-                    }
-                    break;
-                }
-            }
+        if(ret == null) {
+            ret = getMatchingPolicyItem(request, allowEvaluators, allowExceptionEvaluators);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + request + "): " + ret);
+        }
+
+        return ret;
+    }
+
+    protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, Set<String> userGroups, String accessType) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")");
+        }
+
+        RangerPolicyItemEvaluator ret = null;
+
+        /*
+         *  1. if a deny matches without hitting any deny-exception, return that
+         *  2. if an allow matches without hitting any allow-exception, return that
+         */
+        ret = getMatchingPolicyItem(user, userGroups, accessType, denyEvaluators, denyExceptionEvaluators);
+
+        if(ret == null) {
+            ret = getMatchingPolicyItem(user, userGroups, accessType, allowEvaluators, allowExceptionEvaluators);
         }
 
         if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.isPolicyItemsMatch(" + request + "): " + ret);
+            LOG.debug("<== RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret);
         }
 
         return ret;
@@ -315,15 +336,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 		boolean ret = false;
 
-		if(CollectionUtils.isNotEmpty(policyItemEvaluators)) {
-	        for (RangerPolicyItemEvaluator policyItemEvaluator : policyItemEvaluators) {
-	        	ret = policyItemEvaluator.matchUserGroup(user, userGroups) &&
-	        		  policyItemEvaluator.matchAccessType(accessType);
+		RangerPolicyItemEvaluator item = this.getDeterminingPolicyItem(user, userGroups, accessType);
 
-	    		if(ret) {
-	    			break;
-	    		}
-	        }
+		if(item != null && item.getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW) {
+			ret = true;
 		}
 
 		if(LOG.isDebugEnabled()) {
@@ -350,7 +366,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	}
 
 	private void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
-		if(policy == null || CollectionUtils.isEmpty(policy.getPolicyItems()) || serviceDef == null) {
+		if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef == null) {
 			return;
 		}
 
@@ -360,7 +376,14 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			return;
 		}
 
-		for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
+		preprocessPolicyItems(policy.getPolicyItems(), impliedAccessGrants);
+		preprocessPolicyItems(policy.getDenyPolicyItems(), impliedAccessGrants);
+		preprocessPolicyItems(policy.getAllowExceptions(), impliedAccessGrants);
+		preprocessPolicyItems(policy.getDenyExceptions(), impliedAccessGrants);
+	}
+
+	private void preprocessPolicyItems(List<RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
+		for(RangerPolicyItem policyItem : policyItems) {
 			if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
 				continue;
 			}
@@ -437,4 +460,104 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 		return ret;
 	}
+
+	private List<RangerPolicyItemEvaluator> createPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerPolicyItem> policyItems, int policyItemType) {
+		List<RangerPolicyItemEvaluator> ret = null;
+
+		if(CollectionUtils.isNotEmpty(policyItems)) {
+			ret = new ArrayList<RangerPolicyItemEvaluator>();
+
+			for(RangerPolicyItem policyItem : policyItems) {
+				RangerPolicyItemEvaluator itemEvaluator = new RangerDefaultPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemType, options);
+
+				itemEvaluator.init();
+
+				ret.add(itemEvaluator);
+
+				if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
+					customConditionsCount += itemEvaluator.getConditionEvaluators().size();
+				}
+			}
+		} else {
+			ret = Collections.<RangerPolicyItemEvaluator>emptyList();
+		}
+
+		return ret;
+	}
+
+	private RangerPolicyItemEvaluator getMatchingPolicyItem(RangerAccessRequest request, List<RangerPolicyItemEvaluator> evaluators, List<RangerPolicyItemEvaluator> exceptionEvaluators) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + ")");
+        }
+
+        RangerPolicyItemEvaluator ret = null;
+
+        if(CollectionUtils.isNotEmpty(evaluators)) {
+            for (RangerPolicyItemEvaluator evaluator : evaluators) {
+                if(evaluator.isMatch(request)) {
+                    ret = evaluator;
+
+                    break;
+                }
+            }
+        }
+
+        if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) {
+            for (RangerPolicyItemEvaluator exceptionEvaluator : exceptionEvaluators) {
+                if(exceptionEvaluator.isMatch(request)) {
+                    if(LOG.isDebugEnabled()) {
+                        LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + "): found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")");
+                    }
+
+                    ret = null;
+
+                    break;
+                }
+            }
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + "): " + ret);
+        }
+
+        return ret;
+    }
+
+	private RangerPolicyItemEvaluator getMatchingPolicyItem(String user, Set<String> userGroups, String accessType, List<RangerPolicyItemEvaluator> evaluators, List<RangerPolicyItemEvaluator> exceptionEvaluators) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")");
+        }
+
+        RangerPolicyItemEvaluator ret = null;
+
+        if(CollectionUtils.isNotEmpty(evaluators)) {
+            for (RangerPolicyItemEvaluator evaluator : evaluators) {
+                if(evaluator.matchUserGroup(user, userGroups) && evaluator.matchAccessType(accessType)) {
+                    ret = evaluator;
+
+                    break;
+                }
+            }
+        }
+
+        if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) {
+            for (RangerPolicyItemEvaluator exceptionEvaluator : exceptionEvaluators) {
+                if(exceptionEvaluator.matchUserGroup(user, userGroups) && exceptionEvaluator.matchAccessType(accessType)) {
+                    if(LOG.isDebugEnabled()) {
+                        LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")");
+                    }
+
+                    ret = null;
+
+                    break;
+                }
+            }
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret);
+        }
+
+        return ret;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
----------------------------------------------------------------------
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 6f8faff..39a0a5e 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
@@ -42,8 +42,8 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 	private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyItemEvaluator.class);
 
 
-	public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, RangerPolicyEngineOptions options) {
-		super(serviceDef, policy, policyItem, options);
+	public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, RangerPolicyEngineOptions options) {
+		super(serviceDef, policy, policyItem, policyItemType, options);
 	}
 
 	public void init() {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index 9fa20cd..a118466 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -35,9 +35,9 @@ 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 Set<String> groups         = new HashSet<String>();
+    private Set<String> users          = new HashSet<String>();
+    private Set<String> accessPerms    = new HashSet<String>();
     private boolean     delegateAdmin  = false;
     private boolean     hasAllPerms    = false;
     private boolean     hasPublicGroup = false;
@@ -48,7 +48,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
     private static final String RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING = "?";
 
     private static final int RANGER_POLICY_EVAL_SCORE_DEFAULT                         = 10000;
-    private static final int RANGER_POLICY_EVAL_SCORE_DISCOUNT_DENY_POLICY            =  4000;
+    private static final int RANGER_POLICY_EVAL_SCORE_DISCOUNT_POLICY_HAS_DENY        =  4000;
 
     private static final int RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_RESOURCE          = 100;
     private static final int RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS       =  25;
@@ -71,25 +71,10 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
 
         super.init(policy, serviceDef, options);
 
-        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());
-        }
+        preprocessPolicyItems(policy.getPolicyItems());
+        preprocessPolicyItems(policy.getDenyPolicyItems());
+        preprocessPolicyItems(policy.getAllowExceptions());
+        preprocessPolicyItems(policy.getDenyExceptions());
 
         hasAllPerms = checkIfHasAllPerms();
 
@@ -203,8 +188,8 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
             evalOrder -= customConditionsDiscount;
         }
 
-        if (policy.isPolicyTypeDeny()) {
-            evalOrder -= RANGER_POLICY_EVAL_SCORE_DISCOUNT_DENY_POLICY;
+        if (hasDeny()) {
+            evalOrder -= RANGER_POLICY_EVAL_SCORE_DISCOUNT_POLICY_HAS_DENY;
         }
 
         if(LOG.isDebugEnabled()) {
@@ -243,19 +228,19 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
 	}
 
 	@Override
-    protected boolean isPolicyItemsMatch(RangerAccessRequest request) {
+    protected RangerPolicyItemEvaluator getDeterminingPolicyItem(RangerAccessRequest request) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> RangerOptimizedPolicyEvaluator.isPolicyItemsMatch()");
         }
 
-        boolean ret = false;
+        RangerPolicyItemEvaluator ret = null;
 
         if (hasPublicGroup || users.contains(request.getUser()) || CollectionUtils.containsAny(groups, request.getUserGroups())) {
             // No need to reject based on users and groups
 
             if (request.isAccessTypeAny() || (request.isAccessTypeDelegatedAdmin() && delegateAdmin) || hasAllPerms || accessPerms.contains(request.getAccessType())) {
                 // No need to reject based on aggregated access permissions
-                ret = super.isPolicyItemsMatch(request);
+                ret = super.getDeterminingPolicyItem(request);
             }
         }
 
@@ -266,6 +251,26 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
         return ret;
     }
 
+    private void preprocessPolicyItems(List<RangerPolicy.RangerPolicyItem> policyItems) {
+        if(CollectionUtils.isNotEmpty(policyItems)) {
+	        for (RangerPolicy.RangerPolicyItem item : policyItems) {
+	            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());
+	        }
+        }
+    }
+
 	private boolean checkIfHasAllPerms() {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> RangerOptimizedPolicyEvaluator.checkIfHasAllPerms()");
@@ -275,7 +280,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
         List<RangerServiceDef.RangerAccessTypeDef> serviceAccessTypes = getServiceDef().getAccessTypes();
         for (RangerServiceDef.RangerAccessTypeDef serviceAccessType : serviceAccessTypes) {
             if(! accessPerms.contains(serviceAccessType.getName())) {
-		result = false;
+                result = false;
                 break;
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index 624ff1c..e5f34a2 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -42,6 +42,10 @@ public interface RangerPolicyEvaluator extends Comparable<RangerPolicyEvaluator>
 
 	RangerServiceDef getServiceDef();
 
+	boolean hasAllow();
+
+	boolean hasDeny();
+
 	int getEvalOrder();
 
 	int getCustomConditionsCount();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index e91d5d1..6360dc9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -26,11 +26,17 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 
 public interface RangerPolicyItemEvaluator extends Comparable<RangerPolicyItemEvaluator> {
+	public static final int POLICY_ITEM_TYPE_ALLOW            = 0;
+	public static final int POLICY_ITEM_TYPE_DENY             = 1;
+	public static final int POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS = 2;
+	public static final int POLICY_ITEM_TYPE_DENY_EXCEPTIONS  = 3;
 
 	void init();
 
 	RangerPolicyItem getPolicyItem();
 
+	int getPolicyItemType();
+
 	List<RangerConditionEvaluator> getConditionEvaluators();
 
 	int getEvalOrder();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
index 772c2d7..abfb350 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
@@ -374,11 +374,22 @@ public class AbstractPredicateUtil {
 				if(object instanceof RangerPolicy) {
 					RangerPolicy policy = (RangerPolicy)object;
 
-					for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
-						if(policyItem.getUsers().contains(userName)) {
-							ret = true;
+					List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
+																policy.getDenyPolicyItems(),
+																policy.getAllowExceptions(),
+																policy.getDenyExceptions()
+															  };
 
-							break;
+					for(List<?> policyItemsObj : policyItemsList) {
+						@SuppressWarnings("unchecked")
+						List<RangerPolicyItem> policyItems = (List<RangerPolicyItem>)policyItemsObj;
+
+						for(RangerPolicyItem policyItem : policyItems) {
+							if(policyItem.getUsers().contains(userName)) {
+								ret = true;
+
+								break;
+							}
 						}
 					}
 				} else {
@@ -413,11 +424,22 @@ public class AbstractPredicateUtil {
 				if(object instanceof RangerPolicy) {
 					RangerPolicy policy = (RangerPolicy)object;
 
-					for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
-						if(policyItem.getGroups().contains(groupName)) {
-							ret = true;
+					List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
+							policy.getDenyPolicyItems(),
+							policy.getAllowExceptions(),
+							policy.getDenyExceptions()
+						  };
 
-							break;
+					for(List<?> policyItemsObj : policyItemsList) {
+						@SuppressWarnings("unchecked")
+						List<RangerPolicyItem> policyItems = (List<RangerPolicyItem>)policyItemsObj;
+
+						for(RangerPolicyItem policyItem : policyItems) {
+							if(policyItem.getGroups().contains(groupName)) {
+								ret = true;
+
+								break;
+							}
 						}
 					}
 				} else {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/test/resources/policyengine/test_policyengine_hbase.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hbase.json b/agents-common/src/test/resources/policyengine/test_policyengine_hbase.json
index de9c130..b267be0 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hbase.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hbase.json
@@ -43,6 +43,14 @@
   ],
 
   "tests":[
+    {"name":"TEST!!! ALLOW 'scan finance restricted-cf;' for finance-admin",
+     "request":{
+      "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},
+      "accessType":"read","user":"user1","userGroups":["users","finance-admin"],"requestData":"scan finance restricted-cf"
+     },
+     "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+    ,
     {"name":"ALLOW 'scan finance restricted-cf;' for finance",
      "request":{
       "resource":{"elements":{"table":"finance","column-family":"restricted-cf"}},

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/test/resources/policyengine/test_policyengine_hive_mutex_conditions.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive_mutex_conditions.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive_mutex_conditions.json
index 9c29cfd..4de74ad 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hive_mutex_conditions.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive_mutex_conditions.json
@@ -33,24 +33,34 @@
   },
 
   "policies":[
-    {"id":1,"name":"db=default; deny select with mutual exclusion of col* for everyone except user2, admin","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+    {"id":1,"name":"db=default; allow select with mutual exclusion of col* only for user2, admin; deny for everyone else","isEnabled":true,"isAuditEnabled":true,
       "resources":{"database":{"values":["default"]},"table":{"values":["testTable"]},"column":{"values":["col*"]}},
       "policyItems":[
-        {"accesses":[{"type":"select"}],"users":[],"groups":["public"],"delegateAdmin":false,"conditions":[{"type":"accessed-together","values":["default.testTable.col*"]}]},
-        {"accesses":[{"type":"select"}],"users":["user2","admin"],"groups":["admin"],"delegateAdmin":false,"itemType":1}
+        {"accesses":[{"type":"select"}],"users":["user2", "admin"],"groups":[],"delegateAdmin":false}
+      ],
+      "denyPolicyItems":[
+        {"accesses":[{"type":"select"}],"users":[],"groups":["public"],"delegateAdmin":false,"conditions":[{"type":"accessed-together","values":["default.testTable.col*"]}]}
+      ],
+      "denyExceptions":[
+        {"accesses":[{"type":"select"}],"users":["user2","admin"],"groups":["admin"],"delegateAdmin":false}
       ]
     },
-    {"id":2,"name":"db=default; deny select with mutual exclusion of col1, name for everone except admin","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+    {"id":2,"name":"db=default; deny select with mutual exclusion of col1, name for everone except admin","isEnabled":true,"isAuditEnabled":true,
       "resources":{"database":{"values":["default"]},"table":{"values":["testTable"]},"column":{"values":["col1"]}},
       "policyItems":[
-        {"accesses":[{"type":"select"}],"users":[],"groups":["public"],"delegateAdmin":false,"conditions":[{"type":"accessed-together","values":["default.testTable.col1", "default.testTable.name"]}]},
-        {"accesses":[{"type":"select"}],"users":["admin"],"groups":["admin"],"delegateAdmin":false,"itemType":1}
+        {"accesses":[{"type":"select"}],"users":["admin"],"groups":[],"delegateAdmin":false}
+      ],
+      "denyPolicyItems":[
+        {"accesses":[{"type":"select"}],"users":[],"groups":["public"],"delegateAdmin":false,"conditions":[{"type":"accessed-together","values":["default.testTable.col1", "default.testTable.name"]}]}
+      ],
+      "denyExceptions":[
+        {"accesses":[{"type":"select"}],"users":["admin"],"groups":[],"delegateAdmin":false}
       ]
     },
-    {"id":3,"name":"db=default; allow default.testTable.* for user1, user2, admin","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+    {"id":3,"name":"db=default; table=testTable; column=*; allow access to everyone","isEnabled":true,"isAuditEnabled":true,
       "resources":{"database":{"values":["default"]},"table":{"values":["testTable"]},"column":{"values":["*"]}},
       "policyItems":[
-        {"accesses":[{"type":"select"}],"users":["user1", "user2", "admin"],"groups":[],"delegateAdmin":false}
+        {"accesses":[{"type":"select"}],"users":[""],"groups":["public"],"delegateAdmin":false}
       ]
     }
   ],
@@ -82,8 +92,9 @@
         "policyId": 1
       }
     }
-    , {
-      "name": "DENY 'select col1, name from default.testtable;' to user2",
+    ,
+    {
+      "name": "ALLOW 'select col1, col2 from default.testtable;' to admin",
       "request": {
         "resource": {
           "elements": {
@@ -93,23 +104,23 @@
           }
         },
         "accessType": "select",
-        "user": "user2",
+        "user": "admin",
         "userGroups": [
         ],
-        "requestData": "select col1,name from default.testtable",
+        "requestData": "select col1,col2 from default.testtable",
         "context": {
-          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col1\"} }, {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"name\"} } ]}"
+          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col1\"} }, {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col2\"} } ]}"
         }
       },
       "result": {
         "isAudited": true,
-        "isAllowed": false,
-        "policyId": 2
+        "isAllowed": true,
+        "policyId": 1
       }
     }
     ,
-    {
-      "name": "ALLOW 'select col1, col2 from default.testtable;' to admin",
+	{
+      "name": "DENY 'select col1, name from default.testtable;' to user2",
       "request": {
         "resource": {
           "elements": {
@@ -119,22 +130,23 @@
           }
         },
         "accessType": "select",
-        "user": "admin",
+        "user": "user2",
         "userGroups": [
         ],
-        "requestData": "select col1,col2 from default.testtable",
+        "requestData": "select col1,name from default.testtable",
         "context": {
-          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col1\"} }, {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col2\"} } ]}"
+          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col1\"} }, {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"name\"} } ]}"
         }
       },
       "result": {
         "isAudited": true,
-        "isAllowed": true,
-        "policyId": 3
+        "isAllowed": false,
+        "policyId": 2
       }
     }
-    ,{
-      "name": "ALLOW 'select col2, name from default.testtable;' to user1",
+    ,
+    {
+      "name": "ALLOW 'select col2 from default.testtable;' to user1",
       "request": {
         "resource": {
           "elements": {
@@ -148,9 +160,9 @@
         "userGroups": [
           "public"
         ],
-        "requestData": "select col2,name from default.testtable",
+        "requestData": "select col2 from default.testtable",
         "context": {
-          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col2\"} }, {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"name\"} } ]}"
+          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col2\"} } ]}"
         }
       },
       "result": {
@@ -159,8 +171,9 @@
         "policyId": 3
       }
     }
-    ,{
-      "name": "ALLOW 'select col2, col2 from default.testtable;' to user1",
+    ,
+    {
+      "name": "ALLOW 'select col2, name from default.testtable;' to user1",
       "request": {
         "resource": {
           "elements": {
@@ -174,9 +187,9 @@
         "userGroups": [
           "public"
         ],
-        "requestData": "select col2 from default.testtable",
+        "requestData": "select col2,name from default.testtable",
         "context": {
-          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col2\"} } ]}"
+          "REQUESTED_RESOURCES": "{\"requestedResources\":[ {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"col2\"} }, {\"elements\":{\"database\":\"default\",\"table\":\"testTable\",\"column\":\"name\"} } ]}"
         }
       },
       "result": {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
index 454cf51..ed42d5c 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hdfs.json
@@ -15,26 +15,6 @@
   },
 
   "policies":[
-    {"id":1,"name":"audit-all-access under /finance/restricted/","isEnabled":true,"isAuditEnabled":true,
-     "resources":{"path":{"values":["/finance/restricted/"],"isRecursive":true}},
-     "policyItems":[
-       {"accesses":[],"users":[],"groups":["public"],"delegateAdmin":false}
-     ]
-    }
-    ,
-    {"id":2,"name":"allow-read-to-all under /public/","isEnabled":true,"isAuditEnabled":false,
-     "resources":{"path":{"values":["/public/*"],"isRecursive":true}},
-     "policyItems":[
-       {"accesses":[{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}
-     ]
-    }
-    ,
-    {"id":3,"name":"allow-read-to-finance under /finance/restricted","isEnabled":true,"isAuditEnabled":true,
-     "resources":{"path":{"values":["/finance/restricted"],"isRecursive":true}},
-     "policyItems":[
-       {"accesses":[{"type":"read","isAllowed":true}],"users":[],"groups":["finance"],"delegateAdmin":false}
-     ]
-    }
   ],
   "tagPolicyInfo": {
 
@@ -120,7 +100,7 @@
       ]
     },
     "tagPolicies":[
-      {"id":101,"name":"test_policy","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      {"id":101,"name":"PII with expiry","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["PII"],"isRecursive":false}},
         "policyItems":[
           {
@@ -128,29 +108,43 @@
 				{"type":"hdfs:read", "isAllowed":true},
 				{"type":"hive:grant", "isAllowed":true},
 				{"type":"delete", "isAllowed":true},
-				{"type":":write", "isAllowed":true}
+				{"type":"hdfs:write", "isAllowed":true}
+			 ],
+			 "users":["user1"],
+			 "groups":["finance"],
+			 "delegateAdmin":false,
+			 "conditions" : []
+          }
+        ],
+        "denyPolicyItems":[
+          {
+            "accesses":[
+				{"type":"hdfs:read", "isAllowed":true},
+				{"type":"hive:grant", "isAllowed":true},
+				{"type":"delete", "isAllowed":true},
+				{"type":"hdfs:write", "isAllowed":true}
 			 ],
 			 "users":[""],
 			 "groups":["public"],
 			 "delegateAdmin":false,
-			 "itemType":0,
 			 "conditions" : [
 				{"type":"ScriptConditionEvaluator", "values": [
-					"ctx.result = true; importPackage(java.util); var accessDate = ctx.getAsDate(ctx.accessTime); var expiryDate =ctx.getTagAttributeAsDate('pii','expiry'); expiryDate.getTime() < accessDate.getTime();"
+					"ctx.result = true; importPackage(java.util); var accessDate = ctx.accessTime; var expiryDate = ctx.getTagAttributeAsDate('PII','expiry_date'); expiryDate.getTime() < accessDate.getTime();"
 				]}
              ]
-          },
+          }
+        ],
+        "denyExceptions":[
           {
             "accesses":[
 				{"type":"hdfs:read", "isAllowed":true},
 				{"type":"hive:grant", "isAllowed":true},
 				{"type":"delete", "isAllowed":true},
-				{"type":":write", "isAllowed":true}
+				{"type":"hdfs:write", "isAllowed":true}
 			 ],
 			 "users":["user1"],
 			 "groups":["finance"],
 			 "delegateAdmin":false,
-			 "itemType":1,
 			 "conditions" : []
           }
         ]
@@ -161,10 +155,28 @@
     {"name":"ALLOW 'read /finance/restricted/sales.db' for g=finance",
      "request":{
       "resource":{"elements":{"path":"/finance/restricted/sales.db"}},
-      "accessType":"read","user":"user1","userGroups":["finance"],"requestData":"read /finance/restricted/sales.db",
-       "context": {"TAGS":"[{\"type\":\"PII\"}]"}
+      "accessType":"read","user":"userx","userGroups":["finance"],"requestData":"read /finance/restricted/sales.db",
+       "context": {"TAGS":"[{\"type\":\"PII\",\"attributes\":{\"expiry_date\":\"2015/09/01\"}}]"}
+     },
+     "result":{"isAudited":true,"isAllowed":true,"policyId":101}
+    }
+    ,
+    {"name":"ALLOW 'read /finance/restricted/sales.db' for u=user1",
+     "request":{
+      "resource":{"elements":{"path":"/finance/restricted/sales.db"}},
+      "accessType":"read","user":"user1","userGroups":["employee"],"requestData":"read /finance/restricted/sales.db",
+       "context": {"TAGS":"[{\"type\":\"PII\",\"attributes\":{\"expiry_date\":\"2015/09/01\"}}]"}
+     },
+     "result":{"isAudited":true,"isAllowed":true,"policyId":101}
+    }
+    ,
+    {"name":"DENY 'read /finance/restricted/sales.db' for u=user2",
+     "request":{
+      "resource":{"elements":{"path":"/finance/restricted/sales.db"}},
+      "accessType":"read","user":"user2","userGroups":["employee"],"requestData":"read /finance/restricted/sales.db",
+       "context": {"TAGS":"[{\"type\":\"PII\",\"attributes\":{\"expiry_date\":\"2015/09/01\"}}]"}
      },
-     "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+     "result":{"isAudited":true,"isAllowed":false,"policyId":101}
     }
   ]
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
index f071cdc..cb07b17 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
@@ -153,7 +153,7 @@
       ]
     },
     "tagPolicies":[
-      {"id":1,"name":"RESTRICTED_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+      {"id":1,"name":"RESTRICTED_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["RESTRICTED"],"isRecursive":false}},
         "policyItems":[
           {
@@ -165,24 +165,30 @@
           }
         ]
       },
-      {"id":2,"name":"PII_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+      {"id":2,"name":"PII_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["PII"],"isRecursive":false}},
         "policyItems":[
           {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
         ]
       },
-      {"id":3,"name":"PII_TAG_POLICY-FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      {"id":3,"name":"PII_TAG_POLICY-FINAL","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["PII-FINAL"],"isRecursive":false}},
-        "policyItems":[
-          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[""],"groups":["public"],"delegateAdmin":false},
-		  {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false,"itemType":1}
+        "denyPolicyItems":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[""],"groups":["public"],"delegateAdmin":false}
+        ]
+        ,
+        "denyExceptions":[
+		  {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
         ]
       },
       {"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1,
         "resources":{"tag":{"values":["RESTRICTED-FINAL"],"isRecursive":false}},
-        "policyItems":[
-          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false},
-          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false,"itemType":1,
+        "denyPolicyItems":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}
+        ]
+        ,
+        "denyExceptions":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false,
             "conditions":[{
               "type":"ScriptConditionEvaluator",
               "values":["if ( ctx.isAccessedBefore('expiry') ) ctx.result = true;"]
@@ -190,13 +196,16 @@
           }
         ]
       },
-      {"id":5,"name":"EXPIRES_ON","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      {"id":5,"name":"EXPIRES_ON","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["EXPIRES_ON"],"isRecursive":false}},
-        "policyItems":[
+        "denyPolicyItems":[
           {"accesses":[{"type":"hive:select","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false,
             "conditions":[{"type":"enforce-expiry","values":["yes"]}]
-          },
-          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["dataloader"],"groups":[],"delegateAdmin":false,"itemType":1}
+          }
+        ]
+        ,
+        "denyExceptions":[
+          {"accesses":[{"type":"hive:select","isAllowed":true}],"users":["dataloader"],"groups":[],"delegateAdmin":false}
         ]
       }
     ]

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c18f8bf7/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index cccea3e..73a9109 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -103,6 +103,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator;
 import org.apache.ranger.plugin.store.*;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.plugin.util.ServicePolicies;
@@ -1417,7 +1418,10 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 
 		Map<String, RangerPolicyResource> resources = policy.getResources();
-		List<RangerPolicyItem> policyItems = policy.getPolicyItems();
+		List<RangerPolicyItem> policyItems     = policy.getPolicyItems();
+		List<RangerPolicyItem> denyPolicyItems = policy.getDenyPolicyItems();
+		List<RangerPolicyItem> allowExceptions = policy.getAllowExceptions();
+		List<RangerPolicyItem> denyExceptions  = policy.getDenyExceptions();
 
 		policy.setVersion(new Long(1));
 		updatePolicySignature(policy);
@@ -1438,7 +1442,10 @@ public class ServiceDBStore extends AbstractServiceStore {
 		XXPolicy xCreatedPolicy = daoMgr.getXXPolicy().getById(policy.getId());
 
 		createNewResourcesForPolicy(policy, xCreatedPolicy, resources);
-		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, policyItems, xServiceDef);
+		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, policyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
+		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, denyPolicyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
+		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, allowExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
+		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, denyExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
 		handlePolicyUpdate(service);
 		RangerPolicy createdPolicy = policyService.getPopulatedViewObject(xCreatedPolicy);
 		dataHistService.createObjectDataHistory(createdPolicy, RangerDataHistService.ACTION_CREATE);
@@ -1487,7 +1494,10 @@ public class ServiceDBStore extends AbstractServiceStore {
 			}
 		}
 		Map<String, RangerPolicyResource> newResources = policy.getResources();
-		List<RangerPolicyItem> newPolicyItems = policy.getPolicyItems();
+		List<RangerPolicyItem> policyItems     = policy.getPolicyItems();
+		List<RangerPolicyItem> denyPolicyItems = policy.getDenyPolicyItems();
+		List<RangerPolicyItem> allowExceptions = policy.getAllowExceptions();
+		List<RangerPolicyItem> denyExceptions  = policy.getDenyExceptions();
 		
 		List<XXTrxLog> trxLogList = policyService.getTransactionLog(policy, xxExisting, RangerPolicyService.OPERATION_UPDATE_CONTEXT);
 		
@@ -1509,7 +1519,10 @@ public class ServiceDBStore extends AbstractServiceStore {
 		deleteExistingPolicyItems(policy);
 		
 		createNewResourcesForPolicy(policy, newUpdPolicy, newResources);
-		createNewPolicyItemsForPolicy(policy, newUpdPolicy, newPolicyItems, xServiceDef);
+		createNewPolicyItemsForPolicy(policy, newUpdPolicy, policyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW);
+		createNewPolicyItemsForPolicy(policy, newUpdPolicy, denyPolicyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
+		createNewPolicyItemsForPolicy(policy, newUpdPolicy, allowExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
+		createNewPolicyItemsForPolicy(policy, newUpdPolicy, denyExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
 		
 		handlePolicyUpdate(service);
 		RangerPolicy updPolicy = policyService.getPopulatedViewObject(newUpdPolicy);
@@ -1831,7 +1844,6 @@ public class ServiceDBStore extends AbstractServiceStore {
 			policy.setService(createdService.getName());
 			policy.setDescription(tagType + " Policy for TAG Service: " + createdService.getName());
 			policy.setIsAuditEnabled(true);
-			policy.setPolicyType(RangerPolicy.POLICY_TYPE_DENY);
 
 			Map<String, RangerPolicyResource> resourceMap = new HashMap<String, RangerPolicyResource>();
 
@@ -1872,7 +1884,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 
 			policyItems.add(policyItem);
 
-			policy.setPolicyItems(policyItems);
+			policy.setDenyPolicyItems(policyItems);
 
 			policy = createPolicy(policy);
 		} else {
@@ -2026,7 +2038,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 	}
 
-	private void createNewPolicyItemsForPolicy(RangerPolicy policy, XXPolicy xPolicy, List<RangerPolicyItem> policyItems, XXServiceDef xServiceDef) throws Exception {
+	private void createNewPolicyItemsForPolicy(RangerPolicy policy, XXPolicy xPolicy, List<RangerPolicyItem> policyItems, XXServiceDef xServiceDef, int policyItemType) throws Exception {
 		
 		for (int itemOrder = 0; itemOrder < policyItems.size(); itemOrder++) {
 			RangerPolicyItem policyItem = policyItems.get(itemOrder);
@@ -2034,7 +2046,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 			xPolicyItem = (XXPolicyItem) rangerAuditFields.populateAuditFields(
 					xPolicyItem, xPolicy);
 			xPolicyItem.setDelegateAdmin(policyItem.getDelegateAdmin());
-			xPolicyItem.setItemType(policyItem.getItemType());
+			xPolicyItem.setItemType(policyItemType);
 			xPolicyItem.setPolicyId(policy.getId());
 			xPolicyItem.setOrder(itemOrder);
 			xPolicyItem = daoMgr.getXXPolicyItem().create(xPolicyItem);



Mime
View raw message