ranger-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mad...@apache.org
Subject incubator-ranger git commit: RANGER-873: Ranger policy model update to support data masking
Date Thu, 31 Mar 2016 22:18:19 GMT
Repository: incubator-ranger
Updated Branches:
  refs/heads/master a50fcf116 -> 164d46fd1


RANGER-873: Ranger policy model update to support data masking


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

Branch: refs/heads/master
Commit: 164d46fd188789fdae8f3f1f28e08941a1dc530e
Parents: a50fcf1
Author: Madhan Neethiraj <madhan@apache.org>
Authored: Wed Mar 30 18:30:11 2016 -0700
Committer: Madhan Neethiraj <madhan@apache.org>
Committed: Thu Mar 31 15:18:07 2016 -0700

----------------------------------------------------------------------
 .../ranger/plugin/model/RangerPolicy.java       |   2 +
 .../ranger/plugin/model/RangerServiceDef.java   | 115 ++++++++++-------
 .../model/validation/RangerPolicyValidator.java |   2 +-
 .../validation/RangerServiceDefHelper.java      | 111 ++++++++++------
 .../validation/RangerServiceDefValidator.java   |  13 +-
 .../model/validation/RangerValidator.java       |   4 +-
 .../policyengine/RangerPolicyRepository.java    |  11 +-
 .../RangerDefaultPolicyEvaluator.java           |   8 +-
 .../RangerOptimizedPolicyEvaluator.java         |   3 +-
 .../RangerDefaultPolicyResourceMatcher.java     |  14 ++-
 .../RangerPolicyResourceMatcher.java            |   3 +
 .../RangerAbstractResourceMatcher.java          |  12 +-
 .../ranger/plugin/service/RangerBasePlugin.java |  12 ++
 .../ranger/plugin/util/ServiceDefUtil.java      | 125 +++++++++++++++++++
 .../service-defs/ranger-servicedef-hive.json    |  80 +++++++++++-
 .../TestRangerPolicyResourceSignature.java      |   6 +-
 .../validation/TestRangerServiceDefHelper.java  |   7 +-
 .../test_policyengine_hive_masking.json         |  26 ++--
 .../db/mysql/patches/020-datamask-policy.sql    |  28 ++---
 .../db/postgres/patches/020-datamask-policy.sql |  97 ++++++++++++++
 .../org/apache/ranger/biz/ServiceDBStore.java   |  91 +++++++++-----
 .../java/org/apache/ranger/common/JSONUtil.java |  25 +++-
 .../apache/ranger/entity/XXAccessTypeDef.java   |  22 ++--
 .../org/apache/ranger/entity/XXResourceDef.java |  22 ++--
 .../service/RangerServiceDefServiceBase.java    |  48 ++++++-
 25 files changed, 689 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 522d130..f022707 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -43,6 +43,8 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	public static final int POLICY_TYPE_ACCESS   = 0;
 	public static final int POLICY_TYPE_DATAMASK = 1;
 
+	public static final int[] POLICY_TYPES = new int[] { POLICY_TYPE_ACCESS, POLICY_TYPE_DATAMASK };
+
 	// For future use
 	private static final long serialVersionUID = 1L;
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index 8b919d0..febd85b 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -1248,6 +1248,28 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			this(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
 		}
 
