You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2016/03/08 02:31:39 UTC

[1/2] incubator-ranger git commit: RANGER-699: API for deny/allow from external tool. Commented out extracting users and groups from appliedPolicy, truncated processing of allow and deny exceptions

Repository: incubator-ranger
Updated Branches:
  refs/heads/master 6dbd2b8f1 -> dddc4d420


RANGER-699: API for deny/allow from external tool. Commented out extracting users and groups from appliedPolicy, truncated processing of allow and deny exceptions

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


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

Branch: refs/heads/master
Commit: 5423ee4f6074f3a4a01991431fd7d03e8712ddf1
Parents: 6dbd2b8
Author: Abhay Kulkarni <ak...@hortonworks.com>
Authored: Tue Jan 19 23:32:30 2016 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sun Mar 6 22:08:07 2016 -0800

----------------------------------------------------------------------
 .../org/apache/ranger/rest/PublicAPIsv2.java    |   8 +-
 .../org/apache/ranger/rest/ServiceREST.java     | 372 +++------
 .../org/apache/ranger/rest/ServiceRESTUtil.java | 750 +++++++++++++++++++
 .../org/apache/ranger/rest/TestServiceREST.java | 333 ++++++++
 4 files changed, 1181 insertions(+), 282 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5423ee4f/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java b/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
index 2c30daa..8601b95 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
@@ -322,6 +322,13 @@ public class PublicAPIsv2 {
 		return serviceREST.createPolicy(policy);
 	}
 
+	@POST
+	@Path("/api/policy/apply/")
+	@Produces({ "application/json", "application/xml" })
+	public RangerPolicy applyPolicy(RangerPolicy policy) { // new API
+		return serviceREST.applyPolicy(policy);
+	}
+
 	@PUT
 	@Path("/api/policy/{id}")
 	@Produces({ "application/json", "application/xml" })
@@ -336,7 +343,6 @@ public class PublicAPIsv2 {
 		return serviceREST.updatePolicy(policy);
 	}
 
-
 	@PUT
 	@Path("/api/service/{servicename}/policy/{policyname}")
 	@Produces({ "application/json", "application/xml" })

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5423ee4f/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index a28eca1..5e5d626 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -55,7 +55,6 @@ import org.apache.ranger.biz.XUserMgr;
 import org.apache.ranger.common.GUIDUtil;
 import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.RESTErrorUtil;
-import org.apache.ranger.common.RangerConfigUtil;
 import org.apache.ranger.common.RangerSearchUtil;
 import org.apache.ranger.common.RangerValidatorFactory;
 import org.apache.ranger.common.ServiceUtil;
@@ -67,6 +66,7 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicyResourceSignature;
 import org.apache.ranger.plugin.model.RangerService;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.validation.RangerPolicyValidator;
@@ -127,10 +127,7 @@ public class ServiceREST {
 	
 	@Autowired
 	ServiceUtil serviceUtil;
-	
-	@Autowired
-	RangerConfigUtil configUtil;
-	
+
 	@Autowired
 	RangerPolicyService policyService;
 	
@@ -851,69 +848,16 @@ public class ServiceREST {
 				}
 	
 				RangerPolicy policy = getExactMatchPolicyForResource(policyEngine, resource);
-		
+
 				if(policy != null) {
 					boolean policyUpdated = false;
-	
-					// replace all existing privileges for users and groups
-					if(grantRequest.getReplaceExistingPermissions()) {
-						policyUpdated = removeUsersAndGroupsFromPolicy(policy, grantRequest.getUsers(), grantRequest.getGroups());
-					}
-	
-					for(String user : grantRequest.getUsers()) {
-						RangerPolicyItem policyItem = getPolicyItemForUser(policy, user);
-						
-						if(policyItem != null) {
-							if(addAccesses(policyItem, grantRequest.getAccessTypes())) {
-								policyUpdated = true;
-							}
-						} else {
-							policyItem = new RangerPolicyItem();
-							
-							policyItem.getUsers().add(user);
-							addAccesses(policyItem, grantRequest.getAccessTypes());
-							policy.getPolicyItems().add(policyItem);
-	
-							policyUpdated = true;
-						}
-	
-						if(grantRequest.getDelegateAdmin()) {
-							if(!policyItem.getDelegateAdmin()) {
-								policyItem.setDelegateAdmin(Boolean.TRUE);
-		
-								policyUpdated = true;
-							}
-						}
-					}
-	
-					for(String group : grantRequest.getGroups()) {
-						RangerPolicyItem policyItem = getPolicyItemForGroup(policy, group);
-						
-						if(policyItem != null) {
-							if(addAccesses(policyItem, grantRequest.getAccessTypes())) {
-								policyUpdated = true;
-							}
-						} else {
-							policyItem = new RangerPolicyItem();
-							
-							policyItem.getGroups().add(group);
-							addAccesses(policyItem, grantRequest.getAccessTypes());
-							policy.getPolicyItems().add(policyItem);
-	
-							policyUpdated = true;
-						}
-	
-						if(grantRequest.getDelegateAdmin()) {
-							if(!policyItem.getDelegateAdmin()) {
-								policyItem.setDelegateAdmin(Boolean.TRUE);
-		
-								policyUpdated = true;
-							}
-						}
-					}
-	
+					policyUpdated = ServiceRESTUtil.processGrantRequest(policy, grantRequest);
+
 					if(policyUpdated) {
 						svcStore.updatePolicy(policy);
+					} else {
+						LOG.error("processGrantRequest processing failed");
+						throw new Exception("processGrantRequest processing failed");
 					}
 				} else {
 					policy = new RangerPolicy();
@@ -935,29 +879,19 @@ public class ServiceREST {
 						}
 					}
 					policy.setResources(policyResources);
-		
-					for(String user : grantRequest.getUsers()) {
-						RangerPolicyItem policyItem = new RangerPolicyItem();
-			
-						policyItem.getUsers().add(user);
-						for(String accessType : grantRequest.getAccessTypes()) {
-							policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
-						}
-						policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
-						policy.getPolicyItems().add(policyItem);
-					}
-					
-					for(String group : grantRequest.getGroups()) {
-						RangerPolicyItem policyItem = new RangerPolicyItem();
-			
-						policyItem.getGroups().add(group);
-						for(String accessType : grantRequest.getAccessTypes()) {
-							policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
-						}
-						policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
-						policy.getPolicyItems().add(policyItem);
+
+					RangerPolicyItem policyItem = new RangerPolicyItem();
+
+					policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
+					policyItem.getUsers().addAll(grantRequest.getUsers());
+					policyItem.getGroups().addAll(grantRequest.getGroups());
+
+					for(String accessType : grantRequest.getAccessTypes()) {
+						policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
 					}
-		
+
+					policy.getPolicyItems().add(policyItem);
+
 					svcStore.createPolicy(policy);
 				}
 			} catch(WebApplicationException excp) {
@@ -1013,53 +947,13 @@ public class ServiceREST {
 				
 				if(policy != null) {
 					boolean policyUpdated = false;
+					policyUpdated = ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);
 
-					// remove all existing privileges for users and groups
-					if(revokeRequest.getReplaceExistingPermissions()) {
-						policyUpdated = removeUsersAndGroupsFromPolicy(policy, revokeRequest.getUsers(), revokeRequest.getGroups());
-					} else {
-						for(String user : revokeRequest.getUsers()) {
-							RangerPolicyItem policyItem = getPolicyItemForUser(policy, user);
-
-							if (policyItem != null) {
-								if (removeAccesses(policyItem, revokeRequest.getAccessTypes())) {
-									policyUpdated = true;
-								}
-
-								if (revokeRequest.getDelegateAdmin()) { // remove delegate?
-									if (policyItem.getDelegateAdmin()) {
-										policyItem.setDelegateAdmin(Boolean.FALSE);
-										policyUpdated = true;
-									}
-
-								}
-							}
-						}
-	
-						for(String group : revokeRequest.getGroups()) {
-							RangerPolicyItem policyItem = getPolicyItemForGroup(policy, group);
-						
-							if(policyItem != null) {
-								if(removeAccesses(policyItem, revokeRequest.getAccessTypes())) {
-									policyUpdated = true;
-								}
-
-								if(revokeRequest.getDelegateAdmin()) { // remove delegate?
-									if(policyItem.getDelegateAdmin()) {
-										policyItem.setDelegateAdmin(Boolean.FALSE);
-										policyUpdated = true;
-									}
-								}
-							}
-						}
-	
-						if(compactPolicy(policy)) {
-							policyUpdated = true;
-						}
-					}
-	
 					if(policyUpdated) {
 						svcStore.updatePolicy(policy);
+					} else {
+						LOG.error("processRevokeRequest processing failed");
+						throw new Exception("processRevokeRequest processing failed");
 					}
 				} else {
 					// nothing to revoke!
@@ -1139,6 +1033,72 @@ public class ServiceREST {
 		return ret;
 	}
 
+	/*
+	The verb for applyPolicy is POST as it could be partial update or a create
+	*/
+
+	@POST
+	@Path("/policies/apply")
+	@Produces({ "application/json", "application/xml" })
+	public RangerPolicy applyPolicy(RangerPolicy policy) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceREST.applyPolicy(" + policy + ")");
+		}
+
+		RangerPolicy ret = null;
+
+		if (policy != null && StringUtils.isNotBlank(policy.getService())) {
+
+			try {
+				RangerPolicyResourceSignature resourceSignature = new RangerPolicyResourceSignature(policy);
+
+				List<RangerPolicy> existingPolicies = svcStore.getPoliciesByResourceSignature(policy.getService(), resourceSignature.getSignature(), true);
+
+				if (CollectionUtils.isEmpty(existingPolicies)) {
+
+					ret = createPolicy(policy);
+
+				} else if (existingPolicies.size() == 1) {
+
+					// Check if applied policy contains any conditions
+					if (ServiceRESTUtil.containsRangerCondition(policy)) {
+						LOG.error("Applied policy contains condition(s); not supported:" + policy);
+						throw new Exception("Applied policy contains condition(s); not supported:" + policy);
+					}
+					RangerPolicy existingPolicy = existingPolicies.get(0);
+
+					// If existing policy-items contains conditions, then we add/remove specified accesses to
+					// existing policy-items as specified in applied policy, ignoring those conditions.
+					// New policy-items will have no conditions.
+
+					boolean applyResult = ServiceRESTUtil.processApplyPolicy(existingPolicy, policy);
+
+					if (applyResult) {
+						ret = updatePolicy(existingPolicy);
+					} else {
+						LOG.error("applyPolicy processing failed");
+						throw new Exception("applyPolicy processing failed");
+					}
+
+				} else {
+					// there should be only one policy for the given resources
+					throw new Exception("Invalid state: multiple policies exists for resource " + policy.getResources());
+				}
+			} catch (Exception exception) {
+				LOG.error("Failed to apply policy:", exception);
+				throw restErrorUtil.createRESTException(exception.getMessage());
+			}
+		} else {
+			throw restErrorUtil.createRESTException("Non-existing service specified:" + policy == null ? null : policy.getService());
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceREST.applyPolicy(" + policy + ") : " + ret);
+		}
+
+		return ret;
+	}
+
 	@PUT
 	@Path("/policies/{id}")
 	@Produces({ "application/json", "application/xml" })
@@ -1603,156 +1563,6 @@ public class ServiceREST {
 		return ret;
 	}
 
-	private boolean compactPolicy(RangerPolicy policy) {
-		boolean ret = false;
-
-		List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
-													policy.getDenyPolicyItems(),
-													policy.getAllowExceptions(),
-													policy.getDenyExceptions()
-												  };
-
-		for(List<?> policyItemsObj : policyItemsList) {
-			@SuppressWarnings("unchecked")
-			List<RangerPolicyItem> policyItems = (List<RangerPolicyItem>)policyItemsObj;
-
-			int numOfItems = policyItems.size();
-		
-			for(int i = 0; i < numOfItems; i++) {
-				RangerPolicyItem policyItem = policyItems.get(i);
-			
-				// remove the policy item if 1) there are no users and groups OR 2) if there are no accessTypes and not a delegate-admin
-				if((CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups())) ||
-				   (CollectionUtils.isEmpty(policyItem.getAccesses()) && !policyItem.getDelegateAdmin())) {
-					policyItems.remove(i);
-					numOfItems--;
-					i--;
-
-					ret = true;
-				}
-			}
-		}
-
-		return ret;
-	}
-
-	private RangerPolicyItem getPolicyItemForUser(RangerPolicy policy, String userName) {
-		RangerPolicyItem ret = null;
-
-		for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
-			if(policyItem.getUsers().size() != 1) {
-				continue;
-			}
-
-			if(policyItem.getUsers().contains(userName)) {
-				ret = policyItem;
-				break;
-			}
-		}
-
-		return ret;
-	}
-
-	private RangerPolicyItem getPolicyItemForGroup(RangerPolicy policy, String groupName) {
-		RangerPolicyItem ret = null;
-
-		for(RangerPolicyItem policyItem : policy.getPolicyItems()) {
-			if(policyItem.getGroups().size() != 1) {
-				continue;
-			}
-
-			if(policyItem.getGroups().contains(groupName)) {
-				ret = policyItem;
-				break;
-			}
-		}
-
-		return ret;
-	}
-
-	private boolean addAccesses(RangerPolicyItem policyItem, Set<String> accessTypes) {
-		boolean ret = false;
-
-		for(String accessType : accessTypes) {
-			RangerPolicyItemAccess policyItemAccess = null;
-
-			for(RangerPolicyItemAccess itemAccess : policyItem.getAccesses()) {
-				if(StringUtils.equals(itemAccess.getType(), accessType)) {
-					policyItemAccess = itemAccess;
-					break;
-				}
-			}
-
-			if(policyItemAccess != null) {
-				if(!policyItemAccess.getIsAllowed()) {
-					policyItemAccess.setIsAllowed(Boolean.TRUE);
-					ret = true;
-				}
-			} else {
-				policyItem.getAccesses().add(new RangerPolicyItemAccess(accessType, Boolean.TRUE));
-				ret = true;
-			}
-		}
-
-		return ret;
-	}
-
-	private boolean removeAccesses(RangerPolicyItem policyItem, Set<String> accessTypes) {
-		boolean ret = false;
-
-		for(String accessType : accessTypes) {
-			int numOfItems = policyItem.getAccesses().size();
-
-			for(int i = 0; i < numOfItems; i++) {
-				RangerPolicyItemAccess itemAccess = policyItem.getAccesses().get(i);
-				
-				if(StringUtils.equals(itemAccess.getType(), accessType)) {
-					policyItem.getAccesses().remove(i);
-					numOfItems--;
-					i--;
-
-					ret = true;
-				}
-			}
-		}
-
-		return ret;
-	}
-
-	private boolean removeUsersAndGroupsFromPolicy(RangerPolicy policy, Set<String> users, Set<String> groups) {
-		boolean policyUpdated = false;
-
-		List<RangerPolicyItem> policyItems = policy.getPolicyItems();
-
-		int numOfItems = policyItems.size();
-
-		for(int i = 0; i < numOfItems; i++) {
-			RangerPolicyItem policyItem = policyItems.get(i);
-
-			if(CollectionUtils.containsAny(policyItem.getUsers(), users)) {
-				policyItem.getUsers().removeAll(users);
-
-				policyUpdated = true;
-			}
-
-			if(CollectionUtils.containsAny(policyItem.getGroups(), groups)) {
-				policyItem.getGroups().removeAll(groups);
-
-				policyUpdated = true;
-			}
-
-			if(CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups())) {
-				policyItems.remove(i);
-				numOfItems--;
-				i--;
-
-				policyUpdated = true;
-			}
-		}
-
-		return policyUpdated;
-	}
-
 	@GET
 	@Path("/policies/eventTime")
 	@Produces({ "application/json", "application/xml" })
@@ -1969,7 +1779,7 @@ public class ServiceREST {
 			options.disableCustomConditions = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.custom.conditions", true);
 			options.evaluateDelegateAdminOnly = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.evaluate.delegateadmin.only", true);
 
-			RangerPolicyEngineCache.getInstance().setPolicyEngineOptions(options);;
+			RangerPolicyEngineCache.getInstance().setPolicyEngineOptions(options);
 		}
 
 		RangerPolicyEngine ret = RangerPolicyEngineCache.getInstance().getPolicyEngine(serviceName, svcStore);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5423ee4f/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
new file mode 100644
index 0000000..7518363
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
@@ -0,0 +1,750 @@
+/*
+ * 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.rest;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.util.GrantRevokeRequest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class ServiceRESTUtil {
+	private static final Log LOG = LogFactory.getLog(ServiceRESTUtil.class);
+
+	private enum POLICYITEM_TYPE {
+		ALLOW, DENY, ALLOW_EXCEPTIONS, DENY_EXCEPTIONS
+	}
+
+	static public boolean processGrantRequest(RangerPolicy policy, GrantRevokeRequest grantRequest) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.processGrantRequest()");
+		}
+
+		boolean policyUpdated = false;
+
+		// replace all existing privileges for users and groups
+		if (grantRequest.getReplaceExistingPermissions()) {
+			policyUpdated = removeUsersAndGroupsFromPolicy(policy, grantRequest.getUsers(), grantRequest.getGroups());
+		}
+
+		//Build a policy and set up policyItem in it to mimic grant request
+		RangerPolicy appliedPolicy = new RangerPolicy();
+
+		RangerPolicy.RangerPolicyItem policyItem = new RangerPolicy.RangerPolicyItem();
+
+		policyItem.setDelegateAdmin(grantRequest.getDelegateAdmin());
+		policyItem.getUsers().addAll(grantRequest.getUsers());
+		policyItem.getGroups().addAll(grantRequest.getGroups());
+
+		List<RangerPolicy.RangerPolicyItemAccess> accesses = new ArrayList<RangerPolicy.RangerPolicyItemAccess>();
+
+		Set<String> accessTypes = grantRequest.getAccessTypes();
+		for (String accessType : accessTypes) {
+			accesses.add(new RangerPolicy.RangerPolicyItemAccess(accessType, true));
+		}
+
+		policyItem.setAccesses(accesses);
+
+		appliedPolicy.getPolicyItems().add(policyItem);
+
+		policyUpdated = processApplyPolicy(policy, appliedPolicy) || policyUpdated;
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.processGrantRequest() : " + policyUpdated);
+		}
+
+		return policyUpdated;
+	}
+
+	static public boolean processRevokeRequest(RangerPolicy policy, GrantRevokeRequest revokeRequest) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.processRevokeRequest()");
+		}
+
+		boolean policyUpdated = false;
+
+		// remove all existing privileges for users and groups
+		if (revokeRequest.getReplaceExistingPermissions()) {
+			policyUpdated = removeUsersAndGroupsFromPolicy(policy, revokeRequest.getUsers(), revokeRequest.getGroups());
+		} else {
+			//Build a policy and set up policyItem in it to mimic revoke request
+			RangerPolicy appliedPolicy = new RangerPolicy();
+
+			RangerPolicy.RangerPolicyItem policyItem = new RangerPolicy.RangerPolicyItem();
+
+			policyItem.setDelegateAdmin(revokeRequest.getDelegateAdmin());
+			policyItem.getUsers().addAll(revokeRequest.getUsers());
+			policyItem.getGroups().addAll(revokeRequest.getGroups());
+
+			List<RangerPolicy.RangerPolicyItemAccess> accesses = new ArrayList<RangerPolicy.RangerPolicyItemAccess>();
+
+			Set<String> accessTypes = revokeRequest.getAccessTypes();
+			for (String accessType : accessTypes) {
+				accesses.add(new RangerPolicy.RangerPolicyItemAccess(accessType, true));
+			}
+
+			policyItem.setAccesses(accesses);
+
+			appliedPolicy.getDenyPolicyItems().add(policyItem);
+
+			policyUpdated = processApplyPolicy(policy, appliedPolicy);
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.processRevokeRequest() : " + policyUpdated);
+		}
+
+		return policyUpdated;
+	}
+
+	static public boolean processApplyPolicy(RangerPolicy existingPolicy, RangerPolicy appliedPolicy) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.processApplyPolicy()");
+		}
+
+		boolean ret = false;
+
+		ret = processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.ALLOW);
+		ret = ret && processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.DENY);
+		ret = ret && processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.ALLOW_EXCEPTIONS);
+		ret = ret && processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.DENY_EXCEPTIONS);
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.processApplyPolicy()");
+		}
+
+		return ret;
+	}
+
+	static public boolean processApplyPolicyForItemType(RangerPolicy existingPolicy, RangerPolicy appliedPolicy, POLICYITEM_TYPE policyItemType) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.processApplyPolicyForItemType()");
+		}
+
+		boolean ret = false;
+
+		List<RangerPolicy.RangerPolicyItem> appliedPolicyItems = null;
+
+		switch (policyItemType) {
+			case ALLOW:
+				appliedPolicyItems = appliedPolicy.getPolicyItems();
+				break;
+			case DENY:
+				appliedPolicyItems = appliedPolicy.getDenyPolicyItems();
+				break;
+			case ALLOW_EXCEPTIONS:
+				appliedPolicyItems = appliedPolicy.getAllowExceptions();
+				break;
+			case DENY_EXCEPTIONS:
+				appliedPolicyItems = appliedPolicy.getDenyExceptions();
+				break;
+			default:
+				LOG.warn("Should not have come here..");
+				return false;
+		}
+
+		if (CollectionUtils.isNotEmpty(appliedPolicyItems)) {
+
+			Set<String> users = new HashSet<String>();
+			Set<String> groups = new HashSet<String>();
+
+			Map<String, RangerPolicy.RangerPolicyItem[]> userPolicyItems = new HashMap<String, RangerPolicy.RangerPolicyItem[]>();
+			Map<String, RangerPolicy.RangerPolicyItem[]> groupPolicyItems = new HashMap<String, RangerPolicy.RangerPolicyItem[]>();
+
+			// Extract users and groups specified in appliedPolicy items
+			extractUsersAndGroups(appliedPolicyItems, users, groups);
+
+			// Split existing policyItems for users and groups extracted from appliedPolicyItem into userPolicyItems and groupPolicyItems
+			splitExistingPolicyItems(existingPolicy, users, userPolicyItems, groups, groupPolicyItems);
+
+			// Apply policyItems of given type in appliedPolicy to policyItems extracted from existingPolicy
+			applyPolicyItems(appliedPolicyItems, policyItemType, userPolicyItems, groupPolicyItems);
+
+			// Add modified/new policyItems back to existing policy
+			mergeProcessedPolicyItems(existingPolicy, userPolicyItems, groupPolicyItems);
+
+			ret = compactPolicy(existingPolicy);
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.processApplyPolicyForItemType()");
+		}
+
+		return ret;
+	}
+
+	static private void extractUsersAndGroups(List<RangerPolicy.RangerPolicyItem> policyItems, Set<String> users, Set<String> groups) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.extractUsersAndGroups()");
+		}
+		if (CollectionUtils.isNotEmpty(policyItems)) {
+			for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
+				if (CollectionUtils.isNotEmpty(policyItem.getUsers())) {
+					users.addAll(policyItem.getUsers());
+				}
+				if (CollectionUtils.isNotEmpty(policyItem.getGroups())) {
+					groups.addAll(policyItem.getGroups());
+				}
+			}
+		}
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.extractUsersAndGroups()");
+		}
+	}
+
+	static private void splitExistingPolicyItems(RangerPolicy existingPolicy,
+												 Set<String> users, Map<String, RangerPolicy.RangerPolicyItem[]> userPolicyItems, Set<String> groups,
+												 Map<String, RangerPolicy.RangerPolicyItem[]> groupPolicyItems) {
+
+		if (existingPolicy == null
+				|| users == null || userPolicyItems == null
+				|| groups == null || groupPolicyItems == null) {
+			return;
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.splitExistingPolicyItems()");
+		}
+
+		List<RangerPolicy.RangerPolicyItem> allowItems = existingPolicy.getPolicyItems();
+		List<RangerPolicy.RangerPolicyItem> denyItems = existingPolicy.getDenyPolicyItems();
+		List<RangerPolicy.RangerPolicyItem> allowExceptionItems = existingPolicy.getAllowExceptions();
+		List<RangerPolicy.RangerPolicyItem> denyExceptionItems = existingPolicy.getDenyExceptions();
+
+		for (String user : users) {
+			RangerPolicy.RangerPolicyItem value[] = userPolicyItems.get(user);
+			if (value == null) {
+				value = new RangerPolicy.RangerPolicyItem[4];
+				userPolicyItems.put(user, value);
+			}
+
+			RangerPolicy.RangerPolicyItem policyItem = null;
+
+			policyItem = splitAndGetConsolidatedPolicyItemForUser(allowItems, user);
+			value[POLICYITEM_TYPE.ALLOW.ordinal()] = policyItem;
+			policyItem = splitAndGetConsolidatedPolicyItemForUser(denyItems, user);
+			value[POLICYITEM_TYPE.DENY.ordinal()] = policyItem;
+			policyItem = splitAndGetConsolidatedPolicyItemForUser(allowExceptionItems, user);
+			value[POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal()] = policyItem;
+			policyItem = splitAndGetConsolidatedPolicyItemForUser(denyExceptionItems, user);
+			value[POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal()] = policyItem;
+		}
+
+		for (String group : groups) {
+			RangerPolicy.RangerPolicyItem value[] = groupPolicyItems.get(group);
+			if (value == null) {
+				value = new RangerPolicy.RangerPolicyItem[4];
+				groupPolicyItems.put(group, value);
+			}
+
+			RangerPolicy.RangerPolicyItem policyItem = null;
+
+			policyItem = splitAndGetConsolidatedPolicyItemForGroup(allowItems, group);
+			value[POLICYITEM_TYPE.ALLOW.ordinal()] = policyItem;
+			policyItem = splitAndGetConsolidatedPolicyItemForGroup(denyItems, group);
+			value[POLICYITEM_TYPE.DENY.ordinal()] = policyItem;
+			policyItem = splitAndGetConsolidatedPolicyItemForGroup(allowExceptionItems, group);
+			value[POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal()] = policyItem;
+			policyItem = splitAndGetConsolidatedPolicyItemForGroup(denyExceptionItems, group);
+			value[POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal()] = policyItem;
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.splitExistingPolicyItems()");
+		}
+	}
+
+	static private RangerPolicy.RangerPolicyItem splitAndGetConsolidatedPolicyItemForUser(List<RangerPolicy.RangerPolicyItem> userPolicyItems, String user) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.splitAndGetConsolidatedPolicyItemForUser()");
+		}
+
+		RangerPolicy.RangerPolicyItem ret = null;
+
+		if (CollectionUtils.isNotEmpty(userPolicyItems)) {
+
+			for (RangerPolicy.RangerPolicyItem policyItem : userPolicyItems) {
+				List<String> users = policyItem.getUsers();
+				if (users.contains(user)) {
+					if (ret == null) {
+						ret = new RangerPolicy.RangerPolicyItem();
+					}
+					ret.getUsers().add(user);
+					if (policyItem.getDelegateAdmin()) {
+						ret.setDelegateAdmin(Boolean.TRUE);
+					}
+					addAccesses(ret, policyItem.getAccesses());
+
+					// Remove this user/group from existingPolicyItem
+					users.remove(user);
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.splitAndGetConsolidatedPolicyItemForUser()");
+		}
+
+		return ret;
+	}
+
+	static private RangerPolicy.RangerPolicyItem splitAndGetConsolidatedPolicyItemForGroup(List<RangerPolicy.RangerPolicyItem> groupPolicyItems, String group) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.splitAndGetConsolidatedPolicyItemForGroup()");
+		}
+
+		RangerPolicy.RangerPolicyItem ret = null;
+
+		if (CollectionUtils.isNotEmpty(groupPolicyItems)) {
+
+			for (RangerPolicy.RangerPolicyItem policyItem : groupPolicyItems) {
+				List<String> groups = policyItem.getGroups();
+				if (groups.contains(group)) {
+					if (ret == null) {
+						ret = new RangerPolicy.RangerPolicyItem();
+					}
+					ret.getGroups().add(group);
+					if (policyItem.getDelegateAdmin()) {
+						ret.setDelegateAdmin(Boolean.TRUE);
+					}
+					addAccesses(ret, policyItem.getAccesses());
+
+					// Remove this user/group from existingPolicyItem
+					groups.remove(group);
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.splitAndGetConsolidatedPolicyItemForGroup()");
+		}
+
+		return ret;
+	}
+
+	static private void applyPolicyItems(List<RangerPolicy.RangerPolicyItem> appliedPolicyItems, POLICYITEM_TYPE policyItemType, Map<String, RangerPolicy.RangerPolicyItem[]> existingUserPolicyItems,
+										 Map<String, RangerPolicy.RangerPolicyItem[]> existingGroupPolicyItems) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.applyPolicyItems()");
+		}
+
+		for (RangerPolicy.RangerPolicyItem policyItem : appliedPolicyItems) {
+			List<String> users = policyItem.getUsers();
+			for (String user : users) {
+				RangerPolicy.RangerPolicyItem[] items = existingUserPolicyItems.get(user);
+
+				if (items == null) {
+					// Should not get here
+					LOG.warn("Should not have come here..");
+					items = new RangerPolicy.RangerPolicyItem[4];
+					existingUserPolicyItems.put(user, items);
+				}
+
+				addPolicyItemForUser(items, policyItemType.ordinal(), user, policyItem);
+
+				switch (policyItemType) {
+					case ALLOW:
+						removeAccesses(items[POLICYITEM_TYPE.DENY.ordinal()], policyItem.getAccesses());
+						removeAccesses(items[POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal()], policyItem.getAccesses());
+						addPolicyItemForUser(items, POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal(), user, policyItem);
+						break;
+					case DENY:
+						removeAccesses(items[POLICYITEM_TYPE.ALLOW.ordinal()], policyItem.getAccesses());
+						addPolicyItemForUser(items, POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal(), user, policyItem);
+						removeAccesses(items[POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal()], policyItem.getAccesses());
+						break;
+					case ALLOW_EXCEPTIONS:
+						removeAccesses(items[POLICYITEM_TYPE.ALLOW.ordinal()], policyItem.getAccesses());
+						break;
+					case DENY_EXCEPTIONS:
+						break;
+					default:
+						LOG.warn("Should not have come here..");
+						break;
+				}
+			}
+		}
+
+		for (RangerPolicy.RangerPolicyItem policyItem : appliedPolicyItems) {
+			List<String> groups = policyItem.getGroups();
+			for (String group : groups) {
+				RangerPolicy.RangerPolicyItem[] items = existingGroupPolicyItems.get(group);
+
+				if (items == null) {
+					// Should not get here
+					items = new RangerPolicy.RangerPolicyItem[4];
+					existingGroupPolicyItems.put(group, items);
+				}
+
+				addPolicyItemForGroup(items, policyItemType.ordinal(), group, policyItem);
+
+				switch (policyItemType) {
+					case ALLOW:
+						removeAccesses(items[POLICYITEM_TYPE.DENY.ordinal()], policyItem.getAccesses());
+						removeAccesses(items[POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal()], policyItem.getAccesses());
+						addPolicyItemForGroup(items, POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal(), group, policyItem);
+						break;
+					case DENY:
+						removeAccesses(items[POLICYITEM_TYPE.ALLOW.ordinal()], policyItem.getAccesses());
+						addPolicyItemForGroup(items, POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal(), group, policyItem);
+						removeAccesses(items[POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal()], policyItem.getAccesses());
+						break;
+					case ALLOW_EXCEPTIONS:
+						removeAccesses(items[POLICYITEM_TYPE.ALLOW.ordinal()], policyItem.getAccesses());
+						break;
+					case DENY_EXCEPTIONS:
+						break;
+					default:
+						break;
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.applyPolicyItems()");
+		}
+	}
+
+	static private void mergeProcessedPolicyItems(RangerPolicy existingPolicy, Map<String, RangerPolicy.RangerPolicyItem[]> userPolicyItems,
+												  Map<String, RangerPolicy.RangerPolicyItem[]> groupPolicyItems) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.mergeProcessedPolicyItems()");
+		}
+
+		for (Map.Entry<String, RangerPolicy.RangerPolicyItem[]> entry : userPolicyItems.entrySet()) {
+			RangerPolicy.RangerPolicyItem[] items = entry.getValue();
+
+			RangerPolicy.RangerPolicyItem item = null;
+
+			item = items[POLICYITEM_TYPE.ALLOW.ordinal()];
+			if (item != null) {
+				existingPolicy.getPolicyItems().add(item);
+			}
+
+			item = items[POLICYITEM_TYPE.DENY.ordinal()];
+			if (item != null) {
+				existingPolicy.getDenyPolicyItems().add(item);
+			}
+
+			item = items[POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal()];
+			if (item != null) {
+				existingPolicy.getAllowExceptions().add(item);
+			}
+
+			item = items[POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal()];
+			if (item != null) {
+				existingPolicy.getDenyExceptions().add(item);
+			}
+		}
+
+		for (Map.Entry<String, RangerPolicy.RangerPolicyItem[]> entry : groupPolicyItems.entrySet()) {
+			RangerPolicy.RangerPolicyItem[] items = entry.getValue();
+
+			RangerPolicy.RangerPolicyItem item = null;
+
+			item = items[POLICYITEM_TYPE.ALLOW.ordinal()];
+			if (item != null) {
+				existingPolicy.getPolicyItems().add(item);
+			}
+
+			item = items[POLICYITEM_TYPE.DENY.ordinal()];
+			if (item != null) {
+				existingPolicy.getDenyPolicyItems().add(item);
+			}
+
+			item = items[POLICYITEM_TYPE.ALLOW_EXCEPTIONS.ordinal()];
+			if (item != null) {
+				existingPolicy.getAllowExceptions().add(item);
+			}
+
+			item = items[POLICYITEM_TYPE.DENY_EXCEPTIONS.ordinal()];
+			if (item != null) {
+				existingPolicy.getDenyExceptions().add(item);
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.mergeProcessedPolicyItems()");
+		}
+	}
+
+	static private boolean addAccesses(RangerPolicy.RangerPolicyItem policyItem, List<RangerPolicy.RangerPolicyItemAccess> accesses) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.addAccesses()");
+		}
+
+		boolean ret = false;
+
+		for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
+			RangerPolicy.RangerPolicyItemAccess policyItemAccess = null;
+			String accessType = access.getType();
+
+			for (RangerPolicy.RangerPolicyItemAccess itemAccess : policyItem.getAccesses()) {
+				if (StringUtils.equals(itemAccess.getType(), accessType)) {
+					policyItemAccess = itemAccess;
+					break;
+				}
+			}
+
+			if (policyItemAccess != null) {
+				if (!policyItemAccess.getIsAllowed()) {
+					policyItemAccess.setIsAllowed(Boolean.TRUE);
+					ret = true;
+				}
+			} else {
+				policyItem.getAccesses().add(new RangerPolicy.RangerPolicyItemAccess(accessType, Boolean.TRUE));
+				ret = true;
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.addAccesses() " + ret);
+		}
+		return ret;
+	}
+
+	static private boolean removeAccesses(RangerPolicy.RangerPolicyItem policyItem, List<RangerPolicy.RangerPolicyItemAccess> accesses) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.removeAccesses()");
+		}
+
+		boolean ret = false;
+
+		if (policyItem != null) {
+			for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
+				String accessType = access.getType();
+
+				int numOfItems = policyItem.getAccesses().size();
+
+				for (int i = 0; i < numOfItems; i++) {
+					RangerPolicy.RangerPolicyItemAccess itemAccess = policyItem.getAccesses().get(i);
+
+					if (StringUtils.equals(itemAccess.getType(), accessType)) {
+						policyItem.getAccesses().remove(i);
+						numOfItems--;
+						i--;
+
+						ret = true;
+					}
+				}
+			}
+		}
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.removeAccesses() " + ret);
+		}
+		return ret;
+	}
+
+	static private boolean compactPolicy(RangerPolicy policy) {
+		boolean ret = true;			// Always true for now
+
+		List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
+				policy.getDenyPolicyItems(),
+				policy.getAllowExceptions(),
+				policy.getDenyExceptions()
+		};
+
+		for(List<?> policyItemsObj : policyItemsList) {
+			@SuppressWarnings("unchecked")
+			List<RangerPolicy.RangerPolicyItem> policyItems = (List<RangerPolicy.RangerPolicyItem>)policyItemsObj;
+
+			int numOfItems = policyItems.size();
+
+			for(int i = 0; i < numOfItems; i++) {
+				RangerPolicy.RangerPolicyItem policyItem = policyItems.get(i);
+
+				// remove the policy item if 1) there are no users and groups OR 2) if there are no accessTypes and not a delegate-admin
+				if((CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups())) ||
+						(CollectionUtils.isEmpty(policyItem.getAccesses()) && !policyItem.getDelegateAdmin())) {
+					policyItems.remove(i);
+					numOfItems--;
+					i--;
+
+					ret = true;
+				}
+			}
+		}
+
+		policy.setPolicyItems(mergePolicyItems(policy.getPolicyItems()));
+		policy.setDenyPolicyItems(mergePolicyItems(policy.getDenyPolicyItems()));
+		policy.setAllowExceptions(mergePolicyItems(policy.getAllowExceptions()));
+		policy.setDenyExceptions(mergePolicyItems(policy.getDenyExceptions()));
+
+		return ret;
+	}
+
+	static private List<RangerPolicy.RangerPolicyItem> mergePolicyItems(List<RangerPolicy.RangerPolicyItem> policyItems) {
+		List<RangerPolicy.RangerPolicyItem> ret = new ArrayList<RangerPolicy.RangerPolicyItem>();
+
+		if (CollectionUtils.isNotEmpty(policyItems)) {
+			Map<String, RangerPolicy.RangerPolicyItem> matchedPolicyItems = new HashMap<String, RangerPolicy.RangerPolicyItem>();
+
+			for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
+				if (policyItem.getConditions().size() > 1) {
+					ret.add(policyItem);
+					continue;
+				}
+				TreeSet<String> accesses = new TreeSet<String>();
+
+				for (RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
+					accesses.add(access.getType());
+				}
+				if (policyItem.getDelegateAdmin()) {
+					accesses.add("delegateAdmin");
+				}
+
+				StringBuilder allAccessesString = new StringBuilder();
+
+				for (String access = accesses.first(); access != null; access = accesses.higher(access)) {
+					allAccessesString.append(access);
+				}
+
+				RangerPolicy.RangerPolicyItem matchingPolicyItem = matchedPolicyItems.get(allAccessesString.toString());
+
+				if (matchingPolicyItem != null) {
+					addDistinctItems(policyItem.getUsers(), matchingPolicyItem.getUsers());
+					addDistinctItems(policyItem.getGroups(), matchingPolicyItem.getGroups());
+				} else {
+					matchedPolicyItems.put(allAccessesString.toString(), policyItem);
+				}
+			}
+
+			for (Map.Entry<String, RangerPolicy.RangerPolicyItem> entry : matchedPolicyItems.entrySet()) {
+				ret.add(entry.getValue());
+			}
+		}
+
+		return ret;
+	}
+
+	static void addPolicyItemForUser(RangerPolicy.RangerPolicyItem[] items, int typeOfItems, String user, RangerPolicy.RangerPolicyItem policyItem) {
+
+		if (items[typeOfItems] == null) {
+			RangerPolicy.RangerPolicyItem newItem = new RangerPolicy.RangerPolicyItem();
+			newItem.getUsers().add(user);
+
+			items[typeOfItems] = newItem;
+		}
+
+		addAccesses(items[typeOfItems], policyItem.getAccesses());
+
+		if (policyItem.getDelegateAdmin()) {
+			items[typeOfItems].setDelegateAdmin(Boolean.TRUE);
+		}
+	}
+
+	static void addPolicyItemForGroup(RangerPolicy.RangerPolicyItem[] items, int typeOfItems, String group, RangerPolicy.RangerPolicyItem policyItem) {
+
+		if (items[typeOfItems] == null) {
+			RangerPolicy.RangerPolicyItem newItem = new RangerPolicy.RangerPolicyItem();
+			newItem.getGroups().add(group);
+
+			items[typeOfItems] = newItem;
+		}
+
+		addAccesses(items[typeOfItems], policyItem.getAccesses());
+
+		if (policyItem.getDelegateAdmin()) {
+			items[typeOfItems].setDelegateAdmin(Boolean.TRUE);
+		}
+	}
+
+	static private void addDistinctItems(List<String> fromItems, List<String> toItems) {
+		for (String fromItem : fromItems) {
+			if (! toItems.contains(fromItem)) {
+				toItems.add(fromItem);
+			}
+		}
+	}
+
+	static private boolean removeUsersAndGroupsFromPolicy(RangerPolicy policy, Set<String> users, Set<String> groups) {
+		boolean policyUpdated = false;
+
+		List<RangerPolicy.RangerPolicyItem> policyItems = policy.getPolicyItems();
+
+		int numOfItems = policyItems.size();
+
+		for(int i = 0; i < numOfItems; i++) {
+			RangerPolicy.RangerPolicyItem policyItem = policyItems.get(i);
+
+			if(CollectionUtils.containsAny(policyItem.getUsers(), users)) {
+				policyItem.getUsers().removeAll(users);
+
+				policyUpdated = true;
+			}
+
+			if(CollectionUtils.containsAny(policyItem.getGroups(), groups)) {
+				policyItem.getGroups().removeAll(groups);
+
+				policyUpdated = true;
+			}
+
+			if(CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups())) {
+				policyItems.remove(i);
+				numOfItems--;
+				i--;
+
+				policyUpdated = true;
+			}
+		}
+
+		return policyUpdated;
+	}
+
+	static boolean containsRangerCondition(RangerPolicy policy) {
+		boolean ret = false;
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceRESTUtil.containsRangerCondition(" + policy +")");
+		}
+
+		if (policy != null) {
+			List<RangerPolicy.RangerPolicyItem> allItems = new ArrayList<RangerPolicy.RangerPolicyItem>();
+
+			allItems.addAll(policy.getPolicyItems());
+			allItems.addAll(policy.getDenyPolicyItems());
+			allItems.addAll(policy.getAllowExceptions());
+			allItems.addAll(policy.getDenyExceptions());
+
+			for (RangerPolicy.RangerPolicyItem policyItem : allItems) {
+				if (policyItem.getConditions().size() > 0) {
+					ret = true;
+					break;
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceRESTUtil.containsRangerCondition(" + policy +"): " + ret);
+		}
+
+		return ret;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/5423ee4f/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
----------------------------------------------------------------------
diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
index 881eed9..2be9441 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java
@@ -1088,4 +1088,337 @@ public class TestServiceREST {
 		Assert.assertNotNull(dbVXResponse);
 		Mockito.verify(serviceMgr).validateConfig(rangerService, svcStore);
 	}
+
+	@Test
+	public void test40applyPolicy() {
+		RangerPolicy existingPolicy = rangerPolicy();
+		RangerPolicy appliedPolicy = rangerPolicy();
+
+		existingPolicy.setPolicyItems(null);
+		appliedPolicy.setPolicyItems(null);
+
+		Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
+		RangerPolicyResource rangerPolicyResource = new RangerPolicyResource("/tmp");
+		rangerPolicyResource.setIsExcludes(true);
+		rangerPolicyResource.setIsRecursive(true);
+		policyResources.put("path", rangerPolicyResource);
+
+		existingPolicy.setResources(policyResources);
+		appliedPolicy.setResources(policyResources);
+
+		RangerPolicyItem rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		existingPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("public");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("finance");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		appliedPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		String existingPolicyStr = existingPolicy.toString();
+		System.out.println("existingPolicy=" + existingPolicyStr);
+
+		ServiceRESTUtil.processApplyPolicy(existingPolicy, appliedPolicy);
+
+		String resultPolicyStr = existingPolicy.toString();
+		System.out.println("resultPolicy=" + resultPolicyStr);
+
+		assert(true);
+	}
+
+	@Test
+	public void test41applyPolicy() {
+		RangerPolicy existingPolicy = rangerPolicy();
+		RangerPolicy appliedPolicy = rangerPolicy();
+
+		existingPolicy.setPolicyItems(null);
+		appliedPolicy.setPolicyItems(null);
+
+		Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
+		RangerPolicyResource rangerPolicyResource = new RangerPolicyResource("/tmp");
+		rangerPolicyResource.setIsExcludes(true);
+		rangerPolicyResource.setIsRecursive(true);
+		policyResources.put("path", rangerPolicyResource);
+
+		existingPolicy.setResources(policyResources);
+		appliedPolicy.setResources(policyResources);
+
+		RangerPolicyItem rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group3");
+		rangerPolicyItem.getUsers().add("user3");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		existingPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getAllowExceptions().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("index", true));
+		rangerPolicyItem.getGroups().add("public");
+		rangerPolicyItem.getUsers().add("user");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("index", true));
+
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		appliedPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+
+		rangerPolicyItem.getGroups().add("public");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		appliedPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		String existingPolicyStr = existingPolicy.toString();
+		System.out.println("existingPolicy=" + existingPolicyStr);
+
+		ServiceRESTUtil.processApplyPolicy(existingPolicy, appliedPolicy);
+
+		String resultPolicyStr = existingPolicy.toString();
+		System.out.println("resultPolicy=" + resultPolicyStr);
+
+		assert(true);
+	}
+
+	@Test
+	public void test42grant() {
+		RangerPolicy existingPolicy = rangerPolicy();
+
+		existingPolicy.setPolicyItems(null);
+
+		Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
+		RangerPolicyResource rangerPolicyResource = new RangerPolicyResource("/tmp");
+		rangerPolicyResource.setIsExcludes(true);
+		rangerPolicyResource.setIsRecursive(true);
+		policyResources.put("path", rangerPolicyResource);
+
+		existingPolicy.setResources(policyResources);
+
+		RangerPolicyItem rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		existingPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group3");
+		rangerPolicyItem.getUsers().add("user3");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		existingPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getAllowExceptions().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("index", true));
+		rangerPolicyItem.getGroups().add("public");
+		rangerPolicyItem.getUsers().add("user");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		GrantRevokeRequest grantRequestObj = new GrantRevokeRequest();
+		Map<String, String> resource = new HashMap<String, String>();
+		resource.put("path", "/tmp");
+		grantRequestObj.setResource(resource);
+
+		grantRequestObj.getUsers().add("user1");
+		grantRequestObj.getGroups().add("group1");
+
+		grantRequestObj.getAccessTypes().add("delete");
+		grantRequestObj.getAccessTypes().add("index");
+
+		grantRequestObj.setDelegateAdmin(true);
+
+		grantRequestObj.setEnableAudit(true);
+		grantRequestObj.setIsRecursive(true);
+
+		grantRequestObj.setGrantor("test42Grant");
+
+		String existingPolicyStr = existingPolicy.toString();
+		System.out.println("existingPolicy=" + existingPolicyStr);
+
+		ServiceRESTUtil.processGrantRequest(existingPolicy, grantRequestObj);
+
+		String resultPolicyStr = existingPolicy.toString();
+		System.out.println("resultPolicy=" + resultPolicyStr);
+
+		assert(true);
+	}
+
+	@Test
+	public void test43revoke() {
+		RangerPolicy existingPolicy = rangerPolicy();
+
+		existingPolicy.setPolicyItems(null);
+
+		Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
+		RangerPolicyResource rangerPolicyResource = new RangerPolicyResource("/tmp");
+		rangerPolicyResource.setIsExcludes(true);
+		rangerPolicyResource.setIsRecursive(true);
+		policyResources.put("path", rangerPolicyResource);
+
+		existingPolicy.setResources(policyResources);
+
+		RangerPolicyItem rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		existingPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("read", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("write", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group3");
+		rangerPolicyItem.getUsers().add("user3");
+		rangerPolicyItem.setDelegateAdmin(true);
+
+		existingPolicy.getPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("lock", true));
+		rangerPolicyItem.getGroups().add("group1");
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user1");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getAllowExceptions().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("delete", true));
+		rangerPolicyItem.getGroups().add("group2");
+		rangerPolicyItem.getUsers().add("user2");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		rangerPolicyItem = new RangerPolicyItem();
+		rangerPolicyItem.getAccesses().add(new RangerPolicyItemAccess("index", true));
+		rangerPolicyItem.getGroups().add("public");
+		rangerPolicyItem.getUsers().add("user");
+		rangerPolicyItem.setDelegateAdmin(false);
+
+		existingPolicy.getDenyPolicyItems().add(rangerPolicyItem);
+
+		GrantRevokeRequest revokeRequestObj = new GrantRevokeRequest();
+		Map<String, String> resource = new HashMap<String, String>();
+		resource.put("path", "/tmp");
+		revokeRequestObj.setResource(resource);
+
+		revokeRequestObj.getUsers().add("user1");
+		revokeRequestObj.getGroups().add("group1");
+
+		revokeRequestObj.getAccessTypes().add("delete");
+		revokeRequestObj.getAccessTypes().add("index");
+
+		revokeRequestObj.setDelegateAdmin(true);
+
+		revokeRequestObj.setEnableAudit(true);
+		revokeRequestObj.setIsRecursive(true);
+
+		revokeRequestObj.setGrantor("test43Revoke");
+
+		String existingPolicyStr = existingPolicy.toString();
+		System.out.println("existingPolicy=" + existingPolicyStr);
+
+		ServiceRESTUtil.processRevokeRequest(existingPolicy, revokeRequestObj);
+
+		String resultPolicyStr = existingPolicy.toString();
+		System.out.println("resultPolicy=" + resultPolicyStr);
+
+		assert(true);
+	}
 }


[2/2] incubator-ranger git commit: RANGER-699: updates per review comments and fixes

Posted by ma...@apache.org.
RANGER-699: updates per review comments and fixes


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

Branch: refs/heads/master
Commit: dddc4d42011adf28062853317908259e894964da
Parents: 5423ee4
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Fri Mar 4 02:22:48 2016 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Mon Mar 7 17:26:30 2016 -0800

----------------------------------------------------------------------
 .../plugin/policyengine/RangerPolicyEngine.java |   4 +-
 .../policyengine/RangerPolicyEngineImpl.java    |  41 +++++-
 .../RangerDefaultPolicyEvaluator.java           |  27 +++-
 .../policyevaluator/RangerPolicyEvaluator.java  |   4 +-
 .../RangerDefaultPolicyResourceMatcher.java     |  20 +--
 .../RangerPolicyResourceMatcher.java            |   4 +-
 .../RangerAbstractResourceMatcher.java          |   6 +-
 .../resourcematcher/RangerResourceMatcher.java  |   2 +-
 .../org/apache/ranger/rest/ServiceREST.java     | 132 +++++++++++--------
 .../org/apache/ranger/rest/ServiceRESTUtil.java | 106 +++++----------
 10 files changed, 189 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index 29080b7..02ad9e9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -54,7 +54,9 @@ public interface RangerPolicyEngine {
 
 	boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType);
 
-	RangerPolicy getExactMatchPolicy(RangerAccessResource resource);
+	List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource);
+
+	List<RangerPolicy> getExactMatchPolicies(Map<String, RangerPolicyResource> resources);
 
 	List<RangerPolicy> getAllowedPolicies(String user, Set<String> userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/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 1dd1e7b..92481f6 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
@@ -338,23 +338,50 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 	}
 
 	@Override
-	public RangerPolicy getExactMatchPolicy(RangerAccessResource resource) {
+	public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource) {
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicy(" + resource + ")");
+			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ")");
 		}
 
-		RangerPolicy ret = null;
+		List<RangerPolicy> ret = null;
 
 		for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
-			if (evaluator.isSingleAndExactMatch(resource)) {
-				ret = evaluator.getPolicy();
+			if (evaluator.isCompleteMatch(resource)) {
+				if(ret == null) {
+					ret = new ArrayList<RangerPolicy>();
+				}
 
-				break;
+				ret.add(evaluator.getPolicy());
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + "): " + ret);
+		}
+
+		return ret;
+	}
+
+	@Override
+	public List<RangerPolicy> getExactMatchPolicies(Map<String, RangerPolicyResource> resources) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ")");
+		}
+
+		List<RangerPolicy> ret = null;
+
+		for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
+			if (evaluator.isCompleteMatch(resources)) {
+				if(ret == null) {
+					ret = new ArrayList<RangerPolicy>();
+				}
+
+				ret.add(evaluator.getPolicy());
 			}
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicy(" + resource + "): " + ret);
+			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/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 6171015..9394341 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
@@ -283,19 +283,38 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	}
 
 	@Override
-	public boolean isSingleAndExactMatch(RangerAccessResource resource) {
+	public boolean isCompleteMatch(RangerAccessResource resource) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.isSingleAndExactMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + ")");
 		}
 
 		boolean ret = false;
 
 		if(resourceMatcher != null) {
-			ret = resourceMatcher.isSingleAndExactMatch(resource);
+			ret = resourceMatcher.isCompleteMatch(resource);
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.isSingleAndExactMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + "): " + ret);
+		}
+
+		return ret;
+	}
+
+	@Override
+	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ")");
+		}
+
+		boolean ret = false;
+
+		if(resourceMatcher != null) {
+			ret = resourceMatcher.isCompleteMatch(resources);
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/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 9cb90f4..3f76755 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
@@ -56,7 +56,9 @@ public interface RangerPolicyEvaluator extends Comparable<RangerPolicyEvaluator>
 
 	boolean isMatch(RangerAccessResource resource);
 
-	boolean isSingleAndExactMatch(RangerAccessResource resource);
+	boolean isCompleteMatch(RangerAccessResource resource);
+
+	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources);
 
 	boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
index 7c547f6..4742850 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
@@ -267,9 +267,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
-	public boolean isSingleAndExactMatch(RangerAccessResource resource) {
+	public boolean isCompleteMatch(RangerAccessResource resource) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isSingleAndExactMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource + ")");
 		}
 
 		boolean ret = false;
@@ -291,9 +291,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 					RangerResourceMatcher matcher       = matchers == null ? null : matchers.get(resourceName);
 
 					if(StringUtils.isEmpty(resourceValue)) {
-						ret = matcher == null || matcher.isSingleAndExactMatch(resourceValue);
+						ret = matcher == null || matcher.isCompleteMatch(resourceValue);
 					} else {
-						ret = matcher != null && matcher.isSingleAndExactMatch(resourceValue);
+						ret = matcher != null && matcher.isCompleteMatch(resourceValue);
 					}
 
 					if(! ret) {
@@ -302,13 +302,13 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 				}
 			} else {
 				if(LOG.isDebugEnabled()) {
-					LOG.debug("isSingleAndExactMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
+					LOG.debug("isCompleteMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
 				}
 			}
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isSingleAndExactMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource + "): " + ret);
 		}
 
 		return ret;
@@ -500,9 +500,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
-	public boolean isExactMatch(Map<String, RangerPolicyResource> resources) {
+	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isExactMatch(" + resources + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ")");
 		}
 
 		boolean ret = false;
@@ -535,13 +535,13 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 				}
 			} else {
 				if(LOG.isDebugEnabled()) {
-					LOG.debug("isExactMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
+					LOG.debug("isCompleteMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys);
 				}
 			}
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isExactMatch(" + resources + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
index bf46748..f743d55 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
@@ -36,13 +36,13 @@ public interface RangerPolicyResourceMatcher {
 
 	boolean isMatch(Map<String, RangerPolicyResource> resources);
 
-	boolean isSingleAndExactMatch(RangerAccessResource resource);
+	boolean isCompleteMatch(RangerAccessResource resource);
 
 	boolean isHeadMatch(RangerAccessResource resource);
 
 	boolean isExactHeadMatch(RangerAccessResource resource);
 
-	boolean isExactMatch(Map<String, RangerPolicyResource> resources);
+	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources);
 
 	StringBuilder toString(StringBuilder sb);
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
index b97659f..5063eea 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
@@ -101,9 +101,9 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 	}
 
 	@Override
-	public boolean isSingleAndExactMatch(String resource) {
+	public boolean isCompleteMatch(String resource) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerAbstractResourceMatcher.isSingleAndExactMatch(" + resource + ")");
+			LOG.debug("==> RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ")");
 		}
 
 		boolean ret = false;
@@ -125,7 +125,7 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerAbstractResourceMatcher.isSingleAndExactMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerAbstractResourceMatcher.isCompleteMatch(" + resource + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
index 609d59d..e4d3ce5 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
@@ -31,5 +31,5 @@ public interface RangerResourceMatcher {
 
 	boolean isMatch(String resource);
 
-	boolean isSingleAndExactMatch(String resource);
+	boolean isCompleteMatch(String resource);
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 5e5d626..e1aef0b 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -66,18 +66,13 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
-import org.apache.ranger.plugin.model.RangerPolicyResourceSignature;
 import org.apache.ranger.plugin.model.RangerService;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.validation.RangerPolicyValidator;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
 import org.apache.ranger.plugin.model.validation.RangerServiceValidator;
 import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
-import org.apache.ranger.plugin.policyengine.RangerAccessResource;
-import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
-import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
-import org.apache.ranger.plugin.policyengine.RangerPolicyEngineCache;
-import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+import org.apache.ranger.plugin.policyengine.*;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
 import org.apache.ranger.plugin.service.ResourceLookupContext;
 import org.apache.ranger.plugin.store.PList;
@@ -839,15 +834,14 @@ public class ServiceREST {
 				String               userName   = grantRequest.getGrantor();
 				Set<String>          userGroups = userMgr.getGroupsForUser(userName);
 				RangerAccessResource resource   = new RangerAccessResourceImpl(grantRequest.getResource());
-				RangerPolicyEngine   policyEngine = getPolicyEngine(serviceName);
-	
-				boolean isAdmin = hasAdminAccess(policyEngine, userName, userGroups, resource);
+
+				boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);
 	
 				if(!isAdmin) {
 					throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "", true);
 				}
 	
-				RangerPolicy policy = getExactMatchPolicyForResource(policyEngine, resource);
+				RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource);
 
 				if(policy != null) {
 					boolean policyUpdated = false;
@@ -932,18 +926,17 @@ public class ServiceREST {
 					perf = RangerPerfTracer.getPerfTracer(PERF_LOG, "ServiceREST.revokeAccess(serviceName=" + serviceName + ")");
 				}
 
-				String               userName     = revokeRequest.getGrantor();
-				Set<String>          userGroups   =  userMgr.getGroupsForUser(userName);
-				RangerAccessResource resource     = new RangerAccessResourceImpl(revokeRequest.getResource());
-				RangerPolicyEngine   policyEngine = getPolicyEngine(serviceName);
+				String               userName   = revokeRequest.getGrantor();
+				Set<String>          userGroups =  userMgr.getGroupsForUser(userName);
+				RangerAccessResource resource   = new RangerAccessResourceImpl(revokeRequest.getResource());
 
-				boolean isAdmin = hasAdminAccess(policyEngine, userName, userGroups, resource);
+				boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);
 				
 				if(!isAdmin) {
 					throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "", true);
 				}
 	
-				RangerPolicy policy = getExactMatchPolicyForResource(policyEngine, resource);
+				RangerPolicy policy = getExactMatchPolicyForResource(serviceName, resource);
 				
 				if(policy != null) {
 					boolean policyUpdated = false;
@@ -1048,42 +1041,24 @@ public class ServiceREST {
 		RangerPolicy ret = null;
 
 		if (policy != null && StringUtils.isNotBlank(policy.getService())) {
-
 			try {
-				RangerPolicyResourceSignature resourceSignature = new RangerPolicyResourceSignature(policy);
-
-				List<RangerPolicy> existingPolicies = svcStore.getPoliciesByResourceSignature(policy.getService(), resourceSignature.getSignature(), true);
+				// Check if applied policy contains any conditions
+				if (ServiceRESTUtil.containsRangerCondition(policy)) {
+					LOG.error("Applied policy contains condition(s); not supported:" + policy);
+					throw new Exception("Applied policy contains condition(s); not supported:" + policy);
+				}
 
-				if (CollectionUtils.isEmpty(existingPolicies)) {
+				RangerPolicy existingPolicy = getExactMatchPolicyForResource(policy.getService(), policy.getResources());
 
+				if (existingPolicy == null) {
 					ret = createPolicy(policy);
-
-				} else if (existingPolicies.size() == 1) {
-
-					// Check if applied policy contains any conditions
-					if (ServiceRESTUtil.containsRangerCondition(policy)) {
-						LOG.error("Applied policy contains condition(s); not supported:" + policy);
-						throw new Exception("Applied policy contains condition(s); not supported:" + policy);
-					}
-					RangerPolicy existingPolicy = existingPolicies.get(0);
-
-					// If existing policy-items contains conditions, then we add/remove specified accesses to
-					// existing policy-items as specified in applied policy, ignoring those conditions.
-					// New policy-items will have no conditions.
-
-					boolean applyResult = ServiceRESTUtil.processApplyPolicy(existingPolicy, policy);
-
-					if (applyResult) {
-						ret = updatePolicy(existingPolicy);
-					} else {
-						LOG.error("applyPolicy processing failed");
-						throw new Exception("applyPolicy processing failed");
-					}
-
 				} else {
-					// there should be only one policy for the given resources
-					throw new Exception("Invalid state: multiple policies exists for resource " + policy.getResources());
+					ServiceRESTUtil.processApplyPolicy(existingPolicy, policy);
+
+					ret = updatePolicy(existingPolicy);
 				}
+			} catch(WebApplicationException excp) {
+				throw excp;
 			} catch (Exception exception) {
 				LOG.error("Failed to apply policy:", exception);
 				throw restErrorUtil.createRESTException(exception.getMessage());
@@ -1544,16 +1519,18 @@ public class ServiceREST {
 		}
 	}
 
-	private RangerPolicy getExactMatchPolicyForResource(RangerPolicyEngine policyEngine, RangerAccessResource resource) throws Exception {
+	private RangerPolicy getExactMatchPolicyForResource(String serviceName, RangerAccessResource resource) throws Exception {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + resource + ")");
 		}
 
-		RangerPolicy ret = policyEngine != null ? policyEngine.getExactMatchPolicy(resource) : null;
+		RangerPolicy       ret          = null;
+		RangerPolicyEngine policyEngine = getPolicyEngine(serviceName);
+		List<RangerPolicy> policies     = policyEngine != null ? policyEngine.getExactMatchPolicies(resource) : null;
 
-		if(ret != null) {
+		if(CollectionUtils.isNotEmpty(policies)) {
 			// at this point, ret is a policy in policy-engine; the caller might update the policy (for grant/revoke); so get a copy from the store
-			ret = svcStore.getPolicy(ret.getId());
+			ret = svcStore.getPolicy(policies.get(0).getId());
 		}
 
 		if(LOG.isDebugEnabled()) {
@@ -1563,6 +1540,27 @@ public class ServiceREST {
 		return ret;
 	}
 
+	private RangerPolicy getExactMatchPolicyForResource(String serviceName, Map<String, RangerPolicyResource> resources) throws Exception {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceREST.getExactMatchPolicyForResource(" + resources + ")");
+		}
+
+		RangerPolicy       ret          = null;
+		RangerPolicyEngine policyEngine = getPolicyEngine(serviceName);
+		List<RangerPolicy> policies     = policyEngine != null ? policyEngine.getExactMatchPolicies(resources) : null;
+
+		if(CollectionUtils.isNotEmpty(policies)) {
+			// at this point, ret is a policy in policy-engine; the caller might update the policy (for grant/revoke); so get a copy from the store
+			ret = svcStore.getPolicy(policies.get(0).getId());
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceREST.getExactMatchPolicyForResource(" + resources + "): " + ret);
+		}
+
+		return ret;
+	}
+
 	@GET
 	@Path("/policies/eventTime")
 	@Produces({ "application/json", "application/xml" })
@@ -1683,7 +1681,7 @@ public class ServiceREST {
 						continue;
 					}
 
-					RangerPolicyEngine policyEngine = getPolicyEngine(serviceName);
+					RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);
 
 					if (policyEngine != null) {
 						if(userGroups == null) {
@@ -1714,12 +1712,12 @@ public class ServiceREST {
 		if(!isAdmin && !isKeyAdmin) {
 			boolean isAllowed = false;
 
-			RangerPolicyEngine policyEngine = getPolicyEngine(serviceName);
+			RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);
 
 			if (policyEngine != null) {
 				Set<String> userGroups = userMgr.getGroupsForUser(userName);
 
-				isAllowed = hasAdminAccess(policyEngine, userName, userGroups, resources);
+				isAllowed = hasAdminAccess(serviceName, userName, userGroups, resources);
 			}
 
 			if (!isAllowed) {
@@ -1747,9 +1745,11 @@ public class ServiceREST {
 		}
 	}
 
-	private boolean hasAdminAccess(RangerPolicyEngine policyEngine, String userName, Set<String> userGroups, Map<String, RangerPolicyResource> resources) {
+	private boolean hasAdminAccess(String serviceName, String userName, Set<String> userGroups, Map<String, RangerPolicyResource> resources) {
 		boolean isAllowed = false;
 
+		RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);
+
 		if(policyEngine != null) {
 			isAllowed = policyEngine.isAccessAllowed(resources, userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS);
 		}
@@ -1757,9 +1757,11 @@ public class ServiceREST {
 		return isAllowed;
 	}
 
-	private boolean hasAdminAccess(RangerPolicyEngine policyEngine, String userName, Set<String> userGroups, RangerAccessResource resource) {
+	private boolean hasAdminAccess(String serviceName, String userName, Set<String> userGroups, RangerAccessResource resource) {
 		boolean isAllowed = false;
 
+		RangerPolicyEngine policyEngine = getDelegatedAdminPolicyEngine(serviceName);
+
 		if(policyEngine != null) {
 			isAllowed = policyEngine.isAccessAllowed(resource, userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS);
 		}
@@ -1767,7 +1769,7 @@ public class ServiceREST {
 		return isAllowed;
 	}
 
-	private RangerPolicyEngine getPolicyEngine(String serviceName) {
+	private RangerPolicyEngine getDelegatedAdminPolicyEngine(String serviceName) {
 		if(RangerPolicyEngineCache.getInstance().getPolicyEngineOptions() == null) {
 			RangerPolicyEngineOptions options = new RangerPolicyEngineOptions();
 
@@ -1787,6 +1789,24 @@ public class ServiceREST {
 		return ret;
 	}
 
+	private RangerPolicyEngine getPolicyEngine(String serviceName) throws Exception {
+		RangerPolicyEngineOptions options = new RangerPolicyEngineOptions();
+
+		String propertyPrefix = "ranger.admin";
+
+		options.evaluatorType             = RangerPolicyEvaluator.EVALUATOR_TYPE_OPTIMIZED;
+		options.cacheAuditResults         = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.cache.audit.results", false);
+		options.disableContextEnrichers   = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.context.enrichers", true);
+		options.disableCustomConditions   = RangerConfiguration.getInstance().getBoolean(propertyPrefix + ".policyengine.option.disable.custom.conditions", true);
+		options.evaluateDelegateAdminOnly = false;
+
+		ServicePolicies policies = svcStore.getServicePoliciesIfUpdated(serviceName, -1L);
+
+		RangerPolicyEngine ret = new RangerPolicyEngineImpl("ranger-admin", policies, options);
+
+		return ret;
+	}
+
 	@GET
 	@Path("/checksso")
 	@Produces(MediaType.TEXT_PLAIN)

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/dddc4d42/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
index 7518363..dcae9b4 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceRESTUtil.java
@@ -27,7 +27,6 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -74,7 +73,9 @@ public class ServiceRESTUtil {
 
 		appliedPolicy.getPolicyItems().add(policyItem);
 
-		policyUpdated = processApplyPolicy(policy, appliedPolicy) || policyUpdated;
+		processApplyPolicy(policy, appliedPolicy);
+
+		policyUpdated = true;
 
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("<== ServiceRESTUtil.processGrantRequest() : " + policyUpdated);
@@ -114,7 +115,9 @@ public class ServiceRESTUtil {
 
 			appliedPolicy.getDenyPolicyItems().add(policyItem);
 
-			policyUpdated = processApplyPolicy(policy, appliedPolicy);
+			processApplyPolicy(policy, appliedPolicy);
+
+			policyUpdated = true;
 		}
 
 		if (LOG.isDebugEnabled()) {
@@ -124,32 +127,26 @@ public class ServiceRESTUtil {
 		return policyUpdated;
 	}
 
-	static public boolean processApplyPolicy(RangerPolicy existingPolicy, RangerPolicy appliedPolicy) {
+	static public void processApplyPolicy(RangerPolicy existingPolicy, RangerPolicy appliedPolicy) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceRESTUtil.processApplyPolicy()");
 		}
 
-		boolean ret = false;
-
-		ret = processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.ALLOW);
-		ret = ret && processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.DENY);
-		ret = ret && processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.ALLOW_EXCEPTIONS);
-		ret = ret && processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.DENY_EXCEPTIONS);
+		processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.ALLOW);
+		processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.DENY);
+		processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.ALLOW_EXCEPTIONS);
+		processApplyPolicyForItemType(existingPolicy, appliedPolicy, POLICYITEM_TYPE.DENY_EXCEPTIONS);
 
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("<== ServiceRESTUtil.processApplyPolicy()");
 		}
-
-		return ret;
 	}
 
-	static public boolean processApplyPolicyForItemType(RangerPolicy existingPolicy, RangerPolicy appliedPolicy, POLICYITEM_TYPE policyItemType) {
+	static private void processApplyPolicyForItemType(RangerPolicy existingPolicy, RangerPolicy appliedPolicy, POLICYITEM_TYPE policyItemType) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceRESTUtil.processApplyPolicyForItemType()");
 		}
 
-		boolean ret = false;
-
 		List<RangerPolicy.RangerPolicyItem> appliedPolicyItems = null;
 
 		switch (policyItemType) {
@@ -166,8 +163,7 @@ public class ServiceRESTUtil {
 				appliedPolicyItems = appliedPolicy.getDenyExceptions();
 				break;
 			default:
-				LOG.warn("Should not have come here..");
-				return false;
+				LOG.warn("processApplyPolicyForItemType(): invalid policyItemType=" + policyItemType);
 		}
 
 		if (CollectionUtils.isNotEmpty(appliedPolicyItems)) {
@@ -190,14 +186,12 @@ public class ServiceRESTUtil {
 			// Add modified/new policyItems back to existing policy
 			mergeProcessedPolicyItems(existingPolicy, userPolicyItems, groupPolicyItems);
 
-			ret = compactPolicy(existingPolicy);
+			compactPolicy(existingPolicy);
 		}
 
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("<== ServiceRESTUtil.processApplyPolicyForItemType()");
 		}
-
-		return ret;
 	}
 
 	static private void extractUsersAndGroups(List<RangerPolicy.RangerPolicyItem> policyItems, Set<String> users, Set<String> groups) {
@@ -281,16 +275,15 @@ public class ServiceRESTUtil {
 		}
 	}
 
-	static private RangerPolicy.RangerPolicyItem splitAndGetConsolidatedPolicyItemForUser(List<RangerPolicy.RangerPolicyItem> userPolicyItems, String user) {
+	static private RangerPolicy.RangerPolicyItem splitAndGetConsolidatedPolicyItemForUser(List<RangerPolicy.RangerPolicyItem> policyItems, String user) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceRESTUtil.splitAndGetConsolidatedPolicyItemForUser()");
 		}
 
 		RangerPolicy.RangerPolicyItem ret = null;
 
-		if (CollectionUtils.isNotEmpty(userPolicyItems)) {
-
-			for (RangerPolicy.RangerPolicyItem policyItem : userPolicyItems) {
+		if (CollectionUtils.isNotEmpty(policyItems)) {
+			for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
 				List<String> users = policyItem.getUsers();
 				if (users.contains(user)) {
 					if (ret == null) {
@@ -302,7 +295,7 @@ public class ServiceRESTUtil {
 					}
 					addAccesses(ret, policyItem.getAccesses());
 
-					// Remove this user/group from existingPolicyItem
+					// Remove this user from existingPolicyItem
 					users.remove(user);
 				}
 			}
@@ -315,16 +308,15 @@ public class ServiceRESTUtil {
 		return ret;
 	}
 
-	static private RangerPolicy.RangerPolicyItem splitAndGetConsolidatedPolicyItemForGroup(List<RangerPolicy.RangerPolicyItem> groupPolicyItems, String group) {
+	static private RangerPolicy.RangerPolicyItem splitAndGetConsolidatedPolicyItemForGroup(List<RangerPolicy.RangerPolicyItem> policyItems, String group) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceRESTUtil.splitAndGetConsolidatedPolicyItemForGroup()");
 		}
 
 		RangerPolicy.RangerPolicyItem ret = null;
 
-		if (CollectionUtils.isNotEmpty(groupPolicyItems)) {
-
-			for (RangerPolicy.RangerPolicyItem policyItem : groupPolicyItems) {
+		if (CollectionUtils.isNotEmpty(policyItems)) {
+			for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
 				List<String> groups = policyItem.getGroups();
 				if (groups.contains(group)) {
 					if (ret == null) {
@@ -336,7 +328,7 @@ public class ServiceRESTUtil {
 					}
 					addAccesses(ret, policyItem.getAccesses());
 
-					// Remove this user/group from existingPolicyItem
+					// Remove this group from existingPolicyItem
 					groups.remove(group);
 				}
 			}
@@ -541,14 +533,14 @@ public class ServiceRESTUtil {
 			for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
 				String accessType = access.getType();
 
-				int numOfItems = policyItem.getAccesses().size();
+				int numOfAccesses = policyItem.getAccesses().size();
 
-				for (int i = 0; i < numOfItems; i++) {
+				for (int i = 0; i < numOfAccesses; i++) {
 					RangerPolicy.RangerPolicyItemAccess itemAccess = policyItem.getAccesses().get(i);
 
 					if (StringUtils.equals(itemAccess.getType(), accessType)) {
 						policyItem.getAccesses().remove(i);
-						numOfItems--;
+						numOfAccesses--;
 						i--;
 
 						ret = true;
@@ -562,42 +554,11 @@ public class ServiceRESTUtil {
 		return ret;
 	}
 
-	static private boolean compactPolicy(RangerPolicy policy) {
-		boolean ret = true;			// Always true for now
-
-		List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
-				policy.getDenyPolicyItems(),
-				policy.getAllowExceptions(),
-				policy.getDenyExceptions()
-		};
-
-		for(List<?> policyItemsObj : policyItemsList) {
-			@SuppressWarnings("unchecked")
-			List<RangerPolicy.RangerPolicyItem> policyItems = (List<RangerPolicy.RangerPolicyItem>)policyItemsObj;
-
-			int numOfItems = policyItems.size();
-
-			for(int i = 0; i < numOfItems; i++) {
-				RangerPolicy.RangerPolicyItem policyItem = policyItems.get(i);
-
-				// remove the policy item if 1) there are no users and groups OR 2) if there are no accessTypes and not a delegate-admin
-				if((CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups())) ||
-						(CollectionUtils.isEmpty(policyItem.getAccesses()) && !policyItem.getDelegateAdmin())) {
-					policyItems.remove(i);
-					numOfItems--;
-					i--;
-
-					ret = true;
-				}
-			}
-		}
-
+	static private void compactPolicy(RangerPolicy policy) {
 		policy.setPolicyItems(mergePolicyItems(policy.getPolicyItems()));
 		policy.setDenyPolicyItems(mergePolicyItems(policy.getDenyPolicyItems()));
 		policy.setAllowExceptions(mergePolicyItems(policy.getAllowExceptions()));
 		policy.setDenyExceptions(mergePolicyItems(policy.getDenyExceptions()));
-
-		return ret;
 	}
 
 	static private List<RangerPolicy.RangerPolicyItem> mergePolicyItems(List<RangerPolicy.RangerPolicyItem> policyItems) {
@@ -607,6 +568,11 @@ public class ServiceRESTUtil {
 			Map<String, RangerPolicy.RangerPolicyItem> matchedPolicyItems = new HashMap<String, RangerPolicy.RangerPolicyItem>();
 
 			for (RangerPolicy.RangerPolicyItem policyItem : policyItems) {
+				if((CollectionUtils.isEmpty(policyItem.getUsers()) && CollectionUtils.isEmpty(policyItem.getGroups())) ||
+				   (CollectionUtils.isEmpty(policyItem.getAccesses()) && !policyItem.getDelegateAdmin())) {
+					continue;
+				}
+
 				if (policyItem.getConditions().size() > 1) {
 					ret.add(policyItem);
 					continue;
@@ -620,19 +586,15 @@ public class ServiceRESTUtil {
 					accesses.add("delegateAdmin");
 				}
 
-				StringBuilder allAccessesString = new StringBuilder();
-
-				for (String access = accesses.first(); access != null; access = accesses.higher(access)) {
-					allAccessesString.append(access);
-				}
+				String allAccessesString = accesses.toString();
 
-				RangerPolicy.RangerPolicyItem matchingPolicyItem = matchedPolicyItems.get(allAccessesString.toString());
+				RangerPolicy.RangerPolicyItem matchingPolicyItem = matchedPolicyItems.get(allAccessesString);
 
 				if (matchingPolicyItem != null) {
 					addDistinctItems(policyItem.getUsers(), matchingPolicyItem.getUsers());
 					addDistinctItems(policyItem.getGroups(), matchingPolicyItem.getGroups());
 				} else {
-					matchedPolicyItems.put(allAccessesString.toString(), policyItem);
+					matchedPolicyItems.put(allAccessesString, policyItem);
 				}
 			}