RANGER-873: Ranger policy model 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/d242dd6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/d242dd6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/d242dd6e

Branch: refs/heads/master
Commit: d242dd6e9dea78586393e6a50b47944652502eb1
Parents: ca84cf7
Author: Madhan Neethiraj <[email protected]>
Authored: Tue Mar 15 18:36:58 2016 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Tue Mar 22 16:43:50 2016 -0700

----------------------------------------------------------------------
 .../plugin/errors/ValidationErrorCode.java      |   2 +
 .../ranger/plugin/model/RangerPolicy.java       | 222 ++++++++-
 .../model/RangerPolicyResourceSignature.java    |   2 +-
 .../ranger/plugin/model/RangerServiceDef.java   | 443 +++++++++++++++++-
 .../model/validation/RangerPolicyValidator.java |  35 +-
 .../model/validation/RangerValidator.java       |   4 +-
 .../policyengine/RangerDataMaskResult.java      | 113 +++++
 .../plugin/policyengine/RangerPolicyEngine.java |   1 +
 .../policyengine/RangerPolicyEngineImpl.java    |  35 ++
 .../policyengine/RangerPolicyRepository.java    |  26 +-
 .../RangerDataMaskPolicyItemEvaluator.java      |  34 ++
 ...angerDefaultDataMaskPolicyItemEvaluator.java |  61 +++
 .../RangerDefaultPolicyEvaluator.java           | 118 ++++-
 .../policyevaluator/RangerPolicyEvaluator.java  |   3 +
 .../RangerPolicyItemEvaluator.java              |   1 +
 .../TestRangerPolicyResourceSignature.java      |   6 +-
 .../validation/TestRangerPolicyValidator.java   |  51 ++-
 .../plugin/policyengine/TestPolicyEngine.java   |  33 +-
 .../test_policyengine_hive_masking.json         | 150 ++++++
 .../test_policyengine_tag_hive.json             |   2 +-
 .../test_policyengine_tag_hive_filebased.json   |   2 +-
 .../db/mysql/patches/020-datamask-policy.sql    |  94 ++++
 .../ranger/biz/RangerPolicyRetriever.java       | 105 +++--
 .../org/apache/ranger/biz/ServiceDBStore.java   | 454 +++++++++++++------
 .../org/apache/ranger/common/AppConstants.java  |  10 +-
 .../apache/ranger/db/RangerDaoManagerBase.java  |  20 +-
 .../apache/ranger/db/XXDataMaskTypeDefDao.java  |  62 +++
 .../ranger/db/XXPolicyItemDataMaskInfoDao.java  |  85 ++++
 .../apache/ranger/entity/XXAccessTypeDef.java   |  22 +-
 .../apache/ranger/entity/XXDataMaskTypeDef.java | 403 ++++++++++++++++
 .../ranger/entity/XXPolicyItemDataMaskInfo.java | 282 ++++++++++++
 .../org/apache/ranger/entity/XXResourceDef.java |  24 +-
 .../ranger/service/RangerPolicyServiceBase.java |   4 +-
 .../service/RangerServiceDefServiceBase.java    |  80 +++-
 .../resources/META-INF/jpa_named_queries.xml    |  35 ++
 .../apache/ranger/biz/TestServiceDBStore.java   |  68 +--
 .../service/TestRangerServiceDefService.java    |  44 +-
 37 files changed, 2859 insertions(+), 277 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
index 72f7205..6ac82f5 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
@@ -87,6 +87,8 @@ public enum ValidationErrorCode {
     POLICY_VALIDATION_ERR_POLICY_ITEM_ACCESS_TYPE_DENY(3023, "Currently deny 
access types are not supported. Access type is set to deny."),
     
POLICY_VALIDATION_ERR_INVALID_RESOURCE_NO_COMPATIBLE_HIERARCHY_SINGLE(3024, 
"Invalid resources specified. {0} policy can specify values for the following 
resources: {1}"),
     POLICY_VALIDATION_ERR_INVALID_RESOURCE_MISSING_MANDATORY_SINGLE(3025, 
"Invalid resources specified. {0} policy must specify values for the following 
resources: {1}"),
+    POLICY_VALIDATION_ERR_POLICY_UPDATE_MOVE_SERVICE_NOT_ALLOWED(3026, 
"attempt to move policy id={0} from service={1} to service={2} is not allowed"),
+    POLICY_VALIDATION_ERR_POLICY_TYPE_CHANGE_NOT_ALLOWED(3027, "attempt to 
change type of policy id={0} from type={1} to type={2} is not allowed"),
     ;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 7354dfe..522d130 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
@@ -40,6 +40,8 @@ import org.codehaus.jackson.map.annotate.JsonSerialize;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 public class RangerPolicy extends RangerBaseModelObject implements 
java.io.Serializable {
+       public static final int POLICY_TYPE_ACCESS   = 0;
+       public static final int POLICY_TYPE_DATAMASK = 1;
 
        // For future use
        private static final long serialVersionUID = 1L;
@@ -55,6 +57,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
        private List<RangerPolicyItem>            denyPolicyItems       = null;
        private List<RangerPolicyItem>            allowExceptions       = null;
        private List<RangerPolicyItem>            denyExceptions        = null;
+       private List<RangerDataMaskPolicyItem>    dataMaskPolicyItems = null;
 
 
        /**
@@ -87,6 +90,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                setDenyPolicyItems(null);
                setAllowExceptions(null);
                setDenyExceptions(null);
+               setDataMaskPolicyItems(null);
        }
 
        /**
@@ -106,6 +110,8 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                setDenyPolicyItems(other.getDenyPolicyItems());
                setAllowExceptions(other.getAllowExceptions());
                setDenyExceptions(other.getDenyExceptions());
+               setDataMaskPolicyItems(other.getDataMaskPolicyItems());
+
        }
 
        /**
@@ -332,6 +338,28 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                }
        }
 
+       public List<RangerDataMaskPolicyItem> getDataMaskPolicyItems() {
+               return dataMaskPolicyItems;
+       }
+
+       public void setDataMaskPolicyItems(List<RangerDataMaskPolicyItem> 
dataMaskPolicyItems) {
+               if(this.dataMaskPolicyItems == null) {
+                       this.dataMaskPolicyItems = new 
ArrayList<RangerDataMaskPolicyItem>();
+               }
+
+               if(this.dataMaskPolicyItems == dataMaskPolicyItems) {
+                       return;
+               }
+
+               this.dataMaskPolicyItems.clear();
+
+               if(dataMaskPolicyItems != null) {
+                       for(RangerDataMaskPolicyItem dataMaskPolicyItem : 
dataMaskPolicyItems) {
+                               
this.dataMaskPolicyItems.add(dataMaskPolicyItem);
+                       }
+               }
+       }
+
        @Override
        public String toString( ) {
                StringBuilder sb = new StringBuilder();
@@ -834,8 +862,95 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                        } else if (!users.equals(other.users))
                                return false;
                        return true;
+
+               }
+       }
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerDataMaskPolicyItem extends RangerPolicyItem 
implements java.io.Serializable {
+               private static final long serialVersionUID = 1L;
+
+               private RangerPolicyItemDataMaskInfo dataMaskInfo = null;
+
+               public RangerDataMaskPolicyItem() {
+                       this(null, null, null, null, null, null);
+               }
+
+               public RangerDataMaskPolicyItem(List<RangerPolicyItemAccess> 
accesses, RangerPolicyItemDataMaskInfo dataMaskDetail, List<String> users, 
List<String> groups, List<RangerPolicyItemCondition> conditions, Boolean 
delegateAdmin) {
+                       super(accesses, users, groups, conditions, 
delegateAdmin);
+
+                       setDataMaskInfo(dataMaskDetail);
+               }
+
+               /**
+                * @return the dataMaskInfo
+                */
+               public RangerPolicyItemDataMaskInfo getDataMaskInfo() {
+                       return dataMaskInfo;
+               }
+
+               /**
+                * @param dataMaskInfo the dataMaskInfo to set
+                */
+               public void setDataMaskInfo(RangerPolicyItemDataMaskInfo 
dataMaskInfo) {
+                       this.dataMaskInfo = dataMaskInfo;
+               }
+
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = super.hashCode();
+                       result = prime * result + ((dataMaskInfo == null) ? 0 : 
dataMaskInfo.hashCode());
+                       return result;
+               }
+
+               @Override
+               public boolean equals(Object obj) {
+                       if(! super.equals(obj))
+                               return false;
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       RangerDataMaskPolicyItem other = 
(RangerDataMaskPolicyItem) obj;
+                       if (dataMaskInfo == null) {
+                               if (other.dataMaskInfo != null)
+                                       return false;
+                       } else if (!dataMaskInfo.equals(other.dataMaskInfo))
+                               return false;
+                       return true;
+               }
+
+               @Override
+               public String toString( ) {
+                       StringBuilder sb = new StringBuilder();
+
+                       toString(sb);
+
+                       return sb.toString();
+               }
+
+               public StringBuilder toString(StringBuilder sb) {
+                       sb.append("RangerDataMaskPolicyItem={");
+
+                       super.toString(sb);
+
+                       sb.append("dataMaskInfo={");
+                       if(dataMaskInfo != null) {
+                               dataMaskInfo.toString(sb);
+                       }
+                       sb.append("} ");
+
+                       sb.append("}");
+
+                       return sb;
                }
-               
        }
 
        @JsonAutoDetect(fieldVisibility=Visibility.ANY)
@@ -1061,4 +1176,109 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                }
                
        }
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerPolicyItemDataMaskInfo implements 
java.io.Serializable {
+               private static final long serialVersionUID = 1L;
+
+               private String dataMaskType  = null;
+               private String conditionExpr = null;
+               private String valueExpr     = null;
+
+               public RangerPolicyItemDataMaskInfo() { }
+
+               public RangerPolicyItemDataMaskInfo(String dataMaskType, String 
conditionExpr, String valueExpr) {
+                       setDataMaskType(dataMaskType);
+                       setConditionExpr(conditionExpr);
+                       setValueExpr(valueExpr);
+               }
+
+               public String getDataMaskType() {
+                       return dataMaskType;
+               }
+
+               public void setDataMaskType(String dataMaskType) {
+                       this.dataMaskType = dataMaskType;
+               }
+
+               public String getConditionExpr() {
+                       return conditionExpr;
+               }
+
+               public void setConditionExpr(String conditionExpr) {
+                       this.conditionExpr = conditionExpr;
+               }
+
+               public String getValueExpr() {
+                       return valueExpr;
+               }
+
+               public void setValueExpr(String valueExpr) {
+                       this.valueExpr = valueExpr;
+               }
+
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = super.hashCode();
+                       result = prime * result + ((dataMaskType == null) ? 0 : 
dataMaskType.hashCode());
+                       result = prime * result + ((conditionExpr == null) ? 0 
: conditionExpr.hashCode());
+                       result = prime * result + ((valueExpr == null) ? 0 : 
valueExpr.hashCode());
+                       return result;
+               }
+
+               @Override
+               public boolean equals(Object obj) {
+                       if(! super.equals(obj))
+                               return false;
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       RangerPolicyItemDataMaskInfo other = 
(RangerPolicyItemDataMaskInfo) obj;
+                       if (dataMaskType == null) {
+                               if (other.dataMaskType != null)
+                                       return false;
+                       } else if (!dataMaskType.equals(other.dataMaskType))
+                               return false;
+                       if (conditionExpr == null) {
+                               if (other.conditionExpr != null)
+                                       return false;
+                       } else if (!conditionExpr.equals(other.conditionExpr))
+                               return false;
+                       if (valueExpr == null) {
+                               if (other.valueExpr != null)
+                                       return false;
+                       } else if (!valueExpr.equals(other.valueExpr))
+                               return false;
+                       return true;
+               }
+
+               @Override
+               public String toString( ) {
+                       StringBuilder sb = new StringBuilder();
+
+                       toString(sb);
+
+                       return sb.toString();
+               }
+
+               public StringBuilder toString(StringBuilder sb) {
+                       sb.append("RangerPolicyItemDataMaskInfo={");
+
+                       
sb.append("dataMaskType={").append(dataMaskType).append("} ");
+                       
sb.append("conditionExpr={").append(conditionExpr).append("} ");
+                       sb.append("valueExpr={").append(valueExpr).append("} ");
+
+                       sb.append("}");
+
+                       return sb;
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
index 76d853a..c12d62d 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicyResourceSignature.java
@@ -125,7 +125,7 @@ public class RangerPolicyResourceSignature {
                        if (!isPolicyValidForResourceSignatureComputation()) {
                                return "";
                        }
-                       int type = 0;
+                       int type = RangerPolicy.POLICY_TYPE_ACCESS;
                        if (_policy.getPolicyType() != null) {
                                type = _policy.getPolicyType();
                        }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 f66839e..cec12b6 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
@@ -58,14 +58,19 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
        private List<RangerPolicyConditionDef> policyConditions = null;
        private List<RangerContextEnricherDef> contextEnrichers = null;
        private List<RangerEnumDef>            enums            = null;
+       private RangerDataMaskDef              dataMaskDef      = null;
 
 
        public RangerServiceDef() {
-               this(null, null, null, null, null, null, null, null, null, 
null, null);
+               this(null, null, null, null, null, null, null, null, null, 
null, null, null);
+       }
+
+       public RangerServiceDef(String name, String implClass, String label, 
String description, Map<String, String> options, List<RangerServiceConfigDef> 
configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> 
accessTypes, List<RangerPolicyConditionDef> policyConditions, 
List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums) {
+               this(name, implClass, label, description, options, configs, 
resources, accessTypes, policyConditions, contextEnrichers, enums, null);
        }
 
        /**
-        * @param type
+        * @param name
         * @param implClass
         * @param label
         * @param description
@@ -75,9 +80,10 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
         * @param accessTypes
         * @param policyConditions
         * @param contextEnrichers
+        * @param dataMaskDef
         * @param enums
         */
-       public RangerServiceDef(String name, String implClass, String label, 
String description, Map<String, String> options, List<RangerServiceConfigDef> 
configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> 
accessTypes, List<RangerPolicyConditionDef> policyConditions, 
List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums) {
+       public RangerServiceDef(String name, String implClass, String label, 
String description, Map<String, String> options, List<RangerServiceConfigDef> 
configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> 
accessTypes, List<RangerPolicyConditionDef> policyConditions, 
List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums, 
RangerDataMaskDef dataMaskDef) {
                super();
 
                setName(name);
@@ -91,6 +97,7 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
                setPolicyConditions(policyConditions);
                setContextEnrichers(contextEnrichers);
                setEnums(enums);
+               setDataMaskDef(dataMaskDef);
        }
 
        /**
@@ -108,6 +115,7 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
                setAccessTypes(other.getAccessTypes());
                setPolicyConditions(other.getPolicyConditions());
                setEnums(other.getEnums());
+               setDataMaskDef(other.getDataMaskDef());
        }
 
        /**
@@ -388,6 +396,14 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
        }
 
+       public RangerDataMaskDef getDataMaskDef() {
+               return dataMaskDef;
+       }
+
+       public void setDataMaskDef(RangerDataMaskDef dataMaskDef) {
+               this.dataMaskDef = dataMaskDef == null ? new 
RangerDataMaskDef() : dataMaskDef;
+       }
+
        @Override
        public String toString( ) {
                StringBuilder sb = new StringBuilder();
@@ -477,6 +493,12 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
                sb.append("} ");
 
+               sb.append("dataMaskDef={");
+               if(dataMaskDef != null) {
+                       dataMaskDef.toString(sb);
+               }
+               sb.append("} ");
+
                sb.append("}");
 
                return sb;
@@ -892,14 +914,14 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
 
                /**
-                * @return the type
+                * @return the subType
                 */
                public String getSubType() {
                        return subType;
                }
 
                /**
-                * @param type the type to set
+                * @param subType the subType to set
                 */
                public void setSubType(String subType) {
                        this.subType = subType;
@@ -1389,14 +1411,14 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
 
                /**
-                * @return the matcher
+                * @return the matcherOptions
                 */
                public Map<String, String> getMatcherOptions() {
                        return matcherOptions;
                }
 
                /**
-                * @param matcher the matcher to set
+                * @param matcherOptions the matcherOptions to set
                 */
                public void setMatcherOptions(Map<String, String> 
matcherOptions) {
                        this.matcherOptions = matcherOptions == null ? new 
HashMap<String, String>() : matcherOptions;
@@ -2000,14 +2022,14 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
 
                /**
-                * @return the evaluator
+                * @return the evaluatorOptions
                 */
                public Map<String, String> getEvaluatorOptions() {
                        return evaluatorOptions;
                }
 
                /**
-                * @param evaluator the evaluator to set
+                * @param evaluatorOptions the evaluatorOptions to set
                 */
                public void setEvaluatorOptions(Map<String, String> 
evaluatorOptions) {
                        this.evaluatorOptions = evaluatorOptions == null ? new 
HashMap<String, String>() : evaluatorOptions;
@@ -2336,14 +2358,14 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
 
                /**
-                * @return the evaluator
+                * @return the enricherOptions
                 */
                public Map<String, String> getEnricherOptions() {
                        return enricherOptions;
                }
 
                /**
-                * @param evaluator the evaluator to set
+                * @param enricherOptions the enricherOptions to set
                 */
                public void setEnricherOptions(Map<String, String> 
enricherOptions) {
                        this.enricherOptions = enricherOptions == null ? new 
HashMap<String, String>() : enricherOptions;
@@ -2417,4 +2439,403 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                        return true;
                }
        }
+
+
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerDataMaskDef {
+               private List<RangerDataMaskTypeDef> maskTypes;
+               private List<String>                supportedAccessTypes;
+               private List<String>                supportedResources;
+
+
+               public RangerDataMaskDef() {
+                       setMaskTypes(null);
+                       setSupportedAccessTypes(null);
+                       setSupportedResources(null);
+               }
+
+               public RangerDataMaskDef(List<RangerDataMaskTypeDef> maskTypes, 
List<String> supportedAccessTypes, List<String> supportedResources) {
+                       setMaskTypes(maskTypes);
+                       setSupportedAccessTypes(supportedAccessTypes);
+                       setSupportedResources(supportedResources);
+               }
+
+               public RangerDataMaskDef(RangerDataMaskDef other) {
+                       setMaskTypes(other.getMaskTypes());
+                       
setSupportedAccessTypes(other.getSupportedAccessTypes());
+                       setSupportedResources(other.getSupportedResources());
+               }
+
+               public List<RangerDataMaskTypeDef> getMaskTypes() {
+                       return maskTypes;
+               }
+
+               public void setMaskTypes(List<RangerDataMaskTypeDef> maskTypes) 
{
+                       if(this.maskTypes == null) {
+                               this.maskTypes = new 
ArrayList<RangerDataMaskTypeDef>();
+                       }
+
+                       if(this.maskTypes == maskTypes) {
+                               return;
+                       }
+
+                       this.maskTypes.clear();
+
+                       if(maskTypes != null) {
+                               for(RangerDataMaskTypeDef maskType : maskTypes) 
{
+                                       this.maskTypes.add(maskType);
+                               }
+                       }
+               }
+
+               public List<String> getSupportedAccessTypes() {
+                       return supportedAccessTypes;
+               }
+
+               public void setSupportedAccessTypes(List<String> 
supportedAccessTypes) {
+                       if(this.supportedAccessTypes == null) {
+                               this.supportedAccessTypes = new 
ArrayList<String>();
+                       }
+
+                       if(this.supportedAccessTypes == supportedAccessTypes) {
+                               return;
+                       }
+
+                       this.supportedAccessTypes.clear();
+
+                       if(supportedAccessTypes != null) {
+                               for(String accessType : supportedAccessTypes) {
+                                       
this.supportedAccessTypes.add(accessType);
+                               }
+                       }
+               }
+
+               public List<String> getSupportedResources() {
+                       return supportedResources;
+               }
+
+               public void setSupportedResources(List<String> 
supportedResources) {
+                       if(this.supportedResources == null) {
+                               this.supportedResources = new 
ArrayList<String>();
+                       }
+
+                       if(this.supportedResources == supportedResources) {
+                               return;
+                       }
+
+                       this.supportedResources.clear();
+
+                       if(supportedResources != null) {
+                               for(String resource : supportedResources) {
+                                       this.supportedResources.add(resource);
+                               }
+                       }
+               }
+
+               @Override
+               public String toString( ) {
+                       StringBuilder sb = new StringBuilder();
+
+                       toString(sb);
+
+                       return sb.toString();
+               }
+
+               public StringBuilder toString(StringBuilder sb) {
+                       sb.append("RangerDataMaskDef={");
+
+                       sb.append("maskTypes={");
+                       if(maskTypes != null) {
+                               for(RangerDataMaskTypeDef maskType : maskTypes) 
{
+                                       if(maskType != null) {
+                                               sb.append(maskType).append(" ");
+                                       }
+                               }
+                       }
+                       sb.append("} ");
+
+                       sb.append("supportedAccessTypes={");
+                       if(supportedAccessTypes != null) {
+                               for(String accessType : supportedAccessTypes) {
+                                       if(accessType != null) {
+                                               sb.append(accessType).append(" 
");
+                                       }
+                               }
+                       }
+                       sb.append("} ");
+
+                       sb.append("supportedResources={");
+                       if(supportedResources != null) {
+                               for(String resource : supportedResources) {
+                                       if(resource != null) {
+                                               sb.append(resource).append(" ");
+                                       }
+                               }
+                       }
+                       sb.append("} ");
+
+                       sb.append("}");
+
+                       return sb;
+               }
+
+               @Override
+               public int hashCode() {
+                       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());
+                       return result;
+               }
+
+               @Override
+               public boolean equals(Object obj) {
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       RangerDataMaskDef other = (RangerDataMaskDef) obj;
+                       if (maskTypes == null) {
+                               if (other.maskTypes != null)
+                                       return false;
+                       } else if (other.maskTypes == null || 
!maskTypes.equals(other.maskTypes))
+                               return false;
+
+                       if (supportedAccessTypes == null) {
+                               if (other.supportedAccessTypes != null)
+                                       return false;
+                       } else if 
(!supportedAccessTypes.equals(other.supportedAccessTypes))
+                               return false;
+                       if (supportedResources == null) {
+                               if (other.supportedResources != null)
+                                       return false;
+                       } else if 
(!supportedResources.equals(other.supportedResources))
+                               return false;
+                       return true;
+               }
+       }
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerDataMaskTypeDef implements 
java.io.Serializable {
+               private static final long serialVersionUID = 1L;
+
+               private Long                itemId           = null;
+               private String              name             = null;
+               private String              label            = null;
+               private String              description      = null;
+               private Map<String, String> dataMaskOptions  = null;
+               private String              rbKeyLabel       = null;
+               private String              rbKeyDescription = null;
+
+
+               public RangerDataMaskTypeDef() {
+                       this(null, null, null, null, null, null, null);
+               }
+
+               public RangerDataMaskTypeDef(Long itemId, String name, String 
label, String description, Map<String, String> dataMaskOptions, String 
rbKeyLabel, String rbKeyDescription) {
+                       setItemId(itemId);
+                       setName(name);
+                       setLabel(label);
+                       setDescription(description);
+                       setDataMaskOptions(dataMaskOptions);
+                       setRbKeyLabel(rbKeyLabel);
+                       setRbKeyDescription(rbKeyDescription);
+               }
+
+               public RangerDataMaskTypeDef(RangerDataMaskTypeDef other) {
+                       setItemId(other.getItemId());
+                       setName(other.getName());
+                       setLabel(other.getLabel());
+                       setDescription(other.getDescription());
+                       setDataMaskOptions(other.getDataMaskOptions());
+                       setRbKeyLabel(other.getRbKeyLabel());
+                       setRbKeyDescription(other.getRbKeyDescription());
+               }
+
+               /**
+                * @return the itemId
+                */
+               public Long getItemId() {
+                       return itemId;
+               }
+
+               /**
+                * @param itemId the itemId to set
+                */
+               public void setItemId(Long itemId) {
+                       this.itemId = itemId;
+               }
+
+               /**
+                * @return the name
+                */
+               public String getName() {
+                       return name;
+               }
+
+               /**
+                * @param name the name to set
+                */
+               public void setName(String name) {
+                       this.name = name;
+               }
+
+               /**
+                * @return the label
+                */
+               public String getLabel() {
+                       return label;
+               }
+
+               /**
+                * @param label the label to set
+                */
+               public void setLabel(String label) {
+                       this.label = label;
+               }
+
+               /**
+                * @return the description
+                */
+               public String getDescription() {
+                       return description;
+               }
+
+               /**
+                * @param description the description to set
+                */
+               public void setDescription(String description) {
+                       this.description = description;
+               }
+
+               /**
+                * @return the dataMaskOptions
+                */
+               public Map<String, String> getDataMaskOptions() {
+                       return dataMaskOptions;
+               }
+
+               /**
+                * @param dataMaskOptions the dataMaskOptions to set
+                */
+               public void setDataMaskOptions(Map<String, String> 
dataMaskOptions) {
+                       this.dataMaskOptions = dataMaskOptions == null ? new 
HashMap<String, String>() : dataMaskOptions;
+               }
+
+               /**
+                * @return the rbKeyLabel
+                */
+               public String getRbKeyLabel() {
+                       return rbKeyLabel;
+               }
+
+               /**
+                * @param rbKeyLabel the rbKeyLabel to set
+                */
+               public void setRbKeyLabel(String rbKeyLabel) {
+                       this.rbKeyLabel = rbKeyLabel;
+               }
+
+               /**
+                * @return the rbKeyDescription
+                */
+               public String getRbKeyDescription() {
+                       return rbKeyDescription;
+               }
+
+               /**
+                * @param rbKeyDescription the rbKeyDescription to set
+                */
+               public void setRbKeyDescription(String rbKeyDescription) {
+                       this.rbKeyDescription = rbKeyDescription;
+               }
+
+               @Override
+               public String toString( ) {
+                       StringBuilder sb = new StringBuilder();
+
+                       toString(sb);
+
+                       return sb.toString();
+               }
+
+               public StringBuilder toString(StringBuilder sb) {
+                       sb.append("RangerDataMaskTypeDef={");
+                       sb.append("itemId={").append(itemId).append("} ");
+                       sb.append("name={").append(name).append("} ");
+                       sb.append("label={").append(label).append("} ");
+                       
sb.append("description={").append(description).append("} ");
+                       
sb.append("dataMaskOptions={").append(dataMaskOptions).append("} ");
+                       sb.append("rbKeyLabel={").append(rbKeyLabel).append("} 
");
+                       
sb.append("rbKeyDescription={").append(rbKeyDescription).append("} ");
+
+                       sb.append("}");
+
+                       return sb;
+               }
+
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = 1;
+                       result = prime * result + ((itemId == null) ? 0 : 
itemId.hashCode());
+                       result = prime * result
+                                       + ((dataMaskOptions == null) ? 0 : 
dataMaskOptions.hashCode());
+                       result = prime * result + ((label == null) ? 0 : 
label.hashCode());
+                       result = prime * result + ((name == null) ? 0 : 
name.hashCode());
+                       result = prime * result
+                                       + ((rbKeyLabel == null) ? 0 : 
rbKeyLabel.hashCode());
+                       return result;
+               }
+
+               @Override
+               public boolean equals(Object obj) {
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       RangerDataMaskTypeDef other = (RangerDataMaskTypeDef) 
obj;
+                       if (itemId == null) {
+                               if (other.itemId != null)
+                                       return false;
+                       } else if (other.itemId == null || 
!itemId.equals(other.itemId))
+                               return false;
+
+                       if (dataMaskOptions == null) {
+                               if (other.dataMaskOptions != null)
+                                       return false;
+                       } else if 
(!dataMaskOptions.equals(other.dataMaskOptions))
+                               return false;
+                       if (label == null) {
+                               if (other.label != null)
+                                       return false;
+                       } else if (!label.equals(other.label))
+                               return false;
+                       if (name == null) {
+                               if (other.name != null)
+                                       return false;
+                       } else if (!name.equals(other.name))
+                               return false;
+                       if (rbKeyLabel == null) {
+                               if (other.rbKeyLabel != null)
+                                       return false;
+                       } else if (!rbKeyLabel.equals(other.rbKeyLabel))
+                               return false;
+                       return true;
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 307606f..d354ac7 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
@@ -121,6 +121,8 @@ public class RangerPolicyValidator extends RangerValidator {
                        valid = false;
                } else {
                        Long id = policy.getId();
+                       RangerPolicy existingPolicy = null;
+
                        if (action == Action.UPDATE) { // id is ignored for 
CREATE
                                if (id == null) {
                                        ValidationErrorCode error = 
ValidationErrorCode.POLICY_VALIDATION_ERR_MISSING_FIELD;
@@ -131,7 +133,11 @@ public class RangerPolicyValidator extends RangerValidator 
{
                                                .errorCode(error.getErrorCode())
                                                .build());
                                        valid = false;
-                               } else if (getPolicy(id) == null) {
+                               }
+
+                               existingPolicy = getPolicy(id);
+
+                               if (existingPolicy == null) {
                                        ValidationErrorCode error = 
ValidationErrorCode.POLICY_VALIDATION_ERR_INVALID_POLICY_ID;
                                        failures.add(new 
ValidationFailureDetailsBuilder()
                                                .field("id")
@@ -213,6 +219,33 @@ public class RangerPolicyValidator extends RangerValidator 
{
                                }
                        }
 
+                       if(existingPolicy != null) {
+                               if(! 
StringUtils.equalsIgnoreCase(existingPolicy.getService(), policy.getService())) 
{
+                                       ValidationErrorCode error = 
ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_UPDATE_MOVE_SERVICE_NOT_ALLOWED;
+                                       failures.add(new 
ValidationFailureDetailsBuilder()
+                                                       .field("service name")
+                                                       
.isSemanticallyIncorrect()
+                                                       
.becauseOf(error.getMessage(policy.getId(), existingPolicy.getService(), 
policy.getService()))
+                                                       
.errorCode(error.getErrorCode())
+                                                       .build());
+                                       valid = false;
+                               }
+
+                               int existingPolicyType = 
existingPolicy.getPolicyType() == null ? RangerPolicy.POLICY_TYPE_ACCESS : 
existingPolicy.getPolicyType();
+                               int policyType         = policy.getPolicyType() 
== null ? RangerPolicy.POLICY_TYPE_ACCESS : policy.getPolicyType();
+
+                               if(existingPolicyType != policyType) {
+                                       ValidationErrorCode error = 
ValidationErrorCode.POLICY_VALIDATION_ERR_POLICY_TYPE_CHANGE_NOT_ALLOWED;
+                                       failures.add(new 
ValidationFailureDetailsBuilder()
+                                                       .field("policy type")
+                                                       
.isSemanticallyIncorrect()
+                                                       
.becauseOf(error.getMessage(policy.getId(), existingPolicyType, policyType))
+                                                       
.errorCode(error.getErrorCode())
+                                                       .build());
+                                       valid = false;
+                               }
+                       }
+
                        boolean          isAuditEnabled   = 
getIsAuditEnabled(policy);
                        String           serviceDefName   = null;
                        RangerServiceDef serviceDef       = null;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 381864d..075a374 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.getAccessTypes(" + 
serviceDef + ")");
+                       LOG.debug("==> 
RangerValidator.getSupportedAccessTypes(" + serviceDef + ")");
                }
 
                Set<String> accessTypes = new HashSet<String>();
@@ -316,7 +316,7 @@ public abstract class RangerValidator {
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerValidator.getAccessTypes(" + 
serviceDef + "): " + accessTypes);
+                       LOG.debug("<== 
RangerValidator.getSupportedAccessTypes(" + serviceDef + "): " + accessTypes);
                }
                return accessTypes;
        }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDataMaskResult.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDataMaskResult.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDataMaskResult.java
new file mode 100644
index 0000000..66d8eba
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerDataMaskResult.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.plugin.policyengine;
+
+import org.apache.commons.lang.StringUtils;
+import 
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+
+public class RangerDataMaskResult extends RangerAccessResult {
+       private String maskType      = null;
+       private String maskCondition = null;
+       private String maskedValue   = null;
+
+
+       public RangerDataMaskResult(final String serviceName, final 
RangerServiceDef serviceDef, final RangerAccessRequest request) {
+               this(serviceName, serviceDef, request, null);
+       }
+
+       public RangerDataMaskResult(final String serviceName, final 
RangerServiceDef serviceDef, final RangerAccessRequest request, final 
RangerPolicyItemDataMaskInfo dataMaskInfo) {
+               super(serviceName, serviceDef, request);
+
+               if(dataMaskInfo != null) {
+                       setMaskType(dataMaskInfo.getDataMaskType());
+                       setMaskCondition(dataMaskInfo.getConditionExpr());
+                       setMaskedValue(dataMaskInfo.getValueExpr());
+               }
+       }
+
+       /**
+        * @return the maskType
+        */
+       public String getMaskType() {
+               return maskType;
+       }
+
+       /**
+        * @param maskType the maskType to set
+        */
+       public void setMaskType(String maskType) {
+               this.maskType = maskType;
+       }
+
+       /**
+        * @return the maskCondition
+        */
+       public String getMaskCondition() {
+               return maskCondition;
+       }
+
+       /**
+        * @param maskCondition the maskCondition to set
+        */
+       public void setMaskCondition(String maskCondition) {
+               this.maskCondition = maskCondition;
+       }
+
+       /**
+        * @return the maskedValue
+        */
+       public String getMaskedValue() {
+               return maskedValue;
+       }
+       /**
+        * @param maskedValue the maskedValue to set
+        */
+       public void setMaskedValue(String maskedValue) {
+               this.maskedValue = maskedValue;
+       }
+
+       public boolean isMaskEnabled() {
+               return StringUtils.isNotEmpty(this.getMaskType());
+       }
+
+       @Override
+       public String toString( ) {
+               StringBuilder sb = new StringBuilder();
+
+               toString(sb);
+
+               return sb.toString();
+       }
+
+       public StringBuilder toString(StringBuilder sb) {
+               sb.append("RangerDataMaskResult={");
+
+               super.toString(sb);
+
+        sb.append("maskType={").append(maskType).append("} ");
+        sb.append("maskCondition={").append(maskCondition).append("} ");
+               sb.append("maskedValue={").append(maskedValue).append("} ");
+
+               sb.append("}");
+
+               return sb;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 02ad9e9..64870d9 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
@@ -49,6 +49,7 @@ public interface RangerPolicyEngine {
 
        Collection<RangerAccessResult> 
isAccessAllowed(Collection<RangerAccessRequest> requests, 
RangerAccessResultProcessor resultProcessor);
 
+       RangerDataMaskResult evalDataMaskPolicies(RangerAccessRequest request, 
RangerAccessResultProcessor resultProcessor);
 
        boolean isAccessAllowed(RangerAccessResource resource, String user, 
Set<String> userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 92481f6..9e817d7 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
@@ -276,6 +276,41 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
        }
 
        @Override
+       public RangerDataMaskResult evalDataMaskPolicies(RangerAccessRequest 
request, RangerAccessResultProcessor resultProcessor) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerPolicyEngineImpl.evalDataMaskPolicies(" + request + ")");
+               }
+
+               RangerDataMaskResult ret = new 
RangerDataMaskResult(getServiceName(), getServiceDef(), request);
+
+               if(request != null) {
+                       List<RangerPolicyEvaluator> evaluators = 
policyRepository.getDataMaskPolicyEvaluators();
+                       for (RangerPolicyEvaluator evaluator : evaluators) {
+                               evaluator.evaluate(request, ret);
+
+                               if (ret.getIsAccessDetermined() && 
ret.getIsAuditedDetermined()) {
+                                       break;
+                               }
+                       }
+               }
+
+               // no need to audit if filter/mask is not enabled
+               if(! ret.isMaskEnabled()) {
+                       ret.setIsAudited(false);
+               }
+
+               if (resultProcessor != null) {
+                       resultProcessor.processResult(ret);
+               }
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerPolicyEngineImpl.evalDataMaskPolicies(" + request + "): " + ret);
+               }
+
+               return ret;
+       }
+
+       @Override
        public boolean isAccessAllowed(RangerAccessResource resource, String 
user, Set<String> userGroups, String accessType) {
                if (LOG.isDebugEnabled()) {
                        LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" 
+ resource + ", " + user + ", " + userGroups + ", " + accessType + ")");

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 d39dd52..4a394d4 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
@@ -48,6 +48,7 @@ public class RangerPolicyRepository {
     private final long                        policyVersion;
     private List<RangerContextEnricher>       contextEnrichers;
     private List<RangerPolicyEvaluator>       policyEvaluators;
+    private List<RangerPolicyEvaluator>       dataMaskPolicyEvaluators;
     private final Map<String, Boolean>        accessAuditCache;
 
     private final String                      componentServiceName;
@@ -127,6 +128,10 @@ public class RangerPolicyRepository {
         return policyEvaluators;
     }
 
+    public List<RangerPolicyEvaluator> getDataMaskPolicyEvaluators() {
+        return dataMaskPolicyEvaluators;
+    }
+
     private RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef 
serviceDef, final String componentType) {
 
         if (serviceDef != null && StringUtils.isNotBlank(componentType)) {
@@ -309,6 +314,7 @@ public class RangerPolicyRepository {
     private void init(RangerPolicyEngineOptions options) {
 
         List<RangerPolicyEvaluator> policyEvaluators = new 
ArrayList<RangerPolicyEvaluator>();
+        List<RangerPolicyEvaluator> dataMaskPolicyEvaluators = new 
ArrayList<RangerPolicyEvaluator>();
 
         for (RangerPolicy policy : policies) {
             if (skipBuildingPolicyEvaluator(policy, options)) {
@@ -318,12 +324,21 @@ public class RangerPolicyRepository {
             RangerPolicyEvaluator evaluator = buildPolicyEvaluator(policy, 
serviceDef, options);
 
             if (evaluator != null) {
-                policyEvaluators.add(evaluator);
+                if(policy.getPolicyType() == null || policy.getPolicyType() == 
RangerPolicy.POLICY_TYPE_ACCESS) {
+                    policyEvaluators.add(evaluator);
+                } else if(policy.getPolicyType() == 
RangerPolicy.POLICY_TYPE_DATAMASK) {
+                    dataMaskPolicyEvaluators.add(evaluator);
+                } else {
+                    LOG.warn("RangerPolicyEngine: ignoring policy id=" + 
policy.getId() + " - invalid policyType '" + policy.getPolicyType() + "'");
+                }
             }
         }
         Collections.sort(policyEvaluators);
         this.policyEvaluators = Collections.unmodifiableList(policyEvaluators);
 
+        Collections.sort(dataMaskPolicyEvaluators);
+        this.dataMaskPolicyEvaluators = 
Collections.unmodifiableList(dataMaskPolicyEvaluators);
+
         List<RangerContextEnricher> contextEnrichers = new 
ArrayList<RangerContextEnricher>();
         if (CollectionUtils.isNotEmpty(this.policyEvaluators)) {
             if (!options.disableContextEnrichers && 
!CollectionUtils.isEmpty(serviceDef.getContextEnrichers())) {
@@ -351,6 +366,15 @@ public class RangerPolicyRepository {
 
                 LOG.debug("policy evaluation order: #" + (++order) + " - 
policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + 
policyEvaluator.getEvalOrder());
             }
+
+            LOG.debug("datamasking policy evaluation order: " + 
this.dataMaskPolicyEvaluators.size() + " policies");
+
+            order = 0;
+            for(RangerPolicyEvaluator policyEvaluator : 
this.dataMaskPolicyEvaluators) {
+                RangerPolicy policy = policyEvaluator.getPolicy();
+
+                LOG.debug("datamasking policy evaluation order: #" + (++order) 
+ " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; 
evalOrder=" + policyEvaluator.getEvalOrder());
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
new file mode 100644
index 0000000..62d624c
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.plugin.policyevaluator;
+
+import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
+
+
+public interface RangerDataMaskPolicyItemEvaluator extends 
RangerPolicyItemEvaluator {
+       void init();
+
+       RangerDataMaskPolicyItem getPolicyItem();
+
+       String getMaskType();
+
+       String getMaskCondition();
+
+       String getMaskedValue();
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
new file mode 100644
index 0000000..4583de9
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.plugin.policyevaluator;
+
+
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
+import 
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+
+
+public class RangerDefaultDataMaskPolicyItemEvaluator extends 
RangerDefaultPolicyItemEvaluator implements RangerDataMaskPolicyItemEvaluator {
+
+       public RangerDefaultDataMaskPolicyItemEvaluator(RangerServiceDef 
serviceDef, RangerPolicy policy, RangerDataMaskPolicyItem policyItem, int 
policyItemIndex, RangerPolicyEngineOptions options) {
+               super(serviceDef, policy, policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING, policyItemIndex, 
options);
+       }
+
+       @Override
+       public RangerDataMaskPolicyItem getPolicyItem() {
+               return (RangerDataMaskPolicyItem)policyItem;
+       }
+
+       @Override
+       public String getMaskType() {
+               RangerPolicyItemDataMaskInfo dataMaskInfo = 
getPolicyItem().getDataMaskInfo();
+
+               return dataMaskInfo != null ? dataMaskInfo.getDataMaskType() : 
null;
+       }
+
+       @Override
+       public String getMaskCondition() {
+               RangerPolicyItemDataMaskInfo dataMaskInfo = 
getPolicyItem().getDataMaskInfo();
+
+               return dataMaskInfo != null ? dataMaskInfo.getConditionExpr() : 
null;
+       }
+
+       @Override
+       public String getMaskedValue() {
+               RangerPolicyItemDataMaskInfo dataMaskInfo = 
getPolicyItem().getDataMaskInfo();
+
+               return dataMaskInfo != null ? dataMaskInfo.getValueExpr() : 
null;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 1fa8644..2ce3a54 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -33,6 +33,7 @@ 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.RangerDataMaskPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
@@ -41,6 +42,7 @@ import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
@@ -60,6 +62,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private List<RangerPolicyItemEvaluator> allowExceptionEvaluators = null;
        private List<RangerPolicyItemEvaluator> denyExceptionEvaluators  = null;
        private int                             customConditionsCount    = 0;
+       private List<RangerDataMaskPolicyItemEvaluator> dataMaskEvaluators = 
null;
        private String perfTag;
 
        @Override
@@ -101,17 +104,20 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        denyEvaluators           = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
                        allowExceptionEvaluators = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
                        denyExceptionEvaluators  = 
createPolicyItemEvaluators(policy, serviceDef, options, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
+                       dataMaskEvaluators       = 
createPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
                } else {
                        allowEvaluators          = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        denyEvaluators           = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        allowExceptionEvaluators = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        denyExceptionEvaluators  = 
Collections.<RangerPolicyItemEvaluator>emptyList();
+                       dataMaskEvaluators       = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
                }
 
                Collections.sort(allowEvaluators);
                Collections.sort(denyEvaluators);
                Collections.sort(allowExceptionEvaluators);
                Collections.sort(denyExceptionEvaluators);
+               Collections.sort(dataMaskEvaluators);
 
                RangerPerfTracer.log(perf);
 
@@ -587,7 +593,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
-       private RangerPolicyItemEvaluator 
getMatchingPolicyItem(RangerAccessRequest request, 
List<RangerPolicyItemEvaluator> evaluators, List<RangerPolicyItemEvaluator> 
exceptionEvaluators) {
+       private RangerPolicyItemEvaluator 
getMatchingPolicyItem(RangerAccessRequest request, List<? extends 
RangerPolicyItemEvaluator> evaluators, List<? extends 
RangerPolicyItemEvaluator> exceptionEvaluators) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> 
RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + ")");
         }
@@ -678,4 +684,114 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                return ret;
        }
+
+       @Override
+       public void evaluate(RangerAccessRequest request, RangerDataMaskResult 
result) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" 
+ request + ", " + result + ")");
+               }
+
+               RangerPerfTracer perf = null;
+
+               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.evaluate(requestHashCode=" + 
Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")");
+               }
+
+               if (request != null && result != null && 
CollectionUtils.isNotEmpty(dataMaskEvaluators)) {
+                       boolean isResourceMatchAttempted = false;
+                       boolean isResourceMatch          = false;
+
+                       if (!result.getIsAuditedDetermined()) {
+                               if (!isResourceMatchAttempted) {
+                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatchAttempted = true;
+                               }
+
+                               if (isResourceMatch) {
+                                       if (isAuditEnabled()) {
+                                               result.setIsAudited(true);
+                                       }
+                               }
+                       }
+
+                       if (!result.getIsAccessDetermined()) {
+                               if (!isResourceMatchAttempted) {
+                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatchAttempted = true;
+                               }
+
+                               if (isResourceMatch) {
+                                       evaluatePolicyItems(request, result);
+                               }
+                       }
+               }
+
+               RangerPerfTracer.log(perf);
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + 
", " + result + ")");
+        }
+       }
+
+       protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerDataMaskResult result) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
")");
+               }
+
+               RangerDataMaskPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, dataMaskEvaluators);
+
+               if(matchedPolicyItem != null) {
+                       RangerPolicy policy = getPolicy();
+
+                       result.setIsAllowed(true);
+                       result.setIsAccessDetermined(true);
+
+                       result.setMaskType(matchedPolicyItem.getMaskType());
+                       
result.setMaskCondition(matchedPolicyItem.getMaskCondition());
+                       
result.setMaskedValue(matchedPolicyItem.getMaskedValue());
+                       result.setPolicyId(policy.getId());
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + ")");
+               }
+       }
+
+       protected RangerDataMaskPolicyItemEvaluator 
getMatchingPolicyItem(RangerAccessRequest request, 
List<RangerDataMaskPolicyItemEvaluator> evaluators) {
+               RangerDataMaskPolicyItemEvaluator ret = null;
+
+               RangerPolicyItemEvaluator policyItem = 
getMatchingPolicyItem(request, dataMaskEvaluators, null);
+
+               if(policyItem != null) {
+                       ret = (RangerDataMaskPolicyItemEvaluator)policyItem;
+               }
+
+               return ret;
+       }
+
+       private List<RangerDataMaskPolicyItemEvaluator> 
createPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, 
RangerPolicyEngineOptions options, List<RangerDataMaskPolicyItem> policyItems) {
+               List<RangerDataMaskPolicyItemEvaluator> ret = null;
+
+               if(CollectionUtils.isNotEmpty(policyItems)) {
+                       ret = new 
ArrayList<RangerDataMaskPolicyItemEvaluator>();
+
+                       int policyItemCounter = 1;
+
+                       for(RangerDataMaskPolicyItem policyItem : policyItems) {
+                               RangerDataMaskPolicyItemEvaluator itemEvaluator 
= new RangerDefaultDataMaskPolicyItemEvaluator(serviceDef, policy, policyItem, 
policyItemCounter++, options);
+
+                               itemEvaluator.init();
+
+                               ret.add(itemEvaluator);
+
+                               
if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
+                                       customConditionsCount += 
itemEvaluator.getConditionEvaluators().size();
+                               }
+                       }
+               } else {
+                       ret = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
+               }
+
+               return ret;
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 3f76755..3c73082 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
@@ -29,6 +29,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 
 public interface RangerPolicyEvaluator extends 
Comparable<RangerPolicyEvaluator> {
@@ -54,6 +55,8 @@ public interface RangerPolicyEvaluator extends 
Comparable<RangerPolicyEvaluator>
 
        void evaluate(RangerAccessRequest request, RangerAccessResult result);
 
+       void evaluate(RangerAccessRequest request, RangerDataMaskResult result);
+
        boolean isMatch(RangerAccessResource resource);
 
        boolean isCompleteMatch(RangerAccessResource resource);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index 1dfc8cf..9ac2f93 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -30,6 +30,7 @@ public interface RangerPolicyItemEvaluator extends 
Comparable<RangerPolicyItemEv
        public static final int POLICY_ITEM_TYPE_DENY             = 1;
        public static final int POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS = 2;
        public static final int POLICY_ITEM_TYPE_DENY_EXCEPTIONS  = 3;
+       public static final int POLICY_ITEM_TYPE_DATA_MASKING     = 4;
 
        void init();
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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 8c8c4c0..7cc2831 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.getResources()==null", 
policySerializer.isPolicyValidForResourceSignatureComputation());
+               assertFalse("policy.getSupportedResources()==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.getResources().isEmpty()", 
policySerializer.isPolicyValidForResourceSignatureComputation());
+               assertTrue("policy.getSupportedResources().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.getResources().contains(null)", 
policySerializer.isPolicyValidForResourceSignatureComputation());
+               assertFalse("policy.getSupportedResources().contains(null)", 
policySerializer.isPolicyValidForResourceSignatureComputation());
        }
        
        @Test

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java
index e0f3b0e..c757a0b 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/model/validation/TestRangerPolicyValidator.java
@@ -179,7 +179,51 @@ public class TestRangerPolicyValidator {
                _failures.clear(); assertTrue(_validator.isValid(3L, 
Action.DELETE, _failures));
                assertTrue(_failures.isEmpty());
        }
-       
+
+       @Test
+       public final void testIsValid_errorPaths() throws Exception {
+               boolean isAdmin = true;
+
+               // 1. create policy in a non-existing service
+               Action action = Action.CREATE;
+               
when(_policy.getService()).thenReturn("non-existing-service-name");
+               
when(_store.getServiceByName("non-existing-service-name")).thenReturn(null);
+
+               assertFalse(action.toString(), _validator.isValid(_policy, 
action, isAdmin, _failures));
+
+               // 2. update a policy to change the service-name
+               RangerPolicy existingPolicy = mock(RangerPolicy.class);
+               when(existingPolicy.getId()).thenReturn(8L);
+               when(existingPolicy.getService()).thenReturn("service-name");
+
+               RangerService service = mock(RangerService.class);
+               when(service.getType()).thenReturn("service-type");
+               when(service.getName()).thenReturn("service-name");
+               
when(_store.getServiceByName("service-name")).thenReturn(service);
+
+               RangerService service2 = mock(RangerService.class);
+               when(service2.getType()).thenReturn("service-type");
+               when(service2.getName()).thenReturn("service-name2");
+               
when(_store.getServiceByName("service-name2")).thenReturn(service2);
+
+               when(_policy.getService()).thenReturn("service-name2");
+               
when(_store.getServiceByName("service-name2")).thenReturn(service2);
+               action = Action.UPDATE;
+
+               assertFalse(action.toString(), _validator.isValid(_policy, 
action, isAdmin, _failures));
+
+               // 3. update a policy to change the policy-type
+               when(existingPolicy.getId()).thenReturn(8L);
+               when(existingPolicy.getService()).thenReturn("service-name");
+               
when(existingPolicy.getPolicyType()).thenReturn(Integer.valueOf(0));
+
+               when(_policy.getId()).thenReturn(8L);
+               when(_policy.getService()).thenReturn("service-name");
+               when(_policy.getPolicyType()).thenReturn(Integer.valueOf(1));
+
+               assertFalse(action.toString(), _validator.isValid(_policy, 
action, isAdmin, _failures));
+       }
+
        @Test
        public final void testIsValid_happyPath() throws Exception {
                // valid policy has valid non-empty name and service name 
@@ -196,14 +240,15 @@ public class TestRangerPolicyValidator {
                when(_store.getPolicy(7L)).thenReturn(null);
                RangerPolicy existingPolicy = mock(RangerPolicy.class);
                when(existingPolicy.getId()).thenReturn(8L);
+               when(existingPolicy.getService()).thenReturn("service-name");
                when(_store.getPolicy(8L)).thenReturn(existingPolicy);
                SearchFilter createFilter = new SearchFilter();
-               createFilter.setParam(SearchFilter.POLICY_NAME, "service-type");
+               createFilter.setParam(SearchFilter.SERVICE_TYPE, 
"service-type");
                createFilter.setParam(SearchFilter.POLICY_NAME, 
"policy-name-1"); // this name would be used for create
                when(_store.getPolicies(createFilter)).thenReturn(new 
ArrayList<RangerPolicy>());
                // a matching policy should not exist for update.
                SearchFilter updateFilter = new SearchFilter();
-               updateFilter.setParam(SearchFilter.POLICY_NAME, "service-type");
+               updateFilter.setParam(SearchFilter.SERVICE_TYPE, 
"service-type");
                updateFilter.setParam(SearchFilter.POLICY_NAME, 
"policy-name-2"); // this name would be used for update
                List<RangerPolicy> existingPolicies = new 
ArrayList<RangerPolicy>();
                existingPolicies.add(existingPolicy);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index f9ba62b..cd81836 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -194,6 +194,13 @@ public class TestPolicyEngine {
                runTestsFromResourceFiles(conditionsTestResourceFiles);
        }
 
+       @Test
+       public void testPolicyEngine_hiveMasking() {
+               String[] resourceFiles = { 
"/policyengine/test_policyengine_hive_masking.json" };
+
+               runTestsFromResourceFiles(resourceFiles);
+       }
+
        private void runTestsFromResourceFiles(String[] resourceNames) {
                for(String resourceName : resourceNames) {
                        InputStream       inStream = 
this.getClass().getResourceAsStream(resourceName);
@@ -303,15 +310,28 @@ public class TestPolicyEngine {
                                policyEngine.preProcess(request);
                        }
 
-                       RangerAccessResult expected = test.result;
                        RangerAccessResultProcessor auditHandler = new 
RangerDefaultAuditHandler();
 
-                       RangerAccessResult result   = 
policyEngine.isAccessAllowed(request, auditHandler);
+                       if(test.result != null) {
+                               RangerAccessResult expected = test.result;
+                               RangerAccessResult result   = 
policyEngine.isAccessAllowed(request, auditHandler);
 
-                       assertNotNull("result was null! - " + test.name, 
result);
-                       assertEquals("isAllowed mismatched! - " + test.name, 
expected.getIsAllowed(), result.getIsAllowed());
-                       assertEquals("isAudited mismatched! - " + test.name, 
expected.getIsAudited(), result.getIsAudited());
-                       assertEquals("policyId mismatched! - " + test.name, 
expected.getPolicyId(), result.getPolicyId());
+                               assertNotNull("result was null! - " + 
test.name, result);
+                               assertEquals("isAllowed mismatched! - " + 
test.name, expected.getIsAllowed(), result.getIsAllowed());
+                               assertEquals("isAudited mismatched! - " + 
test.name, expected.getIsAudited(), result.getIsAudited());
+                               assertEquals("policyId mismatched! - " + 
test.name, expected.getPolicyId(), result.getPolicyId());
+                       }
+
+                       if(test.dataMaskResult != null) {
+                               RangerDataMaskResult expected = 
test.dataMaskResult;
+                               RangerDataMaskResult result   = 
policyEngine.evalDataMaskPolicies(request, auditHandler);
+
+                               assertNotNull("result was null! - " + 
test.name, result);
+                               assertEquals("maskType mismatched! - " + 
test.name, expected.getMaskType(), result.getMaskType());
+                               assertEquals("maskCondition mismatched! - " + 
test.name, expected.getMaskCondition(), result.getMaskCondition());
+                               assertEquals("maskedValue mismatched! - " + 
test.name, expected.getMaskedValue(), result.getMaskedValue());
+                               assertEquals("policyId mismatched! - " + 
test.name, expected.getPolicyId(), result.getPolicyId());
+                       }
                }
        }
 
@@ -326,6 +346,7 @@ public class TestPolicyEngine {
                        public String              name;
                        public RangerAccessRequest request;
                        public RangerAccessResult  result;
+                       public RangerDataMaskResult dataMaskResult;
                }
 
                class TagPolicyInfo {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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
new file mode 100644
index 0000000..92b21aa
--- /dev/null
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
@@ -0,0 +1,150 @@
+{
+  "serviceName":"hivedev",
+
+  "serviceDef":{
+    "name":"hive",
+    "id":3,
+    "resources":[
+      
{"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+      
{"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
+      
{"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
+      
{"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
 "ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
+    ],
+    "accessTypes":[
+      {"name":"select","label":"Select"},
+      {"name":"update","label":"Update"},
+      {"name":"create","label":"Create"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"name":"all","label":"All",
+        "impliedGrants": [
+          "select",
+          "update",
+          "create",
+          "drop",
+          "alter",
+          "index",
+          "lock"
+        ]
+      }
+    ],
+    "dataMaskDef": {
+      "maskTypes": [
+        {
+          "itemId": 1,
+          "name": "MASK",
+          "label": "Mask",
+          "description": "Replace lowercase with 'x', uppercase with 'X', 
digits with '0'"
+        },
+        {
+          "itemId": 2,
+          "name": "SHUFFLE",
+          "label": "Shuffle",
+          "description": "Randomly shuffle the contents"
+        }
+
+      ],
+      "supportedAccessTypes": [
+        "select"
+      ],
+      "supportedResources": [
+        "database",
+        "table",
+        "column"
+      ]
+    }
+  },
+
+  "policies":[
+    {"id":1,"name":"db=*: 
audit-all-access","isEnabled":true,"isAuditEnabled":true,
+     
"resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+     "policyItems":[
+       {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", "user1", 
"user2"],"groups":["public"],"delegateAdmin":false}
+     ]
+    },
+    {"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"]}},
+      "dataMaskPolicyItems":[
+        
{"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
+         "dataMaskInfo": {"dataMaskType":"MASK"}
+        },
+        
{"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
+          "dataMaskInfo": {"dataMaskType":"SHUFFLE"}
+        }
+      ]
+    },
+    {"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"]}},
+      "dataMaskPolicyItems":[
+        
{"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
+          "dataMaskInfo": {"dataMaskType":"MASK"}
+        },
+        
{"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
+          "dataMaskInfo": {"dataMaskType":"SHUFFLE"}
+        }
+      ]
+    }
+  ],
+
+  "tests":[
+    {"name":"'select ssn from employee.personal;' for user1 - maskType=MASK",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"ssn"}},
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn 
from employee.personal;' for user1"
+      },
+      
"dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":101}
+    },
+    {"name":"'select ssn from employee.personal;' for user2 - 
maskType=SHUFFLE",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"ssn"}},
+        
"accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn 
from employee.personal;' for user2"
+      },
+      
"dataMaskResult":{"maskType":"SHUFFLE","maskCondition":null,"maskValue":null,"policyId":101}
+    },
+    {"name":"'select ssn from employee.personal;' for user3 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"ssn"}},
+        
"accessType":"select","user":"user3","userGroups":[],"requestData":"select ssn 
from employee.personal;' for user3"
+      },
+      
"dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select name from employee.personal;' for user1 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", 
"column":"name"}},
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select name 
from employee.personal;' for user1"
+      },
+      
"dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select date_of_birth from hr.employee;' for user1 - 
maskType=MASK",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee", 
"column":"date_of_birth"}},
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select 
date_of_birth from hr.employee;' for user1"
+      },
+      
"dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":102}
+    },
+    {"name":"'select date_of_birth from hr.employee2;' for user2 - 
maskType=SHUFFLE",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee2", 
"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}
+    },
+    {"name":"'select date_of_birth1 from hr.employee;' for user1 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee", 
"column":"date_of_birth1"}},
+        
"accessType":"select","user":"user1","userGroups":[],"requestData":"select 
date_of_birth1 from hr.employee;' for user1"
+      },
+      
"dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select date_of_birth from hr2.employee2;' for user2 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"hr2", "table":"employee2", 
"column":"date_of_birth"}},
+        
"accessType":"select","user":"user2","userGroups":[],"requestData":"select 
date_of_birth from hr2.employee2;' for user2"
+      },
+      
"dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    }
+  ]
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
index 9c9bc40..2628863 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
@@ -175,7 +175,7 @@
                  
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
         ]
       },
-      
{"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      
{"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,
         
"resources":{"tag":{"values":["RESTRICTED-FINAL"],"isRecursive":false}},
         "denyPolicyItems":[
           
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
index e9ee355..167a157 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
@@ -181,7 +181,7 @@
                  
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive"],"groups":[],"delegateAdmin":false}
         ]
       },
-      
{"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      
{"id":4,"name":"RESTRICTED_TAG_POLICY_FINAL","isEnabled":true,"isAuditEnabled":true,
         
"resources":{"tag":{"values":["RESTRICTED-FINAL"],"isRecursive":false}},
         "denyPolicyItems":[
           
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":[],"groups":["public"],"delegateAdmin":false}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/d242dd6e/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
new file mode 100644
index 0000000..43d9395
--- /dev/null
+++ b/security-admin/db/mysql/patches/020-datamask-policy.sql
@@ -0,0 +1,94 @@
+-- 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.
+
+/* 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;
+delimiter ;;
+ create procedure add_datamasking_supported_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;
+       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;
+
+/* add datamasking_supported column in x_resource_def table if not exist */
+drop procedure if exists add_datamasking_supported_to_x_resource_def_table;
+delimiter ;;
+ create procedure add_datamasking_supported_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;
+       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;
+
+DROP TABLE IF EXISTS `x_datamask_type_def`;
+CREATE TABLE `x_datamask_type_def` (
+`id` bigint(20) NOT NULL AUTO_INCREMENT ,
+`guid` varchar(1024) DEFAULT NULL,
+`create_time` datetime DEFAULT NULL,
+`update_time` datetime DEFAULT NULL,
+`added_by_id` bigint(20) DEFAULT NULL,
+`upd_by_id` bigint(20) DEFAULT NULL,
+`def_id` bigint(20) NOT NULL,    
+`item_id` bigint(20) 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` tinyint(3) DEFAULT '0',
+primary key (`id`),      
+KEY `x_datamask_type_def_added_by_id` (`added_by_id`),
+KEY `x_datamask_type_def_upd_by_id` (`upd_by_id`),
+KEY `x_datamask_type_def_cr_time` (`create_time`),
+KEY `x_datamask_type_def_up_time` (`update_time`),
+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);
+
+DROP TABLE IF EXISTS `x_policy_item_datamask`;
+CREATE TABLE `x_policy_item_datamask` (
+`id` bigint(20) NOT NULL AUTO_INCREMENT ,
+`guid` varchar(1024) DEFAULT NULL,
+`create_time` datetime DEFAULT NULL,
+`update_time` datetime DEFAULT NULL,
+`added_by_id` bigint(20) DEFAULT NULL,
+`upd_by_id` bigint(20) DEFAULT NULL,
+`policy_item_id` bigint(20) NOT NULL, 
+`type` bigint(20) 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);

Reply via email to