RANGER-908: Ranger policy model updated to support row-filtering

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

Branch: refs/heads/master
Commit: 2c7f617be49fb9fc93b1e0e4fab62701602f6c55
Parents: 38b79e7
Author: Madhan Neethiraj <[email protected]>
Authored: Sun Apr 3 22:01:17 2016 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Tue Apr 5 09:20:12 2016 -0700

----------------------------------------------------------------------
 .../ranger/plugin/model/RangerPolicy.java       | 219 ++++++++-
 .../ranger/plugin/model/RangerServiceDef.java   | 164 ++++++-
 .../validation/RangerServiceDefHelper.java      |   6 +
 .../plugin/policyengine/RangerPolicyEngine.java |   2 +
 .../policyengine/RangerPolicyEngineImpl.java    |  37 +-
 .../policyengine/RangerPolicyRepository.java    |  26 +-
 .../policyengine/RangerRowFilterResult.java     |  80 ++++
 .../RangerDataMaskPolicyItemEvaluator.java      |  10 +-
 ...angerDefaultDataMaskPolicyItemEvaluator.java |  28 +-
 .../RangerDefaultPolicyEvaluator.java           | 468 ++++++++++++-------
 ...ngerDefaultRowFilterPolicyItemEvaluator.java |  42 ++
 .../policyevaluator/RangerPolicyEvaluator.java  |   3 +
 .../RangerPolicyItemEvaluator.java              |   3 +-
 .../RangerRowFilterPolicyItemEvaluator.java     |  28 ++
 .../ranger/plugin/service/RangerBasePlugin.java |  12 +
 .../plugin/store/AbstractPredicateUtil.java     |   8 +-
 .../ranger/plugin/util/ServiceDefUtil.java      |  48 ++
 .../service-defs/ranger-servicedef-hive.json    |  30 +-
 .../plugin/policyengine/TestPolicyEngine.java   |  14 +-
 .../test_policyengine_hive_mask_filter.json     | 243 ++++++++++
 .../test_policyengine_hive_masking.json         | 156 -------
 .../hive/authorizer/RangerHiveAuditHandler.java |  18 +-
 .../db/mysql/patches/020-datamask-policy.sql    |  23 +
 .../db/postgres/patches/020-datamask-policy.sql |  30 ++
 .../ranger/biz/RangerPolicyRetriever.java       |  68 ++-
 .../org/apache/ranger/biz/ServiceDBStore.java   | 312 ++++++++-----
 .../java/org/apache/ranger/biz/XUserMgr.java    |  26 +-
 .../org/apache/ranger/common/AppConstants.java  |   6 +-
 .../apache/ranger/db/RangerDaoManagerBase.java  |  10 +
 .../ranger/db/XXPolicyItemRowFilterInfoDao.java |  71 +++
 .../apache/ranger/entity/XXAccessTypeDef.java   |  23 +-
 .../ranger/entity/XXPolicyItemDataMaskInfo.java |  41 +-
 .../entity/XXPolicyItemRowFilterInfo.java       | 176 +++++++
 .../org/apache/ranger/entity/XXResourceDef.java |  21 +
 .../service/RangerServiceDefServiceBase.java    |  18 +-
 .../resources/META-INF/jpa_named_queries.xml    |  21 +
 .../apache/ranger/biz/TestServiceDBStore.java   |  17 +
 37 files changed, 1952 insertions(+), 556 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 f022707..d8e19b7 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,10 +40,15 @@ 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;
+       public static final int POLICY_TYPE_ACCESS    = 0;
+       public static final int POLICY_TYPE_DATAMASK  = 1;
+       public static final int POLICY_TYPE_ROWFILTER = 2;
 
-       public static final int[] POLICY_TYPES = new int[] { 
POLICY_TYPE_ACCESS, POLICY_TYPE_DATAMASK };
+       public static final int[] POLICY_TYPES = new int[] {
+                       POLICY_TYPE_ACCESS,
+                       POLICY_TYPE_DATAMASK,
+                       POLICY_TYPE_ROWFILTER
+       };
 
        // For future use
        private static final long serialVersionUID = 1L;
@@ -59,7 +64,8 @@ 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;
+       private List<RangerDataMaskPolicyItem>    dataMaskPolicyItems  = null;
+       private List<RangerRowFilterPolicyItem>   rowFilterPolicyItems = null;
 
 
        /**
@@ -93,6 +99,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                setAllowExceptions(null);
                setDenyExceptions(null);
                setDataMaskPolicyItems(null);
+               setRowFilterPolicyItems(null);
        }
 
        /**
@@ -113,7 +120,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                setAllowExceptions(other.getAllowExceptions());
                setDenyExceptions(other.getDenyExceptions());
                setDataMaskPolicyItems(other.getDataMaskPolicyItems());
-
+               setRowFilterPolicyItems(other.getRowFilterPolicyItems());
        }
 
        /**
@@ -362,6 +369,28 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                }
        }
 
+       public List<RangerRowFilterPolicyItem> getRowFilterPolicyItems() {
+               return rowFilterPolicyItems;
+       }
+
+       public void setRowFilterPolicyItems(List<RangerRowFilterPolicyItem> 
rowFilterPolicyItems) {
+               if(this.rowFilterPolicyItems == null) {
+                       this.rowFilterPolicyItems = new 
ArrayList<RangerRowFilterPolicyItem>();
+               }
+
+               if(this.rowFilterPolicyItems == rowFilterPolicyItems) {
+                       return;
+               }
+
+               this.rowFilterPolicyItems.clear();
+
+               if(rowFilterPolicyItems != null) {
+                       for(RangerRowFilterPolicyItem rowFilterPolicyItem : 
rowFilterPolicyItems) {
+                               
this.rowFilterPolicyItems.add(rowFilterPolicyItem);
+                       }
+               }
+       }
+
        @Override
        public String toString( ) {
                StringBuilder sb = new StringBuilder();
@@ -433,6 +462,26 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                }
                sb.append("} ");
 
+               sb.append("dataMaskPolicyItems={");
+               if(dataMaskPolicyItems != null) {
+                       for(RangerDataMaskPolicyItem dataMaskPolicyItem : 
dataMaskPolicyItems) {
+                               if(dataMaskPolicyItem != null) {
+                                       dataMaskPolicyItem.toString(sb);
+                               }
+                       }
+               }
+               sb.append("} ");
+
+               sb.append("rowFilterPolicyItems={");
+               if(rowFilterPolicyItems != null) {
+                       for(RangerRowFilterPolicyItem rowFilterPolicyItem : 
rowFilterPolicyItems) {
+                               if(rowFilterPolicyItem != null) {
+                                       rowFilterPolicyItem.toString(sb);
+                               }
+                       }
+               }
+               sb.append("} ");
+
                sb.append("}");
 
                return sb;
@@ -899,7 +948,7 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                 * @param dataMaskInfo the dataMaskInfo to set
                 */
                public void setDataMaskInfo(RangerPolicyItemDataMaskInfo 
dataMaskInfo) {
-                       this.dataMaskInfo = dataMaskInfo;
+                       this.dataMaskInfo = dataMaskInfo == null ? new 
RangerPolicyItemDataMaskInfo() : dataMaskInfo;
                }
 
                @Override
@@ -960,6 +1009,93 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
        @JsonIgnoreProperties(ignoreUnknown=true)
        @XmlRootElement
        @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerRowFilterPolicyItem extends RangerPolicyItem 
implements java.io.Serializable {
+               private static final long serialVersionUID = 1L;
+
+               private RangerPolicyItemRowFilterInfo rowFilterInfo = null;
+
+               public RangerRowFilterPolicyItem() {
+                       this(null, null, null, null, null, null);
+               }
+
+               public RangerRowFilterPolicyItem(RangerPolicyItemRowFilterInfo 
rowFilterInfo, List<RangerPolicyItemAccess> accesses, List<String> users, 
List<String> groups, List<RangerPolicyItemCondition> conditions, Boolean 
delegateAdmin) {
+                       super(accesses, users, groups, conditions, 
delegateAdmin);
+
+                       setRowFilterInfo(rowFilterInfo);
+               }
+
+               /**
+                * @return the rowFilterInfo
+                */
+               public RangerPolicyItemRowFilterInfo getRowFilterInfo() {
+                       return rowFilterInfo;
+               }
+
+               /**
+                * @param rowFilterInfo the rowFilterInfo to set
+                */
+               public void setRowFilterInfo(RangerPolicyItemRowFilterInfo 
rowFilterInfo) {
+                       this.rowFilterInfo = rowFilterInfo == null ? new 
RangerPolicyItemRowFilterInfo() : rowFilterInfo;
+               }
+
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = super.hashCode();
+                       result = prime * result + ((rowFilterInfo == null) ? 0 
: rowFilterInfo.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;
+                       RangerRowFilterPolicyItem other = 
(RangerRowFilterPolicyItem) obj;
+                       if (rowFilterInfo == null) {
+                               if (other.rowFilterInfo != null)
+                                       return false;
+                       } else if (!rowFilterInfo.equals(other.rowFilterInfo))
+                               return false;
+                       return true;
+               }
+
+               @Override
+               public String toString( ) {
+                       StringBuilder sb = new StringBuilder();
+
+                       toString(sb);
+
+                       return sb.toString();
+               }
+
+               public StringBuilder toString(StringBuilder sb) {
+                       sb.append("RangerRowFilterPolicyItem={");
+
+                       super.toString(sb);
+
+                       sb.append("rowFilterInfo={");
+                       if(rowFilterInfo != null) {
+                               rowFilterInfo.toString(sb);
+                       }
+                       sb.append("} ");
+
+                       sb.append("}");
+
+                       return sb;
+               }
+       }
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
        public static class RangerPolicyItemAccess implements 
java.io.Serializable {
                private static final long serialVersionUID = 1L;
 
@@ -1283,4 +1419,75 @@ public class RangerPolicy extends RangerBaseModelObject 
implements java.io.Seria
                        return sb;
                }
        }
+
+       @JsonAutoDetect(fieldVisibility=Visibility.ANY)
+       @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+       @JsonIgnoreProperties(ignoreUnknown=true)
+       @XmlRootElement
+       @XmlAccessorType(XmlAccessType.FIELD)
+       public static class RangerPolicyItemRowFilterInfo implements 
java.io.Serializable {
+               private static final long serialVersionUID = 1L;
+
+               private String filterExpr = null;
+
+               public RangerPolicyItemRowFilterInfo() { }
+
+               public RangerPolicyItemRowFilterInfo(String filterExpr) {
+                       setFilterExpr(filterExpr);
+               }
+
+               public String getFilterExpr() {
+                       return filterExpr;
+               }
+
+               public void setFilterExpr(String filterExpr) {
+                       this.filterExpr = filterExpr;
+               }
+
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = super.hashCode();
+                       result = prime * result + ((filterExpr == null) ? 0 : 
filterExpr.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;
+                       RangerPolicyItemRowFilterInfo other = 
(RangerPolicyItemRowFilterInfo) obj;
+                       if (filterExpr == null) {
+                               if (other.filterExpr != null)
+                                       return false;
+                       } else if (!filterExpr.equals(other.filterExpr))
+                               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("filterExpr={").append(filterExpr).append("} 
");
+
+                       sb.append("}");
+
+                       return sb;
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 1dac6e8..0f0e5ee 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
@@ -59,14 +59,15 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
        private List<RangerContextEnricherDef> contextEnrichers = null;
        private List<RangerEnumDef>            enums            = null;
        private RangerDataMaskDef              dataMaskDef      = null;
+       private RangerRowFilterDef             rowFilterDef     = null;
 
 
        public RangerServiceDef() {
-               this(null, null, null, null, null, null, null, null, null, 
null, null, null);
+               this(null, null, null, null, null, null, null, null, null, 
null, null, 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);
+               this(name, implClass, label, description, options, configs, 
resources, accessTypes, policyConditions, contextEnrichers, enums, null, null);
        }
 
        /**
@@ -83,7 +84,7 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
         * @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, 
RangerDataMaskDef dataMaskDef) {
+       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, RangerRowFilterDef rowFilterDef) {
                super();
 
                setName(name);
@@ -98,6 +99,7 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
                setContextEnrichers(contextEnrichers);
                setEnums(enums);
                setDataMaskDef(dataMaskDef);
+               setRowFilterDef(rowFilterDef);
        }
 
        /**
@@ -116,6 +118,7 @@ public class RangerServiceDef extends RangerBaseModelObject 
implements java.io.S
                setPolicyConditions(other.getPolicyConditions());
                setEnums(other.getEnums());
                setDataMaskDef(other.getDataMaskDef());
+               setRowFilterDef(other.getRowFilterDef());
        }
 
        /**
@@ -404,6 +407,14 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                this.dataMaskDef = dataMaskDef == null ? new 
RangerDataMaskDef() : dataMaskDef;
        }
 
+       public RangerRowFilterDef getRowFilterDef() {
+               return rowFilterDef;
+       }
+
+       public void setRowFilterDef(RangerRowFilterDef rowFilterDef) {
+               this.rowFilterDef = rowFilterDef == null ? new 
RangerRowFilterDef() : rowFilterDef;
+       }
+
        @Override
        public String toString( ) {
                StringBuilder sb = new StringBuilder();
@@ -499,6 +510,12 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                }
                sb.append("} ");
 
+               sb.append("rowFilterDef={");
+               if(rowFilterDef != null) {
+                       rowFilterDef.toString(sb);
+               }
+               sb.append("} ");
+
                sb.append("}");
 
                return sb;
@@ -2880,4 +2897,145 @@ 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 RangerRowFilterDef implements java.io.Serializable {
+               private static final long serialVersionUID = 1L;
+
+               private List<RangerAccessTypeDef> accessTypes;
+               private List<RangerResourceDef>   resources;
+
+
+               public RangerRowFilterDef() {
+                       setAccessTypes(null);
+                       setResources(null);
+               }
+
+               public RangerRowFilterDef(List<RangerAccessTypeDef> 
accessTypes, List<RangerResourceDef> resources) {
+                       setAccessTypes(accessTypes);
+                       setResources(resources);
+               }
+
+               public RangerRowFilterDef(RangerRowFilterDef other) {
+                       setAccessTypes(other.getAccessTypes());
+                       setResources(other.getResources());
+               }
+
+               public List<RangerAccessTypeDef> getAccessTypes() {
+                       return accessTypes;
+               }
+
+               public void setAccessTypes(List<RangerAccessTypeDef> 
accessTypes) {
+                       if(this.accessTypes == null) {
+                               this.accessTypes = new 
ArrayList<RangerAccessTypeDef>();
+                       }
+
+                       if(this.accessTypes == accessTypes) {
+                               return;
+                       }
+
+                       this.accessTypes.clear();
+
+                       if(accessTypes != null) {
+                               for(RangerAccessTypeDef accessType : 
accessTypes) {
+                                       this.accessTypes.add(accessType);
+                               }
+                       }
+               }
+
+               public List<RangerResourceDef> getResources() {
+                       return resources;
+               }
+
+               public void setResources(List<RangerResourceDef> resources) {
+                       if(this.resources == null) {
+                               this.resources = new 
ArrayList<RangerResourceDef>();
+                       }
+
+                       if(this.resources == resources) {
+                               return;
+                       }
+
+                       this.resources.clear();
+
+                       if(resources != null) {
+                               for(RangerResourceDef resource : resources) {
+                                       this.resources.add(resource);
+                               }
+                       }
+               }
+
+               @Override
+               public String toString( ) {
+                       StringBuilder sb = new StringBuilder();
+
+                       toString(sb);
+
+                       return sb.toString();
+               }
+
+               public StringBuilder toString(StringBuilder sb) {
+                       sb.append("RangerRowFilterDef={");
+
+                       sb.append("accessTypes={");
+                       if(accessTypes != null) {
+                               for(RangerAccessTypeDef accessType : 
accessTypes) {
+                                       if(accessType != null) {
+                                               
accessType.toString(sb).append(" ");
+                                       }
+                               }
+                       }
+                       sb.append("} ");
+
+                       sb.append("resources={");
+                       if(resources != null) {
+                               for(RangerResourceDef resource : resources) {
+                                       if(resource != null) {
+                                               resource.toString(sb).append(" 
");
+                                       }
+                               }
+                       }
+                       sb.append("} ");
+
+                       sb.append("}");
+
+                       return sb;
+               }
+
+               @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = 1;
+                       result = prime * result + ((accessTypes == null) ? 0 : 
accessTypes.hashCode());
+                       result = prime * result + ((resources == null) ? 0 : 
resources.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;
+                       RangerRowFilterDef other = (RangerRowFilterDef) obj;
+
+                       if (accessTypes == null) {
+                               if (other.accessTypes != null)
+                                       return false;
+                       } else if (!accessTypes.equals(other.accessTypes))
+                               return false;
+                       if (resources == null) {
+                               if (other.resources != null)
+                                       return false;
+                       } else if (!resources.equals(other.resources))
+                               return false;
+                       return true;
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index 101d911..273d61f 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -250,6 +250,12 @@ public class RangerServiceDefHelper {
                                } else {
                                        resourceDefs = null;
                                }
+                       } else if(policyType == 
RangerPolicy.POLICY_TYPE_ROWFILTER) {
+                               if(serviceDef.getRowFilterDef() != null) {
+                                       resourceDefs = 
serviceDef.getRowFilterDef().getResources();
+                               } else {
+                                       resourceDefs = null;
+                               }
                        } else { // unknown policyType; use all resources
                                resourceDefs = serviceDef.getResources();
                        }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 d19e3d0..e5f1132 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
@@ -51,6 +51,8 @@ public interface RangerPolicyEngine {
 
        RangerDataMaskResult evalDataMaskPolicies(RangerAccessRequest request, 
RangerAccessResultProcessor resultProcessor);
 
+       RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest 
request, RangerAccessResultProcessor resultProcessor);
+
        boolean isAccessAllowed(RangerAccessResource resource, String user, 
Set<String> userGroups, String accessType);
 
        boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, 
String user, Set<String> userGroups, String accessType);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 51cab80..e6e9a3a 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
@@ -294,7 +294,7 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                        }
                }
 
-               // no need to audit if filter/mask is not enabled
+               // no need to audit if mask is not enabled
                if(! ret.isMaskEnabled()) {
                        ret.setIsAudited(false);
                }
@@ -311,6 +311,41 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
        }
 
        @Override
+       public RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest 
request, RangerAccessResultProcessor resultProcessor) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerPolicyEngineImpl.evalRowFilterPolicies(" + request + ")");
+               }
+
+               RangerRowFilterResult ret = new 
RangerRowFilterResult(getServiceName(), getServiceDef(), request);
+
+               if(request != null) {
+                       List<RangerPolicyEvaluator> evaluators = 
policyRepository.getRowFilterPolicyEvaluators();
+                       for (RangerPolicyEvaluator evaluator : evaluators) {
+                               evaluator.evaluate(request, ret);
+
+                               if (ret.getIsAccessDetermined() && 
ret.getIsAuditedDetermined()) {
+                                       break;
+                               }
+                       }
+               }
+
+               // no need to audit if filter is not enabled
+               if(! ret.isRowFilterEnabled()) {
+                       ret.setIsAudited(false);
+               }
+
+               if (resultProcessor != null) {
+                       resultProcessor.processResult(ret);
+               }
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerPolicyEngineImpl.evalRowFilterPolicies(" + 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/2c7f617b/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 b1463bc..be98f3b 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
@@ -50,6 +50,7 @@ public class RangerPolicyRepository {
     private List<RangerContextEnricher>       contextEnrichers;
     private List<RangerPolicyEvaluator>       policyEvaluators;
     private List<RangerPolicyEvaluator>       dataMaskPolicyEvaluators;
+    private List<RangerPolicyEvaluator>       rowFilterPolicyEvaluators;
     private final Map<String, Boolean>        accessAuditCache;
 
     private final String                      componentServiceName;
@@ -133,6 +134,10 @@ public class RangerPolicyRepository {
         return dataMaskPolicyEvaluators;
     }
 
+    public List<RangerPolicyEvaluator> getRowFilterPolicyEvaluators() {
+        return rowFilterPolicyEvaluators;
+    }
+
     private RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef 
serviceDef, final String componentType) {
 
         if (serviceDef != null && StringUtils.isNotBlank(componentType)) {
@@ -317,7 +322,8 @@ public class RangerPolicyRepository {
     private void init(RangerPolicyEngineOptions options) {
 
         List<RangerPolicyEvaluator> policyEvaluators = new 
ArrayList<RangerPolicyEvaluator>();
-        List<RangerPolicyEvaluator> dataMaskPolicyEvaluators = new 
ArrayList<RangerPolicyEvaluator>();
+        List<RangerPolicyEvaluator> dataMaskPolicyEvaluators  = new 
ArrayList<RangerPolicyEvaluator>();
+        List<RangerPolicyEvaluator> rowFilterPolicyEvaluators = new 
ArrayList<RangerPolicyEvaluator>();
 
         for (RangerPolicy policy : policies) {
             if (skipBuildingPolicyEvaluator(policy, options)) {
@@ -331,6 +337,8 @@ public class RangerPolicyRepository {
                     policyEvaluators.add(evaluator);
                 } else if(policy.getPolicyType() == 
RangerPolicy.POLICY_TYPE_DATAMASK) {
                     dataMaskPolicyEvaluators.add(evaluator);
+                } else if(policy.getPolicyType() == 
RangerPolicy.POLICY_TYPE_ROWFILTER) {
+                    rowFilterPolicyEvaluators.add(evaluator);
                 } else {
                     LOG.warn("RangerPolicyEngine: ignoring policy id=" + 
policy.getId() + " - invalid policyType '" + policy.getPolicyType() + "'");
                 }
@@ -342,6 +350,9 @@ public class RangerPolicyRepository {
         Collections.sort(dataMaskPolicyEvaluators);
         this.dataMaskPolicyEvaluators = 
Collections.unmodifiableList(dataMaskPolicyEvaluators);
 
+        Collections.sort(rowFilterPolicyEvaluators);
+        this.rowFilterPolicyEvaluators = 
Collections.unmodifiableList(rowFilterPolicyEvaluators);
+
         List<RangerContextEnricher> contextEnrichers = new 
ArrayList<RangerContextEnricher>();
         if (CollectionUtils.isNotEmpty(this.policyEvaluators)) {
             if (!options.disableContextEnrichers && 
!CollectionUtils.isEmpty(serviceDef.getContextEnrichers())) {
@@ -370,13 +381,20 @@ 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");
-
+            LOG.debug("dataMask 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());
+                LOG.debug("dataMask policy evaluation order: #" + (++order) + 
" - policy id=" + policy.getId() + "; name=" + policy.getName() + "; 
evalOrder=" + policyEvaluator.getEvalOrder());
+            }
+
+            LOG.debug("rowFilter policy evaluation order: " + 
this.dataMaskPolicyEvaluators.size() + " policies");
+            order = 0;
+            for(RangerPolicyEvaluator policyEvaluator : 
this.rowFilterPolicyEvaluators) {
+                RangerPolicy policy = policyEvaluator.getPolicy();
+
+                LOG.debug("rowFilter 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/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
new file mode 100644
index 0000000..ad82471
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+
+public class RangerRowFilterResult extends RangerAccessResult {
+       private String filterExpr = null;
+
+
+       public RangerRowFilterResult(final String serviceName, final 
RangerServiceDef serviceDef, final RangerAccessRequest request) {
+               this(serviceName, serviceDef, request, null);
+       }
+
+       public RangerRowFilterResult(final String serviceName, final 
RangerServiceDef serviceDef, final RangerAccessRequest request, final 
RangerPolicy.RangerPolicyItemRowFilterInfo rowFilterInfo) {
+               super(serviceName, serviceDef, request);
+
+               if(rowFilterInfo != null) {
+                       setFilterExpr(rowFilterInfo.getFilterExpr());
+               }
+       }
+
+       /**
+        * @return the filterExpr
+        */
+       public String getFilterExpr() {
+               return filterExpr;
+       }
+
+       /**
+        * @param filterExpr the filterExpr to set
+        */
+       public void setFilterExpr(String filterExpr) {
+               this.filterExpr = filterExpr;
+       }
+
+       public boolean isRowFilterEnabled() {
+               return StringUtils.isNotEmpty(filterExpr);
+       }
+
+       @Override
+       public String toString( ) {
+               StringBuilder sb = new StringBuilder();
+
+               toString(sb);
+
+               return sb.toString();
+       }
+
+       public StringBuilder toString(StringBuilder sb) {
+               sb.append("RangerRowFilterResult={");
+
+               super.toString(sb);
+
+               sb.append("filterExpr={").append(filterExpr).append("} ");
+
+               sb.append("}");
+
+               return sb;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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
index 62d624c..fbd7977 100644
--- 
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
@@ -18,17 +18,11 @@
  */
 package org.apache.ranger.plugin.policyevaluator;
 
-import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
+import 
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
 
 
 public interface RangerDataMaskPolicyItemEvaluator extends 
RangerPolicyItemEvaluator {
        void init();
 
-       RangerDataMaskPolicyItem getPolicyItem();
-
-       String getMaskType();
-
-       String getMaskCondition();
-
-       String getMaskedValue();
+       RangerPolicyItemDataMaskInfo getDataMaskInfo();
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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
index 4583de9..45db7b0 100644
--- 
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
@@ -28,34 +28,16 @@ import 
org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 
 
 public class RangerDefaultDataMaskPolicyItemEvaluator extends 
RangerDefaultPolicyItemEvaluator implements RangerDataMaskPolicyItemEvaluator {
+       final private RangerDataMaskPolicyItem dataMaskPolicyItem;
 
        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();
+               super(serviceDef, policy, policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options);
 
-               return dataMaskInfo != null ? dataMaskInfo.getDataMaskType() : 
null;
+               dataMaskPolicyItem = policyItem;
        }
 
        @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;
+       public RangerPolicyItemDataMaskInfo getDataMaskInfo() {
+               return dataMaskPolicyItem == null ? null : 
dataMaskPolicyItem.getDataMaskInfo();
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 b87891f..2b26218 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
@@ -36,7 +36,10 @@ 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.RangerPolicyItemDataMaskInfo;
+import 
org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
@@ -45,6 +48,7 @@ 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.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
@@ -63,7 +67,8 @@ 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 List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators  = 
null;
+       private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators = 
null;
        private String perfTag;
 
        @Override
@@ -105,13 +110,15 @@ 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());
+                       dataMaskEvaluators       = 
createDataMaskPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
+                       rowFilterEvaluators      = 
createRowFilterPolicyItemEvaluators(policy, serviceDef, options, 
policy.getRowFilterPolicyItems());
                } else {
                        allowEvaluators          = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        denyEvaluators           = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        allowExceptionEvaluators = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        denyExceptionEvaluators  = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                        dataMaskEvaluators       = 
Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
+                       rowFilterEvaluators      = 
Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
                }
 
                Collections.sort(allowEvaluators);
@@ -119,8 +126,9 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                Collections.sort(allowExceptionEvaluators);
                Collections.sort(denyExceptionEvaluators);
 
-               /* dataMask policyItems must be evaulated in the order given in 
the policy; hence no sort
+               /* dataMask, rowFilter policyItems must be evaulated in the 
order given in the policy; hence no sort
                Collections.sort(dataMaskEvaluators);
+               Collections.sort(rowFilterEvaluators);
                */
 
                RangerPerfTracer.log(perf);
@@ -206,63 +214,135 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
         }
     }
 
-    protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerAccessResult result, boolean isResourceMatch) {
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" 
+ request + ", " + result + ", " + isResourceMatch + ")");
-        }
+       @Override
+       public void evaluate(RangerAccessRequest request, RangerDataMaskResult 
result) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" 
+ request + ", " + result + ")");
+               }
 
-        RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators);
+               RangerPerfTracer perf = null;
 
-        if(matchedPolicyItem == null && !result.getIsAllowed()) { // if not 
denied, evaluate allowItems only if not already allowed
-            matchedPolicyItem = getMatchingPolicyItem(request, 
allowEvaluators, allowExceptionEvaluators);
-        }
+               
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.evaluate(requestHashCode=" + 
Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")");
+               }
 
-        if(matchedPolicyItem != null) {
-            RangerPolicy policy = getPolicy();
+               if (request != null && result != null && 
CollectionUtils.isNotEmpty(dataMaskEvaluators)) {
+                       boolean isResourceMatchAttempted     = false;
+                       boolean isResourceMatch              = false;
+                       boolean isResourceHeadMatch          = false;
+                       boolean isResourceHeadMatchAttempted = false;
+                       final boolean attemptResourceHeadMatch = 
request.isAccessTypeAny() || request.getResourceMatchingScope() == 
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
 
-            if(matchedPolicyItem.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
-                if(isResourceMatch) {
-                    result.setIsAllowed(false);
-                    result.setPolicyId(policy.getId());
-                    result.setReason(matchedPolicyItem.getComments());
-                }
-            } else {
-                if(! result.getIsAllowed()) { // if access is not yet allowed 
by another policy
-                    result.setIsAllowed(true);
-                    result.setPolicyId(policy.getId());
-                    result.setReason(matchedPolicyItem.getComments());
-                }
-            }
-        }
+                       if (!result.getIsAuditedDetermined()) {
+                               if (!isResourceMatchAttempted) {
+                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatchAttempted = true;
+                               }
 
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" 
+ request + ", " + result + ", " + isResourceMatch + ")");
-        }
-    }
+                               if (!isResourceMatch) {
+                                       if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatchAttempted = 
true;
+                                       }
+                               }
 
-    protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, 
Set<String> userGroups, String accessType) {
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("==> 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + 
userGroups + ", " + accessType + ")");
-        }
+                               if (isResourceMatch || isResourceHeadMatch) {
+                                       if (isAuditEnabled()) {
+                                               result.setIsAudited(true);
+                                       }
+                               }
+                       }
 
-        RangerPolicyItemEvaluator ret = null;
+                       if (!result.getIsAccessDetermined()) {
+                               if (!isResourceMatchAttempted) {
+                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatchAttempted = true;
+                               }
 
-        /*
-         *  1. if a deny matches without hitting any deny-exception, return 
that
-         *  2. if an allow matches without hitting any allow-exception, return 
that
-         */
-        ret = getMatchingPolicyItem(user, userGroups, accessType, 
denyEvaluators, denyExceptionEvaluators);
+                               if (!isResourceMatch) {
+                                       if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatchAttempted = 
true;
+                                       }
+                               }
 
-        if(ret == null) {
-            ret = getMatchingPolicyItem(user, userGroups, accessType, 
allowEvaluators, allowExceptionEvaluators);
-        }
+                               if (isResourceMatch || isResourceHeadMatch) {
+                                       evaluatePolicyItems(request, result);
+                               }
+                       }
+               }
 
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + 
userGroups + ", " + accessType + "): " + ret);
-        }
+               RangerPerfTracer.log(perf);
 
-        return ret;
-    }
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" 
+ request + ", " + result + ")");
+               }
+       }
+
+       @Override
+       public void evaluate(RangerAccessRequest request, RangerRowFilterResult 
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(rowFilterEvaluators)) {
+                       boolean isResourceMatchAttempted     = false;
+                       boolean isResourceMatch              = false;
+                       boolean isResourceHeadMatch          = false;
+                       boolean isResourceHeadMatchAttempted = false;
+                       final boolean attemptResourceHeadMatch = 
request.isAccessTypeAny() || request.getResourceMatchingScope() == 
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
+
+                       if (!result.getIsAuditedDetermined()) {
+                               if (!isResourceMatchAttempted) {
+                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatchAttempted = true;
+                               }
+
+                               if (!isResourceMatch) {
+                                       if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatchAttempted = 
true;
+                                       }
+                               }
+
+                               if (isResourceMatch || isResourceHeadMatch) {
+                                       if (isAuditEnabled()) {
+                                               result.setIsAudited(true);
+                                       }
+                               }
+                       }
+
+                       if (!result.getIsAccessDetermined()) {
+                               if (!isResourceMatchAttempted) {
+                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatchAttempted = true;
+                               }
+
+                               if (!isResourceMatch) {
+                                       if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatchAttempted = 
true;
+                                       }
+                               }
+
+                               if (isResourceMatch || isResourceHeadMatch) {
+                                       evaluatePolicyItems(request, result);
+                               }
+                       }
+               }
+
+               RangerPerfTracer.log(perf);
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" 
+ request + ", " + result + ")");
+               }
+       }
 
        @Override
        public boolean isMatch(RangerAccessResource resource) {
@@ -419,6 +499,112 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        }
 
 
+       protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerAccessResult result, boolean isResourceMatch) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + isResourceMatch + ")");
+               }
+
+               RangerPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators);
+
+               if(matchedPolicyItem == null && !result.getIsAllowed()) { // if 
not denied, evaluate allowItems only if not already allowed
+                       matchedPolicyItem = getMatchingPolicyItem(request, 
allowEvaluators, allowExceptionEvaluators);
+               }
+
+               if(matchedPolicyItem != null) {
+                       RangerPolicy policy = getPolicy();
+
+                       if(matchedPolicyItem.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
+                               if(isResourceMatch) {
+                                       result.setIsAllowed(false);
+                                       result.setPolicyId(policy.getId());
+                                       
result.setReason(matchedPolicyItem.getComments());
+                               }
+                       } else {
+                               if(! result.getIsAllowed()) { // if access is 
not yet allowed by another policy
+                                       result.setIsAllowed(true);
+                                       result.setPolicyId(policy.getId());
+                                       
result.setReason(matchedPolicyItem.getComments());
+                               }
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + isResourceMatch + ")");
+               }
+       }
+
+       protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerDataMaskResult result) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
")");
+               }
+
+               RangerDataMaskPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, dataMaskEvaluators);
+               RangerPolicyItemDataMaskInfo      dataMaskInfo      = 
matchedPolicyItem != null ? matchedPolicyItem.getDataMaskInfo() : null;
+
+               if(dataMaskInfo != null) {
+                       RangerPolicy policy = getPolicy();
+
+                       result.setIsAllowed(true);
+                       result.setIsAccessDetermined(true);
+
+                       result.setMaskType(dataMaskInfo.getDataMaskType());
+                       
result.setMaskCondition(dataMaskInfo.getConditionExpr());
+                       result.setMaskedValue(dataMaskInfo.getValueExpr());
+                       result.setPolicyId(policy.getId());
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + ")");
+               }
+       }
+
+       protected void evaluatePolicyItems(RangerAccessRequest request, 
RangerRowFilterResult result) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
")");
+               }
+
+               RangerRowFilterPolicyItemEvaluator matchedPolicyItem = 
getMatchingPolicyItem(request, rowFilterEvaluators);
+               RangerPolicyItemRowFilterInfo      rowFilterInfo     = 
matchedPolicyItem != null ? matchedPolicyItem.getRowFilterInfo() : null;
+
+               if(rowFilterInfo != null) {
+                       RangerPolicy policy = getPolicy();
+
+                       result.setIsAllowed(true);
+                       result.setIsAccessDetermined(true);
+
+                       result.setFilterExpr(rowFilterInfo.getFilterExpr());
+                       result.setPolicyId(policy.getId());
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + 
", " + ")");
+               }
+       }
+
+       protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String 
user, Set<String> userGroups, String accessType) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + 
userGroups + ", " + accessType + ")");
+               }
+
+               RangerPolicyItemEvaluator ret = null;
+
+               /*
+                *  1. if a deny matches without hitting any deny-exception, 
return that
+                *  2. if an allow matches without hitting any allow-exception, 
return that
+                */
+               ret = getMatchingPolicyItem(user, userGroups, accessType, 
denyEvaluators, denyExceptionEvaluators);
+
+               if(ret == null) {
+                       ret = getMatchingPolicyItem(user, userGroups, 
accessType, allowEvaluators, allowExceptionEvaluators);
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + 
userGroups + ", " + accessType + "): " + ret);
+               }
+
+               return ret;
+       }
+
        private void getResourceAccessInfo(RangerAccessRequest request, List<? 
extends RangerPolicyItemEvaluator> policyItems, Set<String> users, Set<String> 
groups) {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + 
policyItems + ", " + users + ", " + groups + ")");
@@ -668,6 +854,58 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
+       private List<RangerDataMaskPolicyItemEvaluator> 
createDataMaskPolicyItemEvaluators(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;
+       }
+
+       private List<RangerRowFilterPolicyItemEvaluator> 
createRowFilterPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef 
serviceDef, RangerPolicyEngineOptions options, List<RangerRowFilterPolicyItem> 
policyItems) {
+               List<RangerRowFilterPolicyItemEvaluator> ret = null;
+
+               if(CollectionUtils.isNotEmpty(policyItems)) {
+                       ret = new 
ArrayList<RangerRowFilterPolicyItemEvaluator>();
+
+                       int policyItemCounter = 1;
+
+                       for(RangerRowFilterPolicyItem policyItem : policyItems) 
{
+                               RangerRowFilterPolicyItemEvaluator 
itemEvaluator = new RangerDefaultRowFilterPolicyItemEvaluator(serviceDef, 
policy, policyItem, policyItemCounter++, options);
+
+                               itemEvaluator.init();
+
+                               ret.add(itemEvaluator);
+
+                               
if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
+                                       customConditionsCount += 
itemEvaluator.getConditionEvaluators().size();
+                               }
+                       }
+               } else {
+                       ret = 
Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
+               }
+
+               return ret;
+       }
+
        private boolean isPolicyItemTypeEnabled(RangerServiceDef serviceDef, 
int policyItemType) {
                boolean ret = true;
 
@@ -680,15 +918,21 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
-       private RangerPolicyItemEvaluator 
getMatchingPolicyItem(RangerAccessRequest request, List<? extends 
RangerPolicyItemEvaluator> evaluators, List<? extends 
RangerPolicyItemEvaluator> exceptionEvaluators) {
+       protected <T extends RangerPolicyItemEvaluator> T 
getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators) {
+               T ret = getMatchingPolicyItem(request, evaluators, null);
+
+               return ret;
+       }
+
+       private <T extends RangerPolicyItemEvaluator> T 
getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators, List<T> 
exceptionEvaluators) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> 
RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + ")");
         }
 
-        RangerPolicyItemEvaluator ret = null;
+        T ret = null;
 
         if(CollectionUtils.isNotEmpty(evaluators)) {
-            for (RangerPolicyItemEvaluator evaluator : evaluators) {
+            for (T evaluator : evaluators) {
                 if(evaluator.isMatch(request)) {
                     ret = evaluator;
 
@@ -698,7 +942,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
         }
 
         if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) {
-            for (RangerPolicyItemEvaluator exceptionEvaluator : 
exceptionEvaluators) {
+            for (T exceptionEvaluator : exceptionEvaluators) {
                 if(exceptionEvaluator.isMatch(request)) {
                     if(LOG.isDebugEnabled()) {
                         
LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + "): 
found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); 
ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")");
@@ -718,15 +962,15 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
         return ret;
     }
 
-       private RangerPolicyItemEvaluator getMatchingPolicyItem(String user, 
Set<String> userGroups, String accessType, List<RangerPolicyItemEvaluator> 
evaluators, List<RangerPolicyItemEvaluator> exceptionEvaluators) {
+       private <T extends RangerPolicyItemEvaluator> T 
getMatchingPolicyItem(String user, Set<String> userGroups, String accessType, 
List<T> evaluators, List<T> exceptionEvaluators) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> 
RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups 
+ ", " + accessType + ")");
         }
 
-        RangerPolicyItemEvaluator ret = null;
+        T ret = null;
 
         if(CollectionUtils.isNotEmpty(evaluators)) {
-            for (RangerPolicyItemEvaluator evaluator : evaluators) {
+            for (T evaluator : evaluators) {
                 if(evaluator.matchUserGroup(user, userGroups) && 
evaluator.matchAccessType(accessType)) {
                     ret = evaluator;
 
@@ -736,7 +980,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
         }
 
         if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) {
-            for (RangerPolicyItemEvaluator exceptionEvaluator : 
exceptionEvaluators) {
+            for (T exceptionEvaluator : exceptionEvaluators) {
                 if(exceptionEvaluator.matchUserGroup(user, userGroups) && 
exceptionEvaluator.matchAccessType(accessType)) {
                     if(LOG.isDebugEnabled()) {
                         
LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + 
userGroups + ", " + accessType + "): found exception policyItem(" + 
exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + 
ret.getPolicyItem() + ")");
@@ -771,114 +1015,4 @@ 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/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
new file mode 100644
index 0000000..365661b
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
@@ -0,0 +1,42 @@
+/*
+ * 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.RangerPolicy.RangerPolicyItemRowFilterInfo;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+
+
+public class RangerDefaultRowFilterPolicyItemEvaluator extends 
RangerDefaultPolicyItemEvaluator implements RangerRowFilterPolicyItemEvaluator {
+       final private RangerRowFilterPolicyItem rowFilterPolicyItem;
+
+       public RangerDefaultRowFilterPolicyItemEvaluator(RangerServiceDef 
serviceDef, RangerPolicy policy, RangerRowFilterPolicyItem policyItem, int 
policyItemIndex, RangerPolicyEngineOptions options) {
+               super(serviceDef, policy, policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options);
+
+               rowFilterPolicyItem = policyItem;
+       }
+
+       @Override
+       public RangerPolicyItemRowFilterInfo getRowFilterInfo() {
+               return rowFilterPolicyItem == null ? null : 
rowFilterPolicyItem.getRowFilterInfo();
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 1010727..be97830 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
@@ -32,6 +32,7 @@ import 
org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
 
 
 public interface RangerPolicyEvaluator extends 
Comparable<RangerPolicyEvaluator> {
@@ -59,6 +60,8 @@ public interface RangerPolicyEvaluator extends 
Comparable<RangerPolicyEvaluator>
 
        void evaluate(RangerAccessRequest request, RangerDataMaskResult result);
 
+       void evaluate(RangerAccessRequest request, RangerRowFilterResult 
result);
+
        boolean isMatch(RangerAccessResource resource);
 
        boolean isCompleteMatch(RangerAccessResource resource);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 3c4b926..80e46f5 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,7 +30,8 @@ public interface RangerPolicyItemEvaluator extends 
Comparable<RangerPolicyItemEv
        int POLICY_ITEM_TYPE_DENY             = 1;
        int POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS = 2;
        int POLICY_ITEM_TYPE_DENY_EXCEPTIONS  = 3;
-       int POLICY_ITEM_TYPE_DATA_MASKING     = 4;
+       int POLICY_ITEM_TYPE_DATAMASK         = 4;
+       int POLICY_ITEM_TYPE_ROWFILTER        = 5;
 
        void init();
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
new file mode 100644
index 0000000..c108e4f
--- /dev/null
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
@@ -0,0 +1,28 @@
+/*
+ * 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.RangerPolicyItemRowFilterInfo;
+
+
+public interface RangerRowFilterPolicyItemEvaluator extends 
RangerPolicyItemEvaluator {
+       void init();
+
+       RangerPolicyItemRowFilterInfo getRowFilterInfo();
+}

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

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
index b154115..478ea0c 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
@@ -451,7 +451,9 @@ public class AbstractPredicateUtil {
                                        List<?>[] policyItemsList = new 
List<?>[] { policy.getPolicyItems(),
                                                                                
                                                policy.getDenyPolicyItems(),
                                                                                
                                                policy.getAllowExceptions(),
-                                                                               
                                                policy.getDenyExceptions()
+                                                                               
                                                policy.getDenyExceptions(),
+                                                                               
                                                policy.getDataMaskPolicyItems(),
+                                                                               
                                                policy.getRowFilterPolicyItems()
                                                                                
                                          };
 
                                        for(List<?> policyItemsObj : 
policyItemsList) {
@@ -501,7 +503,9 @@ public class AbstractPredicateUtil {
                                        List<?>[] policyItemsList = new 
List<?>[] { policy.getPolicyItems(),
                                                        
policy.getDenyPolicyItems(),
                                                        
policy.getAllowExceptions(),
-                                                       
policy.getDenyExceptions()
+                                                       
policy.getDenyExceptions(),
+                                                       
policy.getDataMaskPolicyItems(),
+                                                       
policy.getRowFilterPolicyItems()
                                                  };
 
                                        for(List<?> policyItemsObj : 
policyItemsList) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index 34f4cc6..eaf60b7 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -68,6 +68,7 @@ public class ServiceDefUtil {
 
     public static RangerServiceDef normalize(RangerServiceDef serviceDef) {
         normalizeDataMaskDef(serviceDef);
+        normalizeRowFilterDef(serviceDef);
 
         return serviceDef;
     }
@@ -119,6 +120,53 @@ public class ServiceDefUtil {
         }
     }
 
+    private static void normalizeRowFilterDef(RangerServiceDef serviceDef) {
+        if(serviceDef != null && serviceDef.getRowFilterDef() != null) {
+            List<RangerResourceDef>   rowFilterResources   = 
serviceDef.getRowFilterDef().getResources();
+            List<RangerAccessTypeDef> rowFilterAccessTypes = 
serviceDef.getRowFilterDef().getAccessTypes();
+
+            if(CollectionUtils.isNotEmpty(rowFilterResources)) {
+                List<RangerResourceDef> resources     = 
serviceDef.getResources();
+                List<RangerResourceDef> processedDefs = new 
ArrayList<RangerResourceDef>(rowFilterResources.size());
+
+                for(RangerResourceDef rowFilterResource : rowFilterResources) {
+                    RangerResourceDef processedDef = rowFilterResource;
+
+                    for(RangerResourceDef resourceDef : resources) {
+                        if(StringUtils.equals(resourceDef.getName(), 
rowFilterResource.getName())) {
+                            processedDef = 
ServiceDefUtil.mergeResourceDef(resourceDef, rowFilterResource);
+                            break;
+                        }
+                    }
+
+                    processedDefs.add(processedDef);
+                }
+
+                serviceDef.getRowFilterDef().setResources(processedDefs);
+            }
+
+            if(CollectionUtils.isNotEmpty(rowFilterAccessTypes)) {
+                List<RangerAccessTypeDef> accessTypes   = 
serviceDef.getAccessTypes();
+                List<RangerAccessTypeDef> processedDefs = new 
ArrayList<RangerAccessTypeDef>(accessTypes.size());
+
+                for(RangerAccessTypeDef rowFilterAccessType : 
rowFilterAccessTypes) {
+                    RangerAccessTypeDef processedDef = rowFilterAccessType;
+
+                    for(RangerAccessTypeDef accessType : accessTypes) {
+                        if(StringUtils.equals(accessType.getName(), 
rowFilterAccessType.getName())) {
+                            processedDef = 
ServiceDefUtil.mergeAccessTypeDef(accessType, rowFilterAccessType);
+                            break;
+                        }
+                    }
+
+                    processedDefs.add(processedDef);
+                }
+
+                serviceDef.getRowFilterDef().setAccessTypes(processedDefs);
+            }
+        }
+    }
+
     private static RangerResourceDef mergeResourceDef(RangerResourceDef base, 
RangerResourceDef delta) {
         RangerResourceDef ret = new RangerResourceDef(base);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json 
b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
index f3c75d1..8cdf273 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
@@ -223,7 +223,6 @@
                "description": "List of Hive resources"
          }
        ],
-
        "dataMaskDef": {
                "accessTypes": [
                        {
@@ -347,7 +346,7 @@
                        },
                        {
                                "itemId": 10,
-                               "name": "MASK_DATE_YEAR",
+                               "name": "MASK_DATE_SHOW_YEAR",
                                "label": "Date: show only year",
                                "description": "Date: show only year",
                                "transformer": 
"org.apache.ranger.authorization.hive.udf.MaskTransformer",
@@ -368,5 +367,32 @@
                                "description": "No masking"
                        }
                ]
+       },
+       "rowFilterDef": {
+               "accessTypes": [
+                       {
+                               "name": "select"
+                       }
+               ],
+               "resources": [
+                       {
+                               "name": "database",
+                               "matcherOptions": {
+                                       "wildCard": "false"
+                               },
+                               "lookupSupported": true,
+                               "mandatory": true,
+                               "uiHint": "{ \"singleValue\":true }"
+                       },
+                       {
+                               "name": "table",
+                               "matcherOptions": {
+                                       "wildCard": "false"
+                               },
+                               "lookupSupported": true,
+                               "mandatory": true,
+                               "uiHint": "{ \"singleValue\":true }"
+                       }
+               ]
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/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 05cbcde..8ee6bea 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
@@ -203,7 +203,7 @@ public class TestPolicyEngine {
 
        @Test
        public void testPolicyEngine_hiveMasking() {
-               String[] resourceFiles = { 
"/policyengine/test_policyengine_hive_masking.json" };
+               String[] resourceFiles = 
{"/policyengine/test_policyengine_hive_mask_filter.json"};
 
                runTestsFromResourceFiles(resourceFiles);
        }
@@ -339,6 +339,15 @@ public class TestPolicyEngine {
                                assertEquals("policyId mismatched! - " + 
test.name, expected.getPolicyId(), result.getPolicyId());
                        }
 
+                       if(test.rowFilterResult != null) {
+                               RangerRowFilterResult expected = 
test.rowFilterResult;
+                               RangerRowFilterResult result   = 
policyEngine.evalRowFilterPolicies(request, auditHandler);
+
+                               assertNotNull("result was null! - " + 
test.name, result);
+                               assertEquals("filterExpr mismatched! - " + 
test.name, expected.getFilterExpr(), result.getFilterExpr());
+                               assertEquals("policyId mismatched! - " + 
test.name, expected.getPolicyId(), result.getPolicyId());
+                       }
+
                        if(test.resourceAccessInfo != null) {
                                RangerResourceAccessInfo expected = new 
RangerResourceAccessInfo(test.resourceAccessInfo);
                                RangerResourceAccessInfo result   = 
policyEngine.getResourceAccessInfo(test.request);
@@ -363,7 +372,8 @@ public class TestPolicyEngine {
                        public String              name;
                        public RangerAccessRequest request;
                        public RangerAccessResult  result;
-                       public RangerDataMaskResult dataMaskResult;
+                       public RangerDataMaskResult  dataMaskResult;
+                       public RangerRowFilterResult rowFilterResult;
                        public RangerResourceAccessInfo resourceAccessInfo;
                }
 

Reply via email to