+		public RangerResourceDef(RangerResourceDef other) {
+			setItemId(other.getItemId());
+			setName(other.getName());
+			setType(other.getType());
+			setLevel(other.getLevel());
+			setParent(other.getParent());
+			setMandatory(other.getMandatory());
+			setLookupSupported(other.getLookupSupported());
+			setRecursiveSupported(other.getRecursiveSupported());
+			setExcludesSupported(other.getExcludesSupported());
+			setMatcher(other.getMatcher());
+			setMatcherOptions(other.getMatcherOptions());
+			setValidationRegEx(other.getValidationRegEx());
+			setValidationMessage(other.getValidationMessage());
+			setUiHint(other.getUiHint());
+			setLabel(other.getLabel());
+			setDescription(other.getDescription());
+			setRbKeyLabel(other.getRbKeyLabel());
+			setRbKeyDescription(other.getRbKeyDescription());
+			setRbKeyValidationMessage(other.getRbKeyValidationMessage());
+		}
+
 		public RangerResourceDef(Long itemId, String name, String type, Integer level, String parent, Boolean mandatory, Boolean lookupSupported, Boolean recursiveSupported, Boolean excludesSupported, String matcher, Map<String, String> matcherOptions, String validationRegEx, String validationMessage, String uiHint, String label, String description, String rbKeyLabel, String rbKeyDescription, String rbKeyValidationMessage) {
 			setItemId(itemId);
 			setName(name);
@@ -1421,7 +1443,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		 * @param matcherOptions the matcherOptions to set
 		 */
 		public void setMatcherOptions(Map<String, String> matcherOptions) {
-			this.matcherOptions = matcherOptions == null ? new HashMap<String, String>() : matcherOptions;
+			this.matcherOptions = matcherOptions == null ? new HashMap<String, String>() : new HashMap<String, String>(matcherOptions);
 		}
 
 		/**
@@ -1759,6 +1781,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		}
 
 		public RangerAccessTypeDef(RangerAccessTypeDef other) {
+			this.setItemId(other.getItemId());
 			this.setName(other.getName());
 			this.setLabel(other.getLabel());
 			this.setRbKeyLabel(other.getRbKeyLabel());
@@ -2451,26 +2474,26 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		private static final long serialVersionUID = 1L;
 
 		private List<RangerDataMaskTypeDef> maskTypes;
-		private List<String>                supportedAccessTypes;
-		private List<String>                supportedResources;
+		private List<RangerAccessTypeDef>   accessTypes;
+		private List<RangerResourceDef>     resources;
 
 
 		public RangerDataMaskDef() {
 			setMaskTypes(null);
-			setSupportedAccessTypes(null);
-			setSupportedResources(null);
+			setAccessTypes(null);
+			setResources(null);
 		}
 
-		public RangerDataMaskDef(List<RangerDataMaskTypeDef> maskTypes, List<String> supportedAccessTypes, List<String> supportedResources) {
+		public RangerDataMaskDef(List<RangerDataMaskTypeDef> maskTypes, List<RangerAccessTypeDef> accessTypes, List<RangerResourceDef> resources) {
 			setMaskTypes(maskTypes);
-			setSupportedAccessTypes(supportedAccessTypes);
-			setSupportedResources(supportedResources);
+			setAccessTypes(accessTypes);
+			setResources(resources);
 		}
 
 		public RangerDataMaskDef(RangerDataMaskDef other) {
 			setMaskTypes(other.getMaskTypes());
-			setSupportedAccessTypes(other.getSupportedAccessTypes());
-			setSupportedResources(other.getSupportedResources());
+			setAccessTypes(other.getAccessTypes());
+			setResources(other.getResources());
 		}
 
 		public List<RangerDataMaskTypeDef> getMaskTypes() {
@@ -2495,46 +2518,46 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			}
 		}
 
-		public List<String> getSupportedAccessTypes() {
-			return supportedAccessTypes;
+		public List<RangerAccessTypeDef> getAccessTypes() {
+			return accessTypes;
 		}
 
-		public void setSupportedAccessTypes(List<String> supportedAccessTypes) {
-			if(this.supportedAccessTypes == null) {
-				this.supportedAccessTypes = new ArrayList<String>();
+		public void setAccessTypes(List<RangerAccessTypeDef> accessTypes) {
+			if(this.accessTypes == null) {
+				this.accessTypes = new ArrayList<RangerAccessTypeDef>();
 			}
 
-			if(this.supportedAccessTypes == supportedAccessTypes) {
+			if(this.accessTypes == accessTypes) {
 				return;
 			}
 
-			this.supportedAccessTypes.clear();
+			this.accessTypes.clear();
 
-			if(supportedAccessTypes != null) {
-				for(String accessType : supportedAccessTypes) {
-					this.supportedAccessTypes.add(accessType);
+			if(accessTypes != null) {
+				for(RangerAccessTypeDef accessType : accessTypes) {
+					this.accessTypes.add(accessType);
 				}
 			}
 		}
 
-		public List<String> getSupportedResources() {
-			return supportedResources;
+		public List<RangerResourceDef> getResources() {
+			return resources;
 		}
 
-		public void setSupportedResources(List<String> supportedResources) {
-			if(this.supportedResources == null) {
-				this.supportedResources = new ArrayList<String>();
+		public void setResources(List<RangerResourceDef> resources) {
+			if(this.resources == null) {
+				this.resources = new ArrayList<RangerResourceDef>();
 			}
 
-			if(this.supportedResources == supportedResources) {
+			if(this.resources == resources) {
 				return;
 			}
 
-			this.supportedResources.clear();
+			this.resources.clear();
 
-			if(supportedResources != null) {
-				for(String resource : supportedResources) {
-					this.supportedResources.add(resource);
+			if(resources != null) {
+				for(RangerResourceDef resource : resources) {
+					this.resources.add(resource);
 				}
 			}
 		}
@@ -2561,21 +2584,21 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			}
 			sb.append("} ");
 
-			sb.append("supportedAccessTypes={");
-			if(supportedAccessTypes != null) {
-				for(String accessType : supportedAccessTypes) {
+			sb.append("accessTypes={");
+			if(accessTypes != null) {
+				for(RangerAccessTypeDef accessType : accessTypes) {
 					if(accessType != null) {
-						sb.append(accessType).append(" ");
+						accessType.toString(sb).append(" ");
 					}
 				}
 			}
 			sb.append("} ");
 
-			sb.append("supportedResources={");
-			if(supportedResources != null) {
-				for(String resource : supportedResources) {
+			sb.append("resources={");
+			if(resources != null) {
+				for(RangerResourceDef resource : resources) {
 					if(resource != null) {
-						sb.append(resource).append(" ");
+						resource.toString(sb).append(" ");
 					}
 				}
 			}
@@ -2591,8 +2614,8 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			final int prime = 31;
 			int result = 1;
 			result = prime * result + ((maskTypes == null) ? 0 : maskTypes.hashCode());
-			result = prime * result + ((supportedAccessTypes == null) ? 0 : supportedAccessTypes.hashCode());
-			result = prime * result + ((supportedResources == null) ? 0 : supportedResources.hashCode());
+			result = prime * result + ((accessTypes == null) ? 0 : accessTypes.hashCode());
+			result = prime * result + ((resources == null) ? 0 : resources.hashCode());
 			return result;
 		}
 
@@ -2611,15 +2634,15 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			} else if (other.maskTypes == null || !maskTypes.equals(other.maskTypes))
 				return false;
 
-			if (supportedAccessTypes == null) {
-				if (other.supportedAccessTypes != null)
+			if (accessTypes == null) {
+				if (other.accessTypes != null)
 					return false;
-			} else if (!supportedAccessTypes.equals(other.supportedAccessTypes))
+			} else if (!accessTypes.equals(other.accessTypes))
 				return false;
-			if (supportedResources == null) {
-				if (other.supportedResources != null)
+			if (resources == null) {
+				if (other.resources != null)
 					return false;
-			} else if (!supportedResources.equals(other.supportedResources))
+			} else if (!resources.equals(other.resources))
 				return false;
 			return true;
 		}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
index cab7006..0bdaf87 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerPolicyValidator.java
@@ -368,7 +368,7 @@ public class RangerPolicyValidator extends RangerValidator {
 		Set<String> policyResources = getPolicyResources(policy);
 
 		RangerServiceDefHelper defHelper = new RangerServiceDefHelper(serviceDef);
-		Set<List<RangerResourceDef>> hierarchies = defHelper.getResourceHierarchies(); // this can be empty but not null!
+		Set<List<RangerResourceDef>> hierarchies = defHelper.getResourceHierarchies(policy.getPolicyType()); // this can be empty but not null!
 		if (hierarchies.isEmpty()) {
 			LOG.warn("RangerPolicyValidator.isValidResourceNames: serviceDef does not have any resource hierarchies, possibly due to a old/migrated service def!  Skipping this check!");
 		} else {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index 53df193..101d911 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -30,9 +30,11 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 
@@ -97,18 +99,10 @@ public class RangerServiceDefHelper {
 	 *  
 	 * @return
 	 */
-	public Set<List<RangerResourceDef>> getResourceHierarchies() {
-		return _delegate.getResourceHierarchies();
+	public Set<List<RangerResourceDef>> getResourceHierarchies(Integer policyType) {
+		return _delegate.getResourceHierarchies(policyType);
 	}
-	
-	/**
-	 * Converts service-def resources from list to a map for constant time lookup
-	 * @return
-	 */
-	public Map<String, RangerResourceDef> getResorceMap() {
-		return _delegate.getResourceMap();
-	}
-	
+
 	public Set<String> getMandatoryResourceNames(List<RangerResourceDef> hierarchy) {
 		Set<String> result = new HashSet<String>(hierarchy.size());
 		for (RangerResourceDef resourceDef : hierarchy) {
@@ -144,7 +138,7 @@ public class RangerServiceDefHelper {
 		}
 		return result;
 	}
-	
+
 	public boolean isResourceGraphValid() {
 		return _delegate.isResourceGraphValid();
 	}
@@ -154,30 +148,36 @@ public class RangerServiceDefHelper {
 	 */
 	static class Delegate {
 
-		final Set<List<RangerResourceDef>> _hierarchies;
+		final Map<Integer, Set<List<RangerResourceDef>>> _hierarchies = new HashMap<Integer, Set<List<RangerResourceDef>>>();
 		final Date _serviceDefFreshnessDate;
 		final String _serviceName;
-		final Map<String, RangerResourceDef> _resourceMap;
 		final boolean _valid;
-		
-		public Delegate(RangerServiceDef serviceDef) {
+		final static Set<List<RangerResourceDef>> EMPTY_RESOURCE_HIERARCHY = Collections.unmodifiableSet(new HashSet<List<RangerResourceDef>>());
+
 
+		public Delegate(RangerServiceDef serviceDef) {
 			// NOTE: we assume serviceDef, its name and update time are can never by null.
 			_serviceName = serviceDef.getName();
 			_serviceDefFreshnessDate = serviceDef.getUpdateTime();
 
-			// NOTE: we assume resource collection on a service def would never be null
-			List<RangerResourceDef> resourceDefs = serviceDef.getResources();
-			_resourceMap = Collections.unmodifiableMap(getResourcesAsMap(resourceDefs));
-			
-			DirectedGraph graph = createGraph(resourceDefs);
-			_valid = isValid(graph); 
-			if (_valid) {
-				Set<List<String>> hierarchies = getHierarchies(graph);
-				_hierarchies = Collections.unmodifiableSet(convertHierarchies(hierarchies, _resourceMap));
-			} else {
-				_hierarchies = Collections.unmodifiableSet(new HashSet<List<RangerResourceDef>>());
+			boolean isValid = true;
+			for(Integer policyType : RangerPolicy.POLICY_TYPES) {
+				List<RangerResourceDef> resources = getResourceDefs(serviceDef, policyType);
+				DirectedGraph graph = createGraph(resources);
+
+				if(graph != null) {
+					if (isValid(graph)) {
+						Set<List<String>> hierarchies = getHierarchies(graph);
+						_hierarchies.put(policyType, Collections.unmodifiableSet(convertHierarchies(hierarchies, getResourcesAsMap(resources))));
+					} else {
+						isValid = false;
+						_hierarchies.put(policyType, EMPTY_RESOURCE_HIERARCHY);
+					}
+				} else {
+					_hierarchies.put(policyType, EMPTY_RESOURCE_HIERARCHY);
+				}
 			}
+			_valid = isValid;
 			if (LOG.isDebugEnabled()) {
 				String message = String.format("Found [%d] resource hierarchies for service [%s] update-date[%s]: %s", _hierarchies.size(), _serviceName, 
 						_serviceDefFreshnessDate == null ? null : _serviceDefFreshnessDate.toString(), _hierarchies); 
@@ -185,12 +185,18 @@ public class RangerServiceDefHelper {
 			}
 		}
 		
-		public Set<List<RangerResourceDef>> getResourceHierarchies() {
-			return _hierarchies;
-		}
-		
-		public Map<String, RangerResourceDef> getResourceMap() {
-			return _resourceMap;
+		public Set<List<RangerResourceDef>> getResourceHierarchies(Integer policyType) {
+			if(policyType == null) {
+				policyType = RangerPolicy.POLICY_TYPE_ACCESS;
+			}
+
+			Set<List<RangerResourceDef>> ret = _hierarchies.get(policyType);
+
+			if(ret == null) {
+				ret = EMPTY_RESOURCE_HIERARCHY;
+			}
+
+			return ret;
 		}
 
 		public String getServiceName() {
@@ -211,21 +217,45 @@ public class RangerServiceDefHelper {
 		 * @return
 		 */
 		DirectedGraph createGraph(List<RangerResourceDef> resourceDefs) {
-			DirectedGraph graph = new DirectedGraph();
-			for (RangerResourceDef resourceDef : resourceDefs) {
-				String name = resourceDef.getName();
-				graph.add(name);
-				String parent = resourceDef.getParent();
-				if (StringUtils.isNotEmpty(parent)) {
-					graph.addArc(parent, name);
+			DirectedGraph graph = null;
+
+			if(CollectionUtils.isNotEmpty(resourceDefs)) {
+				graph = new DirectedGraph();
+
+				for (RangerResourceDef resourceDef : resourceDefs) {
+					String name = resourceDef.getName();
+
+					graph.add(name);
+					String parent = resourceDef.getParent();
+					if (StringUtils.isNotEmpty(parent)) {
+						graph.addArc(parent, name);
+					}
 				}
 			}
+
 			if (LOG.isDebugEnabled()) {
 				LOG.debug("Created graph for resources: " + graph);
 			}
 			return graph;
 		}
 
+		List<RangerResourceDef> getResourceDefs(RangerServiceDef serviceDef, Integer policyType) {
+			final List<RangerResourceDef> resourceDefs;
+
+			if(policyType == null || policyType == RangerPolicy.POLICY_TYPE_ACCESS) {
+				resourceDefs = serviceDef.getResources();
+			} else if(policyType == RangerPolicy.POLICY_TYPE_DATAMASK) {
+				if(serviceDef.getDataMaskDef() != null) {
+					resourceDefs = serviceDef.getDataMaskDef().getResources();
+				} else {
+					resourceDefs = null;
+				}
+			} else { // unknown policyType; use all resources
+				resourceDefs = serviceDef.getResources();
+			}
+
+			return resourceDefs;
+		}
 		/**
 		 * A valid resource graph is a forest, i.e. a disjoint union of trees.  In our case, given that node can have only one "parent" node, we can detect this validity simply by ensuring that 
 		 * the resource graph has:
@@ -249,7 +279,6 @@ public class RangerServiceDefHelper {
 		/**
 		 * Returns all valid resource hierarchies for the configured resource-defs. Behavior is undefined if it is called on and invalid graph. Use <code>isValid</code> to check validation first.
 		 * 
-		 * @param resourceDefs
 		 * @param graph
 		 * @return
 		 */

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
index 0507fc4..0ed563a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefValidator.java
@@ -32,6 +32,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.errors.ValidationErrorCode;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
@@ -496,11 +497,13 @@ public class RangerServiceDefValidator extends RangerValidator {
 			valid = false;
 		}
 		// resource level should be unique within a hierarchy
-		Set<List<RangerResourceDef>> hierarchies = defHelper.getResourceHierarchies();
-		for (List<RangerResourceDef> aHierarchy : hierarchies) {
-			Set<Integer> levels = new HashSet<Integer>(aHierarchy.size());
-			for (RangerResourceDef resourceDef : aHierarchy) {
-				valid = isUnique(resourceDef.getLevel(), levels, "resource level", "resources", failures) && valid;
+		for(int policyType : RangerPolicy.POLICY_TYPES) {
+			Set<List<RangerResourceDef>> hierarchies = defHelper.getResourceHierarchies(policyType);
+			for (List<RangerResourceDef> aHierarchy : hierarchies) {
+				Set<Integer> levels = new HashSet<Integer>(aHierarchy.size());
+				for (RangerResourceDef resourceDef : aHierarchy) {
+					valid = isUnique(resourceDef.getLevel(), levels, "resource level", "resources", failures) && valid;
+				}
 			}
 		}
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
index 075a374..381864d 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerValidator.java
@@ -292,7 +292,7 @@ public abstract class RangerValidator {
 
 	Set<String> getAccessTypes(RangerServiceDef serviceDef) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerValidator.getSupportedAccessTypes(" + serviceDef + ")");
+			LOG.debug("==> RangerValidator.getAccessTypes(" + serviceDef + ")");
 		}
 
 		Set<String> accessTypes = new HashSet<String>();
@@ -316,7 +316,7 @@ public abstract class RangerValidator {
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerValidator.getSupportedAccessTypes(" + serviceDef + "): " + accessTypes);
+			LOG.debug("<== RangerValidator.getAccessTypes(" + serviceDef + "): " + accessTypes);
 		}
 		return accessTypes;
 	}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index 4a394d4..b1463bc 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -32,6 +32,7 @@ import org.apache.ranger.plugin.policyevaluator.RangerOptimizedPolicyEvaluator;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
 import org.apache.ranger.plugin.store.AbstractServiceStore;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.apache.ranger.plugin.util.ServicePolicies;
 
 import java.util.*;
@@ -58,7 +59,7 @@ public class RangerPolicyRepository {
         super();
 
         this.componentServiceName = this.serviceName = servicePolicies.getServiceName();
-        this.componentServiceDef = this.serviceDef = servicePolicies.getServiceDef();
+        this.componentServiceDef = this.serviceDef = ServiceDefUtil.normalize(servicePolicies.getServiceDef());
 
         this.appId = appId;
 
@@ -91,7 +92,7 @@ public class RangerPolicyRepository {
         this.serviceName = tagPolicies.getServiceName();
         this.componentServiceName = componentServiceName;
 
-        this.serviceDef = normalizeAccessTypeDefs(tagPolicies.getServiceDef(), componentServiceDef.getName());
+        this.serviceDef = normalizeAccessTypeDefs(ServiceDefUtil.normalize(tagPolicies.getServiceDef()), componentServiceDef.getName());
         this.componentServiceDef = componentServiceDef;
 
         this.appId = appId;
@@ -203,12 +204,14 @@ public class RangerPolicyRepository {
                 normalizeAndPrunePolicyItems(policy.getDenyPolicyItems(), componentType);
                 normalizeAndPrunePolicyItems(policy.getAllowExceptions(), componentType);
                 normalizeAndPrunePolicyItems(policy.getDenyExceptions(), componentType);
+                normalizeAndPrunePolicyItems(policy.getDataMaskPolicyItems(), componentType);
 
                 if (!policy.getIsAuditEnabled() &&
                     CollectionUtils.isEmpty(policy.getPolicyItems()) &&
                     CollectionUtils.isEmpty(policy.getDenyPolicyItems()) &&
                     CollectionUtils.isEmpty(policy.getAllowExceptions()) &&
-                    CollectionUtils.isEmpty(policy.getDenyExceptions())) {
+                    CollectionUtils.isEmpty(policy.getDenyExceptions()) &&
+                    CollectionUtils.isEmpty(policy.getDataMaskPolicyItems())) {
 
                     if(policiesToPrune == null) {
                         policiesToPrune = new ArrayList<RangerPolicy>();
@@ -226,7 +229,7 @@ public class RangerPolicyRepository {
         return rangerPolicies;
     }
 
-    private List<RangerPolicy.RangerPolicyItem> normalizeAndPrunePolicyItems(List<RangerPolicy.RangerPolicyItem> policyItems, final String componentType) {
+    private List<? extends RangerPolicy.RangerPolicyItem> normalizeAndPrunePolicyItems(List<? extends RangerPolicy.RangerPolicyItem> policyItems, final String componentType) {
         if(CollectionUtils.isNotEmpty(policyItems)) {
             final String                        prefix       = componentType + AbstractServiceStore.COMPONENT_ACCESSTYPE_SEPARATOR;
             List<RangerPolicy.RangerPolicyItem> itemsToPrune = null;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/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 c48fb72..b87891f 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
@@ -97,7 +97,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		resourceMatcher = new RangerDefaultPolicyResourceMatcher();
 
 		resourceMatcher.setServiceDef(serviceDef);
-		resourceMatcher.setPolicyResources(policy == null ? null : policy.getResources());
+		resourceMatcher.setPolicy(policy);
 		resourceMatcher.init();
 
 		if(policy != null) {
@@ -118,7 +118,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		Collections.sort(denyEvaluators);
 		Collections.sort(allowExceptionEvaluators);
 		Collections.sort(denyExceptionEvaluators);
+
+		/* dataMask policyItems must be evaulated in the order given in the policy; hence no sort
 		Collections.sort(dataMaskEvaluators);
+		*/
 
 		RangerPerfTracer.log(perf);
 
@@ -536,9 +539,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		preprocessPolicyItems(policy.getDenyPolicyItems(), impliedAccessGrants);
 		preprocessPolicyItems(policy.getAllowExceptions(), impliedAccessGrants);
 		preprocessPolicyItems(policy.getDenyExceptions(), impliedAccessGrants);
+		preprocessPolicyItems(policy.getDataMaskPolicyItems(), impliedAccessGrants);
 	}
 
-	private void preprocessPolicyItems(List<RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
+	private void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
 		for(RangerPolicyItem policyItem : policyItems) {
 			if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
 				continue;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index 710d0c5..2e777ae 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -74,6 +74,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
         preprocessPolicyItems(policy.getDenyPolicyItems());
         preprocessPolicyItems(policy.getAllowExceptions());
         preprocessPolicyItems(policy.getDenyExceptions());
+        preprocessPolicyItems(policy.getDataMaskPolicyItems());
 
         hasAllPerms = checkIfHasAllPerms();
 
@@ -264,7 +265,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
         return ret;
     }
 
-    private void preprocessPolicyItems(List<RangerPolicy.RangerPolicyItem> policyItems) {
+    private void preprocessPolicyItems(List<? extends RangerPolicy.RangerPolicyItem> policyItems) {
         if(CollectionUtils.isNotEmpty(policyItems)) {
 	        for (RangerPolicy.RangerPolicyItem item : policyItems) {
 	            delegateAdmin = delegateAdmin || item.getDelegateAdmin();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/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 4742850..6ea194d 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
@@ -29,6 +29,7 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef;
@@ -42,7 +43,8 @@ import com.google.common.collect.Sets;
 public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceMatcher {
 	private static final Log LOG = LogFactory.getLog(RangerDefaultPolicyResourceMatcher.class);
 
-	protected RangerServiceDef                  serviceDef     = null;
+	protected RangerServiceDef                  serviceDef      = null;
+	protected RangerPolicy                      policy          = null;
 	protected Map<String, RangerPolicyResource> policyResources = null;
 
 	private Map<String, RangerResourceMatcher> matchers = null;
@@ -54,6 +56,13 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
+	public void setPolicy(RangerPolicy policy) {
+		this.policy = policy;
+
+		setPolicyResources(policy == null ? null : policy.getResources());
+	}
+
+	@Override
 	public void setPolicyResources(Map<String, RangerPolicyResource> policyResources) {
 		this.policyResources = policyResources;
 	}
@@ -71,7 +80,8 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 			Set<String> policyResourceKeySet = policyResources.keySet();
 
 			RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef, false);
-			Set<List<RangerResourceDef>> validResourceHierarchies = serviceDefHelper.getResourceHierarchies();
+			int policyType = policy != null && policy.getPolicyType() != null ? policy.getPolicyType() : RangerPolicy.POLICY_TYPE_ACCESS;
+			Set<List<RangerResourceDef>> validResourceHierarchies = serviceDefHelper.getResourceHierarchies(policyType);
 
 			for (List<RangerResourceDef> validResourceHierarchy : validResourceHierarchies) {
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/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 f743d55..54b9586 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
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.policyresourcematcher;
 
 import java.util.Map;
 
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -28,6 +29,8 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 public interface RangerPolicyResourceMatcher {
 	void setServiceDef(RangerServiceDef serviceDef);
 
+	void setPolicy(RangerPolicy policy);
+
 	void setPolicyResources(Map<String, RangerPolicyResource> policyResources);
 
 	void init();

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/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 5063eea..cd725c9 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
@@ -75,16 +75,18 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 		policyIsExcludes = policyResource == null ? false : policyResource.getIsExcludes();
 
 		if(policyResource != null && policyResource.getValues() != null) {
-			boolean isWildCardPresent = !optWildCard;
+			boolean isWildCardPresent = false;
 			for(String policyValue : policyResource.getValues()) {
 				if(StringUtils.isEmpty(policyValue)) {
 					continue;
 				}
 
-				if(StringUtils.containsOnly(policyValue, WILDCARD_ASTERISK)) {
-					isMatchAny = true;
-				} else if (!isWildCardPresent && StringUtils.containsAny(policyValue, WILDCARDS)) {
-					isWildCardPresent = true;
+				if(optWildCard) {
+					if (StringUtils.containsOnly(policyValue, WILDCARD_ASTERISK)) {
+						isMatchAny = true;
+					} else if (!isWildCardPresent && StringUtils.containsAny(policyValue, WILDCARDS)) {
+						isWildCardPresent = true;
+					}
 				}
 				policyValues.add(policyValue);
 			}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index 1ec88d5..aef7bcb 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -182,6 +182,18 @@ public class RangerBasePlugin {
 		return null;
 	}
 
+	public RangerDataMaskResult evalDataMaskPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
+		RangerPolicyEngine policyEngine = this.policyEngine;
+
+		if(policyEngine != null) {
+			policyEngine.preProcess(request);
+
+			return policyEngine.evalDataMaskPolicies(request, resultProcessor);
+		}
+
+		return null;
+	}
+
 	public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) {
 		RangerPolicyEngine policyEngine = this.policyEngine;
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index 90242da..fa04816 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -19,11 +19,18 @@
 
 package org.apache.ranger.plugin.util;
 
+import org.apache.commons.collections.ArrayStack;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.HashMap;
 import java.util.Map;
 
 public class ServiceDefUtil {
@@ -40,6 +47,124 @@ public class ServiceDefUtil {
         return ret;
     }
 
+    public static RangerServiceDef normalize(RangerServiceDef serviceDef) {
+        normalizeDataMaskDef(serviceDef);
+
+        return serviceDef;
+    }
+
+    private static void normalizeDataMaskDef(RangerServiceDef serviceDef) {
+        if(serviceDef != null && serviceDef.getDataMaskDef() != null) {
+            List<RangerResourceDef>   dataMaskResources   = serviceDef.getDataMaskDef().getResources();
+            List<RangerAccessTypeDef> dataMaskAccessTypes = serviceDef.getDataMaskDef().getAccessTypes();
+
+            if(CollectionUtils.isNotEmpty(dataMaskResources)) {
+                List<RangerResourceDef> resources     = serviceDef.getResources();
+                List<RangerResourceDef> processedDefs = new ArrayList<RangerResourceDef>(dataMaskResources.size());
+
+                for(RangerResourceDef dataMaskResource : dataMaskResources) {
+                    RangerResourceDef processedDef = dataMaskResource;
+
+                    for(RangerResourceDef resourceDef : resources) {
+                        if(StringUtils.equals(resourceDef.getName(), dataMaskResource.getName())) {
+                            processedDef = ServiceDefUtil.mergeResourceDef(resourceDef, dataMaskResource);
+                            break;
+                        }
+                    }
+
+                    processedDefs.add(processedDef);
+                }
+
+                serviceDef.getDataMaskDef().setResources(processedDefs);
+            }
+
+            if(CollectionUtils.isNotEmpty(dataMaskAccessTypes)) {
+                List<RangerAccessTypeDef> accessTypes   = serviceDef.getAccessTypes();
+                List<RangerAccessTypeDef> processedDefs = new ArrayList<RangerAccessTypeDef>(accessTypes.size());
+
+                for(RangerAccessTypeDef dataMaskAccessType : dataMaskAccessTypes) {
+                    RangerAccessTypeDef processedDef = dataMaskAccessType;
+
+                    for(RangerAccessTypeDef accessType : accessTypes) {
+                        if(StringUtils.equals(accessType.getName(), dataMaskAccessType.getName())) {
+                            processedDef = ServiceDefUtil.mergeAccessTypeDef(accessType, dataMaskAccessType);
+                            break;
+                        }
+                    }
+
+                    processedDefs.add(processedDef);
+                }
+
+                serviceDef.getDataMaskDef().setAccessTypes(processedDefs);
+            }
+        }
+    }
+
+    private static RangerResourceDef mergeResourceDef(RangerResourceDef base, RangerResourceDef delta) {
+        RangerResourceDef ret = new RangerResourceDef(base);
+
+        // retain base values for: itemId, name, type, level, parent, mandatory, lookupSupported
+
+        if(delta.getRecursiveSupported() != null)
+            ret.setRecursiveSupported(delta.getRecursiveSupported());
+
+        if(delta.getExcludesSupported() != null)
+            ret.setExcludesSupported(delta.getExcludesSupported());
+
+        if(StringUtils.isNotEmpty(delta.getMatcher()))
+            ret.setMatcher(delta.getMatcher());
+
+        if(MapUtils.isNotEmpty(delta.getMatcherOptions())) {
+            if(ret.getMatcherOptions() == null) {
+                ret.setMatcherOptions(new HashMap<String, String>());
+            }
+
+            for(Map.Entry<String, String> e : delta.getMatcherOptions().entrySet()) {
+                ret.getMatcherOptions().put(e.getKey(), e.getValue());
+            }
+        }
+
+        if(StringUtils.isNotEmpty(delta.getValidationRegEx()))
+            ret.setValidationRegEx(delta.getValidationRegEx());
+
+        if(StringUtils.isNotEmpty(delta.getValidationMessage()))
+            ret.setValidationMessage(delta.getValidationMessage());
+
+        if(StringUtils.isNotEmpty(delta.getUiHint()))
+            ret.setUiHint(delta.getUiHint());
+
+        if(StringUtils.isNotEmpty(delta.getLabel()))
+            ret.setLabel(delta.getLabel());
+
+        if(StringUtils.isNotEmpty(delta.getDescription()))
+            ret.setDescription(delta.getDescription());
+
+        if(StringUtils.isNotEmpty(delta.getRbKeyLabel()))
+            ret.setRbKeyLabel(delta.getRbKeyLabel());
+
+        if(StringUtils.isNotEmpty(delta.getRbKeyDescription()))
+            ret.setRbKeyDescription(delta.getRbKeyDescription());
+
+        if(StringUtils.isNotEmpty(delta.getRbKeyValidationMessage()))
+            ret.setRbKeyValidationMessage(delta.getRbKeyValidationMessage());
+
+        return ret;
+    }
+
+    private static RangerAccessTypeDef mergeAccessTypeDef(RangerAccessTypeDef base, RangerAccessTypeDef delta) {
+        RangerAccessTypeDef ret = new RangerAccessTypeDef(base);
+
+        // retain base values for: itemId, name, impliedGrants
+
+        if(StringUtils.isNotEmpty(delta.getLabel()))
+            ret.setLabel(delta.getLabel());
+
+        if(StringUtils.isNotEmpty(delta.getRbKeyLabel()))
+            ret.setRbKeyLabel(delta.getRbKeyLabel());
+
+        return ret;
+    }
+
     private static boolean getBooleanValue(Map<String, String> map, String elementName, boolean defaultValue) {
         boolean ret = defaultValue;
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
index b966be9..77167c4 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
@@ -222,5 +222,83 @@
 		"label":"Hive Resources Accessed Together?",
 		"description": "List of Hive resources"
 	  }
-	]
+	],
+
+	"dataMaskDef": {
+		"accessTypes": [
+			{
+				"name": "select"
+			}
+		],
+		"resources": [
+			{
+				"name": "database",
+				"matcherOptions": {
+					"wildCard": "false"
+				},
+				"lookupSupported": true,
+				"uiHint":"{ \"singleValue\":true }"
+			},
+			{
+				"name": "table",
+				"matcherOptions": {
+					"wildCard": "false"
+				},
+				"lookupSupported": true,
+				"uiHint":"{ \"singleValue\":true }"
+			},
+			{
+				"name": "column",
+				"matcherOptions": {
+					"wildCard": "false"
+				},
+				"lookupSupported": true,
+				"uiHint":"{ \"singleValue\":true }"
+			}
+		],
+		"maskTypes": [
+			{
+				"itemId": 1,
+				"name": "MASK",
+				"label": "Mask",
+				"description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'",
+				"dataMaskOptions": { }
+			},
+			{
+				"itemId": 2,
+				"name": "SHUFFLE",
+				"label": "Shuffle",
+				"description": "Shuffle the value of the column",
+				"dataMaskOptions": { }
+			},
+			{
+				"itemId": 3,
+				"name": "MASK_x_SHOW_LAST_4",
+				"label": "Partial mask: show last 4",
+				"description": "Show last 4 characters; replace rest with 'x'",
+				"dataMaskOptions": { }
+			},
+			{
+				"itemId": 4,
+				"name": "MASK_x_SHOW_FIRST_4",
+				"label": "Partial mask: show first 4",
+				"description": "Show first 4 characters; replace rest with 'x'",
+				"dataMaskOptions": { }
+			},
+			{
+				"itemId": 10,
+				"name": "NULL",
+				"label": "NULL",
+				"description": "Replace with NULL",
+				"dataMaskOptions": { }
+			},
+			{
+				"itemId": 11,
+				"name": "NONE",
+				"label": "No masking",
+				"description": "No masking",
+				"dataMaskOptions": { }
+			}
+		]
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java
index 7cc2831..8c8c4c0 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/TestRangerPolicyResourceSignature.java
@@ -86,19 +86,19 @@ public class TestRangerPolicyResourceSignature {
 		rangerPolicy = mock(RangerPolicy.class);
 		when(rangerPolicy.getResources()).thenReturn(null);
 		policySerializer = new PolicySerializer(rangerPolicy);
-		assertFalse("policy.getSupportedResources()==null", policySerializer.isPolicyValidForResourceSignatureComputation());
+		assertFalse("policy.getResources()==null", policySerializer.isPolicyValidForResourceSignatureComputation());
 		
 		// empty resources map is ok!
 		Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
 		when(rangerPolicy.getResources()).thenReturn(policyResources);
 		policySerializer = new PolicySerializer(rangerPolicy);
-		assertTrue("policy.getSupportedResources().isEmpty()", policySerializer.isPolicyValidForResourceSignatureComputation());
+		assertTrue("policy.getResources().isEmpty()", policySerializer.isPolicyValidForResourceSignatureComputation());
 		
 		// but having a resource map with null key is not ok!
 		RangerPolicyResource aPolicyResource = mock(RangerPolicyResource.class);
 		policyResources.put(null, aPolicyResource);
 		policySerializer = new PolicySerializer(rangerPolicy);
-		assertFalse("policy.getSupportedResources().contains(null)", policySerializer.isPolicyValidForResourceSignatureComputation());
+		assertFalse("policy.getResources().contains(null)", policySerializer.isPolicyValidForResourceSignatureComputation());
 	}
 	
 	@Test

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
index d9e50e4..af158b0 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerServiceDefHelper.java
@@ -31,6 +31,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper.Delegate;
@@ -79,7 +80,7 @@ public class TestRangerServiceDefHelper {
 		// now assert the behavior
 		_helper = new RangerServiceDefHelper(_serviceDef);
 		assertTrue(_helper.isResourceGraphValid());
-		Set<List<RangerResourceDef>> hierarchies = _helper.getResourceHierarchies();
+		Set<List<RangerResourceDef>> hierarchies = _helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS);
 		// there should be 
 		List<RangerResourceDef> hierarchy = Lists.newArrayList(Database, UDF);
 		assertTrue(hierarchies.contains(hierarchy));
@@ -136,7 +137,7 @@ public class TestRangerServiceDefHelper {
 		when(_serviceDef.getResources()).thenReturn(resourceDefs);
 		_helper = new RangerServiceDefHelper(_serviceDef);
 		assertTrue(_helper.isResourceGraphValid());
-		Set<List<RangerResourceDef>> hierarchies = _helper.getResourceHierarchies();
+		Set<List<RangerResourceDef>> hierarchies = _helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS);
 
 		Set<List<String>> expectedHierarchies = new HashSet<List<String>>(); 
 		expectedHierarchies.add(Lists.newArrayList("database", "table-space"));
@@ -177,7 +178,7 @@ public class TestRangerServiceDefHelper {
 		when(_serviceDef.getResources()).thenReturn(resourceDefs);
 		_helper = new RangerServiceDefHelper(_serviceDef);
 		assertTrue(_helper.isResourceGraphValid());
-		Set<List<RangerResourceDef>> hierarchies = _helper.getResourceHierarchies();
+		Set<List<RangerResourceDef>> hierarchies = _helper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS);
 
 		Set<List<String>> expectedHierarchies = new HashSet<List<String>>(); 
 		expectedHierarchies.add(Lists.newArrayList("database"));

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
index 92b21aa..b0e4557 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
@@ -43,16 +43,22 @@
           "name": "SHUFFLE",
           "label": "Shuffle",
           "description": "Randomly shuffle the contents"
+        },
+        {
+          "itemId": 10,
+          "name": "NULL",
+          "label": "NULL",
+          "description": "Replace with NULL"
         }
 
       ],
-      "supportedAccessTypes": [
-        "select"
+      "accessTypes":[
+        {"name":"select","label":"Select"}
       ],
-      "supportedResources": [
-        "database",
-        "table",
-        "column"
+      "resources":[
+        {"name":"database","matcherOptions":{"wildCard":false}},
+        {"name":"table","matcherOptions":{"wildCard":false}},
+        {"name":"column","matcherOptions":{"wildCard":false}}
       ]
     }
   },
@@ -65,7 +71,7 @@
      ]
     },
     {"id":101,"name":"db=*, table=*, column=ssn: mask ssn column in all tables, databases","isEnabled":true,"isAuditEnabled":true,"policyType":1,
-      "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["ssn"]}},
+      "resources":{"database":{"values":["employee"]},"table":{"values":["personal"]},"column":{"values":["ssn"]}},
       "dataMaskPolicyItems":[
         {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
          "dataMaskInfo": {"dataMaskType":"MASK"}
@@ -76,7 +82,7 @@
       ]
     },
     {"id":102,"name":"db=hr, table=*, column=date_of_birth: mask date_of_birth column in all tables in hr database","isEnabled":true,"isAuditEnabled":true,"policyType":1,
-      "resources":{"database":{"values":["hr"]},"table":{"values":["*"]},"column":{"values":["date_of_birth"]}},
+      "resources":{"database":{"values":["hr"]},"table":{"values":["employee"]},"column":{"values":["date_of_birth"]}},
       "dataMaskPolicyItems":[
         {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
           "dataMaskInfo": {"dataMaskType":"MASK"}
@@ -124,9 +130,9 @@
       },
       "dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":102}
     },
-    {"name":"'select date_of_birth from hr.employee2;' for user2 - maskType=SHUFFLE",
+    {"name":"'select date_of_birth from hr.employee;' for user2 - maskType=SHUFFLE",
       "request":{
-        "resource":{"elements":{"database":"hr", "table":"employee2", "column":"date_of_birth"}},
+        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth"}},
         "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr.employee2;' for user2"
       },
       "dataMaskResult":{"maskType":"SHUFFLE","maskCondition":null,"maskValue":null,"policyId":102}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/db/mysql/patches/020-datamask-policy.sql
----------------------------------------------------------------------
diff --git a/security-admin/db/mysql/patches/020-datamask-policy.sql b/security-admin/db/mysql/patches/020-datamask-policy.sql
index 43d9395..32e8a3e 100644
--- a/security-admin/db/mysql/patches/020-datamask-policy.sql
+++ b/security-admin/db/mysql/patches/020-datamask-policy.sql
@@ -13,37 +13,37 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-/* add datamasking_supported column in x_access_type_def table if not exist */
-drop procedure if exists add_datamasking_supported_to_x_access_type_def_table;
+/* add datamask_options column in x_access_type_def table if not exist */
+drop procedure if exists add_datamask_options_to_x_access_type_def_table;
 delimiter ;;
- create procedure add_datamasking_supported_to_x_access_type_def_table() begin
+ create procedure add_datamask_options_to_x_access_type_def_table() begin
  
  if exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_access_type_def') then
-	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_access_type_def' and column_name = 'datamasking_supported') then
-		ALTER TABLE `x_access_type_def` ADD `datamasking_supported` tinyint NOT NULL DEFAULT 0;
+	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_access_type_def' and column_name = 'datamask_options') then
+		ALTER TABLE `x_access_type_def` ADD `datamask_options` varchar(1024) DEFAULT NULL;
  	end if;
  end if; 
 end;;
 
 delimiter ;
-call add_datamasking_supported_to_x_access_type_def_table();
-drop procedure if exists add_datamasking_supported_to_x_access_type_def_table;
+call add_datamask_options_to_x_access_type_def_table();
+drop procedure if exists add_datamask_options_to_x_access_type_def_table;
 
-/* add datamasking_supported column in x_resource_def table if not exist */
-drop procedure if exists add_datamasking_supported_to_x_resource_def_table;
+/* add datamask_options column in x_resource_def table if not exist */
+drop procedure if exists add_datamask_options_to_x_resource_def_table;
 delimiter ;;
- create procedure add_datamasking_supported_to_x_resource_def_table() begin
+ create procedure add_datamask_options_to_x_resource_def_table() begin
  
  if exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_resource_def') then
-	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_resource_def' and column_name = 'datamasking_supported') then
-		ALTER TABLE `x_resource_def` ADD `datamasking_supported` tinyint NOT NULL DEFAULT 0;
+	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_resource_def' and column_name = 'datamask_options') then
+		ALTER TABLE `x_resource_def` ADD `datamask_options` varchar(1024) DEFAULT NULL;
  	end if;
  end if; 
 end;;
 
 delimiter ;
-call add_datamasking_supported_to_x_resource_def_table();
-drop procedure if exists add_datamasking_supported_to_x_resource_def_table;
+call add_datamask_options_to_x_resource_def_table();
+drop procedure if exists add_datamask_options_to_x_resource_def_table;
 
 DROP TABLE IF EXISTS `x_datamask_type_def`;
 CREATE TABLE `x_datamask_type_def` (

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/db/postgres/patches/020-datamask-policy.sql
----------------------------------------------------------------------
diff --git a/security-admin/db/postgres/patches/020-datamask-policy.sql b/security-admin/db/postgres/patches/020-datamask-policy.sql
new file mode 100644
index 0000000..4387e02
--- /dev/null
+++ b/security-admin/db/postgres/patches/020-datamask-policy.sql
@@ -0,0 +1,97 @@
+-- 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.
+
+select 'delimiter start';
+
+/* add x_access_type_def.datamask_options column if it does not exist */
+CREATE OR REPLACE FUNCTION add_datamask_options_to_x_access_type_def_table() 
+RETURNS void AS $$
+DECLARE
+ exists_access_type_def_datamask_options integer := 0;
+BEGIN
+ select count(*) into exists_access_type_def_datamask_options from pg_attribute where attrelid in(select oid from pg_class where relname='x_access_type_def') and attname='datamask_options';
+ IF exists_access_type_def_datamask_options = 0 THEN
+ 	ALTER TABLE x_access_type_def ADD COLUMN datamask_options VARCHAR(1024) DEFAULT NULL;
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* add x_resource_def.datamask_options column if it does not exist */
+CREATE OR REPLACE FUNCTION add_datamask_options_to_x_resource_def_table() 
+RETURNS void AS $$
+DECLARE
+ exists_resource_def_datamask_options integer := 0;
+BEGIN
+ select count(*) into exists_resource_def_datamask_options from pg_attribute where attrelid in(select oid from pg_class where relname='x_resource_def') and attname='datamask_options';
+ IF exists_resource_def_datamask_options = 0 THEN
+ 	ALTER TABLE x_resource_def ADD COLUMN datamask_options VARCHAR(1024) DEFAULT NULL;
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+select 'delimiter end';
+
+
+SELECT add_datamask_options_to_x_access_type_def_table();
+SELECT add_datamask_options_to_x_resource_def_table();
+
+DROP TABLE IF EXISTS x_datamask_type_def;
+DROP TABLE IF EXISTS x_policy_item_datamask;
+DROP SEQUENCE IF EXISTS x_datamask_type_def_seq;
+DROP SEQUENCE IF EXISTS x_policy_item_datamask_def_seq;
+
+CREATE SEQUENCE x_datamask_type_def_seq;
+CREATE TABLE x_datamask_type_def (
+  id BIGINT DEFAULT nextval('x_datamask_type_def_seq'::regclass),
+  guid VARCHAR(1024) DEFAULT NULL,
+  create_time TIMESTAMP DEFAULT NULL,
+  update_time TIMESTAMP DEFAULT NULL,
+  added_by_id BIGINT DEFAULT NULL,
+  upd_by_id BIGINT DEFAULT NULL,
+  def_id BIGINT NOT NULL,    
+  item_id BIGINT NOT NULL,    
+  name VARCHAR(1024) NOT NULL,
+  label VARCHAR(1024) NOT NULL,
+  description VARCHAR(1024) DEFAULT NULL,
+  datamask_options VARCHAR(1024) DEFAULT NULL,
+  rb_key_label VARCHAR(1024) DEFAULT NULL,
+  rb_key_description VARCHAR(1024) DEFAULT NULL,
+  sort_order SMALLINT DEFAULT '0',
+  primary key (id),      
+  CONSTRAINT x_datamask_type_def_FK_def_id FOREIGN KEY (def_id) REFERENCES x_service_def (id) ,
+  CONSTRAINT x_datamask_type_def_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES x_portal_user (id),
+  CONSTRAINT x_datamask_type_def_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES x_portal_user (id)
+);
+CREATE INDEX x_datamask_type_def_IDX_def_id ON x_datamask_type_def(def_id);
+
+CREATE SEQUENCE x_policy_item_datamask_seq;
+CREATE TABLE x_policy_item_datamask (
+  id BIGINT DEFAULT nextval('x_policy_item_datamask_seq'::regclass),
+  guid VARCHAR(1024) DEFAULT NULL,
+  create_time TIMESTAMP DEFAULT NULL,
+  update_time TIMESTAMP DEFAULT NULL,
+  added_by_id BIGINT DEFAULT NULL,
+  upd_by_id BIGINT DEFAULT NULL,
+  policy_item_id BIGINT NOT NULL, 
+  type BIGINT NOT NULL,
+  condition_expr VARCHAR(1024) DEFAULT NULL,
+  value_expr VARCHAR(1024) DEFAULT NULL,
+  primary key (id), 
+  CONSTRAINT x_policy_item_datamask_FK_policy_item_id FOREIGN KEY (policy_item_id) REFERENCES x_policy_item (id) ,
+  CONSTRAINT x_policy_item_datamask_FK_type FOREIGN KEY (type) REFERENCES x_datamask_type_def (id),
+  CONSTRAINT x_policy_item_datamask_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES x_portal_user (id),
+  CONSTRAINT x_policy_item_datamask_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES x_portal_user (id)
+);
+CREATE INDEX x_policy_item_datamask_IDX_policy_item_id ON x_policy_item_datamask(policy_item_id);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 77203dc..c4a823c 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -326,9 +326,9 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 
 		if(dataMaskDef != null) {
-			List<RangerDataMaskTypeDef> dataMaskTypes        = dataMaskDef.getMaskTypes();
-			List<String>                supportedAccessTypes = dataMaskDef.getSupportedAccessTypes();
-			List<String>                supportedResources   = dataMaskDef.getSupportedResources();
+			List<RangerDataMaskTypeDef> dataMaskTypes       = dataMaskDef.getMaskTypes();
+			List<RangerAccessTypeDef>   dataMaskAccessTypes = dataMaskDef.getAccessTypes();
+			List<RangerResourceDef>     dataMaskResources   = dataMaskDef.getResources();
 
 			if(CollectionUtils.isNotEmpty(dataMaskTypes)) {
 				XXDataMaskTypeDefDao xxDataMaskDefDao = daoMgr.getXXDataMaskTypeDef();
@@ -343,14 +343,15 @@ public class ServiceDBStore extends AbstractServiceStore {
 				}
 			}
 
-			if(CollectionUtils.isNotEmpty(supportedAccessTypes)) {
+			if(CollectionUtils.isNotEmpty(dataMaskAccessTypes)) {
 				List<XXAccessTypeDef> xxAccessTypeDefs = xxATDDao.findByServiceDefId(xServiceDef.getId());
 
-				for(String accessType : supportedAccessTypes) {
+				for(RangerAccessTypeDef accessType : dataMaskAccessTypes) {
 					boolean found = false;
 					for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-						if(StringUtils.equals(xxAccessTypeDef.getName(), accessType)) {
+						if(StringUtils.equals(xxAccessTypeDef.getName(), accessType.getName())) {
 							found = true;
+
 							break;
 						}
 					}
@@ -362,22 +363,29 @@ public class ServiceDBStore extends AbstractServiceStore {
 				}
 
 				for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-					boolean isDatamaskingSupported = supportedAccessTypes.contains(xxAccessTypeDef.getName());
+					String dataMaskOptions = null;
+
+					for(RangerAccessTypeDef dataMaskAccessType : dataMaskAccessTypes) {
+						if(StringUtils.equals(dataMaskAccessType.getName(), xxAccessTypeDef.getName())) {
+							dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskAccessType);
+							break;
+						}
+					}
 
-					if(xxAccessTypeDef.isDatamaskingSupported() != isDatamaskingSupported) {
-						xxAccessTypeDef.setDatamaskingSupported(isDatamaskingSupported);
+					if(! StringUtils.equals(dataMaskOptions, xxAccessTypeDef.getDataMaskOptions())) {
+						xxAccessTypeDef.setDataMaskOptions(dataMaskOptions);
 						xxATDDao.update(xxAccessTypeDef);
 					}
 				}
 			}
 
-			if(CollectionUtils.isNotEmpty(supportedResources)) {
+			if(CollectionUtils.isNotEmpty(dataMaskResources)) {
 				List<XXResourceDef> xxResourceDefs = xxResDefDao.findByServiceDefId(xServiceDef.getId());
 
-				for(String resource : supportedResources) {
+				for(RangerResourceDef resource : dataMaskResources) {
 					boolean found = false;
 					for(XXResourceDef xxResourceDef : xxResourceDefs) {
-						if(StringUtils.equals(xxResourceDef.getName(), resource)) {
+						if(StringUtils.equals(xxResourceDef.getName(), resource.getName())) {
 							found = true;
 							break;
 						}
@@ -390,10 +398,17 @@ public class ServiceDBStore extends AbstractServiceStore {
 				}
 
 				for(XXResourceDef xxResourceDef : xxResourceDefs) {
-					boolean isDatamaskingSupported = supportedResources.contains(xxResourceDef.getName());
+					String dataMaskOptions = null;
+
+					for(RangerResourceDef dataMaskResource : dataMaskResources) {
+						if(StringUtils.equals(dataMaskResource.getName(), xxResourceDef.getName())) {
+							dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskResource);
+							break;
+						}
+					}
 
-					if(xxResourceDef.isDatamaskingSupported() != isDatamaskingSupported) {
-						xxResourceDef.setDatamaskingSupported(isDatamaskingSupported);
+					if(! StringUtils.equals(dataMaskOptions, xxResourceDef.getDataMaskOptions())) {
+						xxResourceDef.setDataMaskOptions(dataMaskOptions);
 						xxResDefDao.update(xxResourceDef);
 					}
 				}
@@ -807,11 +822,11 @@ public class ServiceDBStore extends AbstractServiceStore {
 			}
 		}
 
-		List<RangerDataMaskTypeDef> dataMasks            = dataMaskDef == null || dataMaskDef.getMaskTypes() == null ? new ArrayList<RangerDataMaskTypeDef>() : dataMaskDef.getMaskTypes();
-		List<String>                supportedAccessTypes = dataMaskDef == null || dataMaskDef.getSupportedAccessTypes() == null ? new ArrayList<String>() : dataMaskDef.getSupportedAccessTypes();
-		List<String>                supportedResources   = dataMaskDef == null || dataMaskDef.getSupportedResources() == null ? new ArrayList<String>() : dataMaskDef.getSupportedResources();
-		XXDataMaskTypeDefDao        dataMaskTypeDao      = daoMgr.getXXDataMaskTypeDef();
-		List<XXDataMaskTypeDef>     xxDataMaskTypes      = dataMaskTypeDao.findByServiceDefId(serviceDefId);
+		List<RangerDataMaskTypeDef> dataMasks           = dataMaskDef == null || dataMaskDef.getMaskTypes() == null ? new ArrayList<RangerDataMaskTypeDef>() : dataMaskDef.getMaskTypes();
+		List<RangerAccessTypeDef>   dataMaskAccessTypes = dataMaskDef == null || dataMaskDef.getAccessTypes() == null ? new ArrayList<RangerAccessTypeDef>() : dataMaskDef.getAccessTypes();
+		List<RangerResourceDef>     dataMaskResources   = dataMaskDef == null || dataMaskDef.getResources() == null ? new ArrayList<RangerResourceDef>() : dataMaskDef.getResources();
+		XXDataMaskTypeDefDao        dataMaskTypeDao     = daoMgr.getXXDataMaskTypeDef();
+		List<XXDataMaskTypeDef>     xxDataMaskTypes     = dataMaskTypeDao.findByServiceDefId(serviceDefId);
 		// create or update dataMasks
 		for (RangerServiceDef.RangerDataMaskTypeDef dataMask : dataMasks) {
 			boolean found = false;
@@ -861,10 +876,10 @@ public class ServiceDBStore extends AbstractServiceStore {
 
 		List<XXAccessTypeDef> xxAccessTypeDefs = xxATDDao.findByServiceDefId(serviceDefId);
 
-		for(String accessType : supportedAccessTypes) {
+		for(RangerAccessTypeDef accessType : dataMaskAccessTypes) {
 			boolean found = false;
 			for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-				if(StringUtils.equals(xxAccessTypeDef.getName(), accessType)) {
+				if(StringUtils.equals(xxAccessTypeDef.getName(), accessType.getName())) {
 					found = true;
 					break;
 				}
@@ -877,20 +892,27 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 
 		for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-			boolean isDatamaskingSupported = supportedAccessTypes.contains(xxAccessTypeDef.getName());
+			String dataMaskOptions = null;
 
-			if(xxAccessTypeDef.isDatamaskingSupported() != isDatamaskingSupported) {
-				xxAccessTypeDef.setDatamaskingSupported(isDatamaskingSupported);
+			for(RangerAccessTypeDef dataMaskAccessType : dataMaskAccessTypes) {
+				if(StringUtils.equals(dataMaskAccessType.getName(), xxAccessTypeDef.getName())) {
+					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskAccessType);
+					break;
+				}
+			}
+
+			if(! StringUtils.equals(dataMaskOptions, xxAccessTypeDef.getDataMaskOptions())) {
+				xxAccessTypeDef.setDataMaskOptions(dataMaskOptions);
 				xxATDDao.update(xxAccessTypeDef);
 			}
 		}
 
 		List<XXResourceDef> xxResourceDefs = xxResDefDao.findByServiceDefId(serviceDefId);
 
-		for(String resource : supportedResources) {
+		for(RangerResourceDef resource : dataMaskResources) {
 			boolean found = false;
 			for(XXResourceDef xxResourceDef : xxResourceDefs) {
-				if(StringUtils.equals(xxResourceDef.getName(), resource)) {
+				if(StringUtils.equals(xxResourceDef.getName(), resource.getName())) {
 					found = true;
 					break;
 				}
@@ -903,10 +925,17 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 
 		for(XXResourceDef xxResourceDef : xxResourceDefs) {
-			boolean isDatamaskingSupported = supportedResources.contains(xxResourceDef.getName());
+			String dataMaskOptions = null;
+
+			for(RangerResourceDef dataMaskResource : dataMaskResources) {
+				if(StringUtils.equals(dataMaskResource.getName(), xxResourceDef.getName())) {
+					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskResource);
+					break;
+				}
+			}
 
-			if(xxResourceDef.isDatamaskingSupported() != isDatamaskingSupported) {
-				xxResourceDef.setDatamaskingSupported(isDatamaskingSupported);
+			if(! StringUtils.equals(dataMaskOptions, xxResourceDef.getDataMaskOptions())) {
+				xxResourceDef.setDataMaskOptions(dataMaskOptions);
 				xxResDefDao.update(xxResourceDef);
 			}
 		}
@@ -2016,7 +2045,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 			// we need to create one policy for each resource hierarchy
 			RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef);
 			int i = 1;
-			for (List<RangerResourceDef> aHierarchy : serviceDefHelper.getResourceHierarchies()) {
+			for (List<RangerResourceDef> aHierarchy : serviceDefHelper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS)) {
 				createDefaultPolicy(createdService, vXUser, aHierarchy, i);
 				i++;
 			}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/src/main/java/org/apache/ranger/common/JSONUtil.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/common/JSONUtil.java b/security-admin/src/main/java/org/apache/ranger/common/JSONUtil.java
index 38a1659..db4c9c6 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/JSONUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/JSONUtil.java
@@ -24,6 +24,7 @@ package org.apache.ranger.common;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -34,6 +35,7 @@ import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.map.JsonMappingException;
 import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.ser.StdSerializers;
 import org.codehaus.jackson.type.TypeReference;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -130,12 +132,12 @@ public class JSONUtil {
 		return jsonString;
 	}
 
-	public String writeObjectAsString(ViewBaseBean vObj) {
+	public String writeObjectAsString(Serializable obj) {
 		ObjectMapper mapper = new ObjectMapper();
 
 		String jsonStr;
 		try {
-			jsonStr = mapper.writeValueAsString(vObj);
+			jsonStr = mapper.writeValueAsString(obj);
 			return jsonStr;
 		} catch (JsonParseException e) {
 			throw restErrorUtil.createRESTException(
@@ -151,5 +153,22 @@ public class JSONUtil {
 					MessageEnums.INVALID_INPUT_DATA);
 		}
 	}
-	
+
+	public <T> T writeJsonToJavaObject(String json, Class<T> tClass) {
+		ObjectMapper mapper = new ObjectMapper();
+
+		try {
+			return mapper.readValue(json, tClass);
+		} catch (JsonParseException e) {
+			throw restErrorUtil.createRESTException("Invalid input data: " + e.getMessage(),
+					MessageEnums.INVALID_INPUT_DATA);
+		} catch (JsonMappingException e) {
+			throw restErrorUtil.createRESTException("Invalid input data: " + e.getMessage(),
+					MessageEnums.INVALID_INPUT_DATA);
+		} catch (IOException e) {
+			throw restErrorUtil.createRESTException("Invalid input data: " + e.getMessage(),
+					MessageEnums.INVALID_INPUT_DATA);
+		}
+	}
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java b/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
index 62b11ce..5bc22e0 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
@@ -94,13 +94,13 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 	protected Integer order;
 
 	/**
-	 * datamaskingSupported of the XXAccessTypeDef
+	 * dataMaskOptions of the XXAccessTypeDef
 	 * <ul>
 	 * </ul>
 	 *
 	 */
-	@Column(name = "datamasking_supported")
-	protected boolean datamaskingSupported;
+	@Column(name = "datamask_options")
+	protected String dataMaskOptions;
 
 	/**
 	 * This method sets the value to the member attribute <b> id</b> . You
@@ -242,12 +242,12 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 		return this.order;
 	}
 
-	public boolean isDatamaskingSupported() {
-		return datamaskingSupported;
+	public String getDataMaskOptions() {
+		return dataMaskOptions;
 	}
 
-	public void setDatamaskingSupported(boolean datamaskingSupported) {
-		this.datamaskingSupported = datamaskingSupported;
+	public void setDataMaskOptions(String dataMaskOptions) {
+		this.dataMaskOptions = dataMaskOptions;
 	}
 
 	/*
@@ -319,7 +319,11 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 		} else if (!rbKeyLabel.equals(other.rbKeyLabel)) {
 			return false;
 		}
-		if (datamaskingSupported != other.datamaskingSupported) {
+		if (dataMaskOptions == null) {
+			if (other.dataMaskOptions != null) {
+				return false;
+			}
+		} else if (!dataMaskOptions.equals(other.dataMaskOptions)) {
 			return false;
 		}
 		return true;
@@ -334,7 +338,7 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 	public String toString() {
 		return "XXAccessTypeDef [" + super.toString() + " id=" + id
 				+ ", defId=" + defId + ", itemId=" + itemId + ", name=" + name + ", label=" + label
-				+ ", rbKeyLabel=" + rbKeyLabel + ", datamaskingSupported=" + datamaskingSupported + ", order=" + order + "]";
+				+ ", rbKeyLabel=" + rbKeyLabel + ", dataMaskOptions=" + dataMaskOptions + ", order=" + order + "]";
 	}
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java b/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
index 8a2b6e0..6679c35 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
@@ -229,13 +229,13 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 	protected Integer order;
 
 	/**
-	 * datamaskingSupported of the XXResourceDef
+	 * dataMaskOptions of the XXResourceDef
 	 * <ul>
 	 * </ul>
 	 *
 	 */
-	@Column(name = "datamasking_supported")
-	protected boolean datamaskingSupported;
+	@Column(name = "datamask_options")
+	protected String dataMaskOptions;
 
 	/**
 	 * This method sets the value to the member attribute <b> id</b> . You
@@ -653,12 +653,12 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 		return this.order;
 	}
 
-	public boolean isDatamaskingSupported() {
-		return datamaskingSupported;
+	public String getDataMaskOptions() {
+		return dataMaskOptions;
 	}
 
-	public void setDatamaskingSupported(boolean datamaskingSupported) {
-		this.datamaskingSupported = datamaskingSupported;
+	public void setDataMaskOptions(String dataMaskOptions) {
+		this.dataMaskOptions = dataMaskOptions;
 	}
 
 	/*
@@ -796,7 +796,11 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 		} else if (!type.equals(other.type)) {
 			return false;
 		}
-		if (datamaskingSupported != other.datamaskingSupported) {
+		if (dataMaskOptions == null) {
+			if (other.dataMaskOptions != null) {
+				return false;
+			}
+		} else if (!dataMaskOptions.equals(other.dataMaskOptions)) {
 			return false;
 		}
 		return true;
@@ -824,7 +828,7 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 				+ ", rbKeyDescription=" + rbKeyDescription
 				+ ", rbKeyValidationMessage=" + rbKeyValidationMessage
 				+ ", order=" + order
-				+ ", datamaskingSupported=" + datamaskingSupported
+				+ ", dataMaskOptions=" + dataMaskOptions
 				+ "]";
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/164d46fd/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
index 7a172d4..9e2e9f5 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
@@ -17,6 +17,7 @@
 
 package org.apache.ranger.service;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -45,6 +46,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
 import org.apache.ranger.plugin.util.SearchFilter;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 import org.apache.ranger.view.RangerServiceDefList;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -156,24 +158,30 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 
 		if (!stringUtil.isEmpty(xResources)) {
 			for (XXResourceDef xResource : xResources) {
-				if (xResource.isDatamaskingSupported()) {
-					dataMaskDef.getSupportedResources().add(xResource.getName());
+				if (StringUtils.isNotEmpty(xResource.getDataMaskOptions())) {
+					RangerResourceDef dataMaskResource = jsonToObject(xResource.getDataMaskOptions(), RangerResourceDef.class);
+
+					dataMaskDef.getResources().add(dataMaskResource);
 				}
 			}
 		}
 
 		if (!stringUtil.isEmpty(xAccessTypes)) {
 			for (XXAccessTypeDef xAtd : xAccessTypes) {
-				if(xAtd.isDatamaskingSupported()) {
-					dataMaskDef.getSupportedAccessTypes().add(xAtd.getName());
+				if(StringUtils.isNotEmpty(xAtd.getDataMaskOptions())) {
+					RangerAccessTypeDef dataMaskAccessType = jsonToObject(xAtd.getDataMaskOptions(), RangerAccessTypeDef.class);
+
+					dataMaskDef.getAccessTypes().add(dataMaskAccessType);
 				}
 			}
 		}
 		serviceDef.setDataMaskDef(dataMaskDef);
 
+		ServiceDefUtil.normalize(serviceDef);
+
 		return serviceDef;
 	}
-	
+
 	@SuppressWarnings("unchecked")
 	@Override
 	protected XXServiceDefBase mapViewToEntityBean(RangerServiceDef vObj, XXServiceDefBase xObj, int operationContext) {
@@ -537,7 +545,7 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 		retList.setResultSize(onePageList.size());
 		retList.setTotalCount(xxObjList.size());
 	}
-	
+
 	private String mapToJsonString(Map<String, String> map) {
 		String ret = null;
 
@@ -585,4 +593,32 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 
 		return ret;
 	}
+
+	public String objectToJson(Serializable obj) {
+		String ret = null;
+
+		if(obj != null) {
+			try {
+				ret = jsonUtil.writeObjectAsString(obj);
+			} catch(Exception excp) {
+				LOG.warn("objectToJson() failed to convert object to json: " + obj, excp);
+			}
+		}
+
+		return ret;
+	}
+
+	public <T> T jsonToObject(String jsonStr, Class<T> clz) {
+		T ret = null;
+
+		if(StringUtils.isNotEmpty(jsonStr)) {
+			try {
+				ret = jsonUtil.writeJsonToJavaObject(jsonStr, clz);
+			} catch(Exception excp) {
+				LOG.warn("jsonToObject() failed to convert json to object: " + jsonStr, excp);
+			}
+		}
+
+		return ret;
+	}
 }


Mime
View raw message