You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by co...@apache.org on 2016/04/22 08:28:21 UTC

[01/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Repository: sentry
Updated Branches:
  refs/heads/master 6d79016aa -> d94e900af


http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index 9e41a33..f680bc7 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -18,8 +18,8 @@
 
 package org.apache.sentry.provider.db.service.persistent;
 
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -47,9 +47,9 @@ import javax.jdo.Transaction;
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.SentryUserException;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
-import org.apache.sentry.policy.common.PolicyConstants;
 import org.apache.sentry.provider.db.SentryAccessDeniedException;
 import org.apache.sentry.provider.db.SentryAlreadyExistsException;
 import org.apache.sentry.provider.db.SentryGrantDeniedException;
@@ -1461,7 +1461,7 @@ public class SentryStore {
     if (!isNULL(privilege.getAction())
         && !privilege.getAction().equalsIgnoreCase(AccessConstants.ALL)) {
       authorizable
-      .add(KV_JOINER.join(PolicyConstants.PRIVILEGE_NAME.toLowerCase(),
+      .add(KV_JOINER.join(SentryConstants.PRIVILEGE_NAME.toLowerCase(),
           privilege.getAction()));
     }
     return AUTHORIZABLE_JOINER.join(authorizable);

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
index fa7fc6e..c229374 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/CommandUtil.java
@@ -18,8 +18,8 @@
 package org.apache.sentry.provider.db.tools.command.hive;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.sentry.policy.common.KeyValue;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.utils.KeyValue;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
@@ -32,7 +32,7 @@ public class CommandUtil {
   // parse the privilege in String and get the TSentryPrivilege as result
   public static TSentryPrivilege convertToTSentryPrivilege(String privilegeStr) throws Exception {
     TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
       KeyValue tempKV = new KeyValue(authorizable);
       String key = tempKV.getKey();
       String value = tempKV.getValue();

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
index d990ef3..f671322 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/tools/command/hive/ListPrivilegesCmd.java
@@ -19,7 +19,7 @@ package org.apache.sentry.provider.db.tools.command.hive;
 
 import com.google.common.collect.Lists;
 import org.apache.commons.lang.StringUtils;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
 import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
@@ -64,34 +64,34 @@ public class ListPrivilegesCmd implements Command {
       String grantOption = (tSentryPrivilege.getGrantOption() == TSentryGrantOption.TRUE ? "true"
               : "false");
       if (!StringUtils.isEmpty(serverName)) {
-        privileges.add(PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME,
+        privileges.add(SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME,
                 serverName));
         if (!StringUtils.isEmpty(uri)) {
-          privileges.add(PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME,
+          privileges.add(SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME,
                   uri));
         } else if (!StringUtils.isEmpty(dbName)) {
-          privileges.add(PolicyConstants.KV_JOINER.join(
+          privileges.add(SentryConstants.KV_JOINER.join(
                   PolicyFileConstants.PRIVILEGE_DATABASE_NAME, dbName));
           if (!StringUtils.isEmpty(tableName)) {
-            privileges.add(PolicyConstants.KV_JOINER.join(
+            privileges.add(SentryConstants.KV_JOINER.join(
                     PolicyFileConstants.PRIVILEGE_TABLE_NAME, tableName));
             if (!StringUtils.isEmpty(columnName)) {
-              privileges.add(PolicyConstants.KV_JOINER.join(
+              privileges.add(SentryConstants.KV_JOINER.join(
                       PolicyFileConstants.PRIVILEGE_COLUMN_NAME, columnName));
             }
           }
         }
         if (!StringUtils.isEmpty(action)) {
-          privileges.add(PolicyConstants.KV_JOINER.join(
+          privileges.add(SentryConstants.KV_JOINER.join(
                   PolicyFileConstants.PRIVILEGE_ACTION_NAME, action));
         }
       }
       // only append the grant option to privilege string if it's true
       if ("true".equals(grantOption)) {
-        privileges.add(PolicyConstants.KV_JOINER.join(
+        privileges.add(SentryConstants.KV_JOINER.join(
                 PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
       }
     }
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(privileges);
+    return SentryConstants.AUTHORIZABLE_JOINER.join(privileges);
   }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
index 1da17ee..ae847eb 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/service/thrift/SentryServiceUtil.java
@@ -23,8 +23,8 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.sentry.policy.common.KeyValue;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.utils.KeyValue;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
 import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
@@ -37,7 +37,7 @@ public class SentryServiceUtil {
   // parse the privilege in String and get the TSentryPrivilege as result
   public static TSentryPrivilege convertToTSentryPrivilege(String privilegeStr) {
     TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
       KeyValue tempKV = new KeyValue(authorizable);
       String key = tempKV.getKey();
       String value = tempKV.getValue();
@@ -74,7 +74,7 @@ public class SentryServiceUtil {
     if (StringUtils.isEmpty(objectPath)) {
       return objectMap;
     }
-    for (String kvStr : PolicyConstants.AUTHORIZABLE_SPLITTER.split(objectPath)) {
+    for (String kvStr : SentryConstants.AUTHORIZABLE_SPLITTER.split(objectPath)) {
       KeyValue kv = new KeyValue(kvStr);
       String key = kv.getKey();
       String value = kv.getValue();
@@ -120,34 +120,34 @@ public class SentryServiceUtil {
       String grantOption = (tSentryPrivilege.getGrantOption() == TSentryGrantOption.TRUE ? "true"
           : "false");
       if (!StringUtils.isEmpty(serverName)) {
-        privileges.add(PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME,
+        privileges.add(SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_SERVER_NAME,
             serverName));
         if (!StringUtils.isEmpty(uri)) {
-          privileges.add(PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME,
+          privileges.add(SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_URI_NAME,
               uri));
         } else if (!StringUtils.isEmpty(dbName)) {
-          privileges.add(PolicyConstants.KV_JOINER.join(
+          privileges.add(SentryConstants.KV_JOINER.join(
               PolicyFileConstants.PRIVILEGE_DATABASE_NAME, dbName));
           if (!StringUtils.isEmpty(tableName)) {
-            privileges.add(PolicyConstants.KV_JOINER.join(
+            privileges.add(SentryConstants.KV_JOINER.join(
                 PolicyFileConstants.PRIVILEGE_TABLE_NAME, tableName));
             if (!StringUtils.isEmpty(columnName)) {
-              privileges.add(PolicyConstants.KV_JOINER.join(
+              privileges.add(SentryConstants.KV_JOINER.join(
                   PolicyFileConstants.PRIVILEGE_COLUMN_NAME, columnName));
             }
           }
         }
         if (!StringUtils.isEmpty(action)) {
-          privileges.add(PolicyConstants.KV_JOINER.join(
+          privileges.add(SentryConstants.KV_JOINER.join(
               PolicyFileConstants.PRIVILEGE_ACTION_NAME, action));
         }
       }
       // only append the grant option to privilege string if it's true
       if ("true".equals(grantOption)) {
-        privileges.add(PolicyConstants.KV_JOINER.join(
+        privileges.add(SentryConstants.KV_JOINER.join(
             PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
       }
     }
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(privileges);
+    return SentryConstants.AUTHORIZABLE_JOINER.join(privileges);
   }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
index 7d25ae1..d49bc57 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/generic/tools/TestSentryShellKafka.java
@@ -22,7 +22,7 @@ import com.google.common.collect.Sets;
 import com.google.common.io.Files;
 import org.apache.commons.io.FileUtils;
 import org.apache.sentry.SentryUserException;
-import org.apache.sentry.policy.kafka.KafkaPrivilegeValidator;
+import org.apache.sentry.core.model.kafka.validator.KafkaPrivilegeValidator;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceIntegrationBase;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryPrivilege;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryRole;

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
index 8d8f28c..865f66e 100644
--- a/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
+++ b/sentry-provider/sentry-provider-db/src/test/java/org/apache/sentry/provider/db/service/thrift/TestSentryServiceImportExport.java
@@ -25,7 +25,7 @@ import static org.junit.Assert.fail;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.service.thrift.SentryServiceIntegrationBase;
 import org.junit.Before;
@@ -696,8 +696,8 @@ public class TestSentryServiceImportExport extends SentryServiceIntegrationBase
       for (String actualPrivilege : actualPrivileges) {
         boolean isFound = exceptedPrivileges.contains(actualPrivilege);
         if (!isFound) {
-          String withOptionPrivilege = PolicyConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
-              PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
+          String withOptionPrivilege = SentryConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
+              SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
                   "false"));
           isFound = exceptedPrivileges.contains(withOptionPrivilege);
         }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupMappingService.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupMappingService.java b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupMappingService.java
index fed1195..72e219d 100644
--- a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupMappingService.java
+++ b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupMappingService.java
@@ -26,7 +26,7 @@ import java.util.Set;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.GroupMappingService;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.common.SentryGroupNotFoundException;
@@ -111,7 +111,7 @@ public class LocalGroupMappingService implements GroupMappingService {
             " in the " + resourcePath);
         continue;
       }
-      Set<String> groupList = Sets.newHashSet(PolicyConstants.ROLE_SPLITTER.trimResults().split(
+      Set<String> groupList = Sets.newHashSet(SentryConstants.ROLE_SPLITTER.trimResults().split(
           groupNames));
       LOGGER.debug("Got user mapping: " + userName + ", Groups: " + groupNames);
       groupMap.put(userName, groupList);

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupResourceAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupResourceAuthorizationProvider.java b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupResourceAuthorizationProvider.java
index 489daf4..a9e7836 100644
--- a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupResourceAuthorizationProvider.java
+++ b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/LocalGroupResourceAuthorizationProvider.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
 
@@ -28,11 +29,13 @@ import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
 public class LocalGroupResourceAuthorizationProvider extends
   ResourceAuthorizationProvider {
 
-  public LocalGroupResourceAuthorizationProvider(String resource, PolicyEngine policy) throws IOException {
-    super(policy, new LocalGroupMappingService(new Path(resource)));
+  public LocalGroupResourceAuthorizationProvider(String resource, PolicyEngine policy,
+      Model model) throws IOException {
+    super(policy, new LocalGroupMappingService(new Path(resource)), model);
   }
 
-  public LocalGroupResourceAuthorizationProvider(Configuration conf, String resource, PolicyEngine policy) throws IOException {
-    super(policy, new LocalGroupMappingService(conf, new Path(resource)));
+  public LocalGroupResourceAuthorizationProvider(Configuration conf, String resource, PolicyEngine policy,
+      Model model) throws IOException {
+    super(policy, new LocalGroupMappingService(conf, new Path(resource)), model);
   }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
index 8924657..91fd4a3 100644
--- a/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
+++ b/sentry-provider/sentry-provider-file/src/main/java/org/apache/sentry/provider/file/SimpleFileProviderBackend.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sentry.provider.file;
 
-import static org.apache.sentry.policy.common.PolicyConstants.ROLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.ROLE_SPLITTER;
 
 import java.io.IOException;
 import java.net.URI;
@@ -34,8 +34,8 @@ import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.SentryConfigurationException;
 import org.apache.sentry.policy.common.PrivilegeUtils;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.common.ProviderBackendContext;

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-solr/solr-sentry-handlers/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-solr/solr-sentry-handlers/pom.xml b/sentry-solr/solr-sentry-handlers/pom.xml
index 7dae417..4073359 100644
--- a/sentry-solr/solr-sentry-handlers/pom.xml
+++ b/sentry-solr/solr-sentry-handlers/pom.xml
@@ -67,10 +67,6 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-search</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
       <artifactId>solr-sentry-core</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-tests/sentry-tests-hive/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/pom.xml b/sentry-tests/sentry-tests-hive/pom.xml
index 44b5b7e..9d2ef76 100644
--- a/sentry-tests/sentry-tests-hive/pom.xml
+++ b/sentry-tests/sentry-tests-hive/pom.xml
@@ -244,11 +244,6 @@ limitations under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-db</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-minicluster</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
index 8515a2b..cb5039b 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -16,9 +16,9 @@
  */
 package org.apache.sentry.tests.e2e.hive;
 
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-import static org.apache.sentry.policy.common.PolicyConstants.ROLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+import static org.apache.sentry.core.common.utils.SentryConstants.ROLE_SPLITTER;
 
 import java.io.File;
 import java.io.IOException;
@@ -49,7 +49,7 @@ import org.apache.sentry.binding.hive.SentryHiveAuthorizationTaskFactoryImpl;
 import org.apache.sentry.binding.metastore.SentryMetastorePostEventListener;
 import org.apache.sentry.core.model.db.DBModelAction;
 import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.policy.db.DBModelAuthorizables;
+import org.apache.sentry.core.model.db.DBModelAuthorizables;
 import org.apache.sentry.provider.db.SimpleDBProviderBackend;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
 import org.apache.sentry.provider.file.PolicyFile;

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
index 985f969..d1a34a8 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPerDBConfiguration.java
@@ -26,7 +26,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 
-import org.apache.sentry.policy.db.SimpleDBPolicyEngine;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.file.PolicyFile;
 import org.junit.After;
 import org.junit.Before;
@@ -116,7 +116,7 @@ public class TestPerDBConfiguration extends AbstractTestWithStaticConfiguration
   @After
   public void teardown() throws Exception {
     // one test turns this on so let's disable it in the teardown method
-    System.setProperty(SimpleDBPolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "false");
+    System.setProperty(SentryConstants.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "false");
   }
 
   @Test
@@ -261,7 +261,7 @@ public class TestPerDBConfiguration extends AbstractTestWithStaticConfiguration
     // ugly hack: needs to go away once this becomes a config property. Note that this property
     // will not be set with external HS and this test will fail. Hope is this fix will go away
     // by then.
-    System.setProperty(SimpleDBPolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "true");
+    System.setProperty(SentryConstants.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "true");
     // test execution
     Connection connection = context.createConnection(USER1_1);
     Statement statement = context.createStatement(connection);
@@ -290,11 +290,11 @@ public class TestPerDBConfiguration extends AbstractTestWithStaticConfiguration
     context.assertAuthzException(statement, "USE "  + DB1);
 
     // once we disable this property all queries should fail
-    System.setProperty(SimpleDBPolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "false");
+    System.setProperty(SentryConstants.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "false");
     context.assertAuthzException(statement, "USE "  + DB2);
 
     // re-enable for clean
-    System.setProperty(SimpleDBPolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "true");
+    System.setProperty(SentryConstants.ACCESS_ALLOW_URI_PER_DB_POLICYFILE, "true");
 
     statement.close();
     connection.close();

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
index 3f3daf5..0d09afd 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestPolicyImportExport.java
@@ -28,7 +28,7 @@ import java.util.Set;
 import org.apache.sentry.binding.hive.SentryPolicyFileFormatFactory;
 import org.apache.sentry.binding.hive.SentryPolicyFileFormatter;
 import org.apache.sentry.binding.hive.authz.SentryConfigTool;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -217,8 +217,8 @@ public class TestPolicyImportExport extends AbstractTestWithStaticConfiguration
       for (String actualPrivilege : actualPrivileges) {
         boolean isFound = exceptedPrivileges.contains(actualPrivilege);
         if (!isFound) {
-          String withOptionPrivilege = PolicyConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
-              PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
+          String withOptionPrivilege = SentryConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
+              SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
                   "false"));
           isFound = exceptedPrivileges.contains(withOptionPrivilege);
         }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/SentryPolicyProviderForDb.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/SentryPolicyProviderForDb.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/SentryPolicyProviderForDb.java
index 2507f83..1302316 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/SentryPolicyProviderForDb.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/SentryPolicyProviderForDb.java
@@ -16,9 +16,9 @@
  */
 package org.apache.sentry.tests.e2e.metastore;
 
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-import static org.apache.sentry.policy.common.PolicyConstants.ROLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+import static org.apache.sentry.core.common.utils.SentryConstants.ROLE_SPLITTER;
 
 import java.io.File;
 import java.io.IOException;
@@ -31,7 +31,7 @@ import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.core.model.db.DBModelAction;
 import org.apache.sentry.core.model.db.DBModelAuthorizable;
 import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
-import org.apache.sentry.policy.db.DBModelAuthorizables;
+import org.apache.sentry.core.model.db.DBModelAuthorizables;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
 import org.apache.sentry.provider.db.service.thrift.TSentryRole;
 import org.apache.sentry.provider.file.PolicyFile;


[06/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestCommonPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestCommonPrivilege.java b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestCommonPrivilege.java
new file mode 100644
index 0000000..3f60b19
--- /dev/null
+++ b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestCommonPrivilege.java
@@ -0,0 +1,147 @@
+/*
+ * 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.sentry.policy.common;
+
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.junit.Before;
+import org.junit.Test;
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertFalse;
+
+public class TestCommonPrivilege {
+
+  private Model testModel;
+
+  @Before
+  public void prepareData() {
+    testModel = new ModelForTest();
+  }
+
+  @Test
+  public void testCreateCommonPrivilege() throws Exception {
+    String privilegeHiveStr = "server=server1->db=db1->table=table1->column=column1->action=select";
+    String privilegeSolrStr = "server=server1->collection=col1->action=update";
+    String privilegeSqoopStr = "server=server1->link=link1->action=read";
+
+    CommonPrivilege privilegeHive = new CommonPrivilege(privilegeHiveStr);
+    CommonPrivilege privilegeSolr = new CommonPrivilege(privilegeSolrStr);
+    CommonPrivilege privilegeSqoop = new CommonPrivilege(privilegeSqoopStr);
+
+    List<KeyValue> keyValues = privilegeHive.getParts();
+    assertEquals(5, keyValues.size());
+    // test the value and the order
+    assertEquals("server", keyValues.get(0).getKey());
+    assertEquals("server1", keyValues.get(0).getValue());
+    assertEquals("db", keyValues.get(1).getKey());
+    assertEquals("db1", keyValues.get(1).getValue());
+    assertEquals("table", keyValues.get(2).getKey());
+    assertEquals("table1", keyValues.get(2).getValue());
+    assertEquals("column", keyValues.get(3).getKey());
+    assertEquals("column1", keyValues.get(3).getValue());
+    assertEquals("action", keyValues.get(4).getKey());
+    assertEquals("select", keyValues.get(4).getValue());
+
+    keyValues = privilegeSolr.getParts();
+    assertEquals(3, keyValues.size());
+    assertEquals("server", keyValues.get(0).getKey());
+    assertEquals("server1", keyValues.get(0).getValue());
+    assertEquals("collection", keyValues.get(1).getKey());
+    assertEquals("col1", keyValues.get(1).getValue());
+    assertEquals("action", keyValues.get(2).getKey());
+    assertEquals("update", keyValues.get(2).getValue());
+
+    keyValues = privilegeSqoop.getParts();
+    assertEquals(3, keyValues.size());
+    assertEquals("server", keyValues.get(0).getKey());
+    assertEquals("server1", keyValues.get(0).getValue());
+    assertEquals("link", keyValues.get(1).getKey());
+    assertEquals("link1", keyValues.get(1).getValue());
+    assertEquals("action", keyValues.get(2).getKey());
+    assertEquals("read", keyValues.get(2).getValue());
+  }
+
+  @Test
+  public void testImplyCommonPrivilegeWithoutAction() throws Exception {
+
+    CommonPrivilege requestPrivilege = new CommonPrivilege("server=server1->db=db1->table=table1");
+    CommonPrivilege privilegForTest1 = new CommonPrivilege("server=server1->db=db1->table=table1");
+    CommonPrivilege privilegForTest2 = new CommonPrivilege("server=server1->db=db1");
+    CommonPrivilege privilegForTest3 = new CommonPrivilege("server=server1->db=db1->table=table2");
+    CommonPrivilege privilegForTest4 = new CommonPrivilege("server=server1->db=db1->table=table1->column=col1");
+    CommonPrivilege privilegForTest5 = new CommonPrivilege("server=server1->db=db1->table=table1->column=*");
+
+    assertTrue(privilegForTest1.implies(requestPrivilege, testModel));
+    assertTrue(privilegForTest2.implies(requestPrivilege, testModel));
+    assertFalse(privilegForTest3.implies(requestPrivilege, testModel));
+    assertFalse(privilegForTest4.implies(requestPrivilege, testModel));
+    assertTrue(privilegForTest5.implies(requestPrivilege, testModel));
+  }
+
+  @Test
+  public void testImplyCommonPrivilegeWithUrl() throws Exception {
+
+    CommonPrivilege requestPrivilege = new CommonPrivilege("server=server1->uri=hdfs:///url/for/request");
+    CommonPrivilege privilegForTest1 = new CommonPrivilege("server=server1->uri=hdfs:///url");
+    CommonPrivilege privilegForTest2 = new CommonPrivilege("server=server1->uri=hdfs:///url/for/request");
+    CommonPrivilege privilegForTest3 = new CommonPrivilege("server=server1->uri=hdfs:///url/unvalid/for/request");
+
+    assertTrue(privilegForTest1.implies(requestPrivilege, testModel));
+    assertTrue(privilegForTest2.implies(requestPrivilege, testModel));
+    assertFalse(privilegForTest3.implies(requestPrivilege, testModel));
+  }
+
+  @Test
+  public void testImplyCommonPrivilegeForAction() throws Exception {
+    CommonPrivilege privilegForSelect = new CommonPrivilege("server=server1->db=db1->table=table1->action=select");
+    CommonPrivilege privilegForInsert = new CommonPrivilege("server=server1->db=db1->table=table1->action=insert");
+    CommonPrivilege privilegForAll = new CommonPrivilege("server=server1->db=db1->table=table1->action=all");
+
+    // the privilege should imply itself
+    assertTrue(privilegForSelect.implies(privilegForSelect, testModel));
+    assertTrue(privilegForInsert.implies(privilegForInsert, testModel));
+    assertTrue(privilegForAll.implies(privilegForAll, testModel));
+
+    // do the imply with the different action based on operate &
+    assertFalse(privilegForInsert.implies(privilegForSelect, testModel));
+    assertTrue(privilegForAll.implies(privilegForSelect, testModel));
+
+    assertFalse(privilegForSelect.implies(privilegForInsert, testModel));
+    assertTrue(privilegForAll.implies(privilegForInsert, testModel));
+
+    assertFalse(privilegForSelect.implies(privilegForAll, testModel));
+    assertFalse(privilegForInsert.implies(privilegForAll, testModel));
+  }
+
+  @Test
+  public void testImplyStringCaseSensitive() throws Exception {
+    CommonPrivilege privileg1 = new CommonPrivilege("server=server1->db=db1->table=table1->column=col1->action=select");
+    CommonPrivilege privileg2 = new CommonPrivilege("server=server1->db=db1->table=table1->column=CoL1->action=select");
+    CommonPrivilege privileg3 = new CommonPrivilege("server=SERver1->db=Db1->table=TAbLe1->column=col1->action=select");
+    CommonPrivilege privileg4 = new CommonPrivilege("SERVER=server1->DB=db1->TABLE=table1->COLUMN=col1->ACTION=select");
+
+    // column is case sensitive
+    assertFalse(privileg1.implies(privileg2, testModel));
+    // server, db, table is case insensitive
+    assertTrue(privileg1.implies(privileg3, testModel));
+    // key in privilege is case insensitive
+    assertTrue(privileg1.implies(privileg4, testModel));
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestKeyValue.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestKeyValue.java b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestKeyValue.java
deleted file mode 100644
index 0ab6569..0000000
--- a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/TestKeyValue.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.sentry.policy.common;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-
-import org.junit.Test;
-
-public class TestKeyValue {
-
-  @Test
-  public void testWithSeparators() throws Exception {
-    KeyValue kv = new KeyValue("URI=/u/h/w/t/partition=value/");
-    assertEquals("URI", kv.getKey());
-    assertEquals("/u/h/w/t/partition=value/", kv.getValue());
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    new KeyValue(KV_JOINER.join("", "b"));
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    new KeyValue(KV_JOINER.join("a", ""));
-  }
-
-  @Test
-  public void testOneParameterConstructor() throws Exception {
-    KeyValue kv1 = new KeyValue(KV_JOINER.join("k1", "v1"));
-    KeyValue kv2 = new KeyValue(KV_JOINER.join("k1", "v1"));
-    KeyValue kv3 = new KeyValue(KV_JOINER.join("k2", "v2"));
-    doTest(kv1, kv2, kv3);
-  }
-
-  @Test
-  public void testTwoParameterConstructor() throws Exception {
-    KeyValue kv1 = new KeyValue("k1", "v1");
-    KeyValue kv2 = new KeyValue("k1", "v1");
-    KeyValue kv3 = new KeyValue("k2", "v2");
-    doTest(kv1, kv2, kv3);
-  }
-
-  private void doTest(KeyValue kv1, KeyValue kv2, KeyValue kv3) {
-    assertEquals(kv1, kv2);
-    assertFalse(kv1.equals(kv3));
-
-    assertEquals(kv1.toString(), kv2.toString());
-    assertFalse(kv1.toString().equals(kv3.toString()));
-
-    assertEquals(kv1.hashCode(), kv2.hashCode());
-    assertFalse(kv1.hashCode() == kv3.hashCode());
-
-    assertEquals(kv1.getKey(), kv2.getKey());
-    assertFalse(kv1.getKey().equals(kv3.getKey()));
-
-    assertEquals(kv1.getValue(), kv2.getValue());
-    assertFalse(kv1.getValue().equals(kv3.getValue()));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/pom.xml b/sentry-policy/sentry-policy-db/pom.xml
deleted file mode 100644
index 56206dc..0000000
--- a/sentry-policy/sentry-policy-db/pom.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0"?>
-<!--
-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.
--->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.sentry</groupId>
-    <artifactId>sentry-policy</artifactId>
-    <version>1.8.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>sentry-policy-db</artifactId>
-  <name>Sentry Policy for Databases</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-minicluster</artifactId>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.shiro</groupId>
-      <artifactId>shiro-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hive</groupId>
-      <artifactId>hive-beeline</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-core-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-core-model-db</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-file</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-common</artifactId>
-      <scope>test</scope>
-      <type>test-jar</type>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/AbstractDBPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/AbstractDBPrivilegeValidator.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/AbstractDBPrivilegeValidator.java
deleted file mode 100644
index 8bd311a..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/AbstractDBPrivilegeValidator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.shiro.config.ConfigurationException;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-
-public abstract class AbstractDBPrivilegeValidator implements PrivilegeValidator {
-
-  @VisibleForTesting
-  public static Iterable<DBModelAuthorizable> parsePrivilege(String string) {
-    List<DBModelAuthorizable> result = Lists.newArrayList();
-    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
-      // XXX this ugly hack is because action is not an authorizeable
-      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
-        DBModelAuthorizable authorizable = DBModelAuthorizables.from(section);
-        if(authorizable == null) {
-          String msg = "No authorizable found for " + section;
-          throw new ConfigurationException(msg);
-        }
-        result.add(authorizable);
-      }
-    }
-    return result;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBModelAuthorizables.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBModelAuthorizables.java
deleted file mode 100644
index 96b172d..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBModelAuthorizables.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import org.apache.sentry.core.model.db.AccessURI;
-import org.apache.sentry.core.model.db.Column;
-import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
-import org.apache.sentry.core.model.db.Database;
-import org.apache.sentry.core.model.db.Server;
-import org.apache.sentry.core.model.db.Table;
-import org.apache.sentry.core.model.db.View;
-import org.apache.sentry.policy.common.KeyValue;
-
-public class DBModelAuthorizables {
-
-  public static DBModelAuthorizable from(KeyValue keyValue) {
-    String prefix = keyValue.getKey().toLowerCase();
-    String name = keyValue.getValue();
-    for(AuthorizableType type : AuthorizableType.values()) {
-      if(prefix.equalsIgnoreCase(type.name())) {
-        if (prefix.equalsIgnoreCase(AuthorizableType.URI.toString())) {
-          return from(type, name);
-        } else {
-          return from(type, name.toLowerCase());
-        }
-      }
-    }
-    return null;
-  }
-  public static DBModelAuthorizable from(String s) {
-    return from(new KeyValue(s));
-  }
-
-  private static DBModelAuthorizable from(AuthorizableType type, String name) {
-    switch (type) {
-    case Server:
-      return new Server(name);
-    case Db:
-      return new Database(name);
-    case Table:
-      return new Table(name);
-    case View:
-      return new View(name);
-    case Column:
-      return new Column(name);
-    case URI:
-      return new AccessURI(name);
-    default:
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBWildcardPrivilege.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBWildcardPrivilege.java
deleted file mode 100644
index 116e0aa..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DBWildcardPrivilege.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.
- */
-
-// copied from apache shiro
-
-package org.apache.sentry.policy.db;
-
-import java.util.List;
-
-import org.apache.sentry.core.common.utils.PathUtils;
-import org.apache.sentry.core.model.db.AccessConstants;
-import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
-import org.apache.sentry.policy.common.PolicyConstants;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.KeyValue;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-// XXX this class is made ugly by the fact that Action is not a Authorizable.
-public class DBWildcardPrivilege implements Privilege {
-
-  private final ImmutableList<KeyValue> parts;
-
-  public DBWildcardPrivilege(String wildcardString) {
-    wildcardString = Strings.nullToEmpty(wildcardString).trim();
-    if (wildcardString.isEmpty()) {
-      throw new IllegalArgumentException("Wildcard string cannot be null or empty.");
-    }
-    List<KeyValue>parts = Lists.newArrayList();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.trimResults().split(
-        wildcardString)) {
-      if (authorizable.isEmpty()) {
-        throw new IllegalArgumentException("Privilege '" + wildcardString + "' has an empty section");
-      }
-      parts.add(new KeyValue(authorizable));
-    }
-    if (parts.isEmpty()) {
-      throw new AssertionError("Should never occur: " + wildcardString);
-    }
-    this.parts = ImmutableList.copyOf(parts);
-  }
-
-
-  @Override
-  public boolean implies(Privilege p) {
-    // By default only supports comparisons with other DBWildcardPermissions
-    if (!(p instanceof DBWildcardPrivilege)) {
-      return false;
-    }
-
-    DBWildcardPrivilege wp = (DBWildcardPrivilege) p;
-
-    List<KeyValue> otherParts = wp.parts;
-    if(equals(wp)) {
-      return true;
-    }
-    int index = 0;
-    for (KeyValue otherPart : otherParts) {
-      // If this privilege has less parts than the other privilege, everything
-      // after the number of parts contained
-      // in this privilege is automatically implied, so return true
-      if (parts.size() - 1 < index) {
-        return true;
-      } else {
-        KeyValue part = parts.get(index);
-        // Support for action inheritance from parent to child (eg. Db -> Table)
-        if (part.getKey().equalsIgnoreCase("action") && !(otherPart.getKey().equalsIgnoreCase("action"))) {
-          continue;
-        }
-        // are the keys even equal
-        if(!part.getKey().equalsIgnoreCase(otherPart.getKey())) {
-          return false;
-        }
-        if (!impliesKeyValue(part, otherPart)) {
-          return false;
-        }
-        index++;
-      }
-    }
-    // If this privilege has more parts than
-    // the other parts, only imply it if
-    // all of the other parts are wildcards
-    for (; index < parts.size(); index++) {
-      KeyValue part = parts.get(index);
-      if (!part.getValue().equals(AccessConstants.ALL)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
-    Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()),
-        "Please report, this method should not be called with two different keys");
-    if(policyPart.getValue().equals(AccessConstants.ALL) ||
-        policyPart.getValue().equalsIgnoreCase("ALL")) {
-      return true;
-    } else if (!PolicyConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey())
-        && AccessConstants.ALL.equalsIgnoreCase(requestPart.getValue())) {
-      /* privilege request is to match with any object of given type */
-      return true;
-    } else if (!PolicyConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey())
-        && AccessConstants.SOME.equalsIgnoreCase(requestPart.getValue())) {
-      /* privilege request is to match with any object of given type */
-      return true;
-    } else if(policyPart.getKey().equalsIgnoreCase(AuthorizableType.URI.name())) {
-      return impliesURI(policyPart.getValue(), requestPart.getValue());
-    }
-    return policyPart.equals(requestPart);
-  }
-
-  @VisibleForTesting
-  protected static boolean impliesURI(String privilege, String request) {
-    return PathUtils.impliesURI(privilege, request);
-  }
-
-  @Override
-  public String toString() {
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(parts);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (o instanceof DBWildcardPrivilege) {
-      DBWildcardPrivilege wp = (DBWildcardPrivilege) o;
-      return parts.equals(wp.parts);
-    }
-    return false;
-  }
-
-  @Override
-  public int hashCode() {
-    return parts.hashCode();
-  }
-
-  public static class DBWildcardPrivilegeFactory implements PrivilegeFactory {
-    @Override
-    public Privilege createPrivilege(String privilege) {
-      return new DBWildcardPrivilege(privilege);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseMustMatch.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseMustMatch.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseMustMatch.java
deleted file mode 100644
index d280c41..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseMustMatch.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.core.model.db.Database;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-
-public class DatabaseMustMatch extends AbstractDBPrivilegeValidator {
-
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
-    String database = context.getDatabase();
-    String privilege = context.getPrivilege();
-    /*
-     *  Rule only applies to rules in per database policy file
-     */
-    if(database != null) {
-      Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
-      for(DBModelAuthorizable authorizable : authorizables) {
-        if(authorizable instanceof Database &&
-            !database.equalsIgnoreCase(authorizable.getName())) {
-          String msg = "Privilege " + privilege + " references db " +
-              authorizable.getName() + ", but is only allowed to reference "
-              + database;
-          throw new ConfigurationException(msg);
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseRequiredInPrivilege.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseRequiredInPrivilege.java
deleted file mode 100644
index e89aa16..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/DatabaseRequiredInPrivilege.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import org.apache.sentry.core.model.db.AccessURI;
-import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.core.model.db.Database;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-
-public class DatabaseRequiredInPrivilege extends AbstractDBPrivilegeValidator {
-
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
-    String database = context.getDatabase();
-    String privilege = context.getPrivilege();
-    /*
-     *  Rule only applies to rules in per database policy file
-     */
-    if(database != null) {
-      Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
-      /*
-       * Each permission in a non-global file must have a database
-       * object except for URIs.
-       *
-       * We allow URIs to be specified in the per DB policy file for
-       * ease of mangeability. URIs will contain to remain server scope
-       * objects.
-       */
-      boolean foundDatabaseInAuthorizables = false;
-      boolean foundURIInAuthorizables = false;
-      boolean allowURIInAuthorizables = false;
-
-      if ("true".equalsIgnoreCase(
-          System.getProperty(SimpleDBPolicyEngine.ACCESS_ALLOW_URI_PER_DB_POLICYFILE))) {
-        allowURIInAuthorizables = true;
-      }
-
-      for(DBModelAuthorizable authorizable : authorizables) {
-        if(authorizable instanceof Database) {
-          foundDatabaseInAuthorizables = true;
-        }
-        if (authorizable instanceof AccessURI) {
-          if (foundDatabaseInAuthorizables) {
-            String msg = "URI object is specified at DB scope in " + privilege;
-            throw new ConfigurationException(msg);
-          }
-          foundURIInAuthorizables = true;
-        }
-      }
-      if(!foundDatabaseInAuthorizables && !(foundURIInAuthorizables && allowURIInAuthorizables)) {
-        String msg = "Missing database object in " + privilege;
-        throw new ConfigurationException(msg);
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServerNameMustMatch.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServerNameMustMatch.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServerNameMustMatch.java
deleted file mode 100644
index 1848a32..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServerNameMustMatch.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.core.model.db.Server;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-
-public class ServerNameMustMatch extends AbstractDBPrivilegeValidator {
-
-  private final String serverName;
-  public ServerNameMustMatch(String serverName) {
-    this.serverName = serverName;
-  }
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
-    String privilege = context.getPrivilege();
-    Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
-    for(DBModelAuthorizable authorizable : authorizables) {
-      if(authorizable instanceof Server && !serverName.equalsIgnoreCase(authorizable.getName())) {
-        String msg = "Server name " + authorizable.getName() + " in "
-            + privilege + " is invalid. Expected " + serverName;
-        throw new ConfigurationException(msg);
-      }
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServersAllIsInvalid.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServersAllIsInvalid.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServersAllIsInvalid.java
deleted file mode 100644
index b729ec3..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/ServersAllIsInvalid.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import org.apache.sentry.core.model.db.DBModelAuthorizable;
-import org.apache.sentry.core.model.db.Server;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-
-public class ServersAllIsInvalid extends AbstractDBPrivilegeValidator {
-
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
-    String privilege = context.getPrivilege();
-    Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
-    for(DBModelAuthorizable authorizable : authorizables) {
-      if(authorizable instanceof Server &&
-          authorizable.getName().equals(Server.ALL.getName())) {
-        String msg = "Invalid value for " + authorizable.getAuthzType() + " in " + privilege;
-        throw new ConfigurationException(msg);
-      }
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java b/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
deleted file mode 100644
index 9d25592..0000000
--- a/sentry-policy/sentry-policy-db/src/main/java/org/apache/sentry/policy/db/SimpleDBPolicyEngine.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.util.Set;
-
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.provider.common.ProviderBackend;
-import org.apache.sentry.provider.common.ProviderBackendContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class SimpleDBPolicyEngine implements PolicyEngine {
-
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(SimpleDBPolicyEngine.class);
-
-  public final static String ACCESS_ALLOW_URI_PER_DB_POLICYFILE = "sentry.allow.uri.db.policyfile";
-
-  private final ProviderBackend providerBackend;
-
-  public SimpleDBPolicyEngine(String serverName, ProviderBackend providerBackend) {
-    this.providerBackend = providerBackend;
-    ProviderBackendContext context = new ProviderBackendContext();
-    context.setAllowPerDatabase(true);
-    context.setValidators(createPrivilegeValidators(serverName));
-    this.providerBackend.initialize(context);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public PrivilegeFactory getPrivilegeFactory() {
-    return new DBWildcardPrivilege.DBWildcardPrivilegeFactory();
-  }
-
-
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, roleSet);
-  }
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, users, roleSet);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
-      throws SentryConfigurationException {
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for {}", groups);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet, authorizableHierarchy);
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
-      throws SentryConfigurationException {
-    if (LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet,
-        authorizableHierarchy);
-    if (LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public void validatePolicy(boolean strictValidation) throws SentryConfigurationException {
-    this.providerBackend.validatePolicy(strictValidation);
-  }
-
-  @Override
-  public void close() {
-    if (providerBackend != null) {
-      providerBackend.close();
-    }
-  }
-
-  public static ImmutableList<PrivilegeValidator> createPrivilegeValidators(String serverName) {
-    return ImmutableList.<PrivilegeValidator>of(new ServersAllIsInvalid(), new DatabaseMustMatch(),
-        new DatabaseRequiredInPrivilege(), new ServerNameMustMatch(serverName));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/AbstractTestSimplePolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/AbstractTestSimplePolicyEngine.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/AbstractTestSimplePolicyEngine.java
deleted file mode 100644
index 0a65b2c..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/AbstractTestSimplePolicyEngine.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public abstract class AbstractTestSimplePolicyEngine {
-  private static final String PERM_SERVER1_CUSTOMERS_SELECT = "server=server1->db=customers->table=purchases->action=select";
-  private static final String PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT = "server=server1->db=customers->table=purchases_partial->action=select";
-  private static final String PERM_SERVER1_ANALYST_ALL = "server=server1->db=analyst1";
-  private static final String PERM_SERVER1_JUNIOR_ANALYST_ALL = "server=server1->db=jranalyst1";
-  private static final String PERM_SERVER1_JUNIOR_ANALYST_READ = "server=server1->db=jranalyst1->table=*->action=select";
-  private static final String PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT = "server=server1->db=other_group_db->table=purchases->action=select";
-
-  private static final String PERM_SERVER1_ADMIN = "server=server1";
-  private PolicyEngine policy;
-  private static File baseDir;
-
-  @BeforeClass
-  public static void setupClazz() throws IOException {
-    baseDir = Files.createTempDir();
-  }
-
-  @AfterClass
-  public static void teardownClazz() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  protected void setPolicy(PolicyEngine policy) {
-    this.policy = policy;
-  }
-  protected static File getBaseDir() {
-    return baseDir;
-  }
-  @Before
-  public void setup() throws IOException {
-    afterSetup();
-  }
-  @After
-  public void teardown() throws IOException {
-    beforeTeardown();
-  }
-  protected void afterSetup() throws IOException {
-
-  }
-
-  protected void beforeTeardown() throws IOException {
-
-  }
-
-  @Test
-  public void testManager() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        PERM_SERVER1_CUSTOMERS_SELECT, PERM_SERVER1_ANALYST_ALL,
-        PERM_SERVER1_JUNIOR_ANALYST_ALL, PERM_SERVER1_JUNIOR_ANALYST_READ,
-        PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT
-        ));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("manager"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testAnalyst() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        PERM_SERVER1_CUSTOMERS_SELECT, PERM_SERVER1_ANALYST_ALL,
-        PERM_SERVER1_JUNIOR_ANALYST_READ));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("analyst"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testJuniorAnalyst() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets
-        .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
-            PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PERM_SERVER1_ADMIN));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("admin"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-
-  @Test
-  public void testOtherGroup() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("other_group"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testDbAll() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets
-        .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
-            PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testDbAllforOtherGroup() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getAllPrivileges(set("other_group"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  private static Set<String> set(String... values) {
-    return Sets.newHashSet(values);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/DBPolicyFileBackend.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/DBPolicyFileBackend.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/DBPolicyFileBackend.java
deleted file mode 100644
index 9dc63e4..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/DBPolicyFileBackend.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.io.IOException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.provider.file.SimpleFileProviderBackend;
-
-public class DBPolicyFileBackend extends SimpleDBPolicyEngine {
-  public DBPolicyFileBackend(String server, String resource) throws IOException{
-    super(server, new SimpleFileProviderBackend(new Configuration(), resource));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBModelAuthorizables.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBModelAuthorizables.java
deleted file mode 100644
index ad14278..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBModelAuthorizables.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.sentry.policy.db;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.apache.sentry.core.model.db.AccessURI;
-import org.apache.sentry.core.model.db.Database;
-import org.apache.sentry.core.model.db.Server;
-import org.apache.sentry.core.model.db.Table;
-import org.apache.sentry.core.model.db.View;
-import org.junit.Test;
-
-public class TestDBModelAuthorizables {
-
-  @Test
-  public void testServer() throws Exception {
-    Server server = (Server)DBModelAuthorizables.from("SeRvEr=server1");
-    assertEquals("server1", server.getName());
-  }
-  @Test
-  public void testDb() throws Exception {
-    Database db = (Database)DBModelAuthorizables.from("dB=db1");
-    assertEquals("db1", db.getName());
-  }
-  @Test
-  public void testTable() throws Exception {
-    Table table = (Table)DBModelAuthorizables.from("tAbLe=t1");
-    assertEquals("t1", table.getName());
-  }
-  @Test
-  public void testView() throws Exception {
-    View view = (View)DBModelAuthorizables.from("vIeW=v1");
-    assertEquals("v1", view.getName());
-  }
-  @Test
-  public void testURI() throws Exception {
-    AccessURI uri = (AccessURI)DBModelAuthorizables.from("UrI=hdfs://uri1:8200/blah");
-    assertEquals("hdfs://uri1:8200/blah", uri.getName());
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNoKV() throws Exception {
-    System.out.println(DBModelAuthorizables.from("nonsense"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(DBModelAuthorizables.from("=v"));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(DBModelAuthorizables.from("k="));
-  }
-  @Test
-  public void testNotAuthorizable() throws Exception {
-    assertNull(DBModelAuthorizables.from("k=v"));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBWildcardPrivilege.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBWildcardPrivilege.java
deleted file mode 100644
index aa6fccd..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDBWildcardPrivilege.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * 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.sentry.policy.db;
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_SEPARATOR;
-
-import org.apache.sentry.core.model.db.AccessConstants;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.KeyValue;
-import org.junit.Test;
-
-public class TestDBWildcardPrivilege extends org.junit.Assert {
-
-  private static final String ALL = AccessConstants.ALL;
-
-  private static final Privilege ROLE_SERVER_SERVER1_DB_ALL =
-      create(new KeyValue("server", "server1"), new KeyValue("db", ALL));
-  private static final Privilege ROLE_SERVER_SERVER1_DB_DB1 =
-      create(new KeyValue("server", "server1"), new KeyValue("db", "db1"));
-  private static final Privilege ROLE_SERVER_SERVER2_DB_ALL =
-      create(new KeyValue("server", "server2"), new KeyValue("db", ALL));
-  private static final Privilege ROLE_SERVER_SERVER2_DB_DB1 =
-      create(new KeyValue("server", "server2"), new KeyValue("db", "db1"));
-  private static final Privilege ROLE_SERVER_ALL_DB_ALL =
-      create(new KeyValue("server", ALL), new KeyValue("db", ALL));
-  private static final Privilege ROLE_SERVER_ALL_DB_DB1 =
-      create(new KeyValue("server", ALL), new KeyValue("db", "db1"));
-
-  private static final Privilege ROLE_SERVER_SERVER1_URI_URI1 =
-      create(new KeyValue("server", "server1"), new KeyValue("uri",
-          "hdfs://namenode:8020/path/to/uri1"));
-  private static final Privilege ROLE_SERVER_SERVER1_URI_URI2 =
-      create(new KeyValue("server", "server1"), new KeyValue("uri",
-          "hdfs://namenode:8020/path/to/uri2/"));
-  private static final Privilege ROLE_SERVER_SERVER1_URI_ALL =
-      create(new KeyValue("server", "server1"), new KeyValue("uri", ALL));
-
-
-  private static final Privilege ROLE_SERVER_SERVER1 =
-      create(new KeyValue("server", "server1"));
-
-
-  private static final Privilege REQUEST_SERVER1_DB1 =
-      create(new KeyValue("server", "server1"), new KeyValue("db", "db1"));
-  private static final Privilege REQUEST_SERVER2_DB1 =
-      create(new KeyValue("server", "server2"), new KeyValue("db", "db1"));
-  private static final Privilege REQUEST_SERVER1_DB2 =
-      create(new KeyValue("server", "server1"), new KeyValue("db", "db2"));
-  private static final Privilege REQUEST_SERVER2_DB2 =
-      create(new KeyValue("server", "server2"), new KeyValue("db", "db2"));
-
-  private static final Privilege REQUEST_SERVER1_URI1 =
-      create(new KeyValue("server", "server1"), new KeyValue("uri",
-          "hdfs://namenode:8020/path/to/uri1/some/file"));
-  private static final Privilege REQUEST_SERVER1_URI2 =
-      create(new KeyValue("server", "server1"), new KeyValue("uri",
-          "hdfs://namenode:8020/path/to/uri2/some/other/file"));
-
-  private static final Privilege REQUEST_SERVER1_OTHER =
-      create(new KeyValue("server", "server2"), new KeyValue("other", "thing"));
-
-  private static final Privilege REQUEST_SERVER1 =
-      create(new KeyValue("server", "server2"));
-
-  @Test
-  public void testOther() throws Exception {
-    assertFalse(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_OTHER));
-    assertFalse(REQUEST_SERVER1_OTHER.implies(ROLE_SERVER_ALL_DB_ALL));
-  }
-  @Test
-  public void testRoleShorterThanRequest() throws Exception {
-    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_DB1));
-    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_DB2));
-    assertFalse(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER2_DB1));
-    assertFalse(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER2_DB2));
-
-    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1));
-    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1));
-  }
-  @Test
-  public void testRolesAndRequests() throws Exception {
-    // ROLE_SERVER_SERVER1_DB_ALL
-    assertTrue(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER1_DB1));
-    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER2_DB1));
-    assertTrue(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER1_DB2));
-    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER2_DB2));
-
-    // test inverse
-    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER1_DB_ALL));
-    assertFalse(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER1_DB_ALL));
-    assertTrue(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER1_DB_ALL));
-    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER1_DB_ALL));
-
-    // ROLE_SERVER_SERVER1_DB_DB1
-    assertTrue(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER1_DB1));
-    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER2_DB1));
-    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER1_DB2));
-    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER2_DB2));
-
-    // test inverse
-    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER1_DB_DB1));
-    assertFalse(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER1_DB_DB1));
-    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER1_DB_DB1));
-    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER1_DB_DB1));
-
-    // ROLE_SERVER_SERVER2_DB_ALL
-    assertFalse(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER1_DB1));
-    assertTrue(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER2_DB1));
-    assertFalse(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER1_DB2));
-    assertTrue(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER2_DB2));
-
-    // test inverse
-    assertFalse(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER2_DB_ALL));
-    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER2_DB_ALL));
-    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER2_DB_ALL));
-    assertTrue(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER2_DB_ALL));
-
-    // ROLE_SERVER_SERVER2_DB_DB1
-    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER1_DB1));
-    assertTrue(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER2_DB1));
-    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER1_DB2));
-    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER2_DB2));
-
-    assertFalse(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER2_DB_DB1));
-    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER2_DB_DB1));
-    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER2_DB_DB1));
-    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER2_DB_DB1));
-
-    // ROLE_SERVER_ALL_DB_ALL
-    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_DB1));
-    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER2_DB1));
-    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_DB2));
-    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER2_DB2));
-
-    // test inverse
-    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_ALL_DB_ALL));
-    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_ALL_DB_ALL));
-    assertTrue(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_ALL_DB_ALL));
-    assertTrue(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_ALL_DB_ALL));
-
-    // ROLE_SERVER_ALL_DB_DB1
-    assertTrue(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_DB1));
-    assertTrue(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER2_DB1));
-    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_DB2));
-    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER2_DB2));
-
-    // test inverse
-    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_ALL_DB_DB1));
-    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_ALL_DB_DB1));
-    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_ALL_DB_DB1));
-    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_ALL_DB_DB1));
-
-    // uri
-    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI1));
-    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2));
-    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2));
-    assertTrue(ROLE_SERVER_SERVER1_URI_ALL.implies(REQUEST_SERVER1_URI1));
-    assertTrue(ROLE_SERVER_SERVER1_URI_ALL.implies(REQUEST_SERVER1_URI2));
-    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2));
-    assertTrue(ROLE_SERVER_SERVER1_URI_URI1.implies(REQUEST_SERVER1_URI1));
-    assertFalse(ROLE_SERVER_SERVER1_URI_URI1.implies(REQUEST_SERVER1_URI2));
-    assertTrue(ROLE_SERVER_SERVER1_URI_URI2.implies(REQUEST_SERVER1_URI2));
-    assertFalse(ROLE_SERVER_SERVER1_URI_URI2.implies(REQUEST_SERVER1_URI1));
-    assertFalse(REQUEST_SERVER2_DB2.implies(REQUEST_SERVER1_URI1));
-    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_URI1));
-    // test inverse
-    assertTrue(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_ALL));
-    assertTrue(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_ALL));
-    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1));
-    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_URI1));
-    assertFalse(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_URI1));
-    assertFalse(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_URI2));
-    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_URI2));
-  };
-  @Test
-  public void testUnexpected() throws Exception {
-    Privilege p = new Privilege() {
-      @Override
-      public boolean implies(Privilege p) {
-        return false;
-      }
-    };
-    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(null));
-    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(p));
-    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(null));
-    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(p));
-
-    assertEquals(ROLE_SERVER_SERVER1_DB_ALL.hashCode(),
-        create(ROLE_SERVER_SERVER1_DB_ALL.toString()).hashCode());
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testNullString() throws Exception {
-    System.out.println(create((String)null));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyString() throws Exception {
-    System.out.println(create(""));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(create(KV_JOINER.join("", "db1")));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(create(KV_JOINER.join("db", "")));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyPart() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_JOINER.join("server", "server1"), "")));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testOnlySeperators() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_SEPARATOR, KV_SEPARATOR, KV_SEPARATOR)));
-  }
-  @Test
-  public void testImpliesURIPositive() throws Exception {
-    assertTrue(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "hdfs://namenode:8020/path/to/some/dir"));
-    assertTrue(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "hdfs://namenode:8020/path"));
-    assertTrue(DBWildcardPrivilege.impliesURI("file:///path",
-        "file:///path/to/some/dir"));
-    assertTrue(DBWildcardPrivilege.impliesURI("file:///path",
-        "file:///path"));
-  }
-  @Test
-  public void testImpliesURINegative() throws Exception {
-    // relative path
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "hdfs://namenode:8020/path/to/../../other"));
-    assertFalse(DBWildcardPrivilege.impliesURI("file:///path",
-        "file:///path/to/../../other"));
-    // bad policy
-    assertFalse(DBWildcardPrivilege.impliesURI("blah",
-        "hdfs://namenode:8020/path/to/some/dir"));
-    // bad request
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "blah"));
-    // scheme
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "file:///path/to/some/dir"));
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "file://namenode:8020/path/to/some/dir"));
-    // hostname
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode1:8020/path",
-        "hdfs://namenode2:8020/path/to/some/dir"));
-    // port
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "hdfs://namenode:8021/path/to/some/dir"));
-    // mangled path
-    assertFalse(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path",
-        "hdfs://namenode:8020/pathFooBar"));
-    // ends in /
-    assertTrue(DBWildcardPrivilege.impliesURI("hdfs://namenode:8020/path/",
-        "hdfs://namenode:8020/path/FooBar"));
-  }
-  @Test
-  public void testActionHierarchy() throws Exception {
-    String dbName = "db1";
-    DBWildcardPrivilege dbAll = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "ALL"));
-
-    DBWildcardPrivilege dbSelect = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "SELECT"));
-    DBWildcardPrivilege dbInsert = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "INSERT"));
-    DBWildcardPrivilege dbAlter = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "ALTER"));
-    DBWildcardPrivilege dbCreate = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "CREATE"));
-    DBWildcardPrivilege dbDrop = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "DROP"));
-    DBWildcardPrivilege dbIndex = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "INDEX"));
-    DBWildcardPrivilege dbLock = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "LOCK"));
-
-    assertTrue(dbAll.implies(dbSelect));
-    assertTrue(dbAll.implies(dbInsert));
-    assertTrue(dbAll.implies(dbAlter));
-    assertTrue(dbAll.implies(dbCreate));
-    assertTrue(dbAll.implies(dbDrop));
-    assertTrue(dbAll.implies(dbIndex));
-    assertTrue(dbAll.implies(dbLock));
-
-    dbAll = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName), new KeyValue("action", "*"));
-
-    assertTrue(dbAll.implies(dbSelect));
-    assertTrue(dbAll.implies(dbInsert));
-    assertTrue(dbAll.implies(dbAlter));
-    assertTrue(dbAll.implies(dbCreate));
-    assertTrue(dbAll.implies(dbDrop));
-    assertTrue(dbAll.implies(dbIndex));
-    assertTrue(dbAll.implies(dbLock));
-
-    dbAll = create(new KeyValue("server", "server1"),
-        new KeyValue("db", dbName));
-
-    assertTrue(dbAll.implies(dbSelect));
-    assertTrue(dbAll.implies(dbInsert));
-    assertTrue(dbAll.implies(dbAlter));
-    assertTrue(dbAll.implies(dbCreate));
-    assertTrue(dbAll.implies(dbDrop));
-    assertTrue(dbAll.implies(dbIndex));
-    assertTrue(dbAll.implies(dbLock));
-
-  }
-  static DBWildcardPrivilege create(KeyValue... keyValues) {
-    return create(AUTHORIZABLE_JOINER.join(keyValues));
-
-  }
-  static DBWildcardPrivilege create(String s) {
-    return new DBWildcardPrivilege(s);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDatabaseRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDatabaseRequiredInRole.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDatabaseRequiredInRole.java
deleted file mode 100644
index c08a4f4..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestDatabaseRequiredInRole.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import org.junit.Assert;
-
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-import org.junit.Test;
-
-public class TestDatabaseRequiredInRole {
-
-  @Test
-  public void testURIInPerDbPolicyFile() throws Exception {
-    DatabaseRequiredInPrivilege dbRequiredInRole = new DatabaseRequiredInPrivilege();
-    System.setProperty("sentry.allow.uri.db.policyfile", "true");
-    dbRequiredInRole.validate(new PrivilegeValidatorContext("db1",
-      "server=server1->URI=file:///user/db/warehouse/tab1"));
-    System.setProperty("sentry.allow.uri.db.policyfile", "false");
-  }
-
-  @Test
-  public void testURIWithDBInPerDbPolicyFile() throws Exception {
-    DatabaseRequiredInPrivilege dbRequiredInRole = new DatabaseRequiredInPrivilege();
-    try {
-      dbRequiredInRole.validate(new PrivilegeValidatorContext("db1",
-        "server=server1->db=db1->URI=file:///user/db/warehouse/tab1"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException e) {
-      // expected
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestPolicyParsingNegative.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestPolicyParsingNegative.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestPolicyParsingNegative.java
deleted file mode 100644
index fc21ceb..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestPolicyParsingNegative.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestPolicyParsingNegative {
-
-  @SuppressWarnings("unused")
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(TestPolicyParsingNegative.class);
-
-  private File baseDir;
-  private File globalPolicyFile;
-  private File otherPolicyFile;
-
-  @Before
-  public void setup() {
-    baseDir = Files.createTempDir();
-    globalPolicyFile = new File(baseDir, "global.ini");
-    otherPolicyFile = new File(baseDir, "other.ini");
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void append(String from, File to) throws IOException {
-    Files.append(from + "\n", to, Charsets.UTF_8);
-  }
-
-  @Test
-  public void testUnauthorizedDbSpecifiedInDBPolicyFile() throws Exception {
-    append("[databases]", globalPolicyFile);
-    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
-    append("[groups]", otherPolicyFile);
-    append("other_group = malicious_role", otherPolicyFile);
-    append("[roles]", otherPolicyFile);
-    append("malicious_role = server=server1->db=customers->table=purchases->action=select", otherPolicyFile);
-    PolicyEngine policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-  @Test
-  public void testPerDbFileCannotContainUsersOrDatabases() throws Exception {
-    PolicyEngine policy;
-    ImmutableSet<String> permissions;
-    PolicyFile policyFile;
-    // test sanity
-    policyFile = PolicyFile.setAdminOnServer1("admin");
-    policyFile.addGroupsToUser("admin1", "admin");
-    policyFile.write(globalPolicyFile);
-    policyFile.write(otherPolicyFile);
-    policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
-    Assert.assertEquals(permissions.toString(), "[server=server1]");
-    // test to ensure [users] fails parsing of per-db file
-    policyFile.addDatabase("other", otherPolicyFile.getPath());
-    policyFile.write(globalPolicyFile);
-    policyFile.write(otherPolicyFile);
-    policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
-    Assert.assertEquals(permissions.toString(), "[server=server1]");
-    // test to ensure [databases] fails parsing of per-db file
-    // by removing the user mapping from the per-db policy file
-    policyFile.removeGroupsFromUser("admin1", "admin")
-      .write(otherPolicyFile);
-    policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
-    Assert.assertEquals(permissions.toString(), "[server=server1]");
-  }
-
-  @Test
-  public void testDatabaseRequiredInRole() throws Exception {
-    append("[databases]", globalPolicyFile);
-    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
-    append("[groups]", otherPolicyFile);
-    append("other_group = malicious_role", otherPolicyFile);
-    append("[roles]", otherPolicyFile);
-    append("malicious_role = server=server1", otherPolicyFile);
-    PolicyEngine policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testServerAll() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = server=*", globalPolicyFile);
-    PolicyEngine policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testServerIncorrect() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = server=server2", globalPolicyFile);
-    PolicyEngine policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testAll() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = *", globalPolicyFile);
-    PolicyEngine policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  /**
-   * Create policy file with multiple per db files.
-   * Verify that a file with bad format is the only one that's ignored
-   * @throws Exception
-   */
-  @Test
-  public void testMultiDbWithErrors() throws Exception {
-    File db1PolicyFile = new File(baseDir, "db1.ini");
-    File db2PolicyFile = new File(baseDir, "db2.ini");
-
-    // global policy file
-    append("[databases]", globalPolicyFile);
-    append("db1 = " + db1PolicyFile.getPath(), globalPolicyFile);
-    append("db2 = " + db2PolicyFile.getPath(), globalPolicyFile);
-    append("[groups]", globalPolicyFile);
-    append("db3_group = db3_rule", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("db3_rule = server=server1->db=db3->table=sales->action=select", globalPolicyFile);
-
-    //db1 policy file with badly formatted rule
-    append("[groups]", db1PolicyFile);
-    append("db1_group = bad_rule", db1PolicyFile);
-    append("[roles]", db1PolicyFile);
-    append("bad_rule = server=server1->db=customers->=purchases->action=", db1PolicyFile);
-
-    //db2 policy file with proper rule
-    append("[groups]", db2PolicyFile);
-    append("db2_group = db2_rule", db2PolicyFile);
-    append("[roles]", db2PolicyFile);
-    append("db2_rule = server=server1->db=db2->table=purchases->action=select", db2PolicyFile);
-
-    PolicyEngine policy = new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-
-    // verify that the db1 rule is empty
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("db1_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-
-    permissions = policy.getAllPrivileges(Sets.newHashSet("db2_group"), ActiveRoleSet.ALL);
-    Assert.assertEquals(permissions.toString(), 1, permissions.size());
-  }
-}


[03/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/pom.xml b/sentry-policy/sentry-policy-search/pom.xml
deleted file mode 100644
index 177a62b..0000000
--- a/sentry-policy/sentry-policy-search/pom.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0"?>
-<!--
-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.
--->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.sentry</groupId>
-    <artifactId>sentry-policy</artifactId>
-    <version>1.8.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>sentry-policy-search</artifactId>
-  <name>Sentry Policy for Search</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-minicluster</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.shiro</groupId>
-      <artifactId>shiro-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-core-model-search</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-file</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-common</artifactId>
-      <scope>test</scope>
-      <type>test-jar</type>
-      <version>${project.version}</version>
-    </dependency>
-  </dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/AbstractSearchPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/AbstractSearchPrivilegeValidator.java b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/AbstractSearchPrivilegeValidator.java
deleted file mode 100644
index 054c354..0000000
--- a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/AbstractSearchPrivilegeValidator.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.search.SearchModelAuthorizable;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.shiro.config.ConfigurationException;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-
-public abstract class AbstractSearchPrivilegeValidator implements PrivilegeValidator {
-
-  @VisibleForTesting
-  public static Iterable<SearchModelAuthorizable> parsePrivilege(String string) {
-    List<SearchModelAuthorizable> result = Lists.newArrayList();
-    System.err.println("privilege = " + string);
-    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
-      // XXX this ugly hack is because action is not an authorizable
-      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
-        SearchModelAuthorizable authorizable = SearchModelAuthorizables.from(section);
-        if(authorizable == null) {
-          String msg = "No authorizable found for " + section;
-          throw new ConfigurationException(msg);
-        }
-        result.add(authorizable);
-      }
-    }
-    return result;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/CollectionRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/CollectionRequiredInPrivilege.java b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/CollectionRequiredInPrivilege.java
deleted file mode 100644
index 81ff67f..0000000
--- a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/CollectionRequiredInPrivilege.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.core.model.search.Collection;
-import org.apache.sentry.core.model.search.SearchModelAuthorizable;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-
-public class CollectionRequiredInPrivilege extends AbstractSearchPrivilegeValidator {
-
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws SentryConfigurationException {
-    String privilege = context.getPrivilege();
-    Iterable<SearchModelAuthorizable> authorizables = parsePrivilege(privilege);
-    boolean foundCollectionInAuthorizables = false;
-
-    for(SearchModelAuthorizable authorizable : authorizables) {
-      if(authorizable instanceof Collection) {
-        foundCollectionInAuthorizables = true;
-        break;
-      }
-    }
-    if(!foundCollectionInAuthorizables) {
-      String msg = "Missing collection object in " + privilege;
-      throw new SentryConfigurationException(msg);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchModelAuthorizables.java b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchModelAuthorizables.java
deleted file mode 100644
index 252f50a..0000000
--- a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchModelAuthorizables.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import org.apache.sentry.core.model.search.Collection;
-import org.apache.sentry.core.model.search.SearchModelAuthorizable;
-import org.apache.sentry.core.model.search.SearchModelAuthorizable.AuthorizableType;
-import org.apache.sentry.policy.common.KeyValue;
-
-public class SearchModelAuthorizables {
-
-  public static SearchModelAuthorizable from(KeyValue keyValue) {
-    String prefix = keyValue.getKey().toLowerCase();
-    String name = keyValue.getValue().toLowerCase();
-    for(AuthorizableType type : AuthorizableType.values()) {
-      if(prefix.equalsIgnoreCase(type.name())) {
-        return from(type, name);
-      }
-    }
-    return null;
-  }
-  public static SearchModelAuthorizable from(String s) {
-    return from(new KeyValue(s));
-  }
-
-  private static SearchModelAuthorizable from(AuthorizableType type, String name) {
-    switch (type) {
-    case Collection:
-      return new Collection(name);
-    default:
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchWildcardPrivilege.java b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchWildcardPrivilege.java
deleted file mode 100644
index e25faf2..0000000
--- a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SearchWildcardPrivilege.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.
- */
-
-// copied from apache shiro
-
-package org.apache.sentry.policy.search;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.search.SearchConstants;
-import org.apache.sentry.policy.common.PolicyConstants;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.KeyValue;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class SearchWildcardPrivilege implements Privilege {
-
-  private final ImmutableList<KeyValue> parts;
-
-  public SearchWildcardPrivilege(String wildcardString) {
-    wildcardString = Strings.nullToEmpty(wildcardString).trim();
-    if (wildcardString.isEmpty()) {
-      throw new IllegalArgumentException("Wildcard string cannot be null or empty.");
-    }
-    List<KeyValue>parts = Lists.newArrayList();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.trimResults().split(
-        wildcardString)) {
-      if (authorizable.isEmpty()) {
-        throw new IllegalArgumentException("Privilege '" + wildcardString + "' has an empty section");
-      }
-      parts.add(new KeyValue(authorizable));
-    }
-    if (parts.isEmpty()) {
-      throw new AssertionError("Should never occur: " + wildcardString);
-    }
-    this.parts = ImmutableList.copyOf(parts);
-  }
-
-
-  @Override
-  public boolean implies(Privilege p) {
-    // By default only supports comparisons with other SearchWildcardPermissions
-    if (!(p instanceof SearchWildcardPrivilege)) {
-      return false;
-    }
-
-    SearchWildcardPrivilege wp = (SearchWildcardPrivilege) p;
-
-    List<KeyValue> otherParts = wp.parts;
-    if(equals(wp)) {
-      return true;
-    }
-    int index = 0;
-    for (KeyValue otherPart : otherParts) {
-      // If this privilege has less parts than the other privilege, everything
-      // after the number of parts contained
-      // in this privilege is automatically implied, so return true
-      if (parts.size() - 1 < index) {
-        return true;
-      } else {
-        KeyValue part = parts.get(index);
-        // are the keys even equal
-        if(!part.getKey().equalsIgnoreCase(otherPart.getKey())) {
-          return false;
-        }
-        if (!impliesKeyValue(part, otherPart)) {
-          return false;
-        }
-        index++;
-      }
-    }
-    // If this privilege has more parts than
-    // the other parts, only imply it if
-    // all of the other parts are wildcards
-    for (; index < parts.size(); index++) {
-      KeyValue part = parts.get(index);
-      if (!part.getValue().equals(SearchConstants.ALL)) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
-    Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()),
-        "Please report, this method should not be called with two different keys");
-    if(policyPart.getValue().equals(SearchConstants.ALL) || policyPart.equals(requestPart)) {
-      return true;
-    } else if (!PolicyConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey())
-        && SearchConstants.ALL.equalsIgnoreCase(requestPart.getValue())) {
-      /* privilege request is to match with any object of given type */
-      return true;
-    }
-    return false;
-  }
-
-  @Override
-  public String toString() {
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(parts);
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (o instanceof SearchWildcardPrivilege) {
-      SearchWildcardPrivilege wp = (SearchWildcardPrivilege) o;
-      return parts.equals(wp.parts);
-    }
-    return false;
-  }
-
-  @Override
-  public int hashCode() {
-    return parts.hashCode();
-  }
-
-  public static class SearchWildcardPrivilegeFactory implements PrivilegeFactory {
-    @Override
-    public Privilege createPrivilege(String privilege) {
-      return new SearchWildcardPrivilege(privilege);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java b/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
deleted file mode 100644
index c71036e..0000000
--- a/sentry-policy/sentry-policy-search/src/main/java/org/apache/sentry/policy/search/SimpleSearchPolicyEngine.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.util.Set;
-
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.provider.common.ProviderBackend;
-import org.apache.sentry.provider.common.ProviderBackendContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-/**
- * A PolicyEngine for a search service.
- */
-public class SimpleSearchPolicyEngine implements PolicyEngine {
-
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(SimpleSearchPolicyEngine.class);
-
-  private final ProviderBackend providerBackend;
-
-  public SimpleSearchPolicyEngine(ProviderBackend providerBackend) {
-    this.providerBackend = providerBackend;
-    ProviderBackendContext context = new ProviderBackendContext();
-    context.setAllowPerDatabase(false);
-    context.setValidators(createPrivilegeValidators());
-    this.providerBackend.initialize(context);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public PrivilegeFactory getPrivilegeFactory() {
-    return new SearchWildcardPrivilege.SearchWildcardPrivilegeFactory();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, roleSet);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable... authorizationHierarchy ) {
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for {}", groups);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet);
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, users, roleSet);
-  }
-
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet, Authorizable... authorizationHierarchy) {
-    if (LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
-    if (LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public void validatePolicy(boolean strictValidation)
-      throws SentryConfigurationException {
-    providerBackend.validatePolicy(strictValidation);
-  }
-
-  public static ImmutableList<PrivilegeValidator> createPrivilegeValidators() {
-    return ImmutableList.<PrivilegeValidator>of(new CollectionRequiredInPrivilege());
-  }
-
-  @Override
-  public void close() {
-    if (providerBackend != null) {
-      providerBackend.close();
-    }
-  }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/AbstractTestSearchPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/AbstractTestSearchPolicyEngine.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/AbstractTestSearchPolicyEngine.java
deleted file mode 100644
index 1a9b1a1..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/AbstractTestSearchPolicyEngine.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public abstract class AbstractTestSearchPolicyEngine {
-  private static final String ANALYST_PURCHASES_UPDATE = "collection=purchases->action=update";
-  private static final String ANALYST_ANALYST1_ALL = "collection=analyst1";
-  private static final String ANALYST_JRANALYST1_ACTION_ALL = "collection=jranalyst1->action=*";
-  private static final String ANALYST_TMPCOLLECTION_UPDATE = "collection=tmpcollection->action=update";
-  private static final String ANALYST_TMPCOLLECTION_QUERY = "collection=tmpcollection->action=query";
-  private static final String JRANALYST_JRANALYST1_ALL = "collection=jranalyst1";
-  private static final String JRANALYST_PURCHASES_PARTIAL_QUERY = "collection=purchases_partial->action=query";
-  private static final String ADMIN_COLLECTION_ALL = "collection=*";
-
-  private PolicyEngine policy;
-  private static File baseDir;
-
-  @BeforeClass
-  public static void setupClazz() throws IOException {
-    baseDir = Files.createTempDir();
-  }
-
-  @AfterClass
-  public static void teardownClazz() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  protected void setPolicy(PolicyEngine policy) {
-    this.policy = policy;
-  }
-  protected static File getBaseDir() {
-    return baseDir;
-  }
-  @Before
-  public void setup() throws IOException {
-    afterSetup();
-  }
-  @After
-  public void teardown() throws IOException {
-    beforeTeardown();
-  }
-  protected void afterSetup() throws IOException {
-
-  }
-
-  protected void beforeTeardown() throws IOException {
-
-  }
-
-  @Test
-  public void testManager() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        ANALYST_PURCHASES_UPDATE, ANALYST_ANALYST1_ALL,
-        ANALYST_JRANALYST1_ACTION_ALL, ANALYST_TMPCOLLECTION_UPDATE,
-        ANALYST_TMPCOLLECTION_QUERY, JRANALYST_JRANALYST1_ALL,
-        JRANALYST_PURCHASES_PARTIAL_QUERY));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("manager"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testAnalyst() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        ANALYST_PURCHASES_UPDATE, ANALYST_ANALYST1_ALL,
-        ANALYST_JRANALYST1_ACTION_ALL, ANALYST_TMPCOLLECTION_UPDATE,
-        ANALYST_TMPCOLLECTION_QUERY));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("analyst"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testJuniorAnalyst() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets
-        .newHashSet(JRANALYST_JRANALYST1_ALL,
-            JRANALYST_PURCHASES_PARTIAL_QUERY));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN_COLLECTION_ALL));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("admin"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  private static Set<String> set(String... values) {
-    return Sets.newHashSet(values);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/SearchPolicyFileBackend.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/SearchPolicyFileBackend.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/SearchPolicyFileBackend.java
deleted file mode 100644
index be23e15..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/SearchPolicyFileBackend.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.io.IOException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.provider.file.SimpleFileProviderBackend;
-
-public class SearchPolicyFileBackend extends SimpleSearchPolicyEngine {
-  public SearchPolicyFileBackend(String resource) throws IOException{
-    super(new SimpleFileProviderBackend(new Configuration(), resource));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestCollectionRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestCollectionRequiredInRole.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestCollectionRequiredInRole.java
deleted file mode 100644
index f0bb622..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestCollectionRequiredInRole.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import org.junit.Assert;
-
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-import org.junit.Test;
-
-public class TestCollectionRequiredInRole {
-
-  @Test
-  public void testEmptyRole() throws Exception {
-    CollectionRequiredInPrivilege collRequiredInRole = new CollectionRequiredInPrivilege();
-
-    // check no db
-    try {
-      collRequiredInRole.validate(new PrivilegeValidatorContext("index=index1"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException e) {
-      // expected
-    }
-
-    // check with db
-    try {
-      collRequiredInRole.validate(new PrivilegeValidatorContext("db1","index=index2"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException e) {
-      // expected
-    }
-  }
-
-  @Test
-  public void testCollectionWithoutAction() throws Exception {
-    CollectionRequiredInPrivilege collRequiredInRole = new CollectionRequiredInPrivilege();
-    collRequiredInRole.validate(new PrivilegeValidatorContext("collection=nodb"));
-    collRequiredInRole.validate(new PrivilegeValidatorContext("db2","collection=db"));
-  }
-
-  @Test
-  public void testCollectionWithAction() throws Exception {
-    CollectionRequiredInPrivilege collRequiredInRole = new CollectionRequiredInPrivilege();
-    collRequiredInRole.validate(new PrivilegeValidatorContext(null,"collection=nodb->action=query"));
-    collRequiredInRole.validate(new PrivilegeValidatorContext("db2","collection=db->action=update"));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderGeneralCases.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderGeneralCases.java
deleted file mode 100644
index 9e1b1a7..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderGeneralCases.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.search.Collection;
-import org.apache.sentry.core.model.search.SearchModelAction;
-import org.apache.sentry.provider.common.MockGroupMappingServiceProvider;
-import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.After;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.io.Files;
-
-
-public class TestSearchAuthorizationProviderGeneralCases {
-
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(TestSearchAuthorizationProviderGeneralCases.class);
-
-  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap
-      .create();
-
-  private static final Subject SUB_ADMIN = new Subject("admin1");
-  private static final Subject SUB_MANAGER = new Subject("manager1");
-  private static final Subject SUB_ANALYST = new Subject("analyst1");
-  private static final Subject SUB_JUNIOR_ANALYST = new Subject("jranalyst1");
-
-  private static final Collection COLL_PURCHASES = new Collection("purchases");
-  private static final Collection COLL_ANALYST1 = new Collection("analyst1");
-  private static final Collection COLL_JRANALYST1 = new Collection("jranalyst1");
-  private static final Collection COLL_TMP = new Collection("tmpcollection");
-  private static final Collection COLL_PURCHASES_PARTIAL = new Collection("purchases_partial");
-
-  private static final SearchModelAction QUERY = SearchModelAction.QUERY;
-  private static final SearchModelAction UPDATE = SearchModelAction.UPDATE;
-
-  static {
-    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList("admin"));
-    USER_TO_GROUP_MAP.putAll(SUB_MANAGER.getName(), Arrays.asList("manager"));
-    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList("analyst"));
-    USER_TO_GROUP_MAP.putAll(SUB_JUNIOR_ANALYST.getName(),
-        Arrays.asList("jranalyst"));
-  }
-
-  private final ResourceAuthorizationProvider authzProvider;
-  private File baseDir;
-
-  public TestSearchAuthorizationProviderGeneralCases() throws IOException {
-    baseDir = Files.createTempDir();
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    authzProvider = new HadoopGroupResourceAuthorizationProvider(
-        new SearchPolicyFileBackend(new File(baseDir, "test-authz-provider.ini").getPath()),
-        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP));
-
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void doTestAuthProviderOnCollection(Subject subject,
-      Collection collection, Set<? extends Action> expectedPass) throws Exception {
-    Set<SearchModelAction> allActions = EnumSet.of(SearchModelAction.ALL, SearchModelAction.QUERY, SearchModelAction.UPDATE);
-    for(SearchModelAction action : allActions) {
-      doTestResourceAuthorizationProvider(subject, collection,
-        EnumSet.of(action), expectedPass.contains(action));
-    }
-  }
-
-  private void doTestResourceAuthorizationProvider(Subject subject,
-      Collection collection,
-      Set<? extends Action> privileges, boolean expected) throws Exception {
-    List<Authorizable> authzHierarchy = Arrays.asList(new Authorizable[] {
-        collection
-    });
-    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
-    helper.add("Subject", subject).add("Collection", collection)
-      .add("Privileges", privileges).add("authzHierarchy", authzHierarchy);
-    LOGGER.info("Running with " + helper.toString());
-    Assert.assertEquals(helper.toString(), expected,
-        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
-    LOGGER.info("Passed " + helper.toString());
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
-    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_PURCHASES, allActions);
-    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_ANALYST1, allActions);
-    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_JRANALYST1, allActions);
-    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_TMP, allActions);
-    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_PURCHASES_PARTIAL, allActions);
-  }
-
-  @Test
-  public void testManager() throws Exception {
-    Set<SearchModelAction> updateOnly = EnumSet.of(SearchModelAction.UPDATE);
-    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_PURCHASES, updateOnly);
-
-    Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
-    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_ANALYST1, allActions);
-    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_JRANALYST1, allActions);
-
-    Set<SearchModelAction> queryUpdateOnly = EnumSet.of(QUERY, UPDATE);
-    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_TMP, queryUpdateOnly);
-
-    Set<SearchModelAction> queryOnly = EnumSet.of(SearchModelAction.QUERY);
-    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_PURCHASES_PARTIAL, queryOnly);
-  }
-
-  @Test
-  public void testAnalyst() throws Exception {
-    Set<SearchModelAction> updateOnly = EnumSet.of(SearchModelAction.UPDATE);
-    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_PURCHASES, updateOnly);
-
-    Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
-    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_ANALYST1, allActions);
-    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_JRANALYST1, allActions);
-
-    Set<SearchModelAction> queryUpdateOnly = EnumSet.of(QUERY, UPDATE);
-    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_TMP, queryUpdateOnly);
-
-    Set<SearchModelAction> noActions = EnumSet.noneOf(SearchModelAction.class);
-    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_PURCHASES_PARTIAL, noActions);
-  }
-
-  @Test
-  public void testJuniorAnalyst() throws Exception {
-     Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
-     doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_JRANALYST1, allActions);
-
-    Set<SearchModelAction> queryOnly = EnumSet.of(SearchModelAction.QUERY);
-    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_PURCHASES_PARTIAL, queryOnly);
-
-    Set<SearchModelAction> noActions = EnumSet.noneOf(SearchModelAction.class);
-    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_PURCHASES, noActions);
-    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_ANALYST1, noActions);
-    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_TMP, noActions);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderSpecialCases.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderSpecialCases.java
deleted file mode 100644
index 3cd0b75..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchAuthorizationProviderSpecialCases.java
+++ /dev/null
@@ -1,82 +0,0 @@
- /*
- * 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.sentry.policy.search;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.search.Collection;
-import org.apache.sentry.core.model.search.SearchModelAction;
-import org.apache.sentry.provider.common.AuthorizationProvider;
-import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
-
-public class TestSearchAuthorizationProviderSpecialCases {
-  private AuthorizationProvider authzProvider;
-  private PolicyFile policyFile;
-  private File baseDir;
-  private File iniFile;
-  private String initResource;
-  @Before
-  public void setup() throws IOException {
-    baseDir = Files.createTempDir();
-    iniFile = new File(baseDir, "policy.ini");
-    initResource = "file://" + iniFile.getPath();
-    policyFile = new PolicyFile();
-  }
-
-  @After
-  public void teardown() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  @Test
-  public void testDuplicateEntries() throws Exception {
-    Subject user1 = new Subject("user1");
-    Collection collection1 = new Collection("collection1");
-    Set<? extends Action> actions = EnumSet.allOf(SearchModelAction.class);
-    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
-      .addRolesToGroup("group1",  true, "role1", "role1")
-      .addPermissionsToRole("role1", true, "collection=" + collection1.getName(),
-          "collection=" + collection1.getName());
-    policyFile.write(iniFile);
-    SearchPolicyFileBackend policy = new SearchPolicyFileBackend(initResource);
-    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy);
-    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(collection1);
-    Assert.assertTrue(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchModelAuthorizables.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchModelAuthorizables.java
deleted file mode 100644
index 94fe9f0..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchModelAuthorizables.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.sentry.policy.search;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.apache.sentry.core.model.search.Collection;
-import org.junit.Test;
-
-public class TestSearchModelAuthorizables {
-
-  @Test
-  public void testCollection() throws Exception {
-    Collection coll = (Collection)SearchModelAuthorizables.from("CoLleCtiOn=collection1");
-    assertEquals("collection1", coll.getName());
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNoKV() throws Exception {
-    System.out.println(SearchModelAuthorizables.from("nonsense"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(SearchModelAuthorizables.from("=v"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(SearchModelAuthorizables.from("k="));
-  }
-
-  @Test
-  public void testNotAuthorizable() throws Exception {
-    assertNull(SearchModelAuthorizables.from("k=v"));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineDFS.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineDFS.java
deleted file mode 100644
index 5c14ab6..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineDFS.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hdfs.MiniDFSCluster;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class TestSearchPolicyEngineDFS extends AbstractTestSearchPolicyEngine {
-
-  private static MiniDFSCluster dfsCluster;
-  private static FileSystem fileSystem;
-  private static Path root;
-  private static Path etc;
-
-  @BeforeClass
-  public static void setupLocalClazz() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    File dfsDir = new File(baseDir, "dfs");
-    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
-    Configuration conf = new Configuration();
-    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
-    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
-    fileSystem = dfsCluster.getFileSystem();
-    root = new Path(fileSystem.getUri().toString());
-    etc = new Path(root, "/etc");
-    fileSystem.mkdirs(etc);
-  }
-
-  @AfterClass
-  public static void teardownLocalClazz() {
-    if(dfsCluster != null) {
-      dfsCluster.shutdown();
-    }
-  }
-
-  @Override
-  protected void  afterSetup() throws IOException {
-    fileSystem.delete(etc, true);
-    fileSystem.mkdirs(etc);
-    PolicyFiles.copyToDir(fileSystem, etc, "test-authz-provider.ini");
-    setPolicy(new SearchPolicyFileBackend(new Path(etc,
-        "test-authz-provider.ini").toString()));
-  }
-
-  @Override
-  protected void beforeTeardown() throws IOException {
-    fileSystem.delete(etc, true);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineLocalFS.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineLocalFS.java
deleted file mode 100644
index 593afe7..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyEngineLocalFS.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.provider.file.PolicyFiles;
-
-public class TestSearchPolicyEngineLocalFS extends AbstractTestSearchPolicyEngine {
-
-  @Override
-  protected void  afterSetup() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    setPolicy(new SearchPolicyFileBackend(new File(baseDir, "test-authz-provider.ini").getPath()));
-  }
-  @Override
-  protected void beforeTeardown() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    FileUtils.deleteQuietly(baseDir);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyNegative.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyNegative.java
deleted file mode 100644
index 0993cc4..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchPolicyNegative.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.sentry.policy.search;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestSearchPolicyNegative {
-
-  @SuppressWarnings("unused")
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(TestSearchPolicyNegative.class);
-
-  private File baseDir;
-  private File globalPolicyFile;
-  private File otherPolicyFile;
-
-  @Before
-  public void setup() {
-    baseDir = Files.createTempDir();
-    globalPolicyFile = new File(baseDir, "global.ini");
-    otherPolicyFile = new File(baseDir, "other.ini");
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void append(String from, File to) throws IOException {
-    Files.append(from + "\n", to, Charsets.UTF_8);
-  }
-
-  @Test
-  public void testPerDbFileException() throws Exception {
-    append("[databases]", globalPolicyFile);
-    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
-    append("[groups]", otherPolicyFile);
-    append("other_group = some_role", otherPolicyFile);
-    append("[roles]", otherPolicyFile);
-    append("some_role = collection=c1", otherPolicyFile);
-    SearchPolicyFileBackend policy = new SearchPolicyFileBackend(globalPolicyFile.getPath());
-    Assert.assertEquals(Collections.emptySet(),
-        policy.getPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL));
-  }
-
-  @Test
-  public void testCollectionRequiredInRole() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = some_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("some_role = action=query", globalPolicyFile);
-    PolicyEngine policy = new SearchPolicyFileBackend(globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testGroupIncorrect() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = collection=*", globalPolicyFile);
-    PolicyEngine policy = new SearchPolicyFileBackend(globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getPrivileges(Sets.newHashSet("incorrectGroup"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchWildcardPrivilege.java b/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchWildcardPrivilege.java
deleted file mode 100644
index 3cf4a39..0000000
--- a/sentry-policy/sentry-policy-search/src/test/java/org/apache/sentry/policy/search/TestSearchWildcardPrivilege.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.sentry.policy.search;
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_SEPARATOR;
-
-import org.apache.sentry.core.model.search.SearchConstants;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.KeyValue;
-import org.junit.Test;
-
-public class TestSearchWildcardPrivilege extends org.junit.Assert {
-
-  private static final String ALL = SearchConstants.ALL;
-
-  @Test
-  public void testSimpleNoAction() throws Exception {
-    Privilege collection1 = create(new KeyValue("collection", "coll1"));
-    Privilege collection2 = create(new KeyValue("collection", "coll2"));
-    Privilege collection1Case = create(new KeyValue("colleCtIon", "coLl1"));
-
-    assertTrue(collection1.implies(collection1));
-    assertTrue(collection2.implies(collection2));
-    assertTrue(collection1.implies(collection1Case));
-    assertTrue(collection1Case.implies(collection1));
-
-    assertFalse(collection1.implies(collection2));
-    assertFalse(collection1Case.implies(collection2));
-    assertFalse(collection2.implies(collection1));
-    assertFalse(collection2.implies(collection1Case));
-  }
-
-  @Test
-  public void testSimpleAction() throws Exception {
-    Privilege query =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
-    Privilege update =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
-    Privilege queryCase =
-      create(new KeyValue("colleCtIon", "coLl1"), new KeyValue("AcTiOn", "QuERy"));
-
-    assertTrue(query.implies(query));
-    assertTrue(update.implies(update));
-    assertTrue(query.implies(queryCase));
-    assertTrue(queryCase.implies(query));
-
-    assertFalse(query.implies(update));
-    assertFalse(queryCase.implies(update));
-    assertFalse(update.implies(query));
-    assertFalse(update.implies(queryCase));
-  }
-
-  @Test
-  public void testRoleShorterThanRequest() throws Exception {
-    Privilege collection1 = create(new KeyValue("collection", "coll1"));
-    Privilege query =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
-    Privilege update =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
-    Privilege all =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", ALL));
-
-    assertTrue(collection1.implies(query));
-    assertTrue(collection1.implies(update));
-    assertTrue(collection1.implies(all));
-
-    assertFalse(query.implies(collection1));
-    assertFalse(update.implies(collection1));
-    assertTrue(all.implies(collection1));
-  }
-
-  @Test
-  public void testCollectionAll() throws Exception {
-    Privilege collectionAll = create(new KeyValue("collection", ALL));
-    Privilege collection1 = create(new KeyValue("collection", "coll1"));
-    assertTrue(collectionAll.implies(collection1));
-    assertTrue(collection1.implies(collectionAll));
-
-    Privilege allUpdate =
-      create(new KeyValue("collection", ALL), new KeyValue("action", "update"));
-    Privilege allQuery =
-      create(new KeyValue("collection", ALL), new KeyValue("action", "query"));
-    Privilege coll1Update =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
-    Privilege coll1Query =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
-    assertTrue(allUpdate.implies(coll1Update));
-    assertTrue(allQuery.implies(coll1Query));
-    assertTrue(coll1Update.implies(allUpdate));
-    assertTrue(coll1Query.implies(allQuery));
-    assertFalse(allUpdate.implies(coll1Query));
-    assertFalse(coll1Update.implies(coll1Query));
-    assertFalse(allQuery.implies(coll1Update));
-    assertFalse(coll1Query.implies(allUpdate));
-    assertFalse(allUpdate.implies(allQuery));
-    assertFalse(allQuery.implies(allUpdate));
-    assertFalse(coll1Update.implies(coll1Query));
-    assertFalse(coll1Query.implies(coll1Update));
-
-    // test different length paths
-    assertTrue(collectionAll.implies(allUpdate));
-    assertTrue(collectionAll.implies(allQuery));
-    assertTrue(collectionAll.implies(coll1Update));
-    assertTrue(collectionAll.implies(coll1Query));
-    assertFalse(allUpdate.implies(collectionAll));
-    assertFalse(allQuery.implies(collectionAll));
-    assertFalse(coll1Update.implies(collectionAll));
-    assertFalse(coll1Query.implies(collectionAll));
-  }
-
-  @Test
-  public void testActionAll() throws Exception {
-    Privilege coll1All =
-       create(new KeyValue("collection", "coll1"), new KeyValue("action", ALL));
-    Privilege coll1Update =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
-    Privilege coll1Query =
-      create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
-    assertTrue(coll1All.implies(coll1All));
-    assertTrue(coll1All.implies(coll1Update));
-    assertTrue(coll1All.implies(coll1Query));
-    assertFalse(coll1Update.implies(coll1All));
-    assertFalse(coll1Query.implies(coll1All));
-
-    // test different lengths
-    Privilege coll1 =
-       create(new KeyValue("collection", "coll1"));
-    assertTrue(coll1All.implies(coll1));
-    assertTrue(coll1.implies(coll1All));
-  }
-
-  @Test
-  public void testUnexpected() throws Exception {
-    Privilege p = new Privilege() {
-      @Override
-      public boolean implies(Privilege p) {
-        return false;
-      }
-    };
-    Privilege collection1 = create(new KeyValue("collection", "coll1"));
-    assertFalse(collection1.implies(null));
-    assertFalse(collection1.implies(p));
-    assertFalse(collection1.equals(null));
-    assertFalse(collection1.equals(p));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNullString() throws Exception {
-    System.out.println(create((String)null));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyString() throws Exception {
-    System.out.println(create(""));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(create(KV_JOINER.join("collection", "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(create(KV_JOINER.join("", "coll1")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyPart() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_JOINER.join("collection1", "coll1"), "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testOnlySeperators() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_SEPARATOR, KV_SEPARATOR, KV_SEPARATOR)));
-  }
-
-  static SearchWildcardPrivilege create(KeyValue... keyValues) {
-    return create(AUTHORIZABLE_JOINER.join(keyValues));
-
-  }
-  static SearchWildcardPrivilege create(String s) {
-    return new SearchWildcardPrivilege(s);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/resources/log4j.properties b/sentry-policy/sentry-policy-search/src/test/resources/log4j.properties
deleted file mode 100644
index c41373c..0000000
--- a/sentry-policy/sentry-policy-search/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# 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.
-#
-
-# Define some default values that can be overridden by system properties.
-#
-# For testing, it may also be convenient to specify
-
-log4j.rootLogger=DEBUG,console
-
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.target=System.err
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n
-
-log4j.logger.org.apache.hadoop.conf.Configuration=INFO

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-search/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-search/src/test/resources/test-authz-provider.ini b/sentry-policy/sentry-policy-search/src/test/resources/test-authz-provider.ini
deleted file mode 100644
index 8af8162..0000000
--- a/sentry-policy/sentry-policy-search/src/test/resources/test-authz-provider.ini
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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.
-
-[groups]
-manager = analyst_role, junior_analyst_role
-analyst = analyst_role
-jranalyst = junior_analyst_role
-admin = admin
-
-[roles]
-analyst_role = collection=purchases->action=update, \
-  collection=analyst1, \
-  collection=jranalyst1->action=*, \
-  collection=tmpcollection->action=update, \
-  collection=tmpcollection->action=query
-junior_analyst_role = collection=jranalyst1, collection=purchases_partial->action=query
-admin = collection=*

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/pom.xml b/sentry-policy/sentry-policy-sqoop/pom.xml
deleted file mode 100644
index 84d031a..0000000
--- a/sentry-policy/sentry-policy-sqoop/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<!--
-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.
--->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.sentry</groupId>
-    <artifactId>sentry-policy</artifactId>
-    <version>1.8.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>sentry-policy-sqoop</artifactId>
-  <name>Sentry Policy for Sqoop</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-minicluster</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.shiro</groupId>
-      <artifactId>shiro-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-core-model-sqoop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-file</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/ServerNameRequiredMatch.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/ServerNameRequiredMatch.java b/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/ServerNameRequiredMatch.java
deleted file mode 100644
index ef1c88b..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/ServerNameRequiredMatch.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.sqoop.Server;
-import org.apache.sentry.core.model.sqoop.SqoopAuthorizable;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.shiro.config.ConfigurationException;
-
-import com.google.common.collect.Lists;
-
-public class ServerNameRequiredMatch implements PrivilegeValidator {
-  private final String sqoopServerName;
-  public ServerNameRequiredMatch(String sqoopServerName) {
-    this.sqoopServerName = sqoopServerName;
-  }
-  @Override
-  public void validate(PrivilegeValidatorContext context)
-      throws ConfigurationException {
-    Iterable<SqoopAuthorizable> authorizables = parsePrivilege(context.getPrivilege());
-    boolean match = false;
-    for (SqoopAuthorizable authorizable : authorizables) {
-      if (authorizable instanceof Server && authorizable.getName().equalsIgnoreCase(sqoopServerName)) {
-        match = true;
-        break;
-      }
-    }
-    if (!match) {
-      String msg = "server=[name] in " + context.getPrivilege()
-          + " is required. The name is expected " + sqoopServerName;
-      throw new ConfigurationException(msg);
-    }
-  }
-
-  private Iterable<SqoopAuthorizable> parsePrivilege(String string) {
-    List<SqoopAuthorizable> result = Lists.newArrayList();
-    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
-      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
-        SqoopAuthorizable authorizable = SqoopModelAuthorizables.from(section);
-        if(authorizable == null) {
-          String msg = "No authorizable found for " + section;
-          throw new ConfigurationException(msg);
-        }
-        result.add(authorizable);
-      }
-    }
-    return result;
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java b/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
deleted file mode 100644
index 13f78c6..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SimpleSqoopPolicyEngine.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.util.Set;
-
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.provider.common.ProviderBackend;
-import org.apache.sentry.provider.common.ProviderBackendContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class SimpleSqoopPolicyEngine implements PolicyEngine {
-  private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSqoopPolicyEngine.class);
-  private final ProviderBackend providerBackend;
-
-  public SimpleSqoopPolicyEngine(String sqoopServerName, ProviderBackend providerBackend) {
-    this.providerBackend = providerBackend;
-    ProviderBackendContext context = new ProviderBackendContext();
-    context.setAllowPerDatabase(false);
-    context.setValidators(ImmutableList.<PrivilegeValidator>of(new ServerNameRequiredMatch(sqoopServerName)));
-    this.providerBackend.initialize(context);
-  }
-  @Override
-  public PrivilegeFactory getPrivilegeFactory() {
-    return new SqoopWildcardPrivilege.Factory();
-  }
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, roleSet);
-  }
-
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups,
-      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
-      throws SentryConfigurationException {
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for {}", groups);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet);
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, users, roleSet);
-  }
-
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet, Authorizable... authorizationHierarchy) {
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public void close() {
-    if (providerBackend != null) {
-      providerBackend.close();
-    }
-  }
-
-  @Override
-  public void validatePolicy(boolean strictValidation)
-      throws SentryConfigurationException {
-    if (providerBackend != null) {
-      providerBackend.validatePolicy(strictValidation);
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopModelAuthorizables.java b/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopModelAuthorizables.java
deleted file mode 100644
index b03b4dc..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopModelAuthorizables.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import org.apache.sentry.core.model.sqoop.Connector;
-import org.apache.sentry.core.model.sqoop.Job;
-import org.apache.sentry.core.model.sqoop.Link;
-import org.apache.sentry.core.model.sqoop.Server;
-import org.apache.sentry.core.model.sqoop.SqoopAuthorizable;
-import org.apache.sentry.core.model.sqoop.SqoopAuthorizable.AuthorizableType;
-import org.apache.sentry.policy.common.KeyValue;
-
-public class SqoopModelAuthorizables {
-  public static SqoopAuthorizable from(KeyValue keyValue) {
-    String prefix = keyValue.getKey().toLowerCase();
-    String name = keyValue.getValue().toLowerCase();
-    for (AuthorizableType type : AuthorizableType.values()) {
-      if(prefix.equalsIgnoreCase(type.name())) {
-        return from(type, name);
-      }
-    }
-    return null;
-  }
-
-  public static SqoopAuthorizable from(String keyValue) {
-    return from(new KeyValue(keyValue));
-  }
-
-  public static SqoopAuthorizable from(AuthorizableType type, String name) {
-    switch(type) {
-    case SERVER:
-      return new Server(name);
-    case JOB:
-      return new Job(name);
-    case CONNECTOR:
-      return new Connector(name);
-    case LINK:
-      return new Link(name);
-    default:
-      return null;
-    }
-  }
-}


[13/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)


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

Branch: refs/heads/master
Commit: d94e900af45342d20f0f3c8a56b18240340755f4
Parents: 6d79016
Author: Colin Ma <co...@apache.org>
Authored: Fri Apr 22 14:58:28 2016 +0800
Committer: Colin Ma <co...@apache.org>
Committed: Fri Apr 22 14:58:28 2016 +0800

----------------------------------------------------------------------
 SENTRY-999.001.patch                            | 18685 +++++++++++++++++
 pom.xml                                         |    17 +-
 .../sentry-binding-hive-common/pom.xml          |     4 -
 .../hive/SentryIniPolicyFileFormatter.java      |     6 +-
 .../binding/hive/authz/HiveAuthzBinding.java    |    43 +-
 .../sentry/binding/hive/conf/HiveAuthzConf.java |     2 +-
 sentry-binding/sentry-binding-hive/pom.xml      |    30 +
 .../hive/TestSentryIniPolicyFileFormatter.java  |     6 +-
 .../hive/AbstractTestSimplePolicyEngine.java    |   156 +
 .../sentry/policy/hive/DBPolicyTestUtil.java    |    45 +
 .../policy/hive/TestDBModelAuthorizables.java   |    77 +
 .../policy/hive/TestDatabaseRequiredInRole.java |    50 +
 .../policy/hive/TestPolicyParsingNegative.java  |   194 +
 ...sourceAuthorizationProviderGeneralCases.java |   195 +
 ...sourceAuthorizationProviderSpecialCases.java |   124 +
 .../hive/TestSimpleDBPolicyEngineDFS.java       |   115 +
 .../hive/TestSimpleDBPolicyEngineLocalFS.java   |    44 +
 .../hive/TestCommonPrivilegeForHive.java        |   344 +
 ...e-policy-test-authz-provider-other-group.ini |    22 +
 .../hive-policy-test-authz-provider.ini         |    32 +
 sentry-binding/sentry-binding-kafka/pom.xml     |     9 +-
 .../sentry/kafka/binding/KafkaAuthBinding.java  |   891 +-
 .../apache/sentry/kafka/conf/KafkaAuthConf.java |     4 +-
 .../kafka/AbstractTestKafkaPolicyEngine.java    |   163 +
 .../policy/kafka/KafkaPolicyTestUtil.java       |    48 +
 .../kafka/MockGroupMappingServiceProvider.java  |    39 +
 ...tKafkaAuthorizationProviderGeneralCases.java |   218 +
 ...tKafkaAuthorizationProviderSpecialCases.java |    90 +
 .../kafka/TestKafkaModelAuthorizables.java      |    87 +
 .../policy/kafka/TestKafkaPolicyEngineDFS.java  |    75 +
 .../kafka/TestKafkaPolicyEngineLocalFS.java     |    47 +
 .../policy/kafka/TestKafkaPolicyNegative.java   |   104 +
 .../kafka/TestKafkaPrivilegeValidator.java      |   170 +
 .../kafka/TestKafkaWildcardPrivilege.java       |   188 +
 .../kafka-policy-test-authz-provider.ini        |    38 +
 .../src/test/resources/sentry-site.xml          |     2 +-
 sentry-binding/sentry-binding-solr/pom.xml      |     4 -
 .../binding/solr/authz/SolrAuthzBinding.java    |    37 +-
 .../sentry/binding/solr/conf/SolrAuthzConf.java |     2 +-
 .../solr/AbstractTestSearchPolicyEngine.java    |   129 +
 .../policy/solr/SearchPolicyTestUtil.java       |    45 +
 .../solr/TestCollectionRequiredInRole.java      |    64 +
 ...SearchAuthorizationProviderGeneralCases.java |   193 +
 ...SearchAuthorizationProviderSpecialCases.java |    84 +
 .../solr/TestSearchModelAuthorizables.java      |    54 +
 .../policy/solr/TestSearchPolicyEngineDFS.java  |    74 +
 .../solr/TestSearchPolicyEngineLocalFS.java     |    43 +
 .../policy/solr/TestSearchPolicyNegative.java   |   101 +
 .../solr/TestCommonPrivilegeForSearch.java      |   214 +
 .../solr-policy-test-authz-provider.ini         |    31 +
 sentry-binding/sentry-binding-sqoop/pom.xml     |    17 +-
 .../sentry/sqoop/binding/SqoopAuthBinding.java  |    26 +-
 .../apache/sentry/sqoop/conf/SqoopAuthConf.java |     2 +-
 .../sqoop/AbstractTestSqoopPolicyEngine.java    |   145 +
 .../policy/sqoop/SqoopPolicyTestUtil.java       |    45 +
 .../sqoop/TestServerNameRequiredMatch.java      |    57 +
 ...tSqoopAuthorizationProviderGeneralCases.java |   241 +
 ...tSqoopAuthorizationProviderSpecialCases.java |    89 +
 .../sqoop/TestSqoopModelAuthorizables.java      |    54 +
 .../policy/sqoop/TestSqoopPolicyEngineDFS.java  |    75 +
 .../sqoop/TestSqoopPolicyEngineLocalFS.java     |    45 +
 .../policy/sqoop/TestSqoopPolicyNegative.java   |   121 +
 .../sqoop/TestCommonPrivilegeForSqoop.java      |   196 +
 .../sqoop-policy-test-authz-provider.ini        |    40 +
 .../sentry/core/common/BitFieldAction.java      |     2 +-
 .../sentry/core/common/ImplyMethodType.java     |    24 +
 .../org/apache/sentry/core/common/Model.java    |    29 +
 .../org/apache/sentry/core/common/Resource.java |    26 +
 .../sentry/core/common/utils/KeyValue.java      |    99 +
 .../core/common/utils/SentryConstants.java      |    43 +
 .../common/validator/PrivilegeValidator.java    |    24 +
 .../validator/PrivilegeValidatorContext.java    |    38 +
 .../sentry/core/common/utils/TestKeyValue.java  |    74 +
 .../core/model/db/DBModelAuthorizables.java     |    60 +
 .../sentry/core/model/db/HiveActionFactory.java |    73 +
 .../core/model/db/HivePrivilegeModel.java       |    68 +
 .../validator/AbstractDBPrivilegeValidator.java |    51 +
 .../model/db/validator/DatabaseMustMatch.java   |    46 +
 .../validator/DatabaseRequiredInPrivilege.java  |    72 +
 .../model/db/validator/ServerNameMustMatch.java |    43 +
 .../model/db/validator/ServersAllIsInvalid.java |    39 +
 .../indexer/IndexerModelAuthorizables.java      |    46 +
 .../model/indexer/IndexerPrivilegeModel.java    |    59 +
 .../AbstractIndexerPrivilegeValidator.java      |    51 +
 .../validator/IndexerRequiredInPrivilege.java   |    43 +
 .../core/model/kafka/KafkaActionFactory.java    |     4 +-
 .../model/kafka/KafkaModelAuthorizables.java    |    57 +
 .../core/model/kafka/KafkaPrivilegeModel.java   |    69 +
 .../validator/KafkaPrivilegeValidator.java      |   119 +
 .../model/search/SearchModelAuthorizables.java  |    46 +
 .../core/model/search/SearchPrivilegeModel.java |    60 +
 .../AbstractSearchPrivilegeValidator.java       |    52 +
 .../CollectionRequiredInPrivilege.java          |    43 +
 .../model/sqoop/SqoopModelAuthorizables.java    |    52 +
 .../core/model/sqoop/SqoopPrivilegeModel.java   |    63 +
 .../validator/ServerNameRequiredMatch.java      |    70 +
 sentry-dist/pom.xml                             |    16 -
 sentry-policy/pom.xml                           |     5 +-
 sentry-policy/sentry-policy-common/pom.xml      |     5 +
 .../sentry/policy/common/CommonPrivilege.java   |   176 +
 .../apache/sentry/policy/common/KeyValue.java   |    99 -
 .../sentry/policy/common/PolicyConstants.java   |    38 -
 .../apache/sentry/policy/common/Privilege.java  |     4 +-
 .../policy/common/PrivilegeValidator.java       |    24 -
 .../common/PrivilegeValidatorContext.java       |    38 -
 .../sentry/policy/common/ModelForTest.java      |    87 +
 .../policy/common/TestCommonPrivilege.java      |   147 +
 .../sentry/policy/common/TestKeyValue.java      |    76 -
 sentry-policy/sentry-policy-db/pom.xml          |    98 -
 .../policy/db/AbstractDBPrivilegeValidator.java |    50 -
 .../sentry/policy/db/DBModelAuthorizables.java  |    67 -
 .../sentry/policy/db/DBWildcardPrivilege.java   |   164 -
 .../sentry/policy/db/DatabaseMustMatch.java     |    46 -
 .../policy/db/DatabaseRequiredInPrivilege.java  |    71 -
 .../sentry/policy/db/ServerNameMustMatch.java   |    43 -
 .../sentry/policy/db/ServersAllIsInvalid.java   |    39 -
 .../sentry/policy/db/SimpleDBPolicyEngine.java  |   121 -
 .../db/AbstractTestSimplePolicyEngine.java      |   156 -
 .../sentry/policy/db/DBPolicyFileBackend.java   |    28 -
 .../policy/db/TestDBModelAuthorizables.java     |    75 -
 .../policy/db/TestDBWildcardPrivilege.java      |   335 -
 .../policy/db/TestDatabaseRequiredInRole.java   |    49 -
 .../policy/db/TestPolicyParsingNegative.java    |   194 -
 ...sourceAuthorizationProviderGeneralCases.java |   180 -
 ...sourceAuthorizationProviderSpecialCases.java |   122 -
 .../policy/db/TestSimpleDBPolicyEngineDFS.java  |   114 -
 .../db/TestSimpleDBPolicyEngineLocalFS.java     |    44 -
 .../src/test/resources/log4j.properties         |    31 -
 .../test-authz-provider-other-group.ini         |    22 -
 .../src/test/resources/test-authz-provider.ini  |    32 -
 sentry-policy/sentry-policy-engine/pom.xml      |    53 +
 .../engine/common/CommonPolicyEngine.java       |   106 +
 .../engine/common/CommonPrivilegeFactory.java   |    29 +
 sentry-policy/sentry-policy-indexer/pom.xml     |     4 +
 .../AbstractIndexerPrivilegeValidator.java      |    50 -
 .../indexer/IndexerModelAuthorizables.java      |    48 -
 .../indexer/IndexerRequiredInPrivilege.java     |    43 -
 .../indexer/IndexerWildcardPrivilege.java       |    13 +-
 .../indexer/SimpleIndexerPolicyEngine.java      |    13 +-
 .../policy/indexer/IndexPolicyTestUtil.java     |    44 +
 .../indexer/IndexerPolicyFileBackend.java       |    28 -
 .../indexer/TestCommonPrivilegeForIndexer.java  |   214 +
 ...ndexerAuthorizationProviderGeneralCases.java |     5 +-
 ...ndexerAuthorizationProviderSpecialCases.java |     6 +-
 .../indexer/TestIndexerModelAuthorizables.java  |     3 +-
 .../indexer/TestIndexerPolicyEngineDFS.java     |     2 +-
 .../indexer/TestIndexerPolicyEngineLocalFS.java |     2 +-
 .../indexer/TestIndexerPolicyNegative.java      |     6 +-
 .../indexer/TestIndexerRequiredInRole.java      |     3 +-
 .../indexer/TestIndexerWildcardPrivilege.java   |   203 -
 sentry-policy/sentry-policy-kafka/pom.xml       |    80 -
 .../policy/kafka/KafkaModelAuthorizables.java   |    62 -
 .../policy/kafka/KafkaPrivilegeValidator.java   |   118 -
 .../policy/kafka/KafkaWildcardPrivilege.java    |   146 -
 .../policy/kafka/SimpleKafkaPolicyEngine.java   |   107 -
 .../kafka/KafkaPolicyFileProviderBackend.java   |    34 -
 .../kafka/MockGroupMappingServiceProvider.java  |    39 -
 .../kafka/TestKafkaModelAuthorizables.java      |    86 -
 .../kafka/TestKafkaPrivilegeValidator.java      |   169 -
 .../kafka/TestKafkaWildcardPrivilege.java       |   175 -
 .../engine/AbstractTestKafkaPolicyEngine.java   |   163 -
 .../kafka/engine/TestKafkaPolicyEngineDFS.java  |    76 -
 .../engine/TestKafkaPolicyEngineLocalFS.java    |    47 -
 ...tKafkaAuthorizationProviderGeneralCases.java |   218 -
 ...tKafkaAuthorizationProviderSpecialCases.java |    88 -
 .../kafka/provider/TestKafkaPolicyNegative.java |   105 -
 .../src/test/resources/log4j.properties         |    31 -
 .../src/test/resources/test-authz-provider.ini  |    38 -
 sentry-policy/sentry-policy-search/pom.xml      |    87 -
 .../AbstractSearchPrivilegeValidator.java       |    51 -
 .../search/CollectionRequiredInPrivilege.java   |    43 -
 .../policy/search/SearchModelAuthorizables.java |    48 -
 .../policy/search/SearchWildcardPrivilege.java  |   144 -
 .../policy/search/SimpleSearchPolicyEngine.java |   121 -
 .../search/AbstractTestSearchPolicyEngine.java  |   129 -
 .../policy/search/SearchPolicyFileBackend.java  |    28 -
 .../search/TestCollectionRequiredInRole.java    |    63 -
 ...SearchAuthorizationProviderGeneralCases.java |   178 -
 ...SearchAuthorizationProviderSpecialCases.java |    82 -
 .../search/TestSearchModelAuthorizables.java    |    53 -
 .../search/TestSearchPolicyEngineDFS.java       |    74 -
 .../search/TestSearchPolicyEngineLocalFS.java   |    43 -
 .../policy/search/TestSearchPolicyNegative.java |   101 -
 .../search/TestSearchWildcardPrivilege.java     |   203 -
 .../src/test/resources/log4j.properties         |    31 -
 .../src/test/resources/test-authz-provider.ini  |    31 -
 sentry-policy/sentry-policy-sqoop/pom.xml       |    80 -
 .../policy/sqoop/ServerNameRequiredMatch.java   |    69 -
 .../policy/sqoop/SimpleSqoopPolicyEngine.java   |   105 -
 .../policy/sqoop/SqoopModelAuthorizables.java   |    57 -
 .../policy/sqoop/SqoopWildcardPrivilege.java    |   122 -
 .../sqoop/AbstractTestSqoopPolicyEngine.java    |   145 -
 .../sqoop/MockGroupMappingServiceProvider.java  |    39 -
 .../sqoop/SqoopPolicyFileProviderBackend.java   |    35 -
 .../sqoop/TestServerNameRequiredMatch.java      |    56 -
 ...tSqoopAuthorizationProviderGeneralCases.java |   225 -
 ...tSqoopAuthorizationProviderSpecialCases.java |    87 -
 .../sqoop/TestSqoopModelAuthorizables.java      |    53 -
 .../policy/sqoop/TestSqoopPolicyEngineDFS.java  |    75 -
 .../sqoop/TestSqoopPolicyEngineLocalFS.java     |    44 -
 .../policy/sqoop/TestSqoopPolicyNegative.java   |   121 -
 .../sqoop/TestSqoopWildcardPrivilege.java       |   176 -
 .../src/test/resources/log4j.properties         |    31 -
 .../src/test/resources/test-authz-provider.ini  |    40 -
 ...adoopGroupResourceAuthorizationProvider.java |    15 +-
 .../provider/common/ProviderBackendContext.java |     2 +-
 .../common/ResourceAuthorizationProvider.java   |    15 +-
 ...adoopGroupResourceAuthorizationProvider.java |    14 +-
 .../provider/common/TestGetGroupMapping.java    |     2 +-
 sentry-provider/sentry-provider-db/pom.xml      |     6 +-
 .../service/persistent/PrivilegeObject.java     |     4 +-
 .../thrift/SentryGenericPolicyProcessor.java    |    14 +-
 .../tools/KafkaTSentryPrivilegeConvertor.java   |    20 +-
 .../db/generic/tools/SentryConfigToolSolr.java  |    10 +-
 .../tools/SolrTSentryPrivilegeConvertor.java    |    24 +-
 .../db/service/model/MSentryGMPrivilege.java    |     4 +-
 .../db/service/persistent/SentryStore.java      |     8 +-
 .../db/tools/command/hive/CommandUtil.java      |     6 +-
 .../tools/command/hive/ListPrivilegesCmd.java   |    18 +-
 .../service/thrift/SentryServiceUtil.java       |    24 +-
 .../db/generic/tools/TestSentryShellKafka.java  |     2 +-
 .../thrift/TestSentryServiceImportExport.java   |     6 +-
 .../provider/file/LocalGroupMappingService.java |     4 +-
 ...LocalGroupResourceAuthorizationProvider.java |    11 +-
 .../file/SimpleFileProviderBackend.java         |     6 +-
 sentry-solr/solr-sentry-handlers/pom.xml        |     4 -
 sentry-tests/sentry-tests-hive/pom.xml          |     5 -
 .../AbstractTestWithStaticConfiguration.java    |     8 +-
 .../tests/e2e/hive/TestPerDBConfiguration.java  |    10 +-
 .../tests/e2e/hive/TestPolicyImportExport.java  |     6 +-
 .../metastore/SentryPolicyProviderForDb.java    |     8 +-
 231 files changed, 26741 insertions(+), 8275 deletions(-)
----------------------------------------------------------------------



[07/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java
new file mode 100644
index 0000000..231acca
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HivePrivilegeModel.java
@@ -0,0 +1,68 @@
+/*
+ * 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.sentry.core.model.db;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.db.validator.DatabaseMustMatch;
+import org.apache.sentry.core.model.db.validator.DatabaseRequiredInPrivilege;
+import org.apache.sentry.core.model.db.validator.ServerNameMustMatch;
+import org.apache.sentry.core.model.db.validator.ServersAllIsInvalid;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+
+public class HivePrivilegeModel implements Model {
+  private Map<String, ImplyMethodType> implyMethodMap;
+  private BitFieldActionFactory bitFieldActionFactory;
+  private static HivePrivilegeModel hivePrivilegeModel = new HivePrivilegeModel();
+
+  private HivePrivilegeModel() {
+    implyMethodMap = new HashMap<String, ImplyMethodType>();
+    bitFieldActionFactory = new HiveActionFactory();
+
+    implyMethodMap.put(AuthorizableType.Server.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(AuthorizableType.Db.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(AuthorizableType.Table.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(AuthorizableType.Column.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(AuthorizableType.URI.name().toLowerCase(), ImplyMethodType.URL);
+  }
+
+  @Override
+  public Map<String, ImplyMethodType> getImplyMethodMap() {
+    return implyMethodMap;
+  }
+
+  @Override
+  public BitFieldActionFactory getBitFieldActionFactory() {
+    return bitFieldActionFactory;
+  }
+
+  public static HivePrivilegeModel getInstance() {
+    return hivePrivilegeModel;
+  }
+
+  public ImmutableList<PrivilegeValidator> getPrivilegeValidators(String serverName) {
+    return ImmutableList.<PrivilegeValidator>of(new ServersAllIsInvalid(), new DatabaseMustMatch(),
+            new DatabaseRequiredInPrivilege(), new ServerNameMustMatch(serverName));
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java
new file mode 100644
index 0000000..fa28716
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/AbstractDBPrivilegeValidator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.sentry.core.model.db.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.db.DBModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractDBPrivilegeValidator implements PrivilegeValidator {
+
+  @VisibleForTesting
+  public static Iterable<DBModelAuthorizable> parsePrivilege(String string) {
+    List<DBModelAuthorizable> result = Lists.newArrayList();
+    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+      // XXX this ugly hack is because action is not an authorizeable
+      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+        DBModelAuthorizable authorizable = DBModelAuthorizables.from(section);
+        if(authorizable == null) {
+          String msg = "No authorizable found for " + section;
+          throw new ConfigurationException(msg);
+        }
+        result.add(authorizable);
+      }
+    }
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java
new file mode 100644
index 0000000..4276667
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseMustMatch.java
@@ -0,0 +1,46 @@
+/*
+ * 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.sentry.core.model.db.validator;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class DatabaseMustMatch extends AbstractDBPrivilegeValidator {
+
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+    String database = context.getDatabase();
+    String privilege = context.getPrivilege();
+    /*
+     *  Rule only applies to rules in per database policy file
+     */
+    if(database != null) {
+      Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+      for(DBModelAuthorizable authorizable : authorizables) {
+        if(authorizable instanceof Database &&
+            !database.equalsIgnoreCase(authorizable.getName())) {
+          String msg = "Privilege " + privilege + " references db " +
+              authorizable.getName() + ", but is only allowed to reference "
+              + database;
+          throw new ConfigurationException(msg);
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java
new file mode 100644
index 0000000..fed3038
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/DatabaseRequiredInPrivilege.java
@@ -0,0 +1,72 @@
+/*
+ * 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.sentry.core.model.db.validator;
+
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.db.AccessURI;
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class DatabaseRequiredInPrivilege extends AbstractDBPrivilegeValidator {
+
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+    String database = context.getDatabase();
+    String privilege = context.getPrivilege();
+    /*
+     *  Rule only applies to rules in per database policy file
+     */
+    if(database != null) {
+      Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+      /*
+       * Each permission in a non-global file must have a database
+       * object except for URIs.
+       *
+       * We allow URIs to be specified in the per DB policy file for
+       * ease of mangeability. URIs will contain to remain server scope
+       * objects.
+       */
+      boolean foundDatabaseInAuthorizables = false;
+      boolean foundURIInAuthorizables = false;
+      boolean allowURIInAuthorizables = false;
+
+      if ("true".equalsIgnoreCase(
+          System.getProperty(SentryConstants.ACCESS_ALLOW_URI_PER_DB_POLICYFILE))) {
+        allowURIInAuthorizables = true;
+      }
+
+      for(DBModelAuthorizable authorizable : authorizables) {
+        if(authorizable instanceof Database) {
+          foundDatabaseInAuthorizables = true;
+        }
+        if (authorizable instanceof AccessURI) {
+          if (foundDatabaseInAuthorizables) {
+            String msg = "URI object is specified at DB scope in " + privilege;
+            throw new ConfigurationException(msg);
+          }
+          foundURIInAuthorizables = true;
+        }
+      }
+      if(!foundDatabaseInAuthorizables && !(foundURIInAuthorizables && allowURIInAuthorizables)) {
+        String msg = "Missing database object in " + privilege;
+        throw new ConfigurationException(msg);
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java
new file mode 100644
index 0000000..c79a8bf
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServerNameMustMatch.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sentry.core.model.db.validator;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class ServerNameMustMatch extends AbstractDBPrivilegeValidator {
+
+  private final String serverName;
+  public ServerNameMustMatch(String serverName) {
+    this.serverName = serverName;
+  }
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+    String privilege = context.getPrivilege();
+    Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+    for(DBModelAuthorizable authorizable : authorizables) {
+      if(authorizable instanceof Server && !serverName.equalsIgnoreCase(authorizable.getName())) {
+        String msg = "Server name " + authorizable.getName() + " in "
+            + privilege + " is invalid. Expected " + serverName;
+        throw new ConfigurationException(msg);
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java
new file mode 100644
index 0000000..e3f5a3a
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/validator/ServersAllIsInvalid.java
@@ -0,0 +1,39 @@
+/*
+ * 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.sentry.core.model.db.validator;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.shiro.config.ConfigurationException;
+
+public class ServersAllIsInvalid extends AbstractDBPrivilegeValidator {
+
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+    String privilege = context.getPrivilege();
+    Iterable<DBModelAuthorizable> authorizables = parsePrivilege(privilege);
+    for(DBModelAuthorizable authorizable : authorizables) {
+      if(authorizable instanceof Server &&
+          authorizable.getName().equals(Server.ALL.getName())) {
+        String msg = "Invalid value for " + authorizable.getAuthzType() + " in " + privilege;
+        throw new ConfigurationException(msg);
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java
new file mode 100644
index 0000000..d15e911
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerModelAuthorizables.java
@@ -0,0 +1,46 @@
+/*
+ * 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.sentry.core.model.indexer;
+
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+public class IndexerModelAuthorizables {
+
+  public static IndexerModelAuthorizable from(KeyValue keyValue) {
+    String prefix = keyValue.getKey().toLowerCase();
+    String name = keyValue.getValue().toLowerCase();
+    for(AuthorizableType type : AuthorizableType.values()) {
+      if(prefix.equalsIgnoreCase(type.name())) {
+        return from(type, name);
+      }
+    }
+    return null;
+  }
+  public static IndexerModelAuthorizable from(String s) {
+    return from(new KeyValue(s));
+  }
+
+  private static IndexerModelAuthorizable from(AuthorizableType type, String name) {
+    switch (type) {
+    case Indexer:
+      return new Indexer(name);
+    default:
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java
new file mode 100644
index 0000000..6951513
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/IndexerPrivilegeModel.java
@@ -0,0 +1,59 @@
+/*
+ * 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.sentry.core.model.indexer;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.indexer.validator.IndexerRequiredInPrivilege;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class IndexerPrivilegeModel implements Model {
+
+  private Map<String, ImplyMethodType> implyMethodMap;
+  private BitFieldActionFactory bitFieldActionFactory;
+  private static IndexerPrivilegeModel indexerPrivilegeModel = new IndexerPrivilegeModel();;
+
+  private IndexerPrivilegeModel() {
+    implyMethodMap = new HashMap<String, ImplyMethodType>();
+    bitFieldActionFactory = new IndexerActionFactory();
+
+    implyMethodMap.put(IndexerModelAuthorizable.AuthorizableType.Indexer.name().toLowerCase(), ImplyMethodType.STRING);
+  }
+
+  @Override
+  public Map<String, ImplyMethodType> getImplyMethodMap() {
+    return implyMethodMap;
+  }
+
+  @Override
+  public BitFieldActionFactory getBitFieldActionFactory() {
+    return bitFieldActionFactory;
+  }
+
+  public static IndexerPrivilegeModel getInstance() {
+    return indexerPrivilegeModel;
+  }
+
+  public ImmutableList<PrivilegeValidator> getPrivilegeValidators() {
+    return ImmutableList.<PrivilegeValidator>of(new IndexerRequiredInPrivilege());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java
new file mode 100644
index 0000000..c73fc3c
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/AbstractIndexerPrivilegeValidator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.sentry.core.model.indexer.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractIndexerPrivilegeValidator implements PrivilegeValidator {
+
+  @VisibleForTesting
+  public static Iterable<IndexerModelAuthorizable> parsePrivilege(String string) {
+    List<IndexerModelAuthorizable> result = Lists.newArrayList();
+    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+      // XXX this ugly hack is because action is not an authorizable
+      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+        IndexerModelAuthorizable authorizable = IndexerModelAuthorizables.from(section);
+        if(authorizable == null) {
+          String msg = "No authorizable found for " + section;
+          throw new ConfigurationException(msg);
+        }
+        result.add(authorizable);
+      }
+    }
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java
new file mode 100644
index 0000000..82bc25d
--- /dev/null
+++ b/sentry-core/sentry-core-model-indexer/src/main/java/org/apache/sentry/core/model/indexer/validator/IndexerRequiredInPrivilege.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sentry.core.model.indexer.validator;
+
+import org.apache.sentry.core.common.SentryConfigurationException;
+import org.apache.sentry.core.model.indexer.Indexer;
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+
+public class IndexerRequiredInPrivilege extends AbstractIndexerPrivilegeValidator {
+
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws SentryConfigurationException {
+    String privilege = context.getPrivilege();
+    Iterable<IndexerModelAuthorizable> authorizables = parsePrivilege(privilege);
+    boolean foundIndexerInAuthorizables = false;
+
+    for(IndexerModelAuthorizable authorizable : authorizables) {
+      if(authorizable instanceof Indexer) {
+        foundIndexerInAuthorizables = true;
+        break;
+      }
+    }
+    if(!foundIndexerInAuthorizables) {
+      String msg = "Missing indexer object in " + privilege;
+      throw new SentryConfigurationException(msg);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
index fc3bf7a..a1fec1f 100644
--- a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaActionFactory.java
@@ -52,9 +52,9 @@ public class KafkaActionFactory extends BitFieldActionFactory {
     DELETE(KafkaActionConstant.DELETE, 8),
     ALTER(KafkaActionConstant.ALTER, 16),
     DESCRIBE(KafkaActionConstant.DESCRIBE, 32),
-    CLUSTER_ACTION(KafkaActionConstant.CLUSTER_ACTION, 64),
+    CLUSTERACTION(KafkaActionConstant.CLUSTER_ACTION, 64),
     ALL(KafkaActionConstant.ALL, READ.getCode() | WRITE.getCode() | CREATE.getCode()
-        | DELETE.getCode() | ALTER.getCode()| DESCRIBE.getCode() | CLUSTER_ACTION.getCode());
+        | DELETE.getCode() | ALTER.getCode()| DESCRIBE.getCode() | CLUSTERACTION.getCode());
 
     private String name;
     private int code;

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java
new file mode 100644
index 0000000..45a1148
--- /dev/null
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaModelAuthorizables.java
@@ -0,0 +1,57 @@
+/*
+ * 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.sentry.core.model.kafka;
+
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.model.kafka.KafkaAuthorizable.AuthorizableType;
+import org.apache.shiro.config.ConfigurationException;
+
+public class KafkaModelAuthorizables {
+  public static KafkaAuthorizable from(KeyValue keyValue) throws ConfigurationException {
+    String prefix = keyValue.getKey().toLowerCase();
+    String name = keyValue.getValue();
+    for (AuthorizableType type : AuthorizableType.values()) {
+      if (prefix.equalsIgnoreCase(type.name())) {
+        return from(type, name);
+      }
+    }
+    return null;
+  }
+
+  public static KafkaAuthorizable from(String keyValue) throws ConfigurationException {
+    return from(new KeyValue(keyValue));
+  }
+
+  public static KafkaAuthorizable from(AuthorizableType type, String name) throws ConfigurationException {
+    switch (type) {
+      case HOST:
+        return new Host(name);
+      case CLUSTER: {
+        if (!name.equals(Cluster.NAME)) {
+          throw new ConfigurationException("Kafka's cluster resource can only have name " + Cluster.NAME);
+        }
+        return new Cluster();
+      }
+      case TOPIC:
+        return new Topic(name);
+      case CONSUMERGROUP:
+        return new ConsumerGroup(name);
+      default:
+        return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java
new file mode 100644
index 0000000..74c887e
--- /dev/null
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/KafkaPrivilegeModel.java
@@ -0,0 +1,69 @@
+/**
+ * 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.sentry.core.model.kafka;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.kafka.validator.KafkaPrivilegeValidator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class KafkaPrivilegeModel implements Model {
+
+  private Map<String, ImplyMethodType> implyMethodMap;
+  private BitFieldActionFactory bitFieldActionFactory;
+  private static KafkaPrivilegeModel kafkaPrivilegeModel = new KafkaPrivilegeModel();
+
+  private KafkaPrivilegeModel() {
+    implyMethodMap = new HashMap<String, ImplyMethodType>();
+    bitFieldActionFactory = KafkaActionFactory.getInstance();
+
+    implyMethodMap.put(KafkaAuthorizable.AuthorizableType.CLUSTER.name().toLowerCase(),
+        ImplyMethodType.STRING);
+    implyMethodMap.put(KafkaAuthorizable.AuthorizableType.HOST.name().toLowerCase(),
+        ImplyMethodType.STRING);
+    implyMethodMap.put(KafkaAuthorizable.AuthorizableType.TOPIC.name().toLowerCase(),
+        ImplyMethodType.STRING);
+    implyMethodMap.put(KafkaAuthorizable.AuthorizableType.CONSUMERGROUP.name().toLowerCase(),
+        ImplyMethodType.STRING);
+  }
+
+  @Override
+  public Map<String, ImplyMethodType> getImplyMethodMap() {
+    return implyMethodMap;
+  }
+
+  @Override
+  public BitFieldActionFactory getBitFieldActionFactory() {
+    return bitFieldActionFactory;
+  }
+
+  public static KafkaPrivilegeModel getInstance() {
+    return kafkaPrivilegeModel;
+  }
+
+  public ImmutableList<PrivilegeValidator> getPrivilegeValidators() {
+    return ImmutableList.<PrivilegeValidator>of(new KafkaPrivilegeValidator());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java
new file mode 100644
index 0000000..5c45865
--- /dev/null
+++ b/sentry-core/sentry-core-model-kafka/src/main/java/org/apache/sentry/core/model/kafka/validator/KafkaPrivilegeValidator.java
@@ -0,0 +1,119 @@
+/*
+ * 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.sentry.core.model.kafka.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.kafka.KafkaActionFactory;
+import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
+import org.apache.sentry.core.model.kafka.Host;
+import org.apache.sentry.core.model.kafka.KafkaModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Validator for Kafka privileges.
+ * Below are the requirements for a kafka privilege to be valid.
+ * 1. Privilege must start with Host resource.
+ * 2. Privilege must have at most one non Host resource, Cluster or Topic or ConsumerGroup, followed
+ *    by Host resource.
+ * 3. Privilege must end with exactly one action.
+ */
+public class KafkaPrivilegeValidator implements PrivilegeValidator {
+
+  public static final String KafkaPrivilegeHelpMsg =
+      "Invalid Kafka privilege." +
+      " Kafka privilege must be of the form host=<HOST>-><RESOURCE>=<RESOURCE_NAME>->action=<ACTION>," +
+      " where <HOST> can be '*' or any valid host name," +
+      " <RESOURCE> can be one of " + Arrays.toString(getKafkaAuthorizablesExceptHost()) +
+      " <RESOURCE_NAME> is name of the resource," +
+      " <ACTION> can be one of " + Arrays.toString(KafkaActionFactory.KafkaActionType.values()) +
+      ".";
+
+  private static KafkaAuthorizable.AuthorizableType[] getKafkaAuthorizablesExceptHost() {
+    final KafkaAuthorizable.AuthorizableType[] authorizableTypes = KafkaAuthorizable.AuthorizableType.values();
+    List<KafkaAuthorizable.AuthorizableType> authorizableTypesWithoutHost = new ArrayList<>(authorizableTypes.length - 1);
+    for (KafkaAuthorizable.AuthorizableType authorizableType: authorizableTypes) {
+      if (!authorizableType.equals(KafkaAuthorizable.AuthorizableType.HOST)) {
+        authorizableTypesWithoutHost.add(authorizableType);
+      }
+    }
+    return authorizableTypesWithoutHost.toArray(new KafkaAuthorizable.AuthorizableType[authorizableTypesWithoutHost.size()]);
+  }
+
+  public KafkaPrivilegeValidator() {
+  }
+
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
+    List<String> splits = Lists.newArrayList();
+    for (String section : AUTHORIZABLE_SPLITTER.split(context.getPrivilege())) {
+      splits.add(section);
+    }
+
+    // Check privilege splits length is 2 or 3
+    if (splits.size() < 2 || splits.size() > 3) {
+      throw new ConfigurationException(KafkaPrivilegeHelpMsg);
+    }
+
+    // Check privilege starts with Host resource
+    if (isAction(splits.get(0))) {
+      throw new ConfigurationException("Kafka privilege can not start with an action.\n" + KafkaPrivilegeHelpMsg);
+    }
+    KafkaAuthorizable hostAuthorizable = KafkaModelAuthorizables.from(splits.get(0));
+    if (hostAuthorizable == null) {
+      throw new ConfigurationException("No Kafka authorizable found for " + splits.get(0) + "\n." + KafkaPrivilegeHelpMsg);
+    }
+    if (!(hostAuthorizable instanceof Host)) {
+      throw new ConfigurationException("Kafka privilege must begin with host authorizable.\n" + KafkaPrivilegeHelpMsg);
+    }
+
+    // Check privilege has at most one non Host resource following Host resource
+    if (splits.size() == 3) {
+      if (isAction(splits.get(1))) {
+        throw new ConfigurationException("Kafka privilege can have action only at the end of privilege.\n" + KafkaPrivilegeHelpMsg);
+      }
+      KafkaAuthorizable authorizable = KafkaModelAuthorizables.from(splits.get(1));
+      if (authorizable == null) {
+        throw new ConfigurationException("No Kafka authorizable found for " + splits.get(1) + "\n." + KafkaPrivilegeHelpMsg);
+      }
+      if (authorizable instanceof Host) {
+        throw new ConfigurationException("Host authorizable can be specified just once in a Kafka privilege.\n" + KafkaPrivilegeHelpMsg);
+      }
+    }
+
+    // Check privilege ends with exactly one valid action
+    if (!isAction(splits.get(splits.size() - 1))) {
+      throw new ConfigurationException("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeHelpMsg);
+    }
+  }
+
+  private boolean isAction(String privilegePart) {
+    final String privilege = privilegePart.toLowerCase();
+    final String action = privilege.replace(PRIVILEGE_PREFIX, "").toLowerCase();
+    return privilege.startsWith(PRIVILEGE_PREFIX) &&
+        KafkaActionFactory.getInstance().getActionByName(action) != null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java
new file mode 100644
index 0000000..c3292c7
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchModelAuthorizables.java
@@ -0,0 +1,46 @@
+/*
+ * 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.sentry.core.model.search;
+
+import org.apache.sentry.core.model.search.SearchModelAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+public class SearchModelAuthorizables {
+
+  public static SearchModelAuthorizable from(KeyValue keyValue) {
+    String prefix = keyValue.getKey().toLowerCase();
+    String name = keyValue.getValue().toLowerCase();
+    for(AuthorizableType type : AuthorizableType.values()) {
+      if(prefix.equalsIgnoreCase(type.name())) {
+        return from(type, name);
+      }
+    }
+    return null;
+  }
+  public static SearchModelAuthorizable from(String s) {
+    return from(new KeyValue(s));
+  }
+
+  private static SearchModelAuthorizable from(AuthorizableType type, String name) {
+    switch (type) {
+    case Collection:
+      return new Collection(name);
+    default:
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java
new file mode 100644
index 0000000..9429a25
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/SearchPrivilegeModel.java
@@ -0,0 +1,60 @@
+/*
+ * 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.sentry.core.model.search;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.search.validator.CollectionRequiredInPrivilege;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SearchPrivilegeModel implements Model {
+
+  private Map<String, ImplyMethodType> implyMethodMap;
+  private BitFieldActionFactory bitFieldActionFactory;
+  private static SearchPrivilegeModel searchPrivilegeModel = new SearchPrivilegeModel();
+
+  private SearchPrivilegeModel() {
+    implyMethodMap = new HashMap<String, ImplyMethodType>();
+    bitFieldActionFactory = new SearchActionFactory();
+
+    implyMethodMap.put(SearchModelAuthorizable.AuthorizableType.Collection.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(SearchModelAuthorizable.AuthorizableType.Field.name().toLowerCase(), ImplyMethodType.STRING);
+  }
+
+  @Override
+  public Map<String, ImplyMethodType> getImplyMethodMap() {
+    return implyMethodMap;
+  }
+
+  @Override
+  public BitFieldActionFactory getBitFieldActionFactory() {
+    return bitFieldActionFactory;
+  }
+
+  public static SearchPrivilegeModel getInstance() {
+    return searchPrivilegeModel;
+  }
+
+  public ImmutableList<PrivilegeValidator> getPrivilegeValidators() {
+    return ImmutableList.<PrivilegeValidator>of(new CollectionRequiredInPrivilege());
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java
new file mode 100644
index 0000000..c06131c
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/AbstractSearchPrivilegeValidator.java
@@ -0,0 +1,52 @@
+/*
+ * 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.sentry.core.model.search.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.search.SearchModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+
+public abstract class AbstractSearchPrivilegeValidator implements PrivilegeValidator {
+
+  @VisibleForTesting
+  public static Iterable<SearchModelAuthorizable> parsePrivilege(String string) {
+    List<SearchModelAuthorizable> result = Lists.newArrayList();
+    System.err.println("privilege = " + string);
+    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+      // XXX this ugly hack is because action is not an authorizable
+      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+        SearchModelAuthorizable authorizable = SearchModelAuthorizables.from(section);
+        if(authorizable == null) {
+          String msg = "No authorizable found for " + section;
+          throw new ConfigurationException(msg);
+        }
+        result.add(authorizable);
+      }
+    }
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java
new file mode 100644
index 0000000..17b87df
--- /dev/null
+++ b/sentry-core/sentry-core-model-search/src/main/java/org/apache/sentry/core/model/search/validator/CollectionRequiredInPrivilege.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sentry.core.model.search.validator;
+
+import org.apache.sentry.core.common.SentryConfigurationException;
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+
+public class CollectionRequiredInPrivilege extends AbstractSearchPrivilegeValidator {
+
+  @Override
+  public void validate(PrivilegeValidatorContext context) throws SentryConfigurationException {
+    String privilege = context.getPrivilege();
+    Iterable<SearchModelAuthorizable> authorizables = parsePrivilege(privilege);
+    boolean foundCollectionInAuthorizables = false;
+
+    for(SearchModelAuthorizable authorizable : authorizables) {
+      if(authorizable instanceof Collection) {
+        foundCollectionInAuthorizables = true;
+        break;
+      }
+    }
+    if(!foundCollectionInAuthorizables) {
+      String msg = "Missing collection object in " + privilege;
+      throw new SentryConfigurationException(msg);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java
new file mode 100644
index 0000000..11ce7ec
--- /dev/null
+++ b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopModelAuthorizables.java
@@ -0,0 +1,52 @@
+/*
+ * 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.sentry.core.model.sqoop;
+
+import org.apache.sentry.core.model.sqoop.SqoopAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+public class SqoopModelAuthorizables {
+  public static SqoopAuthorizable from(KeyValue keyValue) {
+    String prefix = keyValue.getKey().toLowerCase();
+    String name = keyValue.getValue().toLowerCase();
+    for (AuthorizableType type : AuthorizableType.values()) {
+      if(prefix.equalsIgnoreCase(type.name())) {
+        return from(type, name);
+      }
+    }
+    return null;
+  }
+
+  public static SqoopAuthorizable from(String keyValue) {
+    return from(new KeyValue(keyValue));
+  }
+
+  public static SqoopAuthorizable from(AuthorizableType type, String name) {
+    switch(type) {
+    case SERVER:
+      return new Server(name);
+    case JOB:
+      return new Job(name);
+    case CONNECTOR:
+      return new Connector(name);
+    case LINK:
+      return new Link(name);
+    default:
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java
new file mode 100644
index 0000000..4bd8f94
--- /dev/null
+++ b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/SqoopPrivilegeModel.java
@@ -0,0 +1,63 @@
+/*
+ * 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.sentry.core.model.sqoop;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.sqoop.validator.ServerNameRequiredMatch;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SqoopPrivilegeModel implements Model {
+
+  private Map<String, ImplyMethodType> implyMethodMap;
+  private BitFieldActionFactory bitFieldActionFactory;
+  private static SqoopPrivilegeModel sqoopPrivilegeModel = new SqoopPrivilegeModel();
+
+  private SqoopPrivilegeModel() {
+    implyMethodMap = new HashMap<String, ImplyMethodType>();
+    bitFieldActionFactory = new SqoopActionFactory();
+
+    implyMethodMap.put(SqoopAuthorizable.AuthorizableType.SERVER.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(SqoopAuthorizable.AuthorizableType.CONNECTOR.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(SqoopAuthorizable.AuthorizableType.LINK.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(SqoopAuthorizable.AuthorizableType.JOB.name().toLowerCase(), ImplyMethodType.STRING);
+  }
+
+  @Override
+  public Map<String, ImplyMethodType> getImplyMethodMap() {
+    return implyMethodMap;
+  }
+
+  @Override
+  public BitFieldActionFactory getBitFieldActionFactory() {
+    return bitFieldActionFactory;
+  }
+
+  public static SqoopPrivilegeModel getInstance() {
+    return sqoopPrivilegeModel;
+  }
+
+  public ImmutableList<PrivilegeValidator> getPrivilegeValidators(String sqoopServerName) {
+    return ImmutableList.<PrivilegeValidator>of(new ServerNameRequiredMatch(sqoopServerName));
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java
new file mode 100644
index 0000000..67347bc
--- /dev/null
+++ b/sentry-core/sentry-core-model-sqoop/src/main/java/org/apache/sentry/core/model/sqoop/validator/ServerNameRequiredMatch.java
@@ -0,0 +1,70 @@
+/*
+ * 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.sentry.core.model.sqoop.validator;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_PREFIX;
+
+import java.util.List;
+
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopAuthorizable;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.model.sqoop.SqoopModelAuthorizables;
+import org.apache.shiro.config.ConfigurationException;
+
+import com.google.common.collect.Lists;
+
+public class ServerNameRequiredMatch implements PrivilegeValidator {
+  private final String sqoopServerName;
+  public ServerNameRequiredMatch(String sqoopServerName) {
+    this.sqoopServerName = sqoopServerName;
+  }
+  @Override
+  public void validate(PrivilegeValidatorContext context)
+      throws ConfigurationException {
+    Iterable<SqoopAuthorizable> authorizables = parsePrivilege(context.getPrivilege());
+    boolean match = false;
+    for (SqoopAuthorizable authorizable : authorizables) {
+      if (authorizable instanceof Server && authorizable.getName().equalsIgnoreCase(sqoopServerName)) {
+        match = true;
+        break;
+      }
+    }
+    if (!match) {
+      String msg = "server=[name] in " + context.getPrivilege()
+          + " is required. The name is expected " + sqoopServerName;
+      throw new ConfigurationException(msg);
+    }
+  }
+
+  private Iterable<SqoopAuthorizable> parsePrivilege(String string) {
+    List<SqoopAuthorizable> result = Lists.newArrayList();
+    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
+      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
+        SqoopAuthorizable authorizable = SqoopModelAuthorizables.from(section);
+        if(authorizable == null) {
+          String msg = "No authorizable found for " + section;
+          throw new ConfigurationException(msg);
+        }
+        result.add(authorizable);
+      }
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index 130de75..80ec9c9 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -92,24 +92,8 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-db</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-policy-indexer</artifactId>
     </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-search</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-sqoop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-kafka</artifactId>
-    </dependency>
   </dependencies>
   <profiles>
     <profile>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/pom.xml b/sentry-policy/pom.xml
index 4abcf03..14fe829 100644
--- a/sentry-policy/pom.xml
+++ b/sentry-policy/pom.xml
@@ -31,11 +31,8 @@ limitations under the License.
 
   <modules>
     <module>sentry-policy-common</module>
-    <module>sentry-policy-db</module>
+    <module>sentry-policy-engine</module>
     <module>sentry-policy-indexer</module>
-    <module>sentry-policy-search</module>
-    <module>sentry-policy-sqoop</module>
-    <module>sentry-policy-kafka</module>
   </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/pom.xml b/sentry-policy/sentry-policy-common/pom.xml
index 1f8c522..57fc9d9 100644
--- a/sentry-policy/sentry-policy-common/pom.xml
+++ b/sentry-policy/sentry-policy-common/pom.xml
@@ -45,6 +45,11 @@ limitations under the License.
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-model-db</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
new file mode 100644
index 0000000..dedd908
--- /dev/null
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/CommonPrivilege.java
@@ -0,0 +1,176 @@
+/*
+ * 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.sentry.policy.common;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.apache.sentry.core.common.BitFieldAction;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.ImplyMethodType;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.PathUtils;
+import org.apache.sentry.core.common.utils.SentryConstants;
+
+import java.util.List;
+
+// The class is used to compare the privilege
+public class CommonPrivilege implements Privilege {
+
+  private ImmutableList<KeyValue> parts;
+
+  public CommonPrivilege(String privilegeStr) {
+    privilegeStr = Strings.nullToEmpty(privilegeStr).trim();
+    if (privilegeStr.isEmpty()) {
+      throw new IllegalArgumentException("Privilege string cannot be null or empty.");
+    }
+    List<KeyValue> parts = Lists.newArrayList();
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.trimResults().split(
+            privilegeStr)) {
+      if (authorizable.isEmpty()) {
+        throw new IllegalArgumentException("Privilege '" + privilegeStr + "' has an empty section");
+      }
+      parts.add(new KeyValue(authorizable));
+    }
+    if (parts.isEmpty()) {
+      throw new AssertionError("Should never occur: " + privilegeStr);
+    }
+    this.parts = ImmutableList.copyOf(parts);
+  }
+
+  @Override
+  public boolean implies(Privilege privilege, Model model) {
+    // By default only supports comparisons with other IndexerWildcardPermissions
+    if (!(privilege instanceof CommonPrivilege)) {
+      return false;
+    }
+
+    List<KeyValue> otherParts = ((CommonPrivilege) privilege).getParts();
+    if(parts.equals(otherParts)) {
+      return true;
+    }
+
+    int index = 0;
+    for (KeyValue otherPart : otherParts) {
+      // If this privilege has less parts than the other privilege, everything
+      // after the number of parts contained
+      // in this privilege is automatically implied, so return true
+      if (parts.size() - 1 < index) {
+        return true;
+      } else {
+        KeyValue part = parts.get(index);
+        String policyKey = part.getKey();
+        // are the keys even equal
+        if(!policyKey.equalsIgnoreCase(otherPart.getKey())) {
+          // Support for action inheritance from parent to child
+          if (SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyKey)) {
+            continue;
+          }
+          return false;
+        }
+
+        // do the imply for action
+        if (SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyKey)) {
+          if (!impliesAction(part.getValue(), otherPart.getValue(), model.getBitFieldActionFactory())) {
+            return false;
+          }
+        } else {
+          if (!impliesResource(model.getImplyMethodMap().get(policyKey.toLowerCase()),
+                  part.getValue(), otherPart.getValue())) {
+            return false;
+          }
+        }
+
+        index++;
+      }
+    }
+
+    // If this privilege has more parts than the other parts, only imply it if
+    // all of the other parts are wildcards
+    for (; index < parts.size(); index++) {
+      KeyValue part = parts.get(index);
+      if (!SentryConstants.PRIVILEGE_WILDCARD_VALUE.equals(part.getValue())) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  // The method is used for compare the value of resource by the ImplyMethodType.
+  // for Hive, databaseName, tableName, columnName will be compared using String.equal(wildcard support)
+  //           url will be compared using PathUtils.impliesURI
+  private boolean impliesResource(ImplyMethodType implyMethodType, String policyValue, String requestValue) {
+    // wildcard support, "*", "+", "all"("+" and "all" are for backward compatibility) are represented as wildcard
+    // if requestValue is wildcard, means privilege request is to match with any value of given resource
+    if (SentryConstants.RESOURCE_WILDCARD_VALUE.equals(policyValue)
+            || SentryConstants.RESOURCE_WILDCARD_VALUE.equals(requestValue)
+            || SentryConstants.RESOURCE_WILDCARD_VALUE_ALL.equalsIgnoreCase(policyValue)
+            || SentryConstants.RESOURCE_WILDCARD_VALUE_ALL.equalsIgnoreCase(requestValue)
+            || SentryConstants.RESOURCE_WILDCARD_VALUE_SOME.equals(requestValue)) {
+      return true;
+    }
+
+    // compare as the url
+    if (ImplyMethodType.URL == implyMethodType) {
+      return PathUtils.impliesURI(policyValue, requestValue);
+    } else if (ImplyMethodType.STRING_CASE_SENSITIVE == implyMethodType) {
+      // compare as the string case sensitive
+      return policyValue.equals(requestValue);
+    }
+    // default: compare as the string case insensitive
+    return policyValue.equalsIgnoreCase(requestValue);
+  }
+
+  // The method is used for compare the action for the privilege model.
+  // for Hive, the action will be select, insert, etc.
+  // for Solr, the action will be update, query, etc.
+  private boolean impliesAction(String policyValue, String requestValue,
+                                BitFieldActionFactory bitFieldActionFactory) {
+    BitFieldAction currentAction = bitFieldActionFactory.getActionByName(policyValue);
+    BitFieldAction requestAction = bitFieldActionFactory.getActionByName(requestValue);
+    // the action in privilege is not supported
+    if (currentAction == null || requestAction == null) {
+      return false;
+    }
+    return currentAction.implies(requestAction);
+  }
+
+  @Override
+  public String toString() {
+    return SentryConstants.AUTHORIZABLE_JOINER.join(parts);
+  }
+
+  public List<KeyValue> getParts() {
+    return parts;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o instanceof CommonPrivilege) {
+      CommonPrivilege cp = (CommonPrivilege) o;
+      return parts.equals(cp.parts);
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return parts.hashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java
deleted file mode 100644
index 77e5fdf..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/KeyValue.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.sentry.policy.common;
-
-import java.util.List;
-
-import com.google.common.collect.Lists;
-
-public class KeyValue {
-  private final String key;
-  private final String value;
-
-  public KeyValue(String keyValue) {
-    List<String> kvList = Lists.newArrayList(PolicyConstants.KV_SPLITTER.trimResults().limit(2).split(keyValue));
-    if (kvList.size() != 2) {
-      throw new IllegalArgumentException("Invalid key value: " + keyValue + " " + kvList);
-    }
-    key = kvList.get(0);
-    value = kvList.get(1);
-    if (key.isEmpty()) {
-      throw new IllegalArgumentException("Key cannot be empty");
-    } else if (value.isEmpty()) {
-      throw new IllegalArgumentException("Value cannot be empty");
-    }
-  }
-
-  public KeyValue(String key, String value) {
-    super();
-    this.key = key;
-    this.value = value;
-  }
-
-  public String getKey() {
-    return key;
-  }
-
-  public String getValue() {
-    return value;
-  }
-
-  @Override
-  public String toString() {
-    return PolicyConstants.KV_JOINER.join(key, value);
-  }
-
-  @Override
-  public int hashCode() {
-    final int prime = 31;
-    int result = 1;
-    result = prime * result + ((key == null) ? 0 : key.hashCode());
-    result = prime * result + ((value == null) ? 0 : value.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;
-    }
-    KeyValue other = (KeyValue) obj;
-    if (key == null) {
-      if (other.key != null) {
-        return false;
-      }
-    } else if (!key.equalsIgnoreCase(other.key)) {
-      return false;
-    }
-    if (value == null) {
-      if (other.value != null) {
-        return false;
-      }
-    } else if (!value.equalsIgnoreCase(other.value)) {
-      return false;
-    }
-    return true;
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java
deleted file mode 100644
index 0bad8c1..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PolicyConstants.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.sentry.policy.common;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-
-public class PolicyConstants {
-
-  public static final String ROLE_SEPARATOR = ",";
-  public static final String AUTHORIZABLE_SEPARATOR = "->";
-  public static final String KV_SEPARATOR = "=";
-
-  public static final Splitter ROLE_SPLITTER = Splitter.on(ROLE_SEPARATOR);
-  public static final Splitter AUTHORIZABLE_SPLITTER = Splitter.on(AUTHORIZABLE_SEPARATOR);
-  public static final Splitter KV_SPLITTER = Splitter.on(KV_SEPARATOR);
-  public static final Joiner ROLE_JOINER = Joiner.on(ROLE_SEPARATOR);
-  public static final Joiner AUTHORIZABLE_JOINER = Joiner.on(AUTHORIZABLE_SEPARATOR);
-  public static final Joiner KV_JOINER = Joiner.on(KV_SEPARATOR);
-
-  // TODO change to privilege
-  public static final String PRIVILEGE_NAME = "action";
-  public static final String PRIVILEGE_PREFIX = (PRIVILEGE_NAME + KV_SEPARATOR).toLowerCase();
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
index 27d5afa..e9f4609 100644
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
+++ b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/Privilege.java
@@ -16,6 +16,8 @@
  */
 package org.apache.sentry.policy.common;
 
+import org.apache.sentry.core.common.Model;
+
 public interface Privilege {
-  boolean implies(Privilege p);
+  boolean implies(Privilege p, Model model);
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java
deleted file mode 100644
index 36abdd4..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidator.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.sentry.policy.common;
-
-import org.apache.shiro.config.ConfigurationException;
-
-public interface PrivilegeValidator {
-
-  void validate(PrivilegeValidatorContext context) throws ConfigurationException;
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java b/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java
deleted file mode 100644
index 2b7fd1a..0000000
--- a/sentry-policy/sentry-policy-common/src/main/java/org/apache/sentry/policy/common/PrivilegeValidatorContext.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.sentry.policy.common;
-
-import javax.annotation.Nullable;
-
-public class PrivilegeValidatorContext {
-  private final String database;
-  private final String privilege;
-  public PrivilegeValidatorContext(String privilege) {
-    this(null, privilege);
-  }
-  public PrivilegeValidatorContext(@Nullable String database, String privilege) {
-    super();
-    this.database = database;
-    this.privilege = privilege;
-  }
-  public @Nullable String getDatabase() {
-    return database;
-  }
-  public String getPrivilege() {
-    return privilege;
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java
new file mode 100644
index 0000000..6c7ea08
--- /dev/null
+++ b/sentry-policy/sentry-policy-common/src/test/java/org/apache/sentry/policy/common/ModelForTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.sentry.policy.common;
+
+import org.apache.sentry.core.common.*;
+import org.apache.sentry.core.model.db.DBModelAuthorizable;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ModelForTest implements Model {
+
+  private Map<String, ImplyMethodType> implyMethodMap;
+  private BitFieldActionFactory bitFieldActionFactory;
+
+  public ModelForTest() {
+    implyMethodMap = new HashMap<String, ImplyMethodType>();
+    bitFieldActionFactory = new ActionFactoryForTest();
+
+    implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Server.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Db.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Table.name().toLowerCase(), ImplyMethodType.STRING);
+    implyMethodMap.put(DBModelAuthorizable.AuthorizableType.Column.name().toLowerCase(), ImplyMethodType.STRING_CASE_SENSITIVE);
+    implyMethodMap.put(DBModelAuthorizable.AuthorizableType.URI.name().toLowerCase(), ImplyMethodType.URL);
+  }
+
+  public Map<String, ImplyMethodType> getImplyMethodMap() {
+    return implyMethodMap;
+  }
+
+  public BitFieldActionFactory getBitFieldActionFactory() {
+    return bitFieldActionFactory;
+  }
+
+  public static class ActionFactoryForTest extends BitFieldActionFactory {
+    enum ActionType {
+      SELECT("select", 1),
+      INSERT("insert", 2),
+      ALL("all", SELECT.getCode() | INSERT.getCode()),
+      ALL_STAR("*", SELECT.getCode() | INSERT.getCode());
+
+      private String name;
+      private int code;
+
+      ActionType(String name, int code) {
+        this.name = name;
+        this.code = code;
+      }
+
+      public int getCode() {
+        return code;
+      }
+
+      public String getName() {
+        return name;
+      }
+    }
+
+    public List<? extends BitFieldAction> getActionsByCode(int actionCode) {
+      return null;
+    }
+
+    public BitFieldAction getActionByName(String name) {
+      for (ActionType action : ActionType.values()) {
+        if (action.name.equalsIgnoreCase(name)) {
+          return new BitFieldAction(action.getName(), action.getCode());
+        }
+      }
+      return null;
+    }
+  }
+}


[09/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyNegative.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyNegative.java
new file mode 100644
index 0000000..fd33b31
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyNegative.java
@@ -0,0 +1,104 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestKafkaPolicyNegative {
+  private File baseDir;
+  private File globalPolicyFile;
+
+  @Before
+  public void setup() {
+    baseDir = Files.createTempDir();
+    globalPolicyFile = new File(baseDir, "global.ini");
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void append(String from, File to) throws IOException {
+    Files.append(from + "\n", to, Charsets.UTF_8);
+  }
+
+  @Test
+  public void testauthorizedKafkaInPolicyFile() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("other_group = other_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("other_role = host=host1->topic=t1->action=read, host=host1->consumergroup=l1->action=read", globalPolicyFile);
+    PolicyEngine policy = KafkaPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    //malicious_group has no privilege
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("malicious_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+    //other_group has two privileges
+    permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.size() == 2);
+  }
+
+  @Test
+  public void testNoHostNameConfig() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("other_group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = topic=t1->action=read", globalPolicyFile);
+    PolicyEngine policy = KafkaPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testHostAllName() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = host=*->action=read", globalPolicyFile);
+    PolicyEngine policy = KafkaPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.size() == 1);
+  }
+
+  @Test
+  public void testAll() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = *", globalPolicyFile);
+    PolicyEngine policy = KafkaPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java
new file mode 100644
index 0000000..ba66d43
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java
@@ -0,0 +1,170 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import junit.framework.Assert;
+
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.kafka.validator.KafkaPrivilegeValidator;
+import org.apache.shiro.config.ConfigurationException;
+import org.junit.Test;
+
+public class TestKafkaPrivilegeValidator {
+  @Test
+  public void testOnlyHostResource() {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1"));
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals(KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+
+  @Test
+  public void testWithoutHostResource() throws Exception {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    testHostResourceIsChecked(kafkaPrivilegeValidator, "cluster=kafka-cluster->action=read");
+    testHostResourceIsChecked(kafkaPrivilegeValidator, "topic=t1->action=read");
+    testHostResourceIsChecked(kafkaPrivilegeValidator, "consumergroup=g1->action=read");
+  }
+
+  private void testHostResourceIsChecked(KafkaPrivilegeValidator kafkaPrivilegeValidator, String privilege) {
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext(privilege));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals("Kafka privilege must begin with host authorizable.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+
+  @Test
+  public void testValidPrivileges() throws Exception {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->cluster=kafka-cluster->action=read"));
+    } catch (ConfigurationException ex) {
+      Assert.fail("Not expected ConfigurationException");
+    }
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->action=read"));
+    } catch (ConfigurationException ex) {
+      Assert.fail("Not expected ConfigurationException");
+    }
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->consumergroup=g1->action=read"));
+    } catch (ConfigurationException ex) {
+      Assert.fail("Not expected ConfigurationException");
+    }
+  }
+
+  @Test
+  public void testInvalidHostResource() throws Exception {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("hhost=host1->cluster=kafka-cluster->action=read"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+    }
+  }
+
+  @Test
+  public void testInvalidClusterResource() throws Exception {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->clluster=kafka-cluster->action=read"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+    }
+  }
+
+  @Test
+  public void testInvalidTopicResource() throws Exception {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->ttopic=t1->action=read"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+    }
+  }
+
+  @Test
+  public void testInvalidConsumerGroupResource() throws Exception {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->coonsumergroup=g1->action=read"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+    }
+  }
+
+  @Test
+  public void testPrivilegeMustHaveExcatlyOneHost() {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->host=host2->action=read"));
+      Assert.fail("Multiple Host resources are not allowed within a Kafka privilege.");
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals("Host authorizable can be specified just once in a Kafka privilege.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+
+  @Test
+  public void testPrivilegeCanNotStartWithAction() {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("action=write->host=host1->topic=t1"));
+      Assert.fail("Kafka privilege can not start with an action.");
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals("Kafka privilege can not start with an action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+
+  @Test
+  public void testPrivilegeWithMoreParts() {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->consumergroup=cg1->action=read"));
+      Assert.fail("Kafka privilege can have one Host authorizable, at most one non Host authorizable and one action.");
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals(KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+
+  @Test
+  public void testPrivilegeNotEndingWithAction() {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->consumergroup=cg1"));
+      Assert.fail("Kafka privilege must end with a valid action.");
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+
+  @Test
+  public void testPrivilegeNotEndingWithValidAction() {
+    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
+    try {
+      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->action=bla"));
+      Assert.fail("Kafka privilege must end with a valid action.");
+    } catch (ConfigurationException ex) {
+      Assert.assertEquals("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
new file mode 100644
index 0000000..a616f67
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/privilege/kafka/TestKafkaWildcardPrivilege.java
@@ -0,0 +1,188 @@
+/*
+ * 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.sentry.privilege.kafka;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.kafka.KafkaActionConstant;
+import org.apache.sentry.core.model.kafka.KafkaPrivilegeModel;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestKafkaWildcardPrivilege {
+
+  private Model kafkaPrivilegeModel;
+
+  private static final CommonPrivilege KAFKA_HOST1_ALL =
+      create(new KeyValue("HOST", "host1"), new KeyValue("action", KafkaActionConstant.ALL));
+  private static final CommonPrivilege KAFKA_HOST1_READ =
+      create(new KeyValue("HOST", "host1"), new KeyValue("action", KafkaActionConstant.READ));
+  private static final CommonPrivilege KAFKA_HOST1_WRITE =
+      create(new KeyValue("HOST", "host1"), new KeyValue("action", KafkaActionConstant.WRITE));
+
+  private static final CommonPrivilege KAFKA_HOST1_TOPIC1_ALL =
+      create(new KeyValue("HOST", "host1"), new KeyValue("TOPIC", "topic1"), new KeyValue("action", KafkaActionConstant.ALL));
+  private static final CommonPrivilege KAFKA_HOST1_TOPIC1_READ =
+      create(new KeyValue("HOST", "host1"), new KeyValue("TOPIC", "topic1"), new KeyValue("action", KafkaActionConstant.READ));
+  private static final CommonPrivilege KAFKA_HOST1_TOPIC1_WRITE =
+      create(new KeyValue("HOST", "host1"), new KeyValue("TOPIC", "topic1"), new KeyValue("action", KafkaActionConstant.WRITE));
+
+  private static final CommonPrivilege KAFKA_HOST1_CLUSTER1_ALL =
+      create(new KeyValue("HOST", "host1"), new KeyValue("CLUSTER", "cluster1"), new KeyValue("action", KafkaActionConstant.ALL));
+  private static final CommonPrivilege KAFKA_HOST1_CLUSTER1_READ =
+      create(new KeyValue("HOST", "host1"), new KeyValue("CLUSTER", "cluster1"), new KeyValue("action", KafkaActionConstant.READ));
+  private static final CommonPrivilege KAFKA_HOST1_CLUSTER1_WRITE =
+      create(new KeyValue("HOST", "host1"), new KeyValue("CLUSTER", "cluster1"), new KeyValue("action", KafkaActionConstant.WRITE));
+
+  private static final CommonPrivilege KAFKA_HOST1_GROUP1_ALL =
+      create(new KeyValue("HOST", "host1"), new KeyValue("GROUP", "cgroup1"), new KeyValue("action", KafkaActionConstant.ALL));
+  private static final CommonPrivilege KAFKA_HOST1_GROUP1_READ =
+      create(new KeyValue("HOST", "host1"), new KeyValue("GROUP", "cgroup1"), new KeyValue("action", KafkaActionConstant.READ));
+  private static final CommonPrivilege KAFKA_HOST1_GROUP1_WRITE =
+      create(new KeyValue("HOST", "host1"), new KeyValue("GROUP", "cgroup1"), new KeyValue("action", KafkaActionConstant.WRITE));
+
+  @Before
+  public void prepareData() {
+    kafkaPrivilegeModel = KafkaPrivilegeModel.getInstance();
+  }
+
+  @Test
+  public void testSimpleAction() throws Exception {
+    //host
+    assertFalse(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_READ, kafkaPrivilegeModel));
+    assertFalse(KAFKA_HOST1_READ.implies(KAFKA_HOST1_WRITE, kafkaPrivilegeModel));
+    //consumer group
+    assertFalse(KAFKA_HOST1_GROUP1_WRITE.implies(KAFKA_HOST1_GROUP1_READ, kafkaPrivilegeModel));
+    assertFalse(KAFKA_HOST1_GROUP1_READ.implies(KAFKA_HOST1_GROUP1_WRITE, kafkaPrivilegeModel));
+    //topic
+    assertFalse(KAFKA_HOST1_TOPIC1_READ.implies(KAFKA_HOST1_TOPIC1_WRITE, kafkaPrivilegeModel));
+    assertFalse(KAFKA_HOST1_TOPIC1_WRITE.implies(KAFKA_HOST1_TOPIC1_READ, kafkaPrivilegeModel));
+    //cluster
+    assertFalse(KAFKA_HOST1_CLUSTER1_READ.implies(KAFKA_HOST1_CLUSTER1_WRITE, kafkaPrivilegeModel));
+    assertFalse(KAFKA_HOST1_CLUSTER1_WRITE.implies(KAFKA_HOST1_CLUSTER1_READ, kafkaPrivilegeModel));
+  }
+
+  @Test
+  public void testShorterThanRequest() throws Exception {
+    //topic
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_TOPIC1_ALL, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_TOPIC1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_TOPIC1_WRITE, kafkaPrivilegeModel));
+
+    assertFalse(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_READ.implies(KAFKA_HOST1_TOPIC1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_TOPIC1_WRITE, kafkaPrivilegeModel));
+
+    //cluster
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_CLUSTER1_ALL, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_CLUSTER1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_CLUSTER1_WRITE, kafkaPrivilegeModel));
+
+    assertTrue(KAFKA_HOST1_READ.implies(KAFKA_HOST1_CLUSTER1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_CLUSTER1_WRITE, kafkaPrivilegeModel));
+
+    //consumer group
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_GROUP1_ALL, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_GROUP1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_GROUP1_WRITE, kafkaPrivilegeModel));
+
+    assertTrue(KAFKA_HOST1_READ.implies(KAFKA_HOST1_GROUP1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_GROUP1_WRITE, kafkaPrivilegeModel));
+  }
+
+  @Test
+  public void testActionAll() throws Exception {
+    //host
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_WRITE, kafkaPrivilegeModel));
+
+    //topic
+    assertTrue(KAFKA_HOST1_TOPIC1_ALL.implies(KAFKA_HOST1_TOPIC1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_TOPIC1_ALL.implies(KAFKA_HOST1_TOPIC1_WRITE, kafkaPrivilegeModel));
+
+    //cluster
+    assertTrue(KAFKA_HOST1_CLUSTER1_ALL.implies(KAFKA_HOST1_CLUSTER1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_CLUSTER1_ALL.implies(KAFKA_HOST1_CLUSTER1_WRITE, kafkaPrivilegeModel));
+
+    //consumer group
+    assertTrue(KAFKA_HOST1_GROUP1_ALL.implies(KAFKA_HOST1_GROUP1_READ, kafkaPrivilegeModel));
+    assertTrue(KAFKA_HOST1_GROUP1_ALL.implies(KAFKA_HOST1_GROUP1_WRITE, kafkaPrivilegeModel));
+  }
+
+  @Test
+  public void testUnexpected() throws Exception {
+    Privilege p = new Privilege() {
+      @Override
+      public boolean implies(Privilege p, Model model) {
+        return false;
+      }
+    };
+    Privilege topic1 = create(new KeyValue("HOST", "host"), new KeyValue("TOPIC", "topic1"));
+    assertFalse(topic1.implies(null, kafkaPrivilegeModel));
+    assertFalse(topic1.implies(p, kafkaPrivilegeModel));
+    assertFalse(topic1.equals(null));
+    assertFalse(topic1.equals(p));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNullString() throws Exception {
+    System.out.println(create((String)null));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyString() throws Exception {
+    System.out.println(create(""));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("", "host1")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("HOST", "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyPart() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+        join(SentryConstants.KV_JOINER.join("HOST", "host1"), "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testOnlySeperators() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+        join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR,
+        SentryConstants.KV_SEPARATOR)));
+  }
+
+  static CommonPrivilege create(KeyValue... keyValues) {
+    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
+
+  }
+  static CommonPrivilege create(String s) {
+    return new CommonPrivilege(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/resources/kafka-policy-test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/resources/kafka-policy-test-authz-provider.ini b/sentry-binding/sentry-binding-kafka/src/test/resources/kafka-policy-test-authz-provider.ini
new file mode 100644
index 0000000..1951aba
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/resources/kafka-policy-test-authz-provider.ini
@@ -0,0 +1,38 @@
+# 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.
+
+[groups]
+admin_group = admin_all
+subadmin_group = admin_host1
+consumer_group0 = consumer_t1_all
+consumer_group1 = consumer_t1_host1
+consumer_group2 = consumer_t2_host2
+producer_group0 = producer_t1_all
+producer_group1 = producer_t1_host1
+producer_group2 = producer_t2_host2
+consumer_producer_group0 = consumer_producer_t1
+
+[roles]
+admin_all = host=*->action=all
+admin_host1 = host=host1->action=all
+consumer_t1_all = host=*->topic=t1->action=read
+consumer_t1_host1 = host=host1->topic=t1->action=read
+consumer_t2_host2 = host=host2->topic=t2->action=read
+producer_t1_all = host=*->topic=t1->action=write
+producer_t1_host1 = host=host1->topic=t1->action=write
+producer_t2_host2 = host=host2->topic=t2->action=write
+consumer_producer_t1 = host=host1->topic=t1->action=all

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/resources/sentry-site.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/resources/sentry-site.xml b/sentry-binding/sentry-binding-kafka/src/test/resources/sentry-site.xml
index 69ce5a7..6383481 100644
--- a/sentry-binding/sentry-binding-kafka/src/test/resources/sentry-site.xml
+++ b/sentry-binding/sentry-binding-kafka/src/test/resources/sentry-site.xml
@@ -32,7 +32,7 @@
   </property>
   <property>
     <name>sentry.kafka.policy.engine</name>
-    <value>org.apache.sentry.policy.kafka.SimpleKafkaPolicyEngine</value>
+    <value>org.apache.sentry.policy.engine.common.CommonPolicyEngine</value>
   </property>
   <property>
     <name>sentry.kafka.provider.backend</name>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/pom.xml b/sentry-binding/sentry-binding-solr/pom.xml
index 3927188..a63a600 100644
--- a/sentry-binding/sentry-binding-solr/pom.xml
+++ b/sentry-binding/sentry-binding-solr/pom.xml
@@ -56,10 +56,6 @@ limitations under the License.
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-search</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-common</artifactId>
       <scope>provided</scope>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
index a6d6c8b..24e5172 100644
--- a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
+++ b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/authz/SolrAuthzBinding.java
@@ -36,15 +36,18 @@ import org.apache.sentry.binding.solr.conf.SolrAuthzConf;
 import org.apache.sentry.binding.solr.conf.SolrAuthzConf.AuthzConfVars;
 import org.apache.sentry.core.common.Action;
 import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.search.Collection;
 import org.apache.sentry.core.model.search.SearchModelAction;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
 import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.AuthorizationComponent;
 import org.apache.sentry.provider.common.AuthorizationProvider;
 import org.apache.sentry.provider.common.GroupMappingService;
 import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider;
 import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
@@ -65,6 +68,7 @@ public class SolrAuthzBinding {
   public static final String KERBEROS_ENABLED = "solr.hdfs.security.kerberos.enabled";
   public static final String KERBEROS_KEYTAB = "solr.hdfs.security.kerberos.keytabfile";
   public static final String KERBEROS_PRINCIPAL = "solr.hdfs.security.kerberos.principal";
+  private static final String SOLR_POLICY_ENGINE_OLD = "org.apache.sentry.policy.search.SimpleSearchPolicyEngine";
   private static final String kerberosEnabledProp = Strings.nullToEmpty(System.getProperty(KERBEROS_ENABLED)).trim();
   private static final String keytabProp = Strings.nullToEmpty(System.getProperty(KERBEROS_KEYTAB)).trim();
   private static final String principalProp = Strings.nullToEmpty(System.getProperty(KERBEROS_PRINCIPAL)).trim();
@@ -94,14 +98,19 @@ public class SolrAuthzBinding {
     String resourceName =
         authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar());
     String providerBackendName =
-      authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar());
+        authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar());
     String policyEngineName =
-      authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar());
+        authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(), AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
     String serviceName = authzConf.get(SENTRY_SEARCH_SERVICE_KEY, SENTRY_SEARCH_SERVICE_DEFAULT);
 
+    // for the backward compatibility
+    if (SOLR_POLICY_ENGINE_OLD.equals(policyEngineName)) {
+      policyEngineName = AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault();
+    }
+
     LOG.debug("Using authorization provider " + authProviderName +
-      " with resource " + resourceName + ", policy engine "
-      + policyEngineName + ", provider backend " + providerBackendName);
+        " with resource " + resourceName + ", policy engine "
+        + policyEngineName + ", provider backend " + providerBackendName);
     // load the provider backend class
     if (kerberosEnabledProp.equalsIgnoreCase("true")) {
       initKerberos(keytabProp, principalProp);
@@ -118,11 +127,11 @@ public class SolrAuthzBinding {
       providerBackendName = SentryGenericProviderBackend.class.getName();
     }
     Constructor<?> providerBackendConstructor =
-      Class.forName(providerBackendName).getDeclaredConstructor(Configuration.class, String.class);
+        Class.forName(providerBackendName).getDeclaredConstructor(Configuration.class, String.class);
     providerBackendConstructor.setAccessible(true);
 
     providerBackend =
-      (ProviderBackend) providerBackendConstructor.newInstance(new Object[] {authzConf, resourceName});
+        (ProviderBackend) providerBackendConstructor.newInstance(new Object[] {authzConf, resourceName});
 
     if (providerBackend instanceof SentryGenericProviderBackend) {
       ((SentryGenericProviderBackend) providerBackend)
@@ -130,12 +139,18 @@ public class SolrAuthzBinding {
       ((SentryGenericProviderBackend) providerBackend).setServiceName(serviceName);
     }
 
+    // Create backend context
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(SearchPrivilegeModel.getInstance().getPrivilegeValidators());
+    providerBackend.initialize(context);
+
     // load the policy engine class
     Constructor<?> policyConstructor =
-      Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
+        Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
     policyConstructor.setAccessible(true);
     PolicyEngine policyEngine =
-      (PolicyEngine) policyConstructor.newInstance(new Object[] {providerBackend});
+        (PolicyEngine) policyConstructor.newInstance(new Object[] {providerBackend});
 
     // if unset, set the hadoop auth provider to use new groups, so we don't
     // conflict with the group mappings that may already be set up
@@ -145,9 +160,11 @@ public class SolrAuthzBinding {
 
     // load the authz provider class
     Constructor<?> constrctor =
-      Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class, PolicyEngine.class);
+      Class.forName(authProviderName).getDeclaredConstructor(Configuration.class,
+              String.class, PolicyEngine.class, Model.class);
     constrctor.setAccessible(true);
-    return (AuthorizationProvider) constrctor.newInstance(new Object[] {authzConf, resourceName, policyEngine});
+    return (AuthorizationProvider) constrctor.newInstance(new Object[] {authzConf, resourceName,
+            policyEngine, SearchPrivilegeModel.getInstance()});
   }
 
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/conf/SolrAuthzConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/conf/SolrAuthzConf.java b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/conf/SolrAuthzConf.java
index 227f75e..b31f4fa 100644
--- a/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/conf/SolrAuthzConf.java
+++ b/sentry-binding/sentry-binding-solr/src/main/java/org/apache/sentry/binding/solr/conf/SolrAuthzConf.java
@@ -33,7 +33,7 @@ public class SolrAuthzConf extends Configuration {
       "org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"),
     AUTHZ_PROVIDER_RESOURCE("sentry.solr.provider.resource", ""),
     AUTHZ_PROVIDER_BACKEND("sentry.solr.provider.backend", "org.apache.sentry.provider.file.SimpleFileProviderBackend"),
-    AUTHZ_POLICY_ENGINE("sentry.solr.policy.engine", "org.apache.sentry.policy.search.SimpleSearchPolicyEngine");
+    AUTHZ_POLICY_ENGINE("sentry.solr.policy.engine", "org.apache.sentry.policy.engine.common.CommonPolicyEngine");
 
     private final String varName;
     private final String defaultVal;

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/AbstractTestSearchPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/AbstractTestSearchPolicyEngine.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/AbstractTestSearchPolicyEngine.java
new file mode 100644
index 0000000..3df6ecf
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/AbstractTestSearchPolicyEngine.java
@@ -0,0 +1,129 @@
+/*
+ * 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.sentry.policy.solr;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public abstract class AbstractTestSearchPolicyEngine {
+  private static final String ANALYST_PURCHASES_UPDATE = "collection=purchases->action=update";
+  private static final String ANALYST_ANALYST1_ALL = "collection=analyst1";
+  private static final String ANALYST_JRANALYST1_ACTION_ALL = "collection=jranalyst1->action=*";
+  private static final String ANALYST_TMPCOLLECTION_UPDATE = "collection=tmpcollection->action=update";
+  private static final String ANALYST_TMPCOLLECTION_QUERY = "collection=tmpcollection->action=query";
+  private static final String JRANALYST_JRANALYST1_ALL = "collection=jranalyst1";
+  private static final String JRANALYST_PURCHASES_PARTIAL_QUERY = "collection=purchases_partial->action=query";
+  private static final String ADMIN_COLLECTION_ALL = "collection=*";
+
+  private PolicyEngine policy;
+  private static File baseDir;
+
+  @BeforeClass
+  public static void setupClazz() throws IOException {
+    baseDir = Files.createTempDir();
+  }
+
+  @AfterClass
+  public static void teardownClazz() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  protected void setPolicy(PolicyEngine policy) {
+    this.policy = policy;
+  }
+  protected static File getBaseDir() {
+    return baseDir;
+  }
+  @Before
+  public void setup() throws IOException {
+    afterSetup();
+  }
+  @After
+  public void teardown() throws IOException {
+    beforeTeardown();
+  }
+  protected void afterSetup() throws IOException {
+
+  }
+
+  protected void beforeTeardown() throws IOException {
+
+  }
+
+  @Test
+  public void testManager() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        ANALYST_PURCHASES_UPDATE, ANALYST_ANALYST1_ALL,
+        ANALYST_JRANALYST1_ACTION_ALL, ANALYST_TMPCOLLECTION_UPDATE,
+        ANALYST_TMPCOLLECTION_QUERY, JRANALYST_JRANALYST1_ALL,
+        JRANALYST_PURCHASES_PARTIAL_QUERY));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("manager"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testAnalyst() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        ANALYST_PURCHASES_UPDATE, ANALYST_ANALYST1_ALL,
+        ANALYST_JRANALYST1_ACTION_ALL, ANALYST_TMPCOLLECTION_UPDATE,
+        ANALYST_TMPCOLLECTION_QUERY));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("analyst"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testJuniorAnalyst() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets
+        .newHashSet(JRANALYST_JRANALYST1_ALL,
+            JRANALYST_PURCHASES_PARTIAL_QUERY));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN_COLLECTION_ALL));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("admin"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  private static Set<String> set(String... values) {
+    return Sets.newHashSet(values);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/SearchPolicyTestUtil.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/SearchPolicyTestUtil.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/SearchPolicyTestUtil.java
new file mode 100644
index 0000000..e198b5c
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/SearchPolicyTestUtil.java
@@ -0,0 +1,45 @@
+/*
+ * 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.sentry.policy.solr;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+
+import java.io.IOException;
+
+public class SearchPolicyTestUtil {
+
+  public static PolicyEngine createPolicyEngineForTest(String resource) throws IOException {
+
+    ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource);
+
+    // create backendContext
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(SearchPrivilegeModel.getInstance().getPrivilegeValidators());
+    // initialize the backend with the context
+    providerBackend.initialize(context);
+
+
+    return new CommonPolicyEngine(providerBackend);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestCollectionRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestCollectionRequiredInRole.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestCollectionRequiredInRole.java
new file mode 100644
index 0000000..76211dd
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestCollectionRequiredInRole.java
@@ -0,0 +1,64 @@
+/*
+ * 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.sentry.policy.solr;
+
+import org.junit.Assert;
+
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.search.validator.CollectionRequiredInPrivilege;
+import org.apache.shiro.config.ConfigurationException;
+import org.junit.Test;
+
+public class TestCollectionRequiredInRole {
+
+  @Test
+  public void testEmptyRole() throws Exception {
+    CollectionRequiredInPrivilege collRequiredInRole = new CollectionRequiredInPrivilege();
+
+    // check no db
+    try {
+      collRequiredInRole.validate(new PrivilegeValidatorContext("index=index1"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException e) {
+      // expected
+    }
+
+    // check with db
+    try {
+      collRequiredInRole.validate(new PrivilegeValidatorContext("db1","index=index2"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException e) {
+      // expected
+    }
+  }
+
+  @Test
+  public void testCollectionWithoutAction() throws Exception {
+    CollectionRequiredInPrivilege collRequiredInRole = new CollectionRequiredInPrivilege();
+    collRequiredInRole.validate(new PrivilegeValidatorContext("collection=nodb"));
+    collRequiredInRole.validate(new PrivilegeValidatorContext("db2","collection=db"));
+  }
+
+  @Test
+  public void testCollectionWithAction() throws Exception {
+    CollectionRequiredInPrivilege collRequiredInRole = new CollectionRequiredInPrivilege();
+    collRequiredInRole.validate(new PrivilegeValidatorContext(null,"collection=nodb->action=query"));
+    collRequiredInRole.validate(new PrivilegeValidatorContext("db2","collection=db->action=update"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderGeneralCases.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderGeneralCases.java
new file mode 100644
index 0000000..6f7f07a
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderGeneralCases.java
@@ -0,0 +1,193 @@
+/*
+ * 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.sentry.policy.solr;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAction;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
+import org.apache.sentry.provider.common.GroupMappingService;
+import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.io.Files;
+
+
+public class TestSearchAuthorizationProviderGeneralCases {
+
+  private static final Logger LOGGER = LoggerFactory
+      .getLogger(TestSearchAuthorizationProviderGeneralCases.class);
+
+  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap
+      .create();
+
+  private static final Subject SUB_ADMIN = new Subject("admin1");
+  private static final Subject SUB_MANAGER = new Subject("manager1");
+  private static final Subject SUB_ANALYST = new Subject("analyst1");
+  private static final Subject SUB_JUNIOR_ANALYST = new Subject("jranalyst1");
+
+  private static final Collection COLL_PURCHASES = new Collection("purchases");
+  private static final Collection COLL_ANALYST1 = new Collection("analyst1");
+  private static final Collection COLL_JRANALYST1 = new Collection("jranalyst1");
+  private static final Collection COLL_TMP = new Collection("tmpcollection");
+  private static final Collection COLL_PURCHASES_PARTIAL = new Collection("purchases_partial");
+
+  private static final SearchModelAction QUERY = SearchModelAction.QUERY;
+  private static final SearchModelAction UPDATE = SearchModelAction.UPDATE;
+
+  static {
+    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList("admin"));
+    USER_TO_GROUP_MAP.putAll(SUB_MANAGER.getName(), Arrays.asList("manager"));
+    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList("analyst"));
+    USER_TO_GROUP_MAP.putAll(SUB_JUNIOR_ANALYST.getName(),
+        Arrays.asList("jranalyst"));
+  }
+
+  private final ResourceAuthorizationProvider authzProvider;
+  private File baseDir;
+
+  public TestSearchAuthorizationProviderGeneralCases() throws IOException {
+    baseDir = Files.createTempDir();
+    PolicyFiles.copyToDir(baseDir, "solr-policy-test-authz-provider.ini");
+    authzProvider = new HadoopGroupResourceAuthorizationProvider(
+            SearchPolicyTestUtil.createPolicyEngineForTest(new File(baseDir, "solr-policy-test-authz-provider.ini").getPath()),
+        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), SearchPrivilegeModel.getInstance());
+
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void doTestAuthProviderOnCollection(Subject subject,
+      Collection collection, Set<? extends Action> expectedPass) throws Exception {
+    Set<SearchModelAction> allActions = EnumSet.of(SearchModelAction.ALL, SearchModelAction.QUERY, SearchModelAction.UPDATE);
+    for(SearchModelAction action : allActions) {
+      doTestResourceAuthorizationProvider(subject, collection,
+        EnumSet.of(action), expectedPass.contains(action));
+    }
+  }
+
+  private void doTestResourceAuthorizationProvider(Subject subject,
+      Collection collection,
+      Set<? extends Action> privileges, boolean expected) throws Exception {
+    List<Authorizable> authzHierarchy = Arrays.asList(new Authorizable[] {
+        collection
+    });
+    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
+    helper.add("Subject", subject).add("Collection", collection)
+      .add("Privileges", privileges).add("authzHierarchy", authzHierarchy);
+    LOGGER.info("Running with " + helper.toString());
+    Assert.assertEquals(helper.toString(), expected,
+        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
+    LOGGER.info("Passed " + helper.toString());
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
+    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_PURCHASES, allActions);
+    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_ANALYST1, allActions);
+    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_JRANALYST1, allActions);
+    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_TMP, allActions);
+    doTestAuthProviderOnCollection(SUB_ADMIN, COLL_PURCHASES_PARTIAL, allActions);
+  }
+
+  @Test
+  public void testManager() throws Exception {
+    Set<SearchModelAction> updateOnly = EnumSet.of(SearchModelAction.UPDATE);
+    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_PURCHASES, updateOnly);
+
+    Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
+    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_ANALYST1, allActions);
+    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_JRANALYST1, allActions);
+
+    Set<SearchModelAction> queryUpdateOnly = EnumSet.of(QUERY, UPDATE);
+    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_TMP, queryUpdateOnly);
+
+    Set<SearchModelAction> queryOnly = EnumSet.of(SearchModelAction.QUERY);
+    doTestAuthProviderOnCollection(SUB_MANAGER, COLL_PURCHASES_PARTIAL, queryOnly);
+  }
+
+  @Test
+  public void testAnalyst() throws Exception {
+    Set<SearchModelAction> updateOnly = EnumSet.of(SearchModelAction.UPDATE);
+    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_PURCHASES, updateOnly);
+
+    Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
+    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_ANALYST1, allActions);
+    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_JRANALYST1, allActions);
+
+    Set<SearchModelAction> queryUpdateOnly = EnumSet.of(QUERY, UPDATE);
+    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_TMP, queryUpdateOnly);
+
+    Set<SearchModelAction> noActions = EnumSet.noneOf(SearchModelAction.class);
+    doTestAuthProviderOnCollection(SUB_ANALYST, COLL_PURCHASES_PARTIAL, noActions);
+  }
+
+  @Test
+  public void testJuniorAnalyst() throws Exception {
+     Set<SearchModelAction> allActions = EnumSet.allOf(SearchModelAction.class);
+     doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_JRANALYST1, allActions);
+
+    Set<SearchModelAction> queryOnly = EnumSet.of(SearchModelAction.QUERY);
+    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_PURCHASES_PARTIAL, queryOnly);
+
+    Set<SearchModelAction> noActions = EnumSet.noneOf(SearchModelAction.class);
+    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_PURCHASES, noActions);
+    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_ANALYST1, noActions);
+    doTestAuthProviderOnCollection(SUB_JUNIOR_ANALYST, COLL_TMP, noActions);
+  }
+
+  public class MockGroupMappingServiceProvider implements GroupMappingService {
+    private final Multimap<String, String> userToGroupMap;
+
+    public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
+      this.userToGroupMap = userToGroupMap;
+    }
+
+    @Override
+    public Set<String> getGroups(String user) {
+      return Sets.newHashSet(userToGroupMap.get(user));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderSpecialCases.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderSpecialCases.java
new file mode 100644
index 0000000..371f361
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchAuthorizationProviderSpecialCases.java
@@ -0,0 +1,84 @@
+ /*
+ * 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.sentry.policy.solr;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAction;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.common.AuthorizationProvider;
+import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.Files;
+
+public class TestSearchAuthorizationProviderSpecialCases {
+  private AuthorizationProvider authzProvider;
+  private PolicyFile policyFile;
+  private File baseDir;
+  private File iniFile;
+  private String initResource;
+  @Before
+  public void setup() throws IOException {
+    baseDir = Files.createTempDir();
+    iniFile = new File(baseDir, "policy.ini");
+    initResource = "file://" + iniFile.getPath();
+    policyFile = new PolicyFile();
+  }
+
+  @After
+  public void teardown() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  @Test
+  public void testDuplicateEntries() throws Exception {
+    Subject user1 = new Subject("user1");
+    Collection collection1 = new Collection("collection1");
+    Set<? extends Action> actions = EnumSet.allOf(SearchModelAction.class);
+    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
+      .addRolesToGroup("group1",  true, "role1", "role1")
+      .addPermissionsToRole("role1", true, "collection=" + collection1.getName(),
+          "collection=" + collection1.getName());
+    policyFile.write(iniFile);
+    PolicyEngine policy = SearchPolicyTestUtil.createPolicyEngineForTest(initResource);
+    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, SearchPrivilegeModel.getInstance());
+    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(collection1);
+    Assert.assertTrue(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchModelAuthorizables.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchModelAuthorizables.java
new file mode 100644
index 0000000..e7da13a
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchModelAuthorizables.java
@@ -0,0 +1,54 @@
+/*
+ * 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.sentry.policy.solr;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import org.apache.sentry.core.model.search.Collection;
+import org.apache.sentry.core.model.search.SearchModelAuthorizables;
+import org.junit.Test;
+
+public class TestSearchModelAuthorizables {
+
+  @Test
+  public void testCollection() throws Exception {
+    Collection coll = (Collection) SearchModelAuthorizables.from("CoLleCtiOn=collection1");
+    assertEquals("collection1", coll.getName());
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNoKV() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("nonsense"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("=v"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(SearchModelAuthorizables.from("k="));
+  }
+
+  @Test
+  public void testNotAuthorizable() throws Exception {
+    assertNull(SearchModelAuthorizables.from("k=v"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineDFS.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineDFS.java
new file mode 100644
index 0000000..3e3aa47
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineDFS.java
@@ -0,0 +1,74 @@
+/*
+ * 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.sentry.policy.solr;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class TestSearchPolicyEngineDFS extends AbstractTestSearchPolicyEngine {
+
+  private static MiniDFSCluster dfsCluster;
+  private static FileSystem fileSystem;
+  private static Path root;
+  private static Path etc;
+
+  @BeforeClass
+  public static void setupLocalClazz() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    File dfsDir = new File(baseDir, "dfs");
+    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
+    Configuration conf = new Configuration();
+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
+    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
+    fileSystem = dfsCluster.getFileSystem();
+    root = new Path(fileSystem.getUri().toString());
+    etc = new Path(root, "/etc");
+    fileSystem.mkdirs(etc);
+  }
+
+  @AfterClass
+  public static void teardownLocalClazz() {
+    if(dfsCluster != null) {
+      dfsCluster.shutdown();
+    }
+  }
+
+  @Override
+  protected void  afterSetup() throws IOException {
+    fileSystem.delete(etc, true);
+    fileSystem.mkdirs(etc);
+    PolicyFiles.copyToDir(fileSystem, etc, "solr-policy-test-authz-provider.ini");
+    setPolicy(SearchPolicyTestUtil.createPolicyEngineForTest(new Path(etc,
+        "solr-policy-test-authz-provider.ini").toString()));
+  }
+
+  @Override
+  protected void beforeTeardown() throws IOException {
+    fileSystem.delete(etc, true);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineLocalFS.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineLocalFS.java
new file mode 100644
index 0000000..a7928b5
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyEngineLocalFS.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sentry.policy.solr;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.provider.file.PolicyFiles;
+
+public class TestSearchPolicyEngineLocalFS extends AbstractTestSearchPolicyEngine {
+
+  @Override
+  protected void  afterSetup() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
+    PolicyFiles.copyToDir(baseDir, "solr-policy-test-authz-provider.ini");
+    setPolicy(SearchPolicyTestUtil.createPolicyEngineForTest(new File(baseDir, "solr-policy-test-authz-provider.ini").getPath()));
+  }
+  @Override
+  protected void beforeTeardown() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    FileUtils.deleteQuietly(baseDir);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyNegative.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyNegative.java
new file mode 100644
index 0000000..20fee76
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/policy/solr/TestSearchPolicyNegative.java
@@ -0,0 +1,101 @@
+/*
+ * 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.sentry.policy.solr;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestSearchPolicyNegative {
+
+  @SuppressWarnings("unused")
+  private static final Logger LOGGER = LoggerFactory
+      .getLogger(TestSearchPolicyNegative.class);
+
+  private File baseDir;
+  private File globalPolicyFile;
+  private File otherPolicyFile;
+
+  @Before
+  public void setup() {
+    baseDir = Files.createTempDir();
+    globalPolicyFile = new File(baseDir, "global.ini");
+    otherPolicyFile = new File(baseDir, "other.ini");
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void append(String from, File to) throws IOException {
+    Files.append(from + "\n", to, Charsets.UTF_8);
+  }
+
+  @Test
+  public void testPerDbFileException() throws Exception {
+    append("[databases]", globalPolicyFile);
+    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
+    append("[groups]", otherPolicyFile);
+    append("other_group = some_role", otherPolicyFile);
+    append("[roles]", otherPolicyFile);
+    append("some_role = collection=c1", otherPolicyFile);
+    PolicyEngine policy = SearchPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    Assert.assertEquals(Collections.emptySet(),
+        policy.getPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL));
+  }
+
+  @Test
+  public void testCollectionRequiredInRole() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = some_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("some_role = action=query", globalPolicyFile);
+    PolicyEngine policy = SearchPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testGroupIncorrect() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = collection=*", globalPolicyFile);
+    PolicyEngine policy = SearchPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getPrivileges(Sets.newHashSet("incorrectGroup"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
new file mode 100644
index 0000000..294091c
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/java/org/apache/sentry/privilege/solr/TestCommonPrivilegeForSearch.java
@@ -0,0 +1,214 @@
+/*
+ * 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.sentry.privilege.solr;
+
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.search.SearchConstants;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+public class TestCommonPrivilegeForSearch {
+
+  private Model searchPrivilegeModel;
+
+  private static final String ALL = SearchConstants.ALL;
+
+  @Before
+  public void prepareData() {
+    searchPrivilegeModel = SearchPrivilegeModel.getInstance();
+  }
+
+  @Test
+  public void testSimpleNoAction() throws Exception {
+    CommonPrivilege collection1 = create(new KeyValue("collection", "coll1"));
+    CommonPrivilege collection2 = create(new KeyValue("collection", "coll2"));
+    CommonPrivilege collection1Case = create(new KeyValue("colleCtIon", "coLl1"));
+
+    assertTrue(collection1.implies(collection1, searchPrivilegeModel));
+    assertTrue(collection2.implies(collection2, searchPrivilegeModel));
+    assertTrue(collection1.implies(collection1Case, searchPrivilegeModel));
+    assertTrue(collection1Case.implies(collection1, searchPrivilegeModel));
+
+    assertFalse(collection1.implies(collection2, searchPrivilegeModel));
+    assertFalse(collection1Case.implies(collection2, searchPrivilegeModel));
+    assertFalse(collection2.implies(collection1, searchPrivilegeModel));
+    assertFalse(collection2.implies(collection1Case, searchPrivilegeModel));
+  }
+
+  @Test
+  public void testSimpleAction() throws Exception {
+    CommonPrivilege query =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    CommonPrivilege update =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    CommonPrivilege queryCase =
+            create(new KeyValue("colleCtIon", "coLl1"), new KeyValue("AcTiOn", "QuERy"));
+
+    assertTrue(query.implies(query, searchPrivilegeModel));
+    assertTrue(update.implies(update, searchPrivilegeModel));
+    assertTrue(query.implies(queryCase, searchPrivilegeModel));
+    assertTrue(queryCase.implies(query, searchPrivilegeModel));
+
+    assertFalse(query.implies(update, searchPrivilegeModel));
+    assertFalse(queryCase.implies(update, searchPrivilegeModel));
+    assertFalse(update.implies(query, searchPrivilegeModel));
+    assertFalse(update.implies(queryCase, searchPrivilegeModel));
+  }
+
+  @Test
+  public void testRoleShorterThanRequest() throws Exception {
+    CommonPrivilege collection1 = create(new KeyValue("collection", "coll1"));
+    CommonPrivilege query =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    CommonPrivilege update =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    CommonPrivilege all =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", ALL));
+
+    assertTrue(collection1.implies(query, searchPrivilegeModel));
+    assertTrue(collection1.implies(update, searchPrivilegeModel));
+    assertTrue(collection1.implies(all, searchPrivilegeModel));
+
+    assertFalse(query.implies(collection1, searchPrivilegeModel));
+    assertFalse(update.implies(collection1, searchPrivilegeModel));
+    assertTrue(all.implies(collection1, searchPrivilegeModel));
+  }
+
+  @Test
+  public void testCollectionAll() throws Exception {
+    CommonPrivilege collectionAll = create(new KeyValue("collection", ALL));
+    CommonPrivilege collection1 = create(new KeyValue("collection", "coll1"));
+    assertTrue(collectionAll.implies(collection1, searchPrivilegeModel));
+    assertTrue(collection1.implies(collectionAll, searchPrivilegeModel));
+
+    CommonPrivilege allUpdate =
+            create(new KeyValue("collection", ALL), new KeyValue("action", "update"));
+    CommonPrivilege allQuery =
+            create(new KeyValue("collection", ALL), new KeyValue("action", "query"));
+    CommonPrivilege coll1Update =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    CommonPrivilege coll1Query =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    assertTrue(allUpdate.implies(coll1Update, searchPrivilegeModel));
+    assertTrue(allQuery.implies(coll1Query, searchPrivilegeModel));
+    assertTrue(coll1Update.implies(allUpdate, searchPrivilegeModel));
+    assertTrue(coll1Query.implies(allQuery, searchPrivilegeModel));
+    assertFalse(allUpdate.implies(coll1Query, searchPrivilegeModel));
+    assertFalse(coll1Update.implies(coll1Query, searchPrivilegeModel));
+    assertFalse(allQuery.implies(coll1Update, searchPrivilegeModel));
+    assertFalse(coll1Query.implies(allUpdate, searchPrivilegeModel));
+    assertFalse(allUpdate.implies(allQuery, searchPrivilegeModel));
+    assertFalse(allQuery.implies(allUpdate, searchPrivilegeModel));
+    assertFalse(coll1Update.implies(coll1Query, searchPrivilegeModel));
+    assertFalse(coll1Query.implies(coll1Update, searchPrivilegeModel));
+
+    // test different length paths
+    assertTrue(collectionAll.implies(allUpdate, searchPrivilegeModel));
+    assertTrue(collectionAll.implies(allQuery, searchPrivilegeModel));
+    assertTrue(collectionAll.implies(coll1Update, searchPrivilegeModel));
+    assertTrue(collectionAll.implies(coll1Query, searchPrivilegeModel));
+    assertFalse(allUpdate.implies(collectionAll, searchPrivilegeModel));
+    assertFalse(allQuery.implies(collectionAll, searchPrivilegeModel));
+    assertFalse(coll1Update.implies(collectionAll, searchPrivilegeModel));
+    assertFalse(coll1Query.implies(collectionAll, searchPrivilegeModel));
+  }
+
+  @Test
+  public void testActionAll() throws Exception {
+    CommonPrivilege coll1All =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", ALL));
+    CommonPrivilege coll1Update =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "update"));
+    CommonPrivilege coll1Query =
+            create(new KeyValue("collection", "coll1"), new KeyValue("action", "query"));
+    assertTrue(coll1All.implies(coll1All, searchPrivilegeModel));
+    assertTrue(coll1All.implies(coll1Update, searchPrivilegeModel));
+    assertTrue(coll1All.implies(coll1Query, searchPrivilegeModel));
+    assertFalse(coll1Update.implies(coll1All, searchPrivilegeModel));
+    assertFalse(coll1Query.implies(coll1All, searchPrivilegeModel));
+
+    // test different lengths
+    CommonPrivilege coll1 =
+            create(new KeyValue("collection", "coll1"));
+    assertTrue(coll1All.implies(coll1, searchPrivilegeModel));
+    assertTrue(coll1.implies(coll1All, searchPrivilegeModel));
+  }
+
+  @Test
+  public void testUnexpected() throws Exception {
+    Privilege p = new Privilege() {
+      @Override
+      public boolean implies(Privilege p, Model m) {
+        return false;
+      }
+    };
+    Privilege collection1 = create(new KeyValue("collection", "coll1"));
+    assertFalse(collection1.implies(null, searchPrivilegeModel));
+    assertFalse(collection1.implies(p, searchPrivilegeModel));
+    assertFalse(collection1.equals(null));
+    assertFalse(collection1.equals(p));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNullString() throws Exception {
+    System.out.println(create((String)null));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyString() throws Exception {
+    System.out.println(create(""));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("collection", "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("", "coll1")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyPart() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_JOINER.join("collection1", "coll1"), "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testOnlySeperators() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR,
+            SentryConstants.KV_SEPARATOR)));
+  }
+
+  static CommonPrivilege create(KeyValue... keyValues) {
+    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
+  }
+
+  static CommonPrivilege create(String s) {
+    return new CommonPrivilege(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-solr/src/test/resources/solr-policy-test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-solr/src/test/resources/solr-policy-test-authz-provider.ini b/sentry-binding/sentry-binding-solr/src/test/resources/solr-policy-test-authz-provider.ini
new file mode 100644
index 0000000..8af8162
--- /dev/null
+++ b/sentry-binding/sentry-binding-solr/src/test/resources/solr-policy-test-authz-provider.ini
@@ -0,0 +1,31 @@
+# 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.
+
+[groups]
+manager = analyst_role, junior_analyst_role
+analyst = analyst_role
+jranalyst = junior_analyst_role
+admin = admin
+
+[roles]
+analyst_role = collection=purchases->action=update, \
+  collection=analyst1, \
+  collection=jranalyst1->action=*, \
+  collection=tmpcollection->action=update, \
+  collection=tmpcollection->action=query
+junior_analyst_role = collection=jranalyst1, collection=purchases_partial->action=query
+admin = collection=*

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/pom.xml b/sentry-binding/sentry-binding-sqoop/pom.xml
index 73ddee8..732da26 100644
--- a/sentry-binding/sentry-binding-sqoop/pom.xml
+++ b/sentry-binding/sentry-binding-sqoop/pom.xml
@@ -59,21 +59,22 @@ limitations under the License.
       <artifactId>sentry-policy-common</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-sqoop</artifactId>
-    </dependency>
-    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-common</artifactId>
       <scope>provided</scope>
     </dependency>
 	<dependency>
-        <groupId>org.apache.sqoop</groupId>
-        <artifactId>sqoop-common</artifactId>
+      <groupId>org.apache.sqoop</groupId>
+      <artifactId>sqoop-common</artifactId>
     </dependency>
 	<dependency>
-        <groupId>org.apache.sqoop</groupId>
-        <artifactId>sqoop-security</artifactId>
+      <groupId>org.apache.sqoop</groupId>
+      <artifactId>sqoop-security</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
     </dependency>
   </dependencies>
 


[05/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderGeneralCases.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderGeneralCases.java
deleted file mode 100644
index 89559a6..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderGeneralCases.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.db.AccessConstants;
-import org.apache.sentry.core.model.db.DBModelAction;
-import org.apache.sentry.core.model.db.Database;
-import org.apache.sentry.core.model.db.Server;
-import org.apache.sentry.core.model.db.Table;
-import org.apache.sentry.provider.common.MockGroupMappingServiceProvider;
-import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.After;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.io.Files;
-
-
-public class TestResourceAuthorizationProviderGeneralCases {
-
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(TestResourceAuthorizationProviderGeneralCases.class);
-
-  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap
-      .create();
-
-  private static final Subject SUB_ADMIN = new Subject("admin1");
-  private static final Subject SUB_MANAGER = new Subject("manager1");
-  private static final Subject SUB_ANALYST = new Subject("analyst1");
-  private static final Subject SUB_JUNIOR_ANALYST = new Subject("jranalyst1");
-
-  private static final Server SVR_SERVER1 = new Server("server1");
-  private static final Server SVR_ALL = new Server(AccessConstants.ALL);
-
-  private static final Database DB_CUSTOMERS = new Database("customers");
-  private static final Database DB_ANALYST = new Database("analyst1");
-  private static final Database DB_JR_ANALYST = new Database("jranalyst1");
-
-  private static final Table TBL_PURCHASES = new Table("purchases");
-
-  private static final Set<? extends Action> ALL = EnumSet.of(DBModelAction.ALL);
-  private static final Set<? extends Action> SELECT = EnumSet.of(DBModelAction.SELECT);
-  private static final Set<? extends Action> INSERT = EnumSet.of(DBModelAction.INSERT);
-
-  static {
-    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList("admin"));
-    USER_TO_GROUP_MAP.putAll(SUB_MANAGER.getName(), Arrays.asList("manager"));
-    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList("analyst"));
-    USER_TO_GROUP_MAP.putAll(SUB_JUNIOR_ANALYST.getName(),
-        Arrays.asList("jranalyst"));
-  }
-
-  private final ResourceAuthorizationProvider authzProvider;
-  private File baseDir;
-
-  public TestResourceAuthorizationProviderGeneralCases() throws IOException {
-    baseDir = Files.createTempDir();
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini", "test-authz-provider-other-group.ini");
-    authzProvider = new HadoopGroupResourceAuthorizationProvider(
-        new DBPolicyFileBackend("server1",
-        new File(baseDir, "test-authz-provider.ini").getPath()),
-        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP));
-
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void doTestAuthorizables(
-      Subject subject, Set<? extends Action> privileges, boolean expected,
-      Authorizable... authorizables) throws Exception {
-    List<Authorizable> authzHierarchy = Arrays.asList(authorizables);
-    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
-      helper.add("authorizables", authzHierarchy).add("Privileges", privileges);
-    LOGGER.info("Running with " + helper.toString());
-    Assert.assertEquals(helper.toString(), expected,
-        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
-    LOGGER.info("Passed " + helper.toString());
-  }
-
-  private void doTestResourceAuthorizationProvider(Subject subject,
-      Server server, Database database, Table table,
-      Set<? extends Action> privileges, boolean expected) throws Exception {
-    List<Authorizable> authzHierarchy = Arrays.asList(new Authorizable[] {
-        server, database, table
-    });
-    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
-    helper.add("Subject", subject).add("Server", server).add("DB", database)
-    .add("Table", table).add("Privileges", privileges).add("authzHierarchy", authzHierarchy);
-    LOGGER.info("Running with " + helper.toString());
-    Assert.assertEquals(helper.toString(), expected,
-        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
-    LOGGER.info("Passed " + helper.toString());
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, true);
-    doTestAuthorizables(SUB_ADMIN, SELECT, true, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES);
-
-  }
-  @Test
-  public void testManager() throws Exception {
-    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
-    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
-    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
-    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
-  }
-  @Test
-  public void testAnalyst() throws Exception {
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
-
-    // analyst sandbox
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, ALL, true);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, SELECT, true);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, INSERT, true);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_ANALYST, TBL_PURCHASES, SELECT, true);
-
-    // jr analyst sandbox
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, ALL, false);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, INSERT, false);
-    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
-  }
-  @Test
-  public void testJuniorAnalyst() throws Exception {
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, false);
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, false);
-    // jr analyst sandbox
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, ALL, true);
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, INSERT, true);
-    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_ALL, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderSpecialCases.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderSpecialCases.java
deleted file mode 100644
index 3d3e45a..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestResourceAuthorizationProviderSpecialCases.java
+++ /dev/null
@@ -1,122 +0,0 @@
- /*
- * 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.sentry.policy.db;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.db.AccessURI;
-import org.apache.sentry.core.model.db.DBModelAction;
-import org.apache.sentry.core.model.db.Server;
-import org.apache.sentry.provider.common.AuthorizationProvider;
-import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
-
-public class TestResourceAuthorizationProviderSpecialCases {
-  private AuthorizationProvider authzProvider;
-  private PolicyFile policyFile;
-  private File baseDir;
-  private File iniFile;
-  private String initResource;
-  @Before
-  public void setup() throws IOException {
-    baseDir = Files.createTempDir();
-    iniFile = new File(baseDir, "policy.ini");
-    initResource = "file://" + iniFile.getPath();
-    policyFile = new PolicyFile();
-  }
-
-  @After
-  public void teardown() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  @Test
-  public void testDuplicateEntries() throws Exception {
-    Subject user1 = new Subject("user1");
-    Server server1 = new Server("server1");
-    AccessURI uri = new AccessURI("file:///path/to/");
-    Set<? extends Action> actions = EnumSet.of(DBModelAction.ALL, DBModelAction.SELECT, DBModelAction.INSERT);
-    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
-      .addRolesToGroup("group1",  true, "role1", "role1")
-      .addPermissionsToRole("role1", true, "server=" + server1.getName() + "->uri=" + uri.getName(),
-          "server=" + server1.getName() + "->uri=" + uri.getName());
-    policyFile.write(iniFile);
-    DBPolicyFileBackend policy = new DBPolicyFileBackend(server1.getName(), initResource);
-    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy);
-    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, uri);
-    Assert.assertTrue(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-  @Test
-  public void testNonAbolutePath() throws Exception {
-    Subject user1 = new Subject("user1");
-    Server server1 = new Server("server1");
-    AccessURI uri = new AccessURI("file:///path/to/");
-    Set<? extends Action> actions = EnumSet.of(DBModelAction.ALL, DBModelAction.SELECT, DBModelAction.INSERT);
-    policyFile.addGroupsToUser(user1.getName(), "group1")
-      .addRolesToGroup("group1", "role1")
-      .addPermissionsToRole("role1", "server=" + server1.getName() + "->uri=" + uri.getName());
-    policyFile.write(iniFile);
-    DBPolicyFileBackend policy = new DBPolicyFileBackend(server1.getName(), initResource);
-    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy);
-    // positive test
-    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, uri);
-    Assert.assertTrue(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-    // negative tests
-    // TODO we should support the case of /path/to/./ but let's to that later
-    uri = new AccessURI("file:///path/to/./");
-    authorizableHierarchy = ImmutableList.of(server1, uri);
-    Assert.assertFalse(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-    uri = new AccessURI("file:///path/to/../");
-    authorizableHierarchy = ImmutableList.of(server1, uri);
-    Assert.assertFalse(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-    uri = new AccessURI("file:///path/to/../../");
-    authorizableHierarchy = ImmutableList.of(server1, uri);
-    Assert.assertFalse(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-    uri = new AccessURI("file:///path/to/dir/../../");
-    authorizableHierarchy = ImmutableList.of(server1, uri);
-    Assert.assertFalse(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-  @Test(expected=IllegalArgumentException.class)
-  public void testInvalidPath() throws Exception {
-    new AccessURI(":invaliduri");
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineDFS.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineDFS.java
deleted file mode 100644
index 77232a6..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineDFS.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hdfs.MiniDFSCluster;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestSimpleDBPolicyEngineDFS extends AbstractTestSimplePolicyEngine {
-
-  private static MiniDFSCluster dfsCluster;
-  private static FileSystem fileSystem;
-  private static Path root;
-  private static Path etc;
-
-  @BeforeClass
-  public static void setupLocalClazz() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    File dfsDir = new File(baseDir, "dfs");
-    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
-    Configuration conf = new Configuration();
-    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
-    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
-    fileSystem = dfsCluster.getFileSystem();
-    root = new Path(fileSystem.getUri().toString());
-    etc = new Path(root, "/etc");
-    fileSystem.mkdirs(etc);
-  }
-  @AfterClass
-  public static void teardownLocalClazz() {
-    if(dfsCluster != null) {
-      dfsCluster.shutdown();
-    }
-  }
-
-  @Override
-  protected void  afterSetup() throws IOException {
-    fileSystem.delete(etc, true);
-    fileSystem.mkdirs(etc);
-    PolicyFiles.copyToDir(fileSystem, etc, "test-authz-provider.ini", "test-authz-provider-other-group.ini");
-    setPolicy(new DBPolicyFileBackend("server1",
-        new Path(etc, "test-authz-provider.ini").toString()));
-  }
-  @Override
-  protected void beforeTeardown() throws IOException {
-    fileSystem.delete(etc, true);
-  }
-
-  @Test
-  public void testMultiFSPolicy() throws Exception {
-    File globalPolicyFile = new File(Files.createTempDir(), "global-policy.ini");
-    File dbPolicyFile = new File(Files.createTempDir(), "db11-policy.ini");
-
-    // Create global policy file
-    PolicyFile dbPolicy = new PolicyFile()
-      .addPermissionsToRole("db11_role", "server=server1->db=db11")
-      .addRolesToGroup("group1", "db11_role");
-
-    dbPolicy.write(dbPolicyFile);
-    Path dbPolicyPath = new Path(etc, "db11-policy.ini");
-
-    // create per-db policy file
-    PolicyFile globalPolicy = new PolicyFile()
-      .addPermissionsToRole("admin_role", "server=server1")
-      .addRolesToGroup("admin_group", "admin_role")
-      .addGroupsToUser("db", "admin_group");
-    globalPolicy.addDatabase("db11", dbPolicyPath.toUri().toString());
-    globalPolicy.write(globalPolicyFile);
-
-
-    PolicyFiles.copyFilesToDir(fileSystem, etc, globalPolicyFile);
-    PolicyFiles.copyFilesToDir(fileSystem, etc, dbPolicyFile);
-    DBPolicyFileBackend multiFSEngine =
-        new DBPolicyFileBackend("server1", globalPolicyFile.getPath());
-
-    Set<String> dbGroups = Sets.newHashSet();
-    dbGroups.add("group1");
-    ImmutableSet<String> dbPerms =
-        multiFSEngine.getAllPrivileges(dbGroups, ActiveRoleSet.ALL);
-    Assert.assertEquals("No DB permissions found", 1, dbPerms.size());
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineLocalFS.java b/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineLocalFS.java
deleted file mode 100644
index f779949..0000000
--- a/sentry-policy/sentry-policy-db/src/test/java/org/apache/sentry/policy/db/TestSimpleDBPolicyEngineLocalFS.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.sentry.policy.db;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.provider.file.PolicyFiles;
-
-public class TestSimpleDBPolicyEngineLocalFS extends AbstractTestSimplePolicyEngine {
-
-  @Override
-  protected void  afterSetup() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini", "test-authz-provider-other-group.ini");
-    setPolicy(new DBPolicyFileBackend("server1",
-        new File(baseDir, "test-authz-provider.ini").getPath()));
-  }
-  @Override
-  protected void beforeTeardown() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    FileUtils.deleteQuietly(baseDir);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/resources/log4j.properties b/sentry-policy/sentry-policy-db/src/test/resources/log4j.properties
deleted file mode 100644
index c41373c..0000000
--- a/sentry-policy/sentry-policy-db/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# 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.
-#
-
-# Define some default values that can be overridden by system properties.
-#
-# For testing, it may also be convenient to specify
-
-log4j.rootLogger=DEBUG,console
-
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.target=System.err
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n
-
-log4j.logger.org.apache.hadoop.conf.Configuration=INFO

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider-other-group.ini
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider-other-group.ini b/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider-other-group.ini
deleted file mode 100644
index cd3695c..0000000
--- a/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider-other-group.ini
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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.
-
-[groups]
-other_group = analyst_role
-
-[roles]
-analyst_role = server=server1->db=other_group_db->table=purchases->action=select
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider.ini b/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider.ini
deleted file mode 100644
index 2d00699..0000000
--- a/sentry-policy/sentry-policy-db/src/test/resources/test-authz-provider.ini
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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.
-
-[databases]
-other_group_db = test-authz-provider-other-group.ini
-
-[groups]
-manager = analyst_role, junior_analyst_role
-analyst = analyst_role
-jranalyst = junior_analyst_role
-admin = admin
-
-[roles]
-analyst_role = server=server1->db=customers->table=purchases->action=select, \
-  server=server1->db=analyst1, \
-  server=server1->db=jranalyst1->table=*->action=select
-junior_analyst_role = server=server1->db=jranalyst1, server=server1->db=customers->table=purchases_partial->action=select
-admin = server=server1

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-engine/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-engine/pom.xml b/sentry-policy/sentry-policy-engine/pom.xml
new file mode 100644
index 0000000..e9c44d7
--- /dev/null
+++ b/sentry-policy/sentry-policy-engine/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+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.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-policy</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>sentry-policy-engine</artifactId>
+    <name>Sentry Policy Engine</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sentry</groupId>
+            <artifactId>sentry-provider-common</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java b/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
new file mode 100644
index 0000000..16e1ba2
--- /dev/null
+++ b/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPolicyEngine.java
@@ -0,0 +1,106 @@
+/*
+ * 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.sentry.policy.engine.common;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.SentryConfigurationException;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.common.PrivilegeFactory;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+public class CommonPolicyEngine implements PolicyEngine {
+
+  private static final Logger LOGGER = LoggerFactory
+          .getLogger(CommonPolicyEngine.class);
+
+  private final ProviderBackend providerBackend;
+
+  public CommonPolicyEngine(ProviderBackend providerBackend) {
+    this.providerBackend = providerBackend;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public PrivilegeFactory getPrivilegeFactory() {
+    return new CommonPrivilegeFactory();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups,
+          ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, roleSet);
+  }
+
+  @Override
+  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
+          ActiveRoleSet roleSet) throws SentryConfigurationException {
+    return getPrivileges(groups, users, roleSet);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
+          throws SentryConfigurationException {
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for {}", groups);
+    }
+
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet);
+    if(LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
+  @Override
+  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users, ActiveRoleSet roleSet,
+          Authorizable... authorizableHierarchy) throws SentryConfigurationException {
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
+    }
+    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
+    if (LOGGER.isDebugEnabled()) {
+      LOGGER.debug("result = " + result);
+    }
+    return result;
+  }
+
+  @Override
+  public void validatePolicy(boolean strictValidation) throws SentryConfigurationException {
+    this.providerBackend.validatePolicy(strictValidation);
+  }
+
+  @Override
+  public void close() {
+    if (providerBackend != null) {
+      providerBackend.close();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPrivilegeFactory.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPrivilegeFactory.java b/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPrivilegeFactory.java
new file mode 100644
index 0000000..d338f0e
--- /dev/null
+++ b/sentry-policy/sentry-policy-engine/src/main/java/org/apache/sentry/policy/engine/common/CommonPrivilegeFactory.java
@@ -0,0 +1,29 @@
+/*
+ * 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.sentry.policy.engine.common;
+
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
+import org.apache.sentry.policy.common.PrivilegeFactory;
+
+public class CommonPrivilegeFactory implements PrivilegeFactory {
+
+  @Override
+  public Privilege createPrivilege(String privilege) {
+    return new CommonPrivilege(privilege);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/pom.xml b/sentry-policy/sentry-policy-indexer/pom.xml
index 9b307c5..e6ef72f 100644
--- a/sentry-policy/sentry-policy-indexer/pom.xml
+++ b/sentry-policy/sentry-policy-indexer/pom.xml
@@ -73,6 +73,10 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-policy-engine</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-file</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/AbstractIndexerPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/AbstractIndexerPrivilegeValidator.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/AbstractIndexerPrivilegeValidator.java
deleted file mode 100644
index a01824c..0000000
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/AbstractIndexerPrivilegeValidator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.sentry.policy.indexer;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.shiro.config.ConfigurationException;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-
-public abstract class AbstractIndexerPrivilegeValidator implements PrivilegeValidator {
-
-  @VisibleForTesting
-  public static Iterable<IndexerModelAuthorizable> parsePrivilege(String string) {
-    List<IndexerModelAuthorizable> result = Lists.newArrayList();
-    for(String section : AUTHORIZABLE_SPLITTER.split(string)) {
-      // XXX this ugly hack is because action is not an authorizable
-      if(!section.toLowerCase().startsWith(PRIVILEGE_PREFIX)) {
-        IndexerModelAuthorizable authorizable = IndexerModelAuthorizables.from(section);
-        if(authorizable == null) {
-          String msg = "No authorizable found for " + section;
-          throw new ConfigurationException(msg);
-        }
-        result.add(authorizable);
-      }
-    }
-    return result;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerModelAuthorizables.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerModelAuthorizables.java
deleted file mode 100644
index 13893b3..0000000
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerModelAuthorizables.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.sentry.policy.indexer;
-
-import org.apache.sentry.core.model.indexer.Indexer;
-import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
-import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable.AuthorizableType;
-import org.apache.sentry.policy.common.KeyValue;
-
-public class IndexerModelAuthorizables {
-
-  public static IndexerModelAuthorizable from(KeyValue keyValue) {
-    String prefix = keyValue.getKey().toLowerCase();
-    String name = keyValue.getValue().toLowerCase();
-    for(AuthorizableType type : AuthorizableType.values()) {
-      if(prefix.equalsIgnoreCase(type.name())) {
-        return from(type, name);
-      }
-    }
-    return null;
-  }
-  public static IndexerModelAuthorizable from(String s) {
-    return from(new KeyValue(s));
-  }
-
-  private static IndexerModelAuthorizable from(AuthorizableType type, String name) {
-    switch (type) {
-    case Indexer:
-      return new Indexer(name);
-    default:
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerRequiredInPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerRequiredInPrivilege.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerRequiredInPrivilege.java
deleted file mode 100644
index 06b815f..0000000
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerRequiredInPrivilege.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.sentry.policy.indexer;
-
-import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.core.model.indexer.Indexer;
-import org.apache.sentry.core.model.indexer.IndexerModelAuthorizable;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-
-public class IndexerRequiredInPrivilege extends AbstractIndexerPrivilegeValidator {
-
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws SentryConfigurationException {
-    String privilege = context.getPrivilege();
-    Iterable<IndexerModelAuthorizable> authorizables = parsePrivilege(privilege);
-    boolean foundIndexerInAuthorizables = false;
-
-    for(IndexerModelAuthorizable authorizable : authorizables) {
-      if(authorizable instanceof Indexer) {
-        foundIndexerInAuthorizables = true;
-        break;
-      }
-    }
-    if(!foundIndexerInAuthorizables) {
-      String msg = "Missing indexer object in " + privilege;
-      throw new SentryConfigurationException(msg);
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
index 0ec0ce1..71d2a66 100644
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
+++ b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/IndexerWildcardPrivilege.java
@@ -23,11 +23,12 @@ package org.apache.sentry.policy.indexer;
 
 import java.util.List;
 
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.model.indexer.IndexerConstants;
-import org.apache.sentry.policy.common.PolicyConstants;
 import org.apache.sentry.policy.common.Privilege;
 import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.KeyValue;
+import org.apache.sentry.core.common.utils.KeyValue;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
@@ -44,7 +45,7 @@ public class IndexerWildcardPrivilege implements Privilege {
       throw new IllegalArgumentException("Wildcard string cannot be null or empty.");
     }
     List<KeyValue>parts = Lists.newArrayList();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.trimResults().split(
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.trimResults().split(
         wildcardString)) {
       if (authorizable.isEmpty()) {
         throw new IllegalArgumentException("Privilege '" + wildcardString + "' has an empty section");
@@ -59,7 +60,7 @@ public class IndexerWildcardPrivilege implements Privilege {
 
 
   @Override
-  public boolean implies(Privilege p) {
+  public boolean implies(Privilege p, Model model) {
     // By default only supports comparisons with other IndexerWildcardPermissions
     if (!(p instanceof IndexerWildcardPrivilege)) {
       return false;
@@ -108,7 +109,7 @@ public class IndexerWildcardPrivilege implements Privilege {
         "Please report, this method should not be called with two different keys");
     if(policyPart.getValue().equals(IndexerConstants.ALL) || policyPart.equals(requestPart)) {
       return true;
-    } else if (!PolicyConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey())
+    } else if (!SentryConstants.PRIVILEGE_NAME.equalsIgnoreCase(policyPart.getKey())
         && IndexerConstants.ALL.equalsIgnoreCase(requestPart.getValue())) {
       /* privilege request is to match with any object of given type */
       return true;
@@ -118,7 +119,7 @@ public class IndexerWildcardPrivilege implements Privilege {
 
   @Override
   public String toString() {
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(parts);
+    return SentryConstants.AUTHORIZABLE_JOINER.join(parts);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
index 8914319..7b1536a 100644
--- a/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
+++ b/sentry-policy/sentry-policy-indexer/src/main/java/org/apache/sentry/policy/indexer/SimpleIndexerPolicyEngine.java
@@ -21,15 +21,12 @@ import java.util.Set;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.PrivilegeValidator;
+import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.ProviderBackend;
-import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -44,10 +41,6 @@ public class SimpleIndexerPolicyEngine implements PolicyEngine {
 
   public SimpleIndexerPolicyEngine(ProviderBackend providerBackend) {
     this.providerBackend = providerBackend;
-    ProviderBackendContext context = new ProviderBackendContext();
-    context.setAllowPerDatabase(false);
-    context.setValidators(createPrivilegeValidators());
-    this.providerBackend.initialize(context);
   }
 
   /**
@@ -107,10 +100,6 @@ public class SimpleIndexerPolicyEngine implements PolicyEngine {
     throw new SentryConfigurationException("Not implemented yet");
   }
 
-  public static ImmutableList<PrivilegeValidator> createPrivilegeValidators() {
-    return ImmutableList.<PrivilegeValidator>of(new IndexerRequiredInPrivilege());
-  }
-
   @Override
   public void close() {
     if (providerBackend != null) {

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java
new file mode 100644
index 0000000..45f100e
--- /dev/null
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexPolicyTestUtil.java
@@ -0,0 +1,44 @@
+/*
+ * 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.sentry.policy.indexer;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+
+import java.io.IOException;
+
+public class IndexPolicyTestUtil {
+
+  public static PolicyEngine createPolicyEngineForTest(String resource) throws IOException {
+
+    ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource);
+
+    // create backendContext
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(IndexerPrivilegeModel.getInstance().getPrivilegeValidators());
+    // initialize the backend with the context
+    providerBackend.initialize(context);
+
+    return new CommonPolicyEngine(providerBackend);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexerPolicyFileBackend.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexerPolicyFileBackend.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexerPolicyFileBackend.java
deleted file mode 100644
index ba1b3ed..0000000
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/IndexerPolicyFileBackend.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.sentry.policy.indexer;
-
-import java.io.IOException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.provider.file.SimpleFileProviderBackend;
-
-public class IndexerPolicyFileBackend extends SimpleIndexerPolicyEngine {
-  public IndexerPolicyFileBackend(String resource) throws IOException{
-    super(new SimpleFileProviderBackend(new Configuration(), resource));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
new file mode 100644
index 0000000..2a3bde7
--- /dev/null
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestCommonPrivilegeForIndexer.java
@@ -0,0 +1,214 @@
+/*
+ * 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.sentry.policy.indexer;
+
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.indexer.IndexerConstants;
+import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+public class TestCommonPrivilegeForIndexer {
+
+  private Model indexerPrivilegeModel;
+
+  private static final String ALL = IndexerConstants.ALL;
+
+  @Before
+  public void prepareData() {
+    indexerPrivilegeModel = IndexerPrivilegeModel.getInstance();
+  }
+
+  @Test
+  public void testSimpleNoAction() throws Exception {
+    CommonPrivilege indexer1 = create(new KeyValue("indexer", "ind1"));
+    CommonPrivilege indexer2 = create(new KeyValue("indexer", "ind2"));
+    CommonPrivilege indexer1Case = create(new KeyValue("indeXeR", "inD1"));
+
+    assertTrue(indexer1.implies(indexer1, indexerPrivilegeModel));
+    assertTrue(indexer2.implies(indexer2, indexerPrivilegeModel));
+    assertTrue(indexer1.implies(indexer1Case, indexerPrivilegeModel));
+    assertTrue(indexer1Case.implies(indexer1, indexerPrivilegeModel));
+
+    assertFalse(indexer1.implies(indexer2, indexerPrivilegeModel));
+    assertFalse(indexer1Case.implies(indexer2, indexerPrivilegeModel));
+    assertFalse(indexer2.implies(indexer1, indexerPrivilegeModel));
+    assertFalse(indexer2.implies(indexer1Case, indexerPrivilegeModel));
+  }
+
+  @Test
+  public void testSimpleAction() throws Exception {
+    CommonPrivilege read =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read"));
+    CommonPrivilege write =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write"));
+    CommonPrivilege readCase =
+            create(new KeyValue("indeXeR", "iNd1"), new KeyValue("AcTiOn", "ReAd"));
+
+    assertTrue(read.implies(read, indexerPrivilegeModel));
+    assertTrue(write.implies(write, indexerPrivilegeModel));
+    assertTrue(read.implies(readCase, indexerPrivilegeModel));
+    assertTrue(readCase.implies(read, indexerPrivilegeModel));
+
+    assertFalse(read.implies(write, indexerPrivilegeModel));
+    assertFalse(readCase.implies(write, indexerPrivilegeModel));
+    assertFalse(write.implies(read, indexerPrivilegeModel));
+    assertFalse(write.implies(readCase, indexerPrivilegeModel));
+  }
+
+  @Test
+  public void testRoleShorterThanRequest() throws Exception {
+    CommonPrivilege indexer1 = create(new KeyValue("indexer", "ind1"));
+    CommonPrivilege read =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read"));
+    CommonPrivilege write =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write"));
+    CommonPrivilege all =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", ALL));
+
+    assertTrue(indexer1.implies(read, indexerPrivilegeModel));
+    assertTrue(indexer1.implies(write, indexerPrivilegeModel));
+    assertTrue(indexer1.implies(all, indexerPrivilegeModel));
+
+    assertFalse(read.implies(indexer1, indexerPrivilegeModel));
+    assertFalse(write.implies(indexer1, indexerPrivilegeModel));
+    assertTrue(all.implies(indexer1, indexerPrivilegeModel));
+  }
+
+  @Test
+  public void testIndexerAll() throws Exception {
+    CommonPrivilege indexerAll = create(new KeyValue("indexer", ALL));
+    CommonPrivilege indexer1 = create(new KeyValue("indexer", "ind1"));
+    assertTrue(indexerAll.implies(indexer1, indexerPrivilegeModel));
+    assertTrue(indexer1.implies(indexerAll, indexerPrivilegeModel));
+
+    CommonPrivilege allWrite =
+            create(new KeyValue("indexer", ALL), new KeyValue("action", "write"));
+    CommonPrivilege allRead =
+            create(new KeyValue("indexer", ALL), new KeyValue("action", "read"));
+    CommonPrivilege ind1Write =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write"));
+    CommonPrivilege ind1Read =
+            create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read"));
+    assertTrue(allWrite.implies(ind1Write, indexerPrivilegeModel));
+    assertTrue(allRead.implies(ind1Read, indexerPrivilegeModel));
+    assertTrue(ind1Write.implies(allWrite, indexerPrivilegeModel));
+    assertTrue(ind1Read.implies(allRead, indexerPrivilegeModel));
+    assertFalse(allWrite.implies(ind1Read, indexerPrivilegeModel));
+    assertFalse(ind1Write.implies(ind1Read, indexerPrivilegeModel));
+    assertFalse(allRead.implies(ind1Write, indexerPrivilegeModel));
+    assertFalse(ind1Read.implies(allWrite, indexerPrivilegeModel));
+    assertFalse(allWrite.implies(allRead, indexerPrivilegeModel));
+    assertFalse(allRead.implies(allWrite, indexerPrivilegeModel));
+    assertFalse(ind1Write.implies(ind1Read, indexerPrivilegeModel));
+    assertFalse(ind1Read.implies(ind1Write, indexerPrivilegeModel));
+
+    // test different length paths
+    assertTrue(indexerAll.implies(allWrite, indexerPrivilegeModel));
+    assertTrue(indexerAll.implies(allRead, indexerPrivilegeModel));
+    assertTrue(indexerAll.implies(ind1Write, indexerPrivilegeModel));
+    assertTrue(indexerAll.implies(ind1Read, indexerPrivilegeModel));
+    assertFalse(allWrite.implies(indexerAll, indexerPrivilegeModel));
+    assertFalse(allRead.implies(indexerAll, indexerPrivilegeModel));
+    assertFalse(ind1Write.implies(indexerAll, indexerPrivilegeModel));
+    assertFalse(ind1Read.implies(indexerAll, indexerPrivilegeModel));
+  }
+
+  @Test
+  public void testActionAll() throws Exception {
+    CommonPrivilege ind1All =
+            create(new KeyValue("indexer", "index1"), new KeyValue("action", ALL));
+    CommonPrivilege ind1Write =
+            create(new KeyValue("indexer", "index1"), new KeyValue("action", "write"));
+    CommonPrivilege ind1Read =
+            create(new KeyValue("indexer", "index1"), new KeyValue("action", "read"));
+    assertTrue(ind1All.implies(ind1All, indexerPrivilegeModel));
+    assertTrue(ind1All.implies(ind1Write, indexerPrivilegeModel));
+    assertTrue(ind1All.implies(ind1Read, indexerPrivilegeModel));
+    assertFalse(ind1Write.implies(ind1All, indexerPrivilegeModel));
+    assertFalse(ind1Read.implies(ind1All, indexerPrivilegeModel));
+
+    // test different lengths
+    CommonPrivilege ind1 =
+            create(new KeyValue("indexer", "index1"));
+    assertTrue(ind1All.implies(ind1, indexerPrivilegeModel));
+    assertTrue(ind1.implies(ind1All, indexerPrivilegeModel));
+  }
+
+  @Test
+  public void testUnexpected() throws Exception {
+    Privilege p = new Privilege() {
+      @Override
+      public boolean implies(Privilege p, Model model) {
+        return false;
+      }
+    };
+    CommonPrivilege indexer1 = create(new KeyValue("indexer", "index1"));
+    assertFalse(indexer1.implies(null, indexerPrivilegeModel));
+    assertFalse(indexer1.implies(p, indexerPrivilegeModel));
+    assertFalse(indexer1.equals(null));
+    assertFalse(indexer1.equals(p));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNullString() throws Exception {
+    System.out.println(create((String)null));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyString() throws Exception {
+    System.out.println(create(""));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("indexer", "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("", "index1")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyPart() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_JOINER.join("indexer11", "index1"), "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testOnlySeperators() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR,
+            SentryConstants.KV_SEPARATOR)));
+  }
+
+  static CommonPrivilege create(KeyValue... keyValues) {
+    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
+  }
+
+  static CommonPrivilege create(String s) {
+    return new CommonPrivilege(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java
index d6d8b79..939621b 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderGeneralCases.java
@@ -32,6 +32,7 @@ import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.indexer.Indexer;
 import org.apache.sentry.core.model.indexer.IndexerModelAction;
+import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel;
 import org.apache.sentry.provider.common.MockGroupMappingServiceProvider;
 import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
 import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider;
@@ -84,8 +85,8 @@ public class TestIndexerAuthorizationProviderGeneralCases {
     baseDir = Files.createTempDir();
     PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
     authzProvider = new HadoopGroupResourceAuthorizationProvider(
-        new IndexerPolicyFileBackend(new File(baseDir, "test-authz-provider.ini").getPath()),
-        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP));
+        IndexPolicyTestUtil.createPolicyEngineForTest(new File(baseDir, "test-authz-provider.ini").getPath()),
+        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), IndexerPrivilegeModel.getInstance());
 
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderSpecialCases.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderSpecialCases.java
index 9c211b7..1717c42 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderSpecialCases.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerAuthorizationProviderSpecialCases.java
@@ -31,6 +31,8 @@ import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.indexer.Indexer;
 import org.apache.sentry.core.model.indexer.IndexerModelAction;
+import org.apache.sentry.core.model.indexer.IndexerPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.AuthorizationProvider;
 import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
 import org.apache.sentry.provider.file.PolicyFile;
@@ -72,8 +74,8 @@ public class TestIndexerAuthorizationProviderSpecialCases {
       .addPermissionsToRole("role1", true, "indexer=" + indexer1.getName(),
           "indexer=" + indexer1.getName());
     policyFile.write(iniFile);
-    IndexerPolicyFileBackend policy = new IndexerPolicyFileBackend(initResource);
-    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy);
+    PolicyEngine policy = IndexPolicyTestUtil.createPolicyEngineForTest(initResource);
+    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, IndexerPrivilegeModel.getInstance());
     List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(indexer1);
     Assert.assertTrue(authorizableHierarchy.toString(),
         authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerModelAuthorizables.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerModelAuthorizables.java
index 8d21dc3..1d8ca53 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerModelAuthorizables.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerModelAuthorizables.java
@@ -21,13 +21,14 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
 import org.apache.sentry.core.model.indexer.Indexer;
+import org.apache.sentry.core.model.indexer.IndexerModelAuthorizables;
 import org.junit.Test;
 
 public class TestIndexerModelAuthorizables {
 
   @Test
   public void testIndexer() throws Exception {
-    Indexer indexer = (Indexer)IndexerModelAuthorizables.from("InDexEr=indexer1");
+    Indexer indexer = (Indexer) IndexerModelAuthorizables.from("InDexEr=indexer1");
     assertEquals("indexer1", indexer.getName());
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineDFS.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineDFS.java
index c6d6718..e644827 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineDFS.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineDFS.java
@@ -63,7 +63,7 @@ public class TestIndexerPolicyEngineDFS extends AbstractTestIndexerPolicyEngine
     fileSystem.delete(etc, true);
     fileSystem.mkdirs(etc);
     PolicyFiles.copyToDir(fileSystem, etc, "test-authz-provider.ini");
-    setPolicy(new IndexerPolicyFileBackend(new Path(etc,
+    setPolicy(IndexPolicyTestUtil.createPolicyEngineForTest(new Path(etc,
         "test-authz-provider.ini").toString()));
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineLocalFS.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineLocalFS.java
index f083f49..bd827fc 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineLocalFS.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyEngineLocalFS.java
@@ -32,7 +32,7 @@ public class TestIndexerPolicyEngineLocalFS extends AbstractTestIndexerPolicyEng
     Assert.assertNotNull(baseDir);
     Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
     PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    setPolicy(new IndexerPolicyFileBackend(new File(baseDir, "test-authz-provider.ini").getPath()));
+    setPolicy(IndexPolicyTestUtil.createPolicyEngineForTest(new File(baseDir, "test-authz-provider.ini").getPath()));
   }
   @Override
   protected void beforeTeardown() throws IOException {

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyNegative.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyNegative.java
index a453c48..e1a0dcc 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyNegative.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerPolicyNegative.java
@@ -72,7 +72,7 @@ public class TestIndexerPolicyNegative {
     append("other_group = some_role", otherPolicyFile);
     append("[roles]", otherPolicyFile);
     append("some_role = indexer=i1", otherPolicyFile);
-    IndexerPolicyFileBackend policy = new IndexerPolicyFileBackend(globalPolicyFile.getPath());
+    PolicyEngine policy = IndexPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
     Assert.assertEquals(Collections.emptySet(),
         policy.getPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL));
   }
@@ -83,7 +83,7 @@ public class TestIndexerPolicyNegative {
     append("group = some_role", globalPolicyFile);
     append("[roles]", globalPolicyFile);
     append("some_role = action=read", globalPolicyFile);
-    PolicyEngine policy = new IndexerPolicyFileBackend(globalPolicyFile.getPath());
+    PolicyEngine policy = IndexPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
     ImmutableSet<String> permissions = policy.getPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
     Assert.assertTrue(permissions.toString(), permissions.isEmpty());
   }
@@ -94,7 +94,7 @@ public class TestIndexerPolicyNegative {
     append("group = malicious_role", globalPolicyFile);
     append("[roles]", globalPolicyFile);
     append("malicious_role = indexer=*", globalPolicyFile);
-    PolicyEngine policy = new IndexerPolicyFileBackend(globalPolicyFile.getPath());
+    PolicyEngine policy = IndexPolicyTestUtil.createPolicyEngineForTest(globalPolicyFile.getPath());
     ImmutableSet<String> permissions = policy.getPrivileges(Sets.newHashSet("incorrectGroup"), ActiveRoleSet.ALL);
     Assert.assertTrue(permissions.toString(), permissions.isEmpty());
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerRequiredInRole.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerRequiredInRole.java
index 57876e5..ff20d03 100644
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerRequiredInRole.java
+++ b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerRequiredInRole.java
@@ -20,7 +20,8 @@ package org.apache.sentry.policy.indexer;
 
 import org.junit.Assert;
 
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.indexer.validator.IndexerRequiredInPrivilege;
 import org.apache.shiro.config.ConfigurationException;
 import org.junit.Test;
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerWildcardPrivilege.java b/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerWildcardPrivilege.java
deleted file mode 100644
index 17cebc3..0000000
--- a/sentry-policy/sentry-policy-indexer/src/test/java/org/apache/sentry/policy/indexer/TestIndexerWildcardPrivilege.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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.sentry.policy.indexer;
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_SEPARATOR;
-
-import org.apache.sentry.core.model.indexer.IndexerConstants;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.KeyValue;
-import org.junit.Test;
-
-public class TestIndexerWildcardPrivilege extends org.junit.Assert {
-
-  private static final String ALL = IndexerConstants.ALL;
-
-  @Test
-  public void testSimpleNoAction() throws Exception {
-    Privilege indexer1 = create(new KeyValue("indexer", "ind1"));
-    Privilege indexer2 = create(new KeyValue("indexer", "ind2"));
-    Privilege indexer1Case = create(new KeyValue("indeXeR", "inD1"));
-
-    assertTrue(indexer1.implies(indexer1));
-    assertTrue(indexer2.implies(indexer2));
-    assertTrue(indexer1.implies(indexer1Case));
-    assertTrue(indexer1Case.implies(indexer1));
-
-    assertFalse(indexer1.implies(indexer2));
-    assertFalse(indexer1Case.implies(indexer2));
-    assertFalse(indexer2.implies(indexer1));
-    assertFalse(indexer2.implies(indexer1Case));
-  }
-
-  @Test
-  public void testSimpleAction() throws Exception {
-    Privilege read =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read"));
-    Privilege write =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write"));
-    Privilege readCase =
-      create(new KeyValue("indeXeR", "iNd1"), new KeyValue("AcTiOn", "ReAd"));
-
-    assertTrue(read.implies(read));
-    assertTrue(write.implies(write));
-    assertTrue(read.implies(readCase));
-    assertTrue(readCase.implies(read));
-
-    assertFalse(read.implies(write));
-    assertFalse(readCase.implies(write));
-    assertFalse(write.implies(read));
-    assertFalse(write.implies(readCase));
-  }
-
-  @Test
-  public void testRoleShorterThanRequest() throws Exception {
-    Privilege indexer1 = create(new KeyValue("indexer", "ind1"));
-    Privilege read =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read"));
-    Privilege write =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write"));
-    Privilege all =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", ALL));
-
-    assertTrue(indexer1.implies(read));
-    assertTrue(indexer1.implies(write));
-    assertTrue(indexer1.implies(all));
-
-    assertFalse(read.implies(indexer1));
-    assertFalse(write.implies(indexer1));
-    assertTrue(all.implies(indexer1));
-  }
-
-  @Test
-  public void testIndexerAll() throws Exception {
-    Privilege indexerAll = create(new KeyValue("indexer", ALL));
-    Privilege indexer1 = create(new KeyValue("indexer", "ind1"));
-    assertTrue(indexerAll.implies(indexer1));
-    assertTrue(indexer1.implies(indexerAll));
-
-    Privilege allWrite =
-      create(new KeyValue("indexer", ALL), new KeyValue("action", "write"));
-    Privilege allRead =
-      create(new KeyValue("indexer", ALL), new KeyValue("action", "read"));
-    Privilege ind1Write =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", "write"));
-    Privilege ind1Read =
-      create(new KeyValue("indexer", "ind1"), new KeyValue("action", "read"));
-    assertTrue(allWrite.implies(ind1Write));
-    assertTrue(allRead.implies(ind1Read));
-    assertTrue(ind1Write.implies(allWrite));
-    assertTrue(ind1Read.implies(allRead));
-    assertFalse(allWrite.implies(ind1Read));
-    assertFalse(ind1Write.implies(ind1Read));
-    assertFalse(allRead.implies(ind1Write));
-    assertFalse(ind1Read.implies(allWrite));
-    assertFalse(allWrite.implies(allRead));
-    assertFalse(allRead.implies(allWrite));
-    assertFalse(ind1Write.implies(ind1Read));
-    assertFalse(ind1Read.implies(ind1Write));
-
-    // test different length paths
-    assertTrue(indexerAll.implies(allWrite));
-    assertTrue(indexerAll.implies(allRead));
-    assertTrue(indexerAll.implies(ind1Write));
-    assertTrue(indexerAll.implies(ind1Read));
-    assertFalse(allWrite.implies(indexerAll));
-    assertFalse(allRead.implies(indexerAll));
-    assertFalse(ind1Write.implies(indexerAll));
-    assertFalse(ind1Read.implies(indexerAll));
-  }
-
-  @Test
-  public void testActionAll() throws Exception {
-    Privilege ind1All =
-       create(new KeyValue("indexer", "index1"), new KeyValue("action", ALL));
-    Privilege ind1Write =
-      create(new KeyValue("indexer", "index1"), new KeyValue("action", "write"));
-    Privilege ind1Read =
-      create(new KeyValue("indexer", "index1"), new KeyValue("action", "read"));
-    assertTrue(ind1All.implies(ind1All));
-    assertTrue(ind1All.implies(ind1Write));
-    assertTrue(ind1All.implies(ind1Read));
-    assertFalse(ind1Write.implies(ind1All));
-    assertFalse(ind1Read.implies(ind1All));
-
-    // test different lengths
-    Privilege ind1 =
-       create(new KeyValue("indexer", "index1"));
-    assertTrue(ind1All.implies(ind1));
-    assertTrue(ind1.implies(ind1All));
-  }
-
-  @Test
-  public void testUnexpected() throws Exception {
-    Privilege p = new Privilege() {
-      @Override
-      public boolean implies(Privilege p) {
-        return false;
-      }
-    };
-    Privilege indexer1 = create(new KeyValue("indexer", "index1"));
-    assertFalse(indexer1.implies(null));
-    assertFalse(indexer1.implies(p));
-    assertFalse(indexer1.equals(null));
-    assertFalse(indexer1.equals(p));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNullString() throws Exception {
-    System.out.println(create((String)null));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyString() throws Exception {
-    System.out.println(create(""));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(create(KV_JOINER.join("indexer", "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(create(KV_JOINER.join("", "index1")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyPart() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_JOINER.join("indexer11", "index1"), "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testOnlySeperators() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_SEPARATOR, KV_SEPARATOR, KV_SEPARATOR)));
-  }
-
-  static IndexerWildcardPrivilege create(KeyValue... keyValues) {
-    return create(AUTHORIZABLE_JOINER.join(keyValues));
-
-  }
-  static IndexerWildcardPrivilege create(String s) {
-    return new IndexerWildcardPrivilege(s);
-  }
-}


[04/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/pom.xml b/sentry-policy/sentry-policy-kafka/pom.xml
deleted file mode 100644
index 44739fa..0000000
--- a/sentry-policy/sentry-policy-kafka/pom.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<!--
-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.
--->
-<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.sentry</groupId>
-    <artifactId>sentry-policy</artifactId>
-    <version>1.8.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>sentry-policy-kafka</artifactId>
-  <name>Sentry Policy for Kafka</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-minicluster</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>log4j</groupId>
-      <artifactId>log4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.shiro</groupId>
-      <artifactId>shiro-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-core-model-kafka</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-provider-file</artifactId>
-    </dependency>
-  </dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaModelAuthorizables.java b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaModelAuthorizables.java
deleted file mode 100644
index 7be4241..0000000
--- a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaModelAuthorizables.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import org.apache.sentry.core.model.kafka.Cluster;
-import org.apache.sentry.core.model.kafka.ConsumerGroup;
-import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
-import org.apache.sentry.core.model.kafka.KafkaAuthorizable.AuthorizableType;
-import org.apache.sentry.core.model.kafka.Host;
-import org.apache.sentry.core.model.kafka.Topic;
-import org.apache.sentry.policy.common.KeyValue;
-import org.apache.shiro.config.ConfigurationException;
-
-public class KafkaModelAuthorizables {
-  public static KafkaAuthorizable from(KeyValue keyValue) throws ConfigurationException {
-    String prefix = keyValue.getKey().toLowerCase();
-    String name = keyValue.getValue();
-    for (AuthorizableType type : AuthorizableType.values()) {
-      if (prefix.equalsIgnoreCase(type.name())) {
-        return from(type, name);
-      }
-    }
-    return null;
-  }
-
-  public static KafkaAuthorizable from(String keyValue) throws ConfigurationException {
-    return from(new KeyValue(keyValue));
-  }
-
-  public static KafkaAuthorizable from(AuthorizableType type, String name) throws ConfigurationException {
-    switch (type) {
-      case HOST:
-        return new Host(name);
-      case CLUSTER: {
-        if (!name.equals(Cluster.NAME)) {
-          throw new ConfigurationException("Kafka's cluster resource can only have name " + Cluster.NAME);
-        }
-        return new Cluster();
-      }
-      case TOPIC:
-        return new Topic(name);
-      case CONSUMERGROUP:
-        return new ConsumerGroup(name);
-      default:
-        return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaPrivilegeValidator.java b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaPrivilegeValidator.java
deleted file mode 100644
index 7383e50..0000000
--- a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaPrivilegeValidator.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_PREFIX;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.sentry.core.model.kafka.KafkaActionFactory;
-import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
-import org.apache.sentry.core.model.kafka.Host;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-
-import com.google.common.collect.Lists;
-
-/**
- * Validator for Kafka privileges.
- * Below are the requirements for a kafka privilege to be valid.
- * 1. Privilege must start with Host resource.
- * 2. Privilege must have at most one non Host resource, Cluster or Topic or ConsumerGroup, followed
- *    by Host resource.
- * 3. Privilege must end with exactly one action.
- */
-public class KafkaPrivilegeValidator implements PrivilegeValidator {
-
-  public static final String KafkaPrivilegeHelpMsg =
-      "Invalid Kafka privilege." +
-      " Kafka privilege must be of the form host=<HOST>-><RESOURCE>=<RESOURCE_NAME>->action=<ACTION>," +
-      " where <HOST> can be '*' or any valid host name," +
-      " <RESOURCE> can be one of " + Arrays.toString(getKafkaAuthorizablesExceptHost()) +
-      " <RESOURCE_NAME> is name of the resource," +
-      " <ACTION> can be one of " + Arrays.toString(KafkaActionFactory.KafkaActionType.values()) +
-      ".";
-
-  private static KafkaAuthorizable.AuthorizableType[] getKafkaAuthorizablesExceptHost() {
-    final KafkaAuthorizable.AuthorizableType[] authorizableTypes = KafkaAuthorizable.AuthorizableType.values();
-    List<KafkaAuthorizable.AuthorizableType> authorizableTypesWithoutHost = new ArrayList<>(authorizableTypes.length - 1);
-    for (KafkaAuthorizable.AuthorizableType authorizableType: authorizableTypes) {
-      if (!authorizableType.equals(KafkaAuthorizable.AuthorizableType.HOST)) {
-        authorizableTypesWithoutHost.add(authorizableType);
-      }
-    }
-    return authorizableTypesWithoutHost.toArray(new KafkaAuthorizable.AuthorizableType[authorizableTypesWithoutHost.size()]);
-  }
-
-  public KafkaPrivilegeValidator() {
-  }
-
-  @Override
-  public void validate(PrivilegeValidatorContext context) throws ConfigurationException {
-    List<String> splits = Lists.newArrayList();
-    for (String section : AUTHORIZABLE_SPLITTER.split(context.getPrivilege())) {
-      splits.add(section);
-    }
-
-    // Check privilege splits length is 2 or 3
-    if (splits.size() < 2 || splits.size() > 3) {
-      throw new ConfigurationException(KafkaPrivilegeHelpMsg);
-    }
-
-    // Check privilege starts with Host resource
-    if (isAction(splits.get(0))) {
-      throw new ConfigurationException("Kafka privilege can not start with an action.\n" + KafkaPrivilegeHelpMsg);
-    }
-    KafkaAuthorizable hostAuthorizable = KafkaModelAuthorizables.from(splits.get(0));
-    if (hostAuthorizable == null) {
-      throw new ConfigurationException("No Kafka authorizable found for " + splits.get(0) + "\n." + KafkaPrivilegeHelpMsg);
-    }
-    if (!(hostAuthorizable instanceof Host)) {
-      throw new ConfigurationException("Kafka privilege must begin with host authorizable.\n" + KafkaPrivilegeHelpMsg);
-    }
-
-    // Check privilege has at most one non Host resource following Host resource
-    if (splits.size() == 3) {
-      if (isAction(splits.get(1))) {
-        throw new ConfigurationException("Kafka privilege can have action only at the end of privilege.\n" + KafkaPrivilegeHelpMsg);
-      }
-      KafkaAuthorizable authorizable = KafkaModelAuthorizables.from(splits.get(1));
-      if (authorizable == null) {
-        throw new ConfigurationException("No Kafka authorizable found for " + splits.get(1) + "\n." + KafkaPrivilegeHelpMsg);
-      }
-      if (authorizable instanceof Host) {
-        throw new ConfigurationException("Host authorizable can be specified just once in a Kafka privilege.\n" + KafkaPrivilegeHelpMsg);
-      }
-    }
-
-    // Check privilege ends with exactly one valid action
-    if (!isAction(splits.get(splits.size() - 1))) {
-      throw new ConfigurationException("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeHelpMsg);
-    }
-  }
-
-  private boolean isAction(String privilegePart) {
-    final String privilege = privilegePart.toLowerCase();
-    final String action = privilege.replace(PRIVILEGE_PREFIX, "").toLowerCase();
-    return privilege.startsWith(PRIVILEGE_PREFIX) &&
-        KafkaActionFactory.getInstance().getActionByName(action) != null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java
deleted file mode 100644
index 6803a46..0000000
--- a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/KafkaWildcardPrivilege.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.kafka.KafkaActionConstant;
-import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.KeyValue;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class KafkaWildcardPrivilege implements Privilege {
-
-  private static String ALL_HOSTS = "*";
-
-  public static class Factory implements PrivilegeFactory {
-    @Override
-    public Privilege createPrivilege(String permission) {
-      return new KafkaWildcardPrivilege(permission);
-    }
-  }
-
-  private final ImmutableList<KeyValue> parts;
-
-  public KafkaWildcardPrivilege(String permission) {
-    if (Strings.isNullOrEmpty(permission)) {
-      throw new IllegalArgumentException("Permission string cannot be null or empty.");
-    }
-    List<KeyValue>parts = Lists.newArrayList();
-    for (String authorizable : AUTHORIZABLE_SPLITTER.trimResults().split(permission.trim())) {
-      if (authorizable.isEmpty()) {
-        throw new IllegalArgumentException("Privilege '" + permission + "' has an empty section");
-      }
-      parts.add(new KeyValue(authorizable));
-    }
-    if (parts.isEmpty()) {
-      throw new AssertionError("Privilege,  " + permission + ", did not consist of any valid authorizable.");
-    }
-    this.parts = ImmutableList.copyOf(parts);
-  }
-
-  @Override
-  public boolean implies(Privilege p) {
-    if (!(p instanceof KafkaWildcardPrivilege)) {
-      return false;
-    }
-    KafkaWildcardPrivilege wp = (KafkaWildcardPrivilege)p;
-    List<KeyValue> otherParts = wp.parts;
-    if(equals(wp)) {
-      return true;
-    }
-    int index = 0;
-    for (KeyValue otherPart : otherParts) {
-      // If this privilege has less parts than the other privilege, everything
-      // after the number of parts contained
-      // in this privilege is automatically implied, so return true
-      if (parts.size() - 1 < index) {
-        return true;
-      } else {
-        KeyValue part = parts.get(index);
-        // Support for action inheritance from parent to child
-        if (part.getKey().equalsIgnoreCase(KafkaActionConstant.actionName)
-            && !(otherPart.getKey().equalsIgnoreCase(KafkaActionConstant.actionName))) {
-          continue;
-        }
-        // are the keys even equal
-        if(!part.getKey().equalsIgnoreCase(otherPart.getKey())) {
-          return false;
-        }
-        if (!impliesKeyValue(part, otherPart)) {
-          return false;
-        }
-        index++;
-      }
-    }
-    // If this privilege has more parts than
-    // the other parts, only imply it if
-    // all of the other parts are "*" or "ALL"
-    for (; index < parts.size(); index++) {
-      KeyValue part = parts.get(index);
-      if (!part.getValue().equals(KafkaActionConstant.ALL)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
-    Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()),
-        "Please report, this method should not be called with two different keys");
-
-    // Host is a special resource, not declared as resource in Kafka. Each Kafka resource can be
-    // authorized based on the host request originated from and to handle this, Sentry uses host as
-    // a resource. Kafka allows using '*' as wildcard for all hosts. '*' however is not a valid
-    // Kafka action.
-    if (hasHostWidCard(policyPart)) {
-      return true;
-    }
-
-    if (KafkaActionConstant.actionName.equalsIgnoreCase(policyPart.getKey())) { // is action
-      return policyPart.getValue().equalsIgnoreCase(KafkaActionConstant.ALL) ||
-          policyPart.getValue().equalsIgnoreCase(requestPart.getValue());
-    } else {
-      return policyPart.getValue().equals(requestPart.getValue());
-    }
-  }
-
-  private boolean hasHostWidCard(KeyValue policyPart) {
-    if (policyPart.getKey().equalsIgnoreCase(KafkaAuthorizable.AuthorizableType.HOST.toString()) &&
-        policyPart.getValue().equalsIgnoreCase(ALL_HOSTS)) {
-      return true;
-    }
-    return false;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    for(KeyValue kv: this.parts) {
-      sb.append(kv.getKey() + "=" + kv.getValue() + "->");
-    }
-    return sb.toString();
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java b/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
deleted file mode 100644
index 4d90544..0000000
--- a/sentry-policy/sentry-policy-kafka/src/main/java/org/apache/sentry/policy/kafka/SimpleKafkaPolicyEngine.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import java.util.Set;
-
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.provider.common.ProviderBackend;
-import org.apache.sentry.provider.common.ProviderBackendContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class SimpleKafkaPolicyEngine implements PolicyEngine {
-  private static final Logger LOGGER = LoggerFactory.getLogger(SimpleKafkaPolicyEngine.class);
-  private final ProviderBackend providerBackend;
-
-  public SimpleKafkaPolicyEngine(ProviderBackend providerBackend) {
-    this.providerBackend = providerBackend;
-    ProviderBackendContext context = new ProviderBackendContext();
-    context.setAllowPerDatabase(false);
-    context.setValidators(ImmutableList.<PrivilegeValidator>of(new KafkaPrivilegeValidator()));
-    this.providerBackend.initialize(context);
-  }
-
-  @Override
-  public PrivilegeFactory getPrivilegeFactory() {
-    return new KafkaWildcardPrivilege.Factory();
-  }
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups, ActiveRoleSet roleSet)
-      throws SentryConfigurationException {
-    return getPrivileges(groups, roleSet);
-  }
-
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, ActiveRoleSet roleSet,
-                                            Authorizable... authorizableHierarchy)
-      throws SentryConfigurationException {
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for {}", groups);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, roleSet);
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-  @Override
-  public void close() {
-    if (providerBackend != null) {
-      providerBackend.close();
-    }
-  }
-
-  @Override
-  public void validatePolicy(boolean strictValidation)
-      throws SentryConfigurationException {
-    if (providerBackend != null) {
-      providerBackend.validatePolicy(strictValidation);
-    }
-  }
-
-  @Override
-  public ImmutableSet<String> getAllPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet) throws SentryConfigurationException {
-    return getPrivileges(groups, users, roleSet);
-  }
-
-  @Override
-  public ImmutableSet<String> getPrivileges(Set<String> groups, Set<String> users,
-      ActiveRoleSet roleSet, Authorizable... authorizableHierarchy)
-      throws SentryConfigurationException {
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("Getting permissions for groups: {}, users: {}", groups, users);
-    }
-    ImmutableSet<String> result = providerBackend.getPrivileges(groups, users, roleSet);
-    if(LOGGER.isDebugEnabled()) {
-      LOGGER.debug("result = " + result);
-    }
-    return result;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyFileProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyFileProviderBackend.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyFileProviderBackend.java
deleted file mode 100644
index c4a2f7b..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyFileProviderBackend.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import java.io.IOException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.provider.file.SimpleFileProviderBackend;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class KafkaPolicyFileProviderBackend extends SimpleKafkaPolicyEngine {
-  private static final Logger LOGGER = LoggerFactory.getLogger(KafkaPolicyFileProviderBackend.class);
-  public KafkaPolicyFileProviderBackend(String resource) throws IOException {
-    super(new SimpleFileProviderBackend(new Configuration(), resource));
-    LOGGER.warn("The DB provider backend is the preferred option over file provider backend as the kafka policy engine");
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java
deleted file mode 100644
index 572c74d..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import java.util.Set;
-
-import org.apache.sentry.provider.common.GroupMappingService;
-
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-public class MockGroupMappingServiceProvider implements GroupMappingService {
-  private final Multimap<String, String> userToGroupMap;
-
-  public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
-    this.userToGroupMap = userToGroupMap;
-  }
-  @Override
-  public Set<String> getGroups(String user) {
-    return Sets.newHashSet(userToGroupMap.get(user));
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java
deleted file mode 100644
index 421466e..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.fail;
-
-import org.apache.sentry.core.model.kafka.Cluster;
-import org.apache.sentry.core.model.kafka.ConsumerGroup;
-import org.apache.sentry.core.model.kafka.Host;
-import org.apache.sentry.core.model.kafka.Topic;
-import org.apache.shiro.config.ConfigurationException;
-import org.junit.Test;
-
-public class TestKafkaModelAuthorizables {
-
-  @Test
-  public void testHost() throws Exception {
-    Host host1 = (Host)KafkaModelAuthorizables.from("HOST=host1");
-    assertEquals("host1", host1.getName());
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNoKV() throws Exception {
-    System.out.println(KafkaModelAuthorizables.from("nonsense"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(KafkaModelAuthorizables.from("=host1"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(KafkaModelAuthorizables.from("HOST="));
-  }
-
-  @Test
-  public void testNotAuthorizable() throws Exception {
-    assertNull(KafkaModelAuthorizables.from("k=v"));
-  }
-
-  @Test
-  public void testResourceNameIsCaseSensitive() throws Exception {
-    Host host1 = (Host)KafkaModelAuthorizables.from("HOST=Host1");
-    assertEquals("Host1", host1.getName());
-
-    Cluster cluster1 = (Cluster)KafkaModelAuthorizables.from("Cluster=kafka-cluster");
-    assertEquals("kafka-cluster", cluster1.getName());
-
-    Topic topic1 = (Topic)KafkaModelAuthorizables.from("topic=topiC1");
-    assertEquals("topiC1", topic1.getName());
-
-    ConsumerGroup consumergroup1 = (ConsumerGroup)KafkaModelAuthorizables.from("ConsumerGroup=CG1");
-    assertEquals("CG1", consumergroup1.getName());
-  }
-
-  @Test
-  public void testClusterResourceNameIsRestricted() throws Exception {
-    try {
-      KafkaModelAuthorizables.from("Cluster=cluster1");
-      fail("Cluster with name other than " + Cluster.NAME + " must not have been created.");
-    } catch (ConfigurationException cex) {
-      assertEquals("Exception message is not as expected.", "Kafka's cluster resource can only have name " + Cluster.NAME, cex.getMessage());
-    } catch (Exception ex) {
-      fail("Configuration exception was expected for invalid Cluster name.");
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java
deleted file mode 100644
index 7caa3a9..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPrivilegeValidator.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-
-import junit.framework.Assert;
-
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-import org.junit.Test;
-
-public class TestKafkaPrivilegeValidator {
-  @Test
-  public void testOnlyHostResource() {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1"));
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals(KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-
-  @Test
-  public void testWithoutHostResource() throws Exception {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    testHostResourceIsChecked(kafkaPrivilegeValidator, "cluster=kafka-cluster->action=read");
-    testHostResourceIsChecked(kafkaPrivilegeValidator, "topic=t1->action=read");
-    testHostResourceIsChecked(kafkaPrivilegeValidator, "consumergroup=g1->action=read");
-  }
-
-  private void testHostResourceIsChecked(KafkaPrivilegeValidator kafkaPrivilegeValidator, String privilege) {
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext(privilege));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals("Kafka privilege must begin with host authorizable.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-
-  @Test
-  public void testValidPrivileges() throws Exception {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->cluster=kafka-cluster->action=read"));
-    } catch (ConfigurationException ex) {
-      Assert.fail("Not expected ConfigurationException");
-    }
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->action=read"));
-    } catch (ConfigurationException ex) {
-      Assert.fail("Not expected ConfigurationException");
-    }
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->consumergroup=g1->action=read"));
-    } catch (ConfigurationException ex) {
-      Assert.fail("Not expected ConfigurationException");
-    }
-  }
-
-  @Test
-  public void testInvalidHostResource() throws Exception {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("hhost=host1->cluster=kafka-cluster->action=read"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-    }
-  }
-
-  @Test
-  public void testInvalidClusterResource() throws Exception {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->clluster=kafka-cluster->action=read"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-    }
-  }
-
-  @Test
-  public void testInvalidTopicResource() throws Exception {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->ttopic=t1->action=read"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-    }
-  }
-
-  @Test
-  public void testInvalidConsumerGroupResource() throws Exception {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->coonsumergroup=g1->action=read"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-    }
-  }
-
-  @Test
-  public void testPrivilegeMustHaveExcatlyOneHost() {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->host=host2->action=read"));
-      Assert.fail("Multiple Host resources are not allowed within a Kafka privilege.");
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals("Host authorizable can be specified just once in a Kafka privilege.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-
-  @Test
-  public void testPrivilegeCanNotStartWithAction() {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("action=write->host=host1->topic=t1"));
-      Assert.fail("Kafka privilege can not start with an action.");
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals("Kafka privilege can not start with an action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-
-  @Test
-  public void testPrivilegeWithMoreParts() {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->consumergroup=cg1->action=read"));
-      Assert.fail("Kafka privilege can have one Host authorizable, at most one non Host authorizable and one action.");
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals(KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-
-  @Test
-  public void testPrivilegeNotEndingWithAction() {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->consumergroup=cg1"));
-      Assert.fail("Kafka privilege must end with a valid action.");
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-
-  @Test
-  public void testPrivilegeNotEndingWithValidAction() {
-    KafkaPrivilegeValidator kafkaPrivilegeValidator = new KafkaPrivilegeValidator();
-    try {
-      kafkaPrivilegeValidator.validate(new PrivilegeValidatorContext("host=host1->topic=t1->action=bla"));
-      Assert.fail("Kafka privilege must end with a valid action.");
-    } catch (ConfigurationException ex) {
-      Assert.assertEquals("Kafka privilege must end with a valid action.\n" + KafkaPrivilegeValidator.KafkaPrivilegeHelpMsg, ex.getMessage());
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaWildcardPrivilege.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaWildcardPrivilege.java
deleted file mode 100644
index bdef91c..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaWildcardPrivilege.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.sentry.policy.kafka;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import org.apache.sentry.core.model.kafka.KafkaActionConstant;
-import org.apache.sentry.policy.common.PolicyConstants;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.KeyValue;
-import org.junit.Test;
-
-public class TestKafkaWildcardPrivilege {
-  private static final Privilege KAFKA_HOST1_ALL =
-      create(new KeyValue("HOST", "host1"), new KeyValue("action", KafkaActionConstant.ALL));
-  private static final Privilege KAFKA_HOST1_READ =
-      create(new KeyValue("HOST", "host1"), new KeyValue("action", KafkaActionConstant.READ));
-  private static final Privilege KAFKA_HOST1_WRITE =
-      create(new KeyValue("HOST", "host1"), new KeyValue("action", KafkaActionConstant.WRITE));
-
-  private static final Privilege KAFKA_HOST1_TOPIC1_ALL =
-      create(new KeyValue("HOST", "host1"), new KeyValue("TOPIC", "topic1"), new KeyValue("action", KafkaActionConstant.ALL));
-  private static final Privilege KAFKA_HOST1_TOPIC1_READ =
-      create(new KeyValue("HOST", "host1"), new KeyValue("TOPIC", "topic1"), new KeyValue("action", KafkaActionConstant.READ));
-  private static final Privilege KAFKA_HOST1_TOPIC1_WRITE =
-      create(new KeyValue("HOST", "host1"), new KeyValue("TOPIC", "topic1"), new KeyValue("action", KafkaActionConstant.WRITE));
-
-  private static final Privilege KAFKA_HOST1_CLUSTER1_ALL =
-      create(new KeyValue("HOST", "host1"), new KeyValue("CLUSTER", "cluster1"), new KeyValue("action", KafkaActionConstant.ALL));
-  private static final Privilege KAFKA_HOST1_CLUSTER1_READ =
-      create(new KeyValue("HOST", "host1"), new KeyValue("CLUSTER", "cluster1"), new KeyValue("action", KafkaActionConstant.READ));
-  private static final Privilege KAFKA_HOST1_CLUSTER1_WRITE =
-      create(new KeyValue("HOST", "host1"), new KeyValue("CLUSTER", "cluster1"), new KeyValue("action", KafkaActionConstant.WRITE));
-
-  private static final Privilege KAFKA_HOST1_GROUP1_ALL =
-      create(new KeyValue("HOST", "host1"), new KeyValue("GROUP", "cgroup1"), new KeyValue("action", KafkaActionConstant.ALL));
-  private static final Privilege KAFKA_HOST1_GROUP1_READ =
-      create(new KeyValue("HOST", "host1"), new KeyValue("GROUP", "cgroup1"), new KeyValue("action", KafkaActionConstant.READ));
-  private static final Privilege KAFKA_HOST1_GROUP1_WRITE =
-      create(new KeyValue("HOST", "host1"), new KeyValue("GROUP", "cgroup1"), new KeyValue("action", KafkaActionConstant.WRITE));
-
-  @Test
-  public void testSimpleAction() throws Exception {
-    //host
-    assertFalse(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_READ));
-    assertFalse(KAFKA_HOST1_READ.implies(KAFKA_HOST1_WRITE));
-    //consumer group
-    assertFalse(KAFKA_HOST1_GROUP1_WRITE.implies(KAFKA_HOST1_GROUP1_READ));
-    assertFalse(KAFKA_HOST1_GROUP1_READ.implies(KAFKA_HOST1_GROUP1_WRITE));
-    //topic
-    assertFalse(KAFKA_HOST1_TOPIC1_READ.implies(KAFKA_HOST1_TOPIC1_WRITE));
-    assertFalse(KAFKA_HOST1_TOPIC1_WRITE.implies(KAFKA_HOST1_TOPIC1_READ));
-    //cluster
-    assertFalse(KAFKA_HOST1_CLUSTER1_READ.implies(KAFKA_HOST1_CLUSTER1_WRITE));
-    assertFalse(KAFKA_HOST1_CLUSTER1_WRITE.implies(KAFKA_HOST1_CLUSTER1_READ));
-  }
-
-  @Test
-  public void testShorterThanRequest() throws Exception {
-    //topic
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_TOPIC1_ALL));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_TOPIC1_READ));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_TOPIC1_WRITE));
-
-    assertFalse(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_READ));
-    assertTrue(KAFKA_HOST1_READ.implies(KAFKA_HOST1_TOPIC1_READ));
-    assertTrue(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_TOPIC1_WRITE));
-
-    //cluster
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_CLUSTER1_ALL));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_CLUSTER1_READ));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_CLUSTER1_WRITE));
-
-    assertTrue(KAFKA_HOST1_READ.implies(KAFKA_HOST1_CLUSTER1_READ));
-    assertTrue(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_CLUSTER1_WRITE));
-
-    //consumer group
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_GROUP1_ALL));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_GROUP1_READ));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_GROUP1_WRITE));
-
-    assertTrue(KAFKA_HOST1_READ.implies(KAFKA_HOST1_GROUP1_READ));
-    assertTrue(KAFKA_HOST1_WRITE.implies(KAFKA_HOST1_GROUP1_WRITE));
-  }
-
-  @Test
-  public void testActionAll() throws Exception {
-    //host
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_READ));
-    assertTrue(KAFKA_HOST1_ALL.implies(KAFKA_HOST1_WRITE));
-
-    //topic
-    assertTrue(KAFKA_HOST1_TOPIC1_ALL.implies(KAFKA_HOST1_TOPIC1_READ));
-    assertTrue(KAFKA_HOST1_TOPIC1_ALL.implies(KAFKA_HOST1_TOPIC1_WRITE));
-
-    //cluster
-    assertTrue(KAFKA_HOST1_CLUSTER1_ALL.implies(KAFKA_HOST1_CLUSTER1_READ));
-    assertTrue(KAFKA_HOST1_CLUSTER1_ALL.implies(KAFKA_HOST1_CLUSTER1_WRITE));
-
-    //consumer group
-    assertTrue(KAFKA_HOST1_GROUP1_ALL.implies(KAFKA_HOST1_GROUP1_READ));
-    assertTrue(KAFKA_HOST1_GROUP1_ALL.implies(KAFKA_HOST1_GROUP1_WRITE));
-  }
-
-  @Test
-  public void testUnexpected() throws Exception {
-    Privilege p = new Privilege() {
-      @Override
-      public boolean implies(Privilege p) {
-        return false;
-      }
-    };
-    Privilege topic1 = create(new KeyValue("HOST", "host"), new KeyValue("TOPIC", "topic1"));
-    assertFalse(topic1.implies(null));
-    assertFalse(topic1.implies(p));
-    assertFalse(topic1.equals(null));
-    assertFalse(topic1.equals(p));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNullString() throws Exception {
-    System.out.println(create((String)null));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyString() throws Exception {
-    System.out.println(create(""));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(create(PolicyConstants.KV_JOINER.join("", "host1")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(create(PolicyConstants.KV_JOINER.join("HOST", "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyPart() throws Exception {
-    System.out.println(create(PolicyConstants.AUTHORIZABLE_JOINER.
-        join(PolicyConstants.KV_JOINER.join("HOST", "host1"), "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testOnlySeperators() throws Exception {
-    System.out.println(create(PolicyConstants.AUTHORIZABLE_JOINER.
-        join(PolicyConstants.KV_SEPARATOR, PolicyConstants.KV_SEPARATOR, PolicyConstants.KV_SEPARATOR)));
-  }
-
-  static KafkaWildcardPrivilege create(KeyValue... keyValues) {
-    return create(PolicyConstants.AUTHORIZABLE_JOINER.join(keyValues));
-
-  }
-  static KafkaWildcardPrivilege create(String s) {
-    return new KafkaWildcardPrivilege(s);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/AbstractTestKafkaPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/AbstractTestKafkaPolicyEngine.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/AbstractTestKafkaPolicyEngine.java
deleted file mode 100644
index 810c05e..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/AbstractTestKafkaPolicyEngine.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.sentry.policy.kafka.engine;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-import java.util.TreeSet;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public abstract class AbstractTestKafkaPolicyEngine {
-
-  private static final String ADMIN = "host=*->action=all";
-  private static final String ADMIN_HOST1 = "host=host1->action=all";
-  private static final String CONSUMER_T1_ALL = "host=*->topic=t1->action=read";
-  private static final String CONSUMER_T1_HOST1 = "host=host1->topic=t1->action=read";
-  private static final String CONSUMER_T2_HOST2 = "host=host2->topic=t2->action=read";
-  private static final String PRODUCER_T1_ALL = "host=*->topic=t1->action=write";
-  private static final String PRODUCER_T1_HOST1 = "host=host1->topic=t1->action=write";
-  private static final String PRODUCER_T2_HOST2 = "host=host2->topic=t2->action=write";
-  private static final String CONSUMER_PRODUCER_T1 = "host=host1->topic=t1->action=all";
-
-  private PolicyEngine policy;
-  private static File baseDir;
-
-  @BeforeClass
-  public static void setupClazz() throws IOException {
-    baseDir = Files.createTempDir();
-  }
-
-  @AfterClass
-  public static void teardownClazz() throws IOException {
-    if (baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  protected void setPolicy(PolicyEngine policy) {
-    this.policy = policy;
-  }
-
-  protected static File getBaseDir() {
-    return baseDir;
-  }
-
-  @Before
-  public void setup() throws IOException {
-    afterSetup();
-  }
-
-  @After
-  public void teardown() throws IOException {
-    beforeTeardown();
-  }
-
-  protected void afterSetup() throws IOException {}
-
-  protected void beforeTeardown() throws IOException {}
-
-
-  @Test
-  public void testConsumer0() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_T1_ALL));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("consumer_group0"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testConsumer1() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_T1_HOST1));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("consumer_group1"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testConsumer2() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_T2_HOST2));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("consumer_group2"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testProducer0() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PRODUCER_T1_ALL));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("producer_group0"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testProducer1() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PRODUCER_T1_HOST1));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("producer_group1"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-
-  @Test
-  public void testProducer2() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PRODUCER_T2_HOST2));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("producer_group2"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testConsumerProducer0() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_PRODUCER_T1));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("consumer_producer_group0"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testSubAdmin() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN_HOST1));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("subadmin_group"), ActiveRoleSet.ALL))
-            .toString());
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN));
-    Assert
-        .assertEquals(expected.toString(),
-            new TreeSet<String>(policy.getPrivileges(set("admin_group"), ActiveRoleSet.ALL))
-                .toString());
-  }
-
-  private static Set<String> set(String... values) {
-    return Sets.newHashSet(values);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineDFS.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineDFS.java
deleted file mode 100644
index f2bd3c8..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineDFS.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.sentry.policy.kafka.engine;
-
-import java.io.File;
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hdfs.MiniDFSCluster;
-import org.apache.sentry.policy.kafka.KafkaPolicyFileProviderBackend;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class TestKafkaPolicyEngineDFS extends AbstractTestKafkaPolicyEngine {
-  private static MiniDFSCluster dfsCluster;
-  private static FileSystem fileSystem;
-  private static Path root;
-  private static Path etc;
-
-  @BeforeClass
-  public static void setupLocalClazz() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    File dfsDir = new File(baseDir, "dfs");
-    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
-    Configuration conf = new Configuration();
-    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
-    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
-    fileSystem = dfsCluster.getFileSystem();
-    root = new Path(fileSystem.getUri().toString());
-    etc = new Path(root, "/etc");
-    fileSystem.mkdirs(etc);
-  }
-
-  @AfterClass
-  public static void teardownLocalClazz() {
-    if(dfsCluster != null) {
-      dfsCluster.shutdown();
-    }
-  }
-
-  @Override
-  protected void afterSetup() throws IOException {
-    fileSystem.delete(etc, true);
-    fileSystem.mkdirs(etc);
-    PolicyFiles.copyToDir(fileSystem, etc, "test-authz-provider.ini");
-    setPolicy(new KafkaPolicyFileProviderBackend(new Path(etc,
-        "test-authz-provider.ini").toString()));
-  }
-
-  @Override
-  protected void beforeTeardown() throws IOException {
-    fileSystem.delete(etc, true);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineLocalFS.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineLocalFS.java
deleted file mode 100644
index 4bc061d..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/engine/TestKafkaPolicyEngineLocalFS.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.sentry.policy.kafka.engine;
-
-import java.io.File;
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.policy.kafka.KafkaPolicyFileProviderBackend;
-import org.apache.sentry.provider.file.PolicyFiles;
-
-public class TestKafkaPolicyEngineLocalFS extends AbstractTestKafkaPolicyEngine {
-
-  @Override
-  protected void  afterSetup() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    setPolicy(new KafkaPolicyFileProviderBackend(new File(baseDir, "test-authz-provider.ini").getPath()));
-  }
-
-  @Override
-  protected void beforeTeardown() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    FileUtils.deleteQuietly(baseDir);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderGeneralCases.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderGeneralCases.java
deleted file mode 100644
index 386d2d5..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderGeneralCases.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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.sentry.policy.kafka.provider;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.kafka.Cluster;
-import org.apache.sentry.core.model.kafka.ConsumerGroup;
-import org.apache.sentry.core.model.kafka.KafkaActionConstant;
-import org.apache.sentry.core.model.kafka.KafkaActionFactory.KafkaAction;
-import org.apache.sentry.core.model.kafka.Host;
-import org.apache.sentry.core.model.kafka.Topic;
-import org.apache.sentry.policy.kafka.KafkaPolicyFileProviderBackend;
-import org.apache.sentry.policy.kafka.MockGroupMappingServiceProvider;
-import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.After;
-import org.junit.Test;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestKafkaAuthorizationProviderGeneralCases {
-  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap.create();
-
-  private static final Host HOST_1 = new Host("host1");
-  private static final Host HOST_2 = new Host("host2");
-  private static final Cluster cluster1 = new Cluster();
-  private static final Topic topic1 = new Topic("t1");
-  private static final Topic topic2 = new Topic("t2");
-  private static final ConsumerGroup cgroup1 = new ConsumerGroup("cg1");
-  private static final ConsumerGroup cgroup2 = new ConsumerGroup("cg2");
-
-  private static final KafkaAction ALL = new KafkaAction(KafkaActionConstant.ALL);
-  private static final KafkaAction READ = new KafkaAction(KafkaActionConstant.READ);
-  private static final KafkaAction WRITE = new KafkaAction(KafkaActionConstant.WRITE);
-  private static final KafkaAction CREATE = new KafkaAction(KafkaActionConstant.CREATE);
-  private static final KafkaAction DELETE = new KafkaAction(KafkaActionConstant.DELETE);
-  private static final KafkaAction ALTER = new KafkaAction(KafkaActionConstant.ALTER);
-  private static final KafkaAction DESCRIBE = new KafkaAction(KafkaActionConstant.DESCRIBE);
-  private static final KafkaAction CLUSTER_ACTION = new KafkaAction(
-      KafkaActionConstant.CLUSTER_ACTION);
-
-  private static final Set<KafkaAction> allActions = Sets.newHashSet(ALL, READ, WRITE, CREATE, DELETE, ALTER, DESCRIBE, CLUSTER_ACTION);
-
-  private static final Subject ADMIN = new Subject("admin1");
-  private static final Subject SUB_ADMIN = new Subject("subadmin1");
-  private static final Subject CONSUMER0 = new Subject("consumer0");
-  private static final Subject CONSUMER1 = new Subject("consumer1");
-  private static final Subject CONSUMER2 = new Subject("consumer2");
-  private static final Subject PRODUCER0 = new Subject("producer0");
-  private static final Subject PRODUCER1 = new Subject("producer1");
-  private static final Subject PRODUCER2 = new Subject("producer2");
-  private static final Subject CONSUMER_PRODUCER0 = new Subject("consumer_producer0");
-
-  private static final String ADMIN_GROUP  = "admin_group";
-  private static final String SUBADMIN_GROUP  = "subadmin_group";
-  private static final String CONSUMER_GROUP0 = "consumer_group0";
-  private static final String CONSUMER_GROUP1 = "consumer_group1";
-  private static final String CONSUMER_GROUP2 = "consumer_group2";
-  private static final String PRODUCER_GROUP0 = "producer_group0";
-  private static final String PRODUCER_GROUP1 = "producer_group1";
-  private static final String PRODUCER_GROUP2 = "producer_group2";
-  private static final String CONSUMER_PRODUCER_GROUP0 = "consumer_producer_group0";
-
-  static {
-    USER_TO_GROUP_MAP.putAll(ADMIN.getName(), Arrays.asList(ADMIN_GROUP));
-    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(),  Arrays.asList(SUBADMIN_GROUP ));
-    USER_TO_GROUP_MAP.putAll(CONSUMER0.getName(),  Arrays.asList(CONSUMER_GROUP0));
-    USER_TO_GROUP_MAP.putAll(CONSUMER1.getName(),  Arrays.asList(CONSUMER_GROUP1));
-    USER_TO_GROUP_MAP.putAll(CONSUMER2.getName(),  Arrays.asList(CONSUMER_GROUP2));
-    USER_TO_GROUP_MAP.putAll(PRODUCER0.getName(),  Arrays.asList(PRODUCER_GROUP0));
-    USER_TO_GROUP_MAP.putAll(PRODUCER1.getName(),  Arrays.asList(PRODUCER_GROUP1));
-    USER_TO_GROUP_MAP.putAll(PRODUCER2.getName(),  Arrays.asList(PRODUCER_GROUP2));
-    USER_TO_GROUP_MAP.putAll(CONSUMER_PRODUCER0.getName(),  Arrays.asList(CONSUMER_PRODUCER_GROUP0));
-  }
-
-  private final ResourceAuthorizationProvider authzProvider;
-  private File baseDir;
-
-  public TestKafkaAuthorizationProviderGeneralCases() throws IOException {
-    baseDir = Files.createTempDir();
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    authzProvider = new HadoopGroupResourceAuthorizationProvider(
-        new KafkaPolicyFileProviderBackend(new File(baseDir, "test-authz-provider.ini").getPath()),
-        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP));
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void doTestResourceAuthorizationProvider(Subject subject, List<? extends Authorizable> authorizableHierarchy,
-      Set<? extends Action> actions, boolean expected) throws Exception {
-    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
-    helper.add("Subject", subject).add("authzHierarchy", authorizableHierarchy).add("action", actions);
-    Assert.assertEquals(helper.toString(), expected,
-        authzProvider.hasAccess(subject, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,cluster1), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,topic1), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,topic2), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,cgroup1), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,cgroup2), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1), allActions, true);
-
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,cluster1), allActions, false);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,topic1), allActions, false);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,topic2), allActions, false);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,cgroup1), allActions, false);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,cgroup2), allActions, false);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2), allActions, false);
-
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,cluster1), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,topic1), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,topic2), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,cgroup1), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,cgroup2), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1), allActions, true);
-
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,cluster1), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,topic1), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,topic2), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,cgroup1), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,cgroup2), allActions, true);
-    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2), allActions, true);
-  }
-
-  @Test
-  public void testConsumer() throws Exception {
-    for (KafkaAction action : allActions) {
-      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
-        doTestResourceAuthorizationProvider(CONSUMER0, Arrays.asList(host, topic1),
-            Sets.newHashSet(action), READ.equals(action));
-      }
-    }
-    for (KafkaAction action : allActions) {
-      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
-        doTestResourceAuthorizationProvider(CONSUMER1, Arrays.asList(host, topic1),
-            Sets.newHashSet(action), HOST_1.equals(host) && READ.equals(action));
-      }
-    }
-    for (KafkaAction action : allActions) {
-      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
-        doTestResourceAuthorizationProvider(CONSUMER2, Arrays.asList(host, topic2),
-            Sets.newHashSet(action), HOST_2.equals(host) && READ.equals(action));
-      }
-    }
-  }
-
-  @Test
-  public void testProducer() throws Exception {
-    for (KafkaAction action : allActions) {
-      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
-        doTestResourceAuthorizationProvider(PRODUCER0, Arrays.asList(host, topic1),
-            Sets.newHashSet(action), WRITE.equals(action));
-      }
-    }
-    for (KafkaAction action : allActions) {
-      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
-        doTestResourceAuthorizationProvider(PRODUCER1, Arrays.asList(host, topic1),
-            Sets.newHashSet(action), HOST_1.equals(host) && WRITE.equals(action));
-      }
-    }
-    for (KafkaAction action : allActions) {
-      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
-        doTestResourceAuthorizationProvider(PRODUCER2, Arrays.asList(host, topic2),
-            Sets.newHashSet(action), HOST_2.equals(host) && WRITE.equals(action));
-      }
-    }
-  }
-
-  @Test
-  public void testConsumerProducer() throws Exception {
-    for (KafkaAction action : allActions) {
-      doTestResourceAuthorizationProvider(CONSUMER_PRODUCER0, Arrays.asList(HOST_1, topic1),
-          Sets.newHashSet(action), true);
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderSpecialCases.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderSpecialCases.java
deleted file mode 100644
index 0a453ce..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaAuthorizationProviderSpecialCases.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.sentry.policy.kafka.provider;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.kafka.KafkaActionConstant;
-import org.apache.sentry.core.model.kafka.KafkaActionFactory.KafkaAction;
-import org.apache.sentry.core.model.kafka.Host;
-import org.apache.sentry.core.model.kafka.Topic;
-import org.apache.sentry.policy.kafka.KafkaPolicyFileProviderBackend;
-import org.apache.sentry.provider.common.AuthorizationProvider;
-import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestKafkaAuthorizationProviderSpecialCases {
-  private AuthorizationProvider authzProvider;
-  private PolicyFile policyFile;
-  private File baseDir;
-  private File iniFile;
-  private String initResource;
-  @Before
-  public void setup() throws IOException {
-    baseDir = Files.createTempDir();
-    iniFile = new File(baseDir, "policy.ini");
-    initResource = "file://" + iniFile.getPath();
-    policyFile = new PolicyFile();
-  }
-
-  @After
-  public void teardown() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  @Test
-  public void testDuplicateEntries() throws Exception {
-    Subject user1 = new Subject("user1");
-    Host host1 = new Host("host1");
-    Topic topic1 = new Topic("t1");
-    Set<? extends Action> actions = Sets.newHashSet(new KafkaAction(KafkaActionConstant.READ));
-    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
-      .addRolesToGroup("group1",  true, "role1", "role1")
-      .addPermissionsToRole("role1", true, "host=host1->topic=t1->action=read",
-          "host=host1->topic=t1->action=read");
-    policyFile.write(iniFile);
-    KafkaPolicyFileProviderBackend policy = new KafkaPolicyFileProviderBackend(initResource);
-    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy);
-    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(host1, topic1);
-    Assert.assertTrue(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaPolicyNegative.java b/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaPolicyNegative.java
deleted file mode 100644
index 1cb694a..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/java/org/apache/sentry/policy/kafka/provider/TestKafkaPolicyNegative.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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.sentry.policy.kafka.provider;
-
-import java.io.File;
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.apache.sentry.policy.kafka.KafkaPolicyFileProviderBackend;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestKafkaPolicyNegative {
-  private File baseDir;
-  private File globalPolicyFile;
-
-  @Before
-  public void setup() {
-    baseDir = Files.createTempDir();
-    globalPolicyFile = new File(baseDir, "global.ini");
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void append(String from, File to) throws IOException {
-    Files.append(from + "\n", to, Charsets.UTF_8);
-  }
-
-  @Test
-  public void testauthorizedKafkaInPolicyFile() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("other_group = other_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("other_role = host=host1->topic=t1->action=read, host=host1->consumergroup=l1->action=read", globalPolicyFile);
-    PolicyEngine policy = new KafkaPolicyFileProviderBackend(globalPolicyFile.getPath());
-    //malicious_group has no privilege
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("malicious_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-    //other_group has two privileges
-    permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.size() == 2);
-  }
-
-  @Test
-  public void testNoHostNameConfig() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("other_group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = topic=t1->action=read", globalPolicyFile);
-    PolicyEngine policy = new KafkaPolicyFileProviderBackend(globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testHostAllName() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = host=*->action=read", globalPolicyFile);
-    PolicyEngine policy = new KafkaPolicyFileProviderBackend(globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.size() == 1);
-  }
-
-  @Test
-  public void testAll() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = *", globalPolicyFile);
-    PolicyEngine policy = new KafkaPolicyFileProviderBackend(globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/resources/log4j.properties b/sentry-policy/sentry-policy-kafka/src/test/resources/log4j.properties
deleted file mode 100644
index 7703069..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# 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.
-#
-
-# Define some default values that can be overridden by system properties.
-#
-# For testing, it may also be convenient to specify
-
-log4j.rootLogger=DEBUG,console
-
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.target=System.err
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n
-
-log4j.logger.org.apache.hadoop.conf.Configuration=INFO
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-kafka/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-kafka/src/test/resources/test-authz-provider.ini b/sentry-policy/sentry-policy-kafka/src/test/resources/test-authz-provider.ini
deleted file mode 100644
index 1951aba..0000000
--- a/sentry-policy/sentry-policy-kafka/src/test/resources/test-authz-provider.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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.
-
-[groups]
-admin_group = admin_all
-subadmin_group = admin_host1
-consumer_group0 = consumer_t1_all
-consumer_group1 = consumer_t1_host1
-consumer_group2 = consumer_t2_host2
-producer_group0 = producer_t1_all
-producer_group1 = producer_t1_host1
-producer_group2 = producer_t2_host2
-consumer_producer_group0 = consumer_producer_t1
-
-[roles]
-admin_all = host=*->action=all
-admin_host1 = host=host1->action=all
-consumer_t1_all = host=*->topic=t1->action=read
-consumer_t1_host1 = host=host1->topic=t1->action=read
-consumer_t2_host2 = host=host2->topic=t2->action=read
-producer_t1_all = host=*->topic=t1->action=write
-producer_t1_host1 = host=host1->topic=t1->action=write
-producer_t2_host2 = host=host2->topic=t2->action=write
-consumer_producer_t1 = host=host1->topic=t1->action=all


[10/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
index c6600a0..15f7359 100644
--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
+++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
@@ -42,16 +42,19 @@ import org.apache.kafka.common.security.auth.KafkaPrincipal;
 import org.apache.sentry.SentryUserException;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.kafka.KafkaActionFactory;
 import org.apache.sentry.core.model.kafka.KafkaActionFactory.KafkaAction;
 import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
+import org.apache.sentry.core.model.kafka.KafkaPrivilegeModel;
 import org.apache.sentry.kafka.ConvertUtil;
 import org.apache.sentry.kafka.conf.KafkaAuthConf.AuthzConfVars;
 import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.AuthorizationComponent;
 import org.apache.sentry.provider.common.AuthorizationProvider;
 import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
@@ -72,491 +75,497 @@ import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY
 
 public class KafkaAuthBinding {
 
-    private static final Logger LOG = LoggerFactory.getLogger(KafkaAuthBinding.class);
-    private static final String COMPONENT_TYPE = AuthorizationComponent.KAFKA;
-    private static final String COMPONENT_NAME = COMPONENT_TYPE;
+  private static final Logger LOG = LoggerFactory.getLogger(KafkaAuthBinding.class);
+  private static final String COMPONENT_TYPE = AuthorizationComponent.KAFKA;
+  private static final String COMPONENT_NAME = COMPONENT_TYPE;
 
-    private static Boolean kerberosInit;
+  private static Boolean kerberosInit;
 
-    private final Configuration authConf;
-    private final AuthorizationProvider authProvider;
-    private final KafkaActionFactory actionFactory = KafkaActionFactory.getInstance();
+  private final Configuration authConf;
+  private final AuthorizationProvider authProvider;
+  private final KafkaActionFactory actionFactory = KafkaActionFactory.getInstance();
 
-    private ProviderBackend providerBackend;
-    private String instanceName;
-    private String requestorName;
-    private java.util.Map<String, ?> kafkaConfigs;
+  private ProviderBackend providerBackend;
+  private String instanceName;
+  private String requestorName;
+  private java.util.Map<String, ?> kafkaConfigs;
 
 
-    public KafkaAuthBinding(String instanceName, String requestorName, Configuration authConf, java.util.Map<String, ?> kafkaConfigs) throws Exception {
-        this.instanceName = instanceName;
-        this.requestorName = requestorName;
-        this.authConf = authConf;
-        this.kafkaConfigs = kafkaConfigs;
-        this.authProvider = createAuthProvider();
-    }
+  public KafkaAuthBinding(String instanceName, String requestorName, Configuration authConf, java.util.Map<String, ?> kafkaConfigs) throws Exception {
+    this.instanceName = instanceName;
+    this.requestorName = requestorName;
+    this.authConf = authConf;
+    this.kafkaConfigs = kafkaConfigs;
+    this.authProvider = createAuthProvider();
+  }
 
+  /**
+   * Instantiate the configured authz provider
+   *
+   * @return {@link AuthorizationProvider}
+   */
+  private AuthorizationProvider createAuthProvider() throws Exception {
     /**
-     * Instantiate the configured authz provider
-     *
-     * @return {@link AuthorizationProvider}
+     * get the authProvider class, policyEngine class, providerBackend class and resources from the
+     * kafkaAuthConf config
      */
-    private AuthorizationProvider createAuthProvider() throws Exception {
-        /**
-         * get the authProvider class, policyEngine class, providerBackend class and resources from the
-         * kafkaAuthConf config
-         */
-        String authProviderName =
-            authConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar(),
-                AuthzConfVars.AUTHZ_PROVIDER.getDefault());
-        String resourceName =
-            authConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(),
-                AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getDefault());
-        String providerBackendName =
-            authConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(),
-                AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getDefault());
-        String policyEngineName =
-            authConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(),
-                AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
-        if (resourceName != null && resourceName.startsWith("classpath:")) {
-            String resourceFileName = resourceName.substring("classpath:".length());
-            resourceName = AuthorizationProvider.class.getClassLoader().getResource(resourceFileName).getPath();
-        }
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Using authorization provider " + authProviderName + " with resource "
-                + resourceName + ", policy engine " + policyEngineName + ", provider backend "
-                + providerBackendName);
-        }
-
-        // Initiate kerberos via UserGroupInformation if required
-        if (ServiceConstants.ServerConfig.SECURITY_MODE_KERBEROS.equals(authConf.get(ServiceConstants.ServerConfig.SECURITY_MODE))
-                && kafkaConfigs != null) {
-            String keytabProp = kafkaConfigs.get(AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar()).toString();
-            String principalProp = kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar()).toString();
-            if (keytabProp != null && principalProp != null) {
-                String actualHost = kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_HOSTNAME.getVar()).toString();
-                if (actualHost != null) {
-                    principalProp = SecurityUtil.getServerPrincipal(principalProp, actualHost);
-                }
-                initKerberos(keytabProp, principalProp);
-            } else {
-                LOG.debug("Could not initialize Kerberos.\n" +
-                        AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar() + " set to " + kafkaConfigs.get(AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar()).toString() + "\n" +
-                        AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar() + " set to " + kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar()).toString());
-            }
-        } else {
-            LOG.debug("Could not initialize Kerberos as no kafka config provided. " +
-                    AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar() + " and " + AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar() +
-                    " are required configs to be able to initialize Kerberos");
-        }
-
-        // Instantiate the configured providerBackend
-        Constructor<?> providerBackendConstructor =
-            Class.forName(providerBackendName)
-                .getDeclaredConstructor(Configuration.class, String.class);
-        providerBackendConstructor.setAccessible(true);
-        providerBackend =
-            (ProviderBackend) providerBackendConstructor.newInstance(new Object[]{authConf,
-                resourceName});
-        if (providerBackend instanceof SentryGenericProviderBackend) {
-            ((SentryGenericProviderBackend) providerBackend).setComponentType(COMPONENT_TYPE);
-            ((SentryGenericProviderBackend) providerBackend).setServiceName(instanceName);
-        }
-
-        // Instantiate the configured policyEngine
-        Constructor<?> policyConstructor =
-            Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
-        policyConstructor.setAccessible(true);
-        PolicyEngine policyEngine =
-            (PolicyEngine) policyConstructor.newInstance(new Object[]{providerBackend});
-
-        // Instantiate the configured authProvider
-        Constructor<?> constructor =
-            Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class,
-                PolicyEngine.class);
-        constructor.setAccessible(true);
-        return (AuthorizationProvider) constructor.newInstance(new Object[]{authConf, resourceName,
-            policyEngine});
+    String authProviderName =
+        authConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar(),
+            AuthzConfVars.AUTHZ_PROVIDER.getDefault());
+    String resourceName =
+        authConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(),
+            AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getDefault());
+    String providerBackendName =
+        authConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(),
+            AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getDefault());
+    String policyEngineName =
+        authConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(),
+            AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
+    if (resourceName != null && resourceName.startsWith("classpath:")) {
+      String resourceFileName = resourceName.substring("classpath:".length());
+      resourceName = AuthorizationProvider.class.getClassLoader().getResource(resourceFileName).getPath();
     }
-
-    /**
-     * Authorize access to a Kafka privilege
-     */
-    public boolean authorize(RequestChannel.Session session, Operation operation, Resource resource) {
-        List<Authorizable> authorizables = ConvertUtil.convertResourceToAuthorizable(session.clientAddress().getHostAddress(), resource);
-        Set<KafkaAction> actions = Sets.newHashSet(actionFactory.getActionByName(operation.name()));
-        return authProvider.hasAccess(new Subject(getName(session)), authorizables, actions, ActiveRoleSet.ALL);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Using authorization provider " + authProviderName + " with resource "
+          + resourceName + ", policy engine " + policyEngineName + ", provider backend "
+          + providerBackendName);
     }
 
-    public void addAcls(scala.collection.immutable.Set<Acl> acls, final Resource resource) {
-        verifyAcls(acls);
-        LOG.info("Adding Acl: acl->" + acls + " resource->" + resource);
-
-        final Iterator<Acl> iterator = acls.iterator();
-        while (iterator.hasNext()) {
-            final Acl acl = iterator.next();
-            final String role = getRole(acl);
-            if (!roleExists(role)) {
-                throw new KafkaException("Can not add Acl for non-existent Role: " + role);
-            }
-            execute(new Command<Void>() {
-                @Override
-                public Void run(SentryGenericServiceClient client) throws Exception {
-                    client.grantPrivilege(
-                        requestorName, role, COMPONENT_NAME, toTSentryPrivilege(acl, resource));
-                    return null;
-                }
-            });
-        }
+    // Initiate kerberos via UserGroupInformation if required
+    if (ServiceConstants.ServerConfig.SECURITY_MODE_KERBEROS.equals(authConf.get(ServiceConstants.ServerConfig.SECURITY_MODE))
+            && kafkaConfigs != null) {
+      String keytabProp = kafkaConfigs.get(AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar()).toString();
+      String principalProp = kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar()).toString();
+      if (keytabProp != null && principalProp != null) {
+          String actualHost = kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_HOSTNAME.getVar()).toString();
+          if (actualHost != null) {
+              principalProp = SecurityUtil.getServerPrincipal(principalProp, actualHost);
+          }
+          initKerberos(keytabProp, principalProp);
+      } else {
+          LOG.debug("Could not initialize Kerberos.\n" +
+                  AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar() + " set to " + kafkaConfigs.get(AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar()).toString() + "\n" +
+                  AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar() + " set to " + kafkaConfigs.get(AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar()).toString());
+      }
+    } else {
+      LOG.debug("Could not initialize Kerberos as no kafka config provided. " +
+              AuthzConfVars.AUTHZ_KEYTAB_FILE_NAME.getVar() + " and " + AuthzConfVars.AUTHZ_PRINCIPAL_NAME.getVar() +
+              " are required configs to be able to initialize Kerberos");
     }
 
-    public boolean removeAcls(scala.collection.immutable.Set<Acl> acls, final Resource resource) {
-        verifyAcls(acls);
-        LOG.info("Removing Acl: acl->" + acls + " resource->" + resource);
-        final Iterator<Acl> iterator = acls.iterator();
-        while (iterator.hasNext()) {
-            final Acl acl = iterator.next();
-            final String role = getRole(acl);
-            try {
-                execute(new Command<Void>() {
-                    @Override
-                    public Void run(SentryGenericServiceClient client) throws Exception {
-                        client.dropPrivilege(
-                                requestorName, role, toTSentryPrivilege(acl, resource));
-                        return null;
-                    }
-                });
-            } catch (KafkaException kex) {
-                LOG.error("Failed to remove acls.", kex);
-                return false;
-            }
-        }
-
-        return true;
+    // Instantiate the configured providerBackend
+    Constructor<?> providerBackendConstructor =
+        Class.forName(providerBackendName)
+            .getDeclaredConstructor(Configuration.class, String.class);
+    providerBackendConstructor.setAccessible(true);
+    providerBackend =
+        (ProviderBackend) providerBackendConstructor.newInstance(new Object[]{authConf,
+            resourceName});
+    if (providerBackend instanceof SentryGenericProviderBackend) {
+      ((SentryGenericProviderBackend) providerBackend).setComponentType(COMPONENT_TYPE);
+      ((SentryGenericProviderBackend) providerBackend).setServiceName(instanceName);
     }
 
-    public void addRole(final String role) {
-        if (roleExists(role)) {
-            throw new KafkaException("Can not create an existing role, " + role + ", again.");
+    // Create backend context
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(KafkaPrivilegeModel.getInstance().getPrivilegeValidators());
+    providerBackend.initialize(context);
+
+    // Instantiate the configured policyEngine
+    Constructor<?> policyConstructor =
+        Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
+    policyConstructor.setAccessible(true);
+    PolicyEngine policyEngine =
+        (PolicyEngine) policyConstructor.newInstance(new Object[]{providerBackend});
+
+    // Instantiate the configured authProvider
+    Constructor<?> constructor =
+        Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class,
+            PolicyEngine.class, Model.class);
+    constructor.setAccessible(true);
+    return (AuthorizationProvider) constructor.newInstance(new Object[]{authConf, resourceName,
+        policyEngine, KafkaPrivilegeModel.getInstance()});
+  }
+
+  /**
+   * Authorize access to a Kafka privilege
+   */
+  public boolean authorize(RequestChannel.Session session, Operation operation, Resource resource) {
+      List<Authorizable> authorizables = ConvertUtil.convertResourceToAuthorizable(session.clientAddress().getHostAddress(), resource);
+      Set<KafkaAction> actions = Sets.newHashSet(actionFactory.getActionByName(operation.name()));
+      return authProvider.hasAccess(new Subject(getName(session)), authorizables, actions, ActiveRoleSet.ALL);
+  }
+
+  public void addAcls(scala.collection.immutable.Set<Acl> acls, final Resource resource) {
+    verifyAcls(acls);
+    LOG.info("Adding Acl: acl->" + acls + " resource->" + resource);
+
+    final Iterator<Acl> iterator = acls.iterator();
+    while (iterator.hasNext()) {
+      final Acl acl = iterator.next();
+      final String role = getRole(acl);
+      if (!roleExists(role)) {
+        throw new KafkaException("Can not add Acl for non-existent Role: " + role);
+      }
+      execute(new Command<Void>() {
+        @Override
+        public Void run(SentryGenericServiceClient client) throws Exception {
+          client.grantPrivilege(
+              requestorName, role, COMPONENT_NAME, toTSentryPrivilege(acl, resource));
+          return null;
         }
-
-        execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                client.createRole(
-                    requestorName, role, COMPONENT_NAME);
-                return null;
-            }
-        });
-    }
-
-    public void addRoleToGroups(final String role, final java.util.Set<String> groups) {
-        execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                client.addRoleToGroups(
-                    requestorName, role, COMPONENT_NAME, groups);
-                return null;
-            }
-        });
+      });
     }
-
-    public void dropAllRoles() {
-        final List<String> roles = getAllRoles();
+  }
+
+  public boolean removeAcls(scala.collection.immutable.Set<Acl> acls, final Resource resource) {
+    verifyAcls(acls);
+    LOG.info("Removing Acl: acl->" + acls + " resource->" + resource);
+    final Iterator<Acl> iterator = acls.iterator();
+    while (iterator.hasNext()) {
+      final Acl acl = iterator.next();
+      final String role = getRole(acl);
+      try {
         execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                for (String role : roles) {
-                    client.dropRole(requestorName, role, COMPONENT_NAME);
-                }
-                return null;
-            }
+          @Override
+          public Void run(SentryGenericServiceClient client) throws Exception {
+            client.dropPrivilege(
+                    requestorName, role, toTSentryPrivilege(acl, resource));
+            return null;
+          }
         });
+      } catch (KafkaException kex) {
+        LOG.error("Failed to remove acls.", kex);
+        return false;
+      }
     }
 
-    private List<String> getRolesforGroup(final String groupName) {
-        final List<String> roles = new ArrayList<>();
-        execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                for (TSentryRole tSentryRole : client.listRolesByGroupName(requestorName, groupName, COMPONENT_NAME)) {
-                    roles.add(tSentryRole.getRoleName());
-                }
-                return null;
-            }
-        });
-
-        return roles;
-    }
+    return true;
+  }
 
-    private SentryGenericServiceClient getClient() throws Exception {
-        return SentryGenericServiceClientFactory.create(this.authConf);
+  public void addRole(final String role) {
+    if (roleExists(role)) {
+      throw new KafkaException("Can not create an existing role, " + role + ", again.");
     }
 
-    public boolean removeAcls(final Resource resource) {
-        LOG.info("Removing Acls for Resource: resource->" + resource);
-        List<String> roles = getAllRoles();
-        final List<TSentryPrivilege> tSentryPrivileges = getAllPrivileges(roles);
-        try {
-            execute(new Command<Void>() {
-                @Override
-                public Void run(SentryGenericServiceClient client) throws Exception {
-                    for (TSentryPrivilege tSentryPrivilege : tSentryPrivileges) {
-                        if (isPrivilegeForResource(tSentryPrivilege, resource)) {
-                            client.dropPrivilege(
-                                    requestorName, COMPONENT_NAME, tSentryPrivilege);
-                        }
-                    }
-                    return null;
-                }
-            });
-        } catch (KafkaException kex) {
-            LOG.error("Failed to remove acls.", kex);
-            return false;
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.createRole(
+            requestorName, role, COMPONENT_NAME);
+        return null;
+      }
+    });
+  }
+
+  public void addRoleToGroups(final String role, final java.util.Set<String> groups) {
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        client.addRoleToGroups(
+            requestorName, role, COMPONENT_NAME, groups);
+        return null;
+      }
+    });
+  }
+
+  public void dropAllRoles() {
+    final List<String> roles = getAllRoles();
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        for (String role : roles) {
+          client.dropRole(requestorName, role, COMPONENT_NAME);
         }
-
-        return true;
-    }
-
-    public scala.collection.immutable.Set<Acl> getAcls(final Resource resource) {
-        final Option<scala.collection.immutable.Set<Acl>> acls = getAcls().get(resource);
-        if (acls.nonEmpty())
-            return acls.get();
-        return new scala.collection.immutable.HashSet<Acl>();
-    }
-
-    public Map<Resource, scala.collection.immutable.Set<Acl>> getAcls(KafkaPrincipal principal) {
-        if (principal.getPrincipalType().toLowerCase().equals("group")) {
-            List<String> roles = getRolesforGroup(principal.getName());
-            return getAclsForRoles(roles);
-        } else {
-            LOG.info("Did not recognize Principal type: " + principal.getPrincipalType() + ". Returning Acls for all principals.");
-            return getAcls();
+        return null;
+      }
+    });
+  }
+
+  private List<String> getRolesforGroup(final String groupName) {
+    final List<String> roles = new ArrayList<>();
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        for (TSentryRole tSentryRole : client.listRolesByGroupName(requestorName, groupName, COMPONENT_NAME)) {
+          roles.add(tSentryRole.getRoleName());
         }
-    }
-
-    public Map<Resource, scala.collection.immutable.Set<Acl>> getAcls() {
-        final List<String> roles = getAllRoles();
-        return getAclsForRoles(roles);
-    }
-
-    /**
-     * A Command is a closure used to pass a block of code from individual
-     * functions to execute, which centralizes connection error
-     * handling. Command is parameterized on the return type of the function.
-     */
-    private interface Command<T> {
-        T run(SentryGenericServiceClient client) throws Exception;
-    }
-
-    private <T> T execute(Command<T> cmd) throws KafkaException {
-        SentryGenericServiceClient client = null;
-        try {
-            client = getClient();
-            return cmd.run(client);
-        } catch (SentryUserException ex) {
-            String msg = "Unable to excute command on sentry server: " + ex.getMessage();
-            LOG.error(msg, ex);
-            throw new KafkaException(msg, ex);
-        } catch (Exception ex) {
-            String msg = "Unable to obtain client:" + ex.getMessage();
-            LOG.error(msg, ex);
-            throw new KafkaException(msg, ex);
-        } finally {
-            if (client != null) {
-                client.close();
+        return null;
+      }
+    });
+
+    return roles;
+  }
+
+  private SentryGenericServiceClient getClient() throws Exception {
+    return SentryGenericServiceClientFactory.create(this.authConf);
+  }
+
+  public boolean removeAcls(final Resource resource) {
+    LOG.info("Removing Acls for Resource: resource->" + resource);
+    List<String> roles = getAllRoles();
+    final List<TSentryPrivilege> tSentryPrivileges = getAllPrivileges(roles);
+    try {
+      execute(new Command<Void>() {
+        @Override
+        public Void run(SentryGenericServiceClient client) throws Exception {
+          for (TSentryPrivilege tSentryPrivilege : tSentryPrivileges) {
+            if (isPrivilegeForResource(tSentryPrivilege, resource)) {
+              client.dropPrivilege(
+                        requestorName, COMPONENT_NAME, tSentryPrivilege);
             }
+          }
+          return null;
         }
+      });
+    } catch (KafkaException kex) {
+      LOG.error("Failed to remove acls.", kex);
+      return false;
     }
 
-    private TSentryPrivilege toTSentryPrivilege(Acl acl, Resource resource) {
-        final List<Authorizable> authorizables = ConvertUtil.convertResourceToAuthorizable(acl.host(), resource);
-        final List<TAuthorizable> tAuthorizables = new ArrayList<>();
-        for (Authorizable authorizable : authorizables) {
-            tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
-        }
-        TSentryPrivilege tSentryPrivilege = new TSentryPrivilege(COMPONENT_NAME, instanceName, tAuthorizables, acl.operation().name());
-        return tSentryPrivilege;
-    }
-
-    private String getRole(Acl acl) {
-        return acl.principal().getName();
-    }
-
-    private boolean isPrivilegeForResource(TSentryPrivilege tSentryPrivilege, Resource resource) {
-        final java.util.Iterator<TAuthorizable> authorizablesIterator = tSentryPrivilege.getAuthorizablesIterator();
-        while (authorizablesIterator.hasNext()) {
-            TAuthorizable tAuthorizable = authorizablesIterator.next();
-            if (tAuthorizable.getType().equals(resource.resourceType().name())) {
-                return true;
-            }
-        }
-        return false;
+    return true;
+  }
+
+  public scala.collection.immutable.Set<Acl> getAcls(final Resource resource) {
+    final Option<scala.collection.immutable.Set<Acl>> acls = getAcls().get(resource);
+    if (acls.nonEmpty())
+      return acls.get();
+    return new scala.collection.immutable.HashSet<Acl>();
+  }
+
+  public Map<Resource, scala.collection.immutable.Set<Acl>> getAcls(KafkaPrincipal principal) {
+    if (principal.getPrincipalType().toLowerCase().equals("group")) {
+      List<String> roles = getRolesforGroup(principal.getName());
+      return getAclsForRoles(roles);
+    } else {
+      LOG.info("Did not recognize Principal type: " + principal.getPrincipalType() + ". Returning Acls for all principals.");
+      return getAcls();
     }
-
-    private List<TSentryPrivilege> getAllPrivileges(final List<String> roles) {
-        final List<TSentryPrivilege> tSentryPrivileges = new ArrayList<>();
-        execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                for (String role : roles) {
-                    tSentryPrivileges.addAll(client.listPrivilegesByRoleName(
-                        requestorName, role, COMPONENT_NAME, instanceName));
-                }
-                return null;
-            }
-        });
-
-        return tSentryPrivileges;
+  }
+
+  public Map<Resource, scala.collection.immutable.Set<Acl>> getAcls() {
+    final List<String> roles = getAllRoles();
+    return getAclsForRoles(roles);
+  }
+
+  /**
+   * A Command is a closure used to pass a block of code from individual
+   * functions to execute, which centralizes connection error
+   * handling. Command is parameterized on the return type of the function.
+   */
+  private interface Command<T> {
+    T run(SentryGenericServiceClient client) throws Exception;
+  }
+
+  private <T> T execute(Command<T> cmd) throws KafkaException {
+    SentryGenericServiceClient client = null;
+    try {
+      client = getClient();
+      return cmd.run(client);
+    } catch (SentryUserException ex) {
+      String msg = "Unable to excute command on sentry server: " + ex.getMessage();
+      LOG.error(msg, ex);
+      throw new KafkaException(msg, ex);
+    } catch (Exception ex) {
+      String msg = "Unable to obtain client:" + ex.getMessage();
+      LOG.error(msg, ex);
+      throw new KafkaException(msg, ex);
+    } finally {
+      if (client != null) {
+        client.close();
+      }
     }
+  }
 
-    private List<String> getAllRoles() {
-        final List<String> roles = new ArrayList<>();
-        execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                for (TSentryRole tSentryRole : client.listAllRoles(requestorName, COMPONENT_NAME)) {
-                    roles.add(tSentryRole.getRoleName());
-                }
-                return null;
-            }
-        });
-
-        return roles;
+  private TSentryPrivilege toTSentryPrivilege(Acl acl, Resource resource) {
+    final List<Authorizable> authorizables = ConvertUtil.convertResourceToAuthorizable(acl.host(), resource);
+    final List<TAuthorizable> tAuthorizables = new ArrayList<>();
+    for (Authorizable authorizable : authorizables) {
+      tAuthorizables.add(new TAuthorizable(authorizable.getTypeName(), authorizable.getName()));
     }
-
-    private Map<Resource, scala.collection.immutable.Set<Acl>> getAclsForRoles(final List<String> roles) {
-        return scala.collection.JavaConverters.mapAsScalaMapConverter(
-                rolePrivilegesToResourceAcls(getRoleToPrivileges(roles)))
-                .asScala().toMap(Predef.<Tuple2<Resource, scala.collection.immutable.Set<Acl>>>conforms());
+    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege(COMPONENT_NAME, instanceName, tAuthorizables, acl.operation().name());
+    return tSentryPrivilege;
+  }
+
+  private String getRole(Acl acl) {
+    return acl.principal().getName();
+  }
+
+  private boolean isPrivilegeForResource(TSentryPrivilege tSentryPrivilege, Resource resource) {
+    final java.util.Iterator<TAuthorizable> authorizablesIterator = tSentryPrivilege.getAuthorizablesIterator();
+    while (authorizablesIterator.hasNext()) {
+      TAuthorizable tAuthorizable = authorizablesIterator.next();
+      if (tAuthorizable.getType().equals(resource.resourceType().name())) {
+        return true;
+      }
     }
-
-    private java.util.Map<Resource, scala.collection.immutable.Set<Acl>> rolePrivilegesToResourceAcls(java.util.Map<String, scala.collection.immutable.Set<TSentryPrivilege>> rolePrivilegesMap) {
-        final java.util.Map<Resource, scala.collection.immutable.Set<Acl>> resourceAclsMap = new HashMap<>();
-        for (String role : rolePrivilegesMap.keySet()) {
-            scala.collection.immutable.Set<TSentryPrivilege> privileges = rolePrivilegesMap.get(role);
-            final Iterator<TSentryPrivilege> iterator = privileges.iterator();
-            while (iterator.hasNext()) {
-                TSentryPrivilege privilege = iterator.next();
-                final List<TAuthorizable> authorizables = privilege.getAuthorizables();
-                String host = null;
-                String operation = privilege.getAction();
-                for (TAuthorizable tAuthorizable : authorizables) {
-                    if (tAuthorizable.getType().equals(KafkaAuthorizable.AuthorizableType.HOST.name())) {
-                        host = tAuthorizable.getName();
-                    } else {
-                        Resource resource = new Resource(ResourceType$.MODULE$.fromString(tAuthorizable.getType()), tAuthorizable.getName());
-                        if (operation.equals("*")) {
-                            operation = "All";
-                        }
-                        Acl acl = new Acl(new KafkaPrincipal("role", role), Allow$.MODULE$, host, Operation$.MODULE$.fromString(operation));
-                        Set<Acl> newAclsJava = new HashSet<Acl>();
-                        newAclsJava.add(acl);
-                        addExistingAclsForResource(resourceAclsMap, resource, newAclsJava);
-                        final scala.collection.mutable.Set<Acl> aclScala = JavaConversions.asScalaSet(newAclsJava);
-                        resourceAclsMap.put(resource, aclScala.<Acl>toSet());
-                    }
-                }
-            }
+    return false;
+  }
+
+  private List<TSentryPrivilege> getAllPrivileges(final List<String> roles) {
+    final List<TSentryPrivilege> tSentryPrivileges = new ArrayList<>();
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        for (String role : roles) {
+          tSentryPrivileges.addAll(client.listPrivilegesByRoleName(
+                requestorName, role, COMPONENT_NAME, instanceName));
         }
-
-        return resourceAclsMap;
-    }
-
-    private java.util.Map<String, scala.collection.immutable.Set<TSentryPrivilege>> getRoleToPrivileges(final List<String> roles) {
-        final java.util.Map<String, scala.collection.immutable.Set<TSentryPrivilege>> rolePrivilegesMap = new HashMap<>();
-        execute(new Command<Void>() {
-            @Override
-            public Void run(SentryGenericServiceClient client) throws Exception {
-                for (String role : roles) {
-                    final Set<TSentryPrivilege> rolePrivileges = client.listPrivilegesByRoleName(
-                        requestorName, role, COMPONENT_NAME, instanceName);
-                    final scala.collection.immutable.Set<TSentryPrivilege> rolePrivilegesScala =
-                        scala.collection.JavaConverters.asScalaSetConverter(rolePrivileges).asScala().toSet();
-                    rolePrivilegesMap.put(role, rolePrivilegesScala);
-                }
-                return null;
+        return null;
+      }
+    });
+
+    return tSentryPrivileges;
+  }
+
+  private List<String> getAllRoles() {
+    final List<String> roles = new ArrayList<>();
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        for (TSentryRole tSentryRole : client.listAllRoles(requestorName, COMPONENT_NAME)) {
+          roles.add(tSentryRole.getRoleName());
+        }
+        return null;
+      }
+    });
+
+    return roles;
+  }
+
+  private Map<Resource, scala.collection.immutable.Set<Acl>> getAclsForRoles(final List<String> roles) {
+    return scala.collection.JavaConverters.mapAsScalaMapConverter(
+              rolePrivilegesToResourceAcls(getRoleToPrivileges(roles)))
+              .asScala().toMap(Predef.<Tuple2<Resource, scala.collection.immutable.Set<Acl>>>conforms());
+  }
+
+  private java.util.Map<Resource, scala.collection.immutable.Set<Acl>> rolePrivilegesToResourceAcls(java.util.Map<String, scala.collection.immutable.Set<TSentryPrivilege>> rolePrivilegesMap) {
+    final java.util.Map<Resource, scala.collection.immutable.Set<Acl>> resourceAclsMap = new HashMap<>();
+    for (String role : rolePrivilegesMap.keySet()) {
+      scala.collection.immutable.Set<TSentryPrivilege> privileges = rolePrivilegesMap.get(role);
+      final Iterator<TSentryPrivilege> iterator = privileges.iterator();
+      while (iterator.hasNext()) {
+        TSentryPrivilege privilege = iterator.next();
+        final List<TAuthorizable> authorizables = privilege.getAuthorizables();
+        String host = null;
+        String operation = privilege.getAction();
+        for (TAuthorizable tAuthorizable : authorizables) {
+          if (tAuthorizable.getType().equals(KafkaAuthorizable.AuthorizableType.HOST.name())) {
+            host = tAuthorizable.getName();
+          } else {
+            Resource resource = new Resource(ResourceType$.MODULE$.fromString(tAuthorizable.getType()), tAuthorizable.getName());
+            if (operation.equals("*")) {
+              operation = "All";
             }
-        });
-
-        return rolePrivilegesMap;
+            Acl acl = new Acl(new KafkaPrincipal("role", role), Allow$.MODULE$, host, Operation$.MODULE$.fromString(operation));
+            Set<Acl> newAclsJava = new HashSet<Acl>();
+            newAclsJava.add(acl);
+            addExistingAclsForResource(resourceAclsMap, resource, newAclsJava);
+            final scala.collection.mutable.Set<Acl> aclScala = JavaConversions.asScalaSet(newAclsJava);
+            resourceAclsMap.put(resource, aclScala.<Acl>toSet());
+          }
+        }
+      }
     }
 
-    private void addExistingAclsForResource(java.util.Map<Resource, scala.collection.immutable.Set<Acl>> resourceAclsMap, Resource resource, java.util.Set<Acl> newAclsJava) {
-        final scala.collection.immutable.Set<Acl> existingAcls = resourceAclsMap.get(resource);
-        if (existingAcls != null) {
-            final Iterator<Acl> aclsIter = existingAcls.iterator();
-            while (aclsIter.hasNext()) {
-                Acl curAcl = aclsIter.next();
-                newAclsJava.add(curAcl);
-            }
+    return resourceAclsMap;
+  }
+
+  private java.util.Map<String, scala.collection.immutable.Set<TSentryPrivilege>> getRoleToPrivileges(final List<String> roles) {
+    final java.util.Map<String, scala.collection.immutable.Set<TSentryPrivilege>> rolePrivilegesMap = new HashMap<>();
+    execute(new Command<Void>() {
+      @Override
+      public Void run(SentryGenericServiceClient client) throws Exception {
+        for (String role : roles) {
+          final Set<TSentryPrivilege> rolePrivileges = client.listPrivilegesByRoleName(
+              requestorName, role, COMPONENT_NAME, instanceName);
+          final scala.collection.immutable.Set<TSentryPrivilege> rolePrivilegesScala =
+              scala.collection.JavaConverters.asScalaSetConverter(rolePrivileges).asScala().toSet();
+          rolePrivilegesMap.put(role, rolePrivilegesScala);
         }
+        return null;
+      }
+    });
+
+    return rolePrivilegesMap;
+  }
+
+  private void addExistingAclsForResource(java.util.Map<Resource, scala.collection.immutable.Set<Acl>> resourceAclsMap, Resource resource, java.util.Set<Acl> newAclsJava) {
+    final scala.collection.immutable.Set<Acl> existingAcls = resourceAclsMap.get(resource);
+    if (existingAcls != null) {
+      final Iterator<Acl> aclsIter = existingAcls.iterator();
+      while (aclsIter.hasNext()) {
+        Acl curAcl = aclsIter.next();
+        newAclsJava.add(curAcl);
+      }
     }
-
-    private boolean roleExists(String role) {
-        return getAllRoles().contains(role);
+  }
+
+  private boolean roleExists(String role) {
+      return getAllRoles().contains(role);
+  }
+
+  private void verifyAcls(scala.collection.immutable.Set<Acl> acls) {
+    final Iterator<Acl> iterator = acls.iterator();
+    while (iterator.hasNext()) {
+      final Acl acl = iterator.next();
+      assert acl.principal().getPrincipalType().toLowerCase().equals("role") : "Only Acls with KafkaPrincipal of type \"role;\" is supported.";
+      assert acl.permissionType().name().equals(Allow.name()) : "Only Acls with Permission of type \"Allow\" is supported.";
     }
-
-    private void verifyAcls(scala.collection.immutable.Set<Acl> acls) {
-        final Iterator<Acl> iterator = acls.iterator();
-        while (iterator.hasNext()) {
-            final Acl acl = iterator.next();
-            assert acl.principal().getPrincipalType().toLowerCase().equals("role") : "Only Acls with KafkaPrincipal of type \"role;\" is supported.";
-            assert acl.permissionType().name().equals(Allow.name()) : "Only Acls with Permission of type \"Allow\" is supported.";
-        }
+  }
+
+  /*
+  * For SSL session's Kafka creates user names with "CN=" prepended to the user name.
+  * "=" is used as splitter by Sentry to parse key value pairs and so it is required to strip off "CN=".
+  * */
+  private String getName(RequestChannel.Session session) {
+    final String principalName = session.principal().getName();
+    int start = principalName.indexOf("CN=");
+    if (start >= 0) {
+      String tmpName, name = "";
+      tmpName = principalName.substring(start + 3);
+      int end = tmpName.indexOf(",");
+      if (end > 0) {
+          name = tmpName.substring(0, end);
+      } else {
+          name = tmpName;
+      }
+      return name;
+    } else {
+      return principalName;
     }
-
-    /*
-    * For SSL session's Kafka creates user names with "CN=" prepended to the user name.
-    * "=" is used as splitter by Sentry to parse key value pairs and so it is required to strip off "CN=".
-    * */
-    private String getName(RequestChannel.Session session) {
-        final String principalName = session.principal().getName();
-        int start = principalName.indexOf("CN=");
-        if (start >= 0) {
-            String tmpName, name = "";
-            tmpName = principalName.substring(start + 3);
-            int end = tmpName.indexOf(",");
-            if (end > 0) {
-                name = tmpName.substring(0, end);
-            } else {
-                name = tmpName;
-            }
-            return name;
-        } else {
-            return principalName;
-        }
+  }
+
+  /**
+   * Initialize kerberos via UserGroupInformation.  Will only attempt to login
+   * during the first request, subsequent calls will have no effect.
+   */
+  private void initKerberos(String keytabFile, String principal) {
+    if (keytabFile == null || keytabFile.length() == 0) {
+      throw new IllegalArgumentException("keytabFile required because kerberos is enabled");
     }
-
-    /**
-     * Initialize kerberos via UserGroupInformation.  Will only attempt to login
-     * during the first request, subsequent calls will have no effect.
-     */
-    private void initKerberos(String keytabFile, String principal) {
-        if (keytabFile == null || keytabFile.length() == 0) {
-            throw new IllegalArgumentException("keytabFile required because kerberos is enabled");
-        }
-        if (principal == null || principal.length() == 0) {
-            throw new IllegalArgumentException("principal required because kerberos is enabled");
-        }
-        synchronized (KafkaAuthBinding.class) {
-            if (kerberosInit == null) {
-                kerberosInit = new Boolean(true);
-                // let's avoid modifying the supplied configuration, just to be conservative
-                final Configuration ugiConf = new Configuration();
-                ugiConf.set(HADOOP_SECURITY_AUTHENTICATION, ServiceConstants.ServerConfig.SECURITY_MODE_KERBEROS);
-                UserGroupInformation.setConfiguration(ugiConf);
-                LOG.info(
-                        "Attempting to acquire kerberos ticket with keytab: {}, principal: {} ",
-                        keytabFile, principal);
-                try {
-                    UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
-                } catch (IOException ioe) {
-                    throw new RuntimeException("Failed to login user with Principal: " + principal +
-                            " and Keytab file: " + keytabFile, ioe);
-                }
-                LOG.info("Got Kerberos ticket");
-            }
+    if (principal == null || principal.length() == 0) {
+      throw new IllegalArgumentException("principal required because kerberos is enabled");
+    }
+    synchronized (KafkaAuthBinding.class) {
+      if (kerberosInit == null) {
+        kerberosInit = new Boolean(true);
+        // let's avoid modifying the supplied configuration, just to be conservative
+        final Configuration ugiConf = new Configuration();
+        ugiConf.set(HADOOP_SECURITY_AUTHENTICATION, ServiceConstants.ServerConfig.SECURITY_MODE_KERBEROS);
+        UserGroupInformation.setConfiguration(ugiConf);
+        LOG.info(
+                "Attempting to acquire kerberos ticket with keytab: {}, principal: {} ",
+                keytabFile, principal);
+        try {
+          UserGroupInformation.loginUserFromKeytab(principal, keytabFile);
+        } catch (IOException ioe) {
+          throw new RuntimeException("Failed to login user with Principal: " + principal +
+                    " and Keytab file: " + keytabFile, ioe);
         }
+        LOG.info("Got Kerberos ticket");
+      }
     }
+  }
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
index 0a57e2e..2f4f8df 100644
--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
+++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/conf/KafkaAuthConf.java
@@ -17,7 +17,7 @@ package org.apache.sentry.kafka.conf;
 import java.net.URL;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.policy.kafka.SimpleKafkaPolicyEngine;
+import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
 import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 
@@ -41,7 +41,7 @@ public class KafkaAuthConf extends Configuration {
     AUTHZ_PROVIDER("sentry.kafka.provider", HadoopGroupResourceAuthorizationProvider.class.getName()),
     AUTHZ_PROVIDER_RESOURCE("sentry.kafka.provider.resource", ""),
     AUTHZ_PROVIDER_BACKEND("sentry.kafka.provider.backend", SentryGenericProviderBackend.class.getName()),
-    AUTHZ_POLICY_ENGINE("sentry.kafka.policy.engine", SimpleKafkaPolicyEngine.class.getName()),
+    AUTHZ_POLICY_ENGINE("sentry.kafka.policy.engine", CommonPolicyEngine.class.getName()),
     AUTHZ_INSTANCE_NAME(KAFKA_SERVICE_INSTANCE_NAME, "kafka"),
     AUTHZ_SERVICE_USER_NAME(KAFKA_SERVICE_USER_NAME, "kafka"),
     AUTHZ_PRINCIPAL_HOSTNAME(KAFKA_PRINCIPAL_HOSTNAME, null),

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/AbstractTestKafkaPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/AbstractTestKafkaPolicyEngine.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/AbstractTestKafkaPolicyEngine.java
new file mode 100644
index 0000000..086b707
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/AbstractTestKafkaPolicyEngine.java
@@ -0,0 +1,163 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public abstract class AbstractTestKafkaPolicyEngine {
+
+  private static final String ADMIN = "host=*->action=all";
+  private static final String ADMIN_HOST1 = "host=host1->action=all";
+  private static final String CONSUMER_T1_ALL = "host=*->topic=t1->action=read";
+  private static final String CONSUMER_T1_HOST1 = "host=host1->topic=t1->action=read";
+  private static final String CONSUMER_T2_HOST2 = "host=host2->topic=t2->action=read";
+  private static final String PRODUCER_T1_ALL = "host=*->topic=t1->action=write";
+  private static final String PRODUCER_T1_HOST1 = "host=host1->topic=t1->action=write";
+  private static final String PRODUCER_T2_HOST2 = "host=host2->topic=t2->action=write";
+  private static final String CONSUMER_PRODUCER_T1 = "host=host1->topic=t1->action=all";
+
+  private PolicyEngine policy;
+  private static File baseDir;
+
+  @BeforeClass
+  public static void setupClazz() throws IOException {
+    baseDir = Files.createTempDir();
+  }
+
+  @AfterClass
+  public static void teardownClazz() throws IOException {
+    if (baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  protected void setPolicy(PolicyEngine policy) {
+    this.policy = policy;
+  }
+
+  protected static File getBaseDir() {
+    return baseDir;
+  }
+
+  @Before
+  public void setup() throws IOException {
+    afterSetup();
+  }
+
+  @After
+  public void teardown() throws IOException {
+    beforeTeardown();
+  }
+
+  protected void afterSetup() throws IOException {}
+
+  protected void beforeTeardown() throws IOException {}
+
+
+  @Test
+  public void testConsumer0() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_T1_ALL));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("consumer_group0"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testConsumer1() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_T1_HOST1));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("consumer_group1"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testConsumer2() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_T2_HOST2));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("consumer_group2"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testProducer0() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PRODUCER_T1_ALL));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("producer_group0"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testProducer1() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PRODUCER_T1_HOST1));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("producer_group1"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+
+  @Test
+  public void testProducer2() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PRODUCER_T2_HOST2));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("producer_group2"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testConsumerProducer0() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(CONSUMER_PRODUCER_T1));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("consumer_producer_group0"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testSubAdmin() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN_HOST1));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("subadmin_group"), ActiveRoleSet.ALL))
+            .toString());
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN));
+    Assert
+        .assertEquals(expected.toString(),
+            new TreeSet<String>(policy.getPrivileges(set("admin_group"), ActiveRoleSet.ALL))
+                .toString());
+  }
+
+  private static Set<String> set(String... values) {
+    return Sets.newHashSet(values);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyTestUtil.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyTestUtil.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyTestUtil.java
new file mode 100644
index 0000000..1ededbd
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/KafkaPolicyTestUtil.java
@@ -0,0 +1,48 @@
+/**
+ * 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.sentry.policy.kafka;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.kafka.KafkaPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+
+import java.io.IOException;
+
+public class KafkaPolicyTestUtil {
+
+  public static PolicyEngine createPolicyEngineForTest(String resource) throws IOException {
+
+    ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource);
+
+    // create backendContext
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(KafkaPrivilegeModel.getInstance().getPrivilegeValidators());
+    // initialize the backend with the context
+    providerBackend.initialize(context);
+
+
+    return new CommonPolicyEngine(providerBackend);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java
new file mode 100644
index 0000000..572c74d
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/MockGroupMappingServiceProvider.java
@@ -0,0 +1,39 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.util.Set;
+
+import org.apache.sentry.provider.common.GroupMappingService;
+
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+
+public class MockGroupMappingServiceProvider implements GroupMappingService {
+  private final Multimap<String, String> userToGroupMap;
+
+  public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
+    this.userToGroupMap = userToGroupMap;
+  }
+  @Override
+  public Set<String> getGroups(String user) {
+    return Sets.newHashSet(userToGroupMap.get(user));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderGeneralCases.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderGeneralCases.java
new file mode 100644
index 0000000..07f4d7d
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderGeneralCases.java
@@ -0,0 +1,218 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.kafka.Cluster;
+import org.apache.sentry.core.model.kafka.ConsumerGroup;
+import org.apache.sentry.core.model.kafka.KafkaActionConstant;
+import org.apache.sentry.core.model.kafka.KafkaActionFactory.KafkaAction;
+import org.apache.sentry.core.model.kafka.Host;
+import org.apache.sentry.core.model.kafka.KafkaPrivilegeModel;
+import org.apache.sentry.core.model.kafka.Topic;
+import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.After;
+import org.junit.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestKafkaAuthorizationProviderGeneralCases {
+  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap.create();
+
+  private static final Host HOST_1 = new Host("host1");
+  private static final Host HOST_2 = new Host("host2");
+  private static final Cluster cluster1 = new Cluster();
+  private static final Topic topic1 = new Topic("t1");
+  private static final Topic topic2 = new Topic("t2");
+  private static final ConsumerGroup cgroup1 = new ConsumerGroup("cg1");
+  private static final ConsumerGroup cgroup2 = new ConsumerGroup("cg2");
+
+  private static final KafkaAction ALL = new KafkaAction(KafkaActionConstant.ALL);
+  private static final KafkaAction READ = new KafkaAction(KafkaActionConstant.READ);
+  private static final KafkaAction WRITE = new KafkaAction(KafkaActionConstant.WRITE);
+  private static final KafkaAction CREATE = new KafkaAction(KafkaActionConstant.CREATE);
+  private static final KafkaAction DELETE = new KafkaAction(KafkaActionConstant.DELETE);
+  private static final KafkaAction ALTER = new KafkaAction(KafkaActionConstant.ALTER);
+  private static final KafkaAction DESCRIBE = new KafkaAction(KafkaActionConstant.DESCRIBE);
+  private static final KafkaAction CLUSTER_ACTION = new KafkaAction(
+      KafkaActionConstant.CLUSTER_ACTION);
+
+  private static final Set<KafkaAction> allActions = Sets.newHashSet(ALL, READ, WRITE, CREATE, DELETE, ALTER, DESCRIBE, CLUSTER_ACTION);
+
+  private static final Subject ADMIN = new Subject("admin1");
+  private static final Subject SUB_ADMIN = new Subject("subadmin1");
+  private static final Subject CONSUMER0 = new Subject("consumer0");
+  private static final Subject CONSUMER1 = new Subject("consumer1");
+  private static final Subject CONSUMER2 = new Subject("consumer2");
+  private static final Subject PRODUCER0 = new Subject("producer0");
+  private static final Subject PRODUCER1 = new Subject("producer1");
+  private static final Subject PRODUCER2 = new Subject("producer2");
+  private static final Subject CONSUMER_PRODUCER0 = new Subject("consumer_producer0");
+
+  private static final String ADMIN_GROUP  = "admin_group";
+  private static final String SUBADMIN_GROUP  = "subadmin_group";
+  private static final String CONSUMER_GROUP0 = "consumer_group0";
+  private static final String CONSUMER_GROUP1 = "consumer_group1";
+  private static final String CONSUMER_GROUP2 = "consumer_group2";
+  private static final String PRODUCER_GROUP0 = "producer_group0";
+  private static final String PRODUCER_GROUP1 = "producer_group1";
+  private static final String PRODUCER_GROUP2 = "producer_group2";
+  private static final String CONSUMER_PRODUCER_GROUP0 = "consumer_producer_group0";
+
+  static {
+    USER_TO_GROUP_MAP.putAll(ADMIN.getName(), Arrays.asList(ADMIN_GROUP));
+    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(),  Arrays.asList(SUBADMIN_GROUP ));
+    USER_TO_GROUP_MAP.putAll(CONSUMER0.getName(),  Arrays.asList(CONSUMER_GROUP0));
+    USER_TO_GROUP_MAP.putAll(CONSUMER1.getName(),  Arrays.asList(CONSUMER_GROUP1));
+    USER_TO_GROUP_MAP.putAll(CONSUMER2.getName(),  Arrays.asList(CONSUMER_GROUP2));
+    USER_TO_GROUP_MAP.putAll(PRODUCER0.getName(),  Arrays.asList(PRODUCER_GROUP0));
+    USER_TO_GROUP_MAP.putAll(PRODUCER1.getName(),  Arrays.asList(PRODUCER_GROUP1));
+    USER_TO_GROUP_MAP.putAll(PRODUCER2.getName(),  Arrays.asList(PRODUCER_GROUP2));
+    USER_TO_GROUP_MAP.putAll(CONSUMER_PRODUCER0.getName(),  Arrays.asList(CONSUMER_PRODUCER_GROUP0));
+  }
+
+  private final ResourceAuthorizationProvider authzProvider;
+  private File baseDir;
+
+  public TestKafkaAuthorizationProviderGeneralCases() throws IOException {
+    baseDir = Files.createTempDir();
+    PolicyFiles.copyToDir(baseDir, "kafka-policy-test-authz-provider.ini");
+    authzProvider = new HadoopGroupResourceAuthorizationProvider(
+        KafkaPolicyTestUtil.createPolicyEngineForTest(new File(baseDir,
+            "kafka-policy-test-authz-provider.ini").getPath()),
+        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), KafkaPrivilegeModel.getInstance());
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void doTestResourceAuthorizationProvider(Subject subject, List<? extends Authorizable> authorizableHierarchy,
+      Set<? extends Action> actions, boolean expected) throws Exception {
+    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
+    helper.add("Subject", subject).add("authzHierarchy", authorizableHierarchy).add("action", actions);
+    Assert.assertEquals(helper.toString(), expected,
+        authzProvider.hasAccess(subject, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,cluster1), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,topic1), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,topic2), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,cgroup1), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1,cgroup2), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_1), allActions, true);
+
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,cluster1), allActions, false);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,topic1), allActions, false);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,topic2), allActions, false);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,cgroup1), allActions, false);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2,cgroup2), allActions, false);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(HOST_2), allActions, false);
+
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,cluster1), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,topic1), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,topic2), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,cgroup1), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1,cgroup2), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_1), allActions, true);
+
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,cluster1), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,topic1), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,topic2), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,cgroup1), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2,cgroup2), allActions, true);
+    doTestResourceAuthorizationProvider(ADMIN, Arrays.asList(HOST_2), allActions, true);
+  }
+
+  @Test
+  public void testConsumer() throws Exception {
+    for (KafkaAction action : allActions) {
+      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
+        doTestResourceAuthorizationProvider(CONSUMER0, Arrays.asList(host, topic1),
+            Sets.newHashSet(action), READ.equals(action));
+      }
+    }
+    for (KafkaAction action : allActions) {
+      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
+        doTestResourceAuthorizationProvider(CONSUMER1, Arrays.asList(host, topic1),
+            Sets.newHashSet(action), HOST_1.equals(host) && READ.equals(action));
+      }
+    }
+    for (KafkaAction action : allActions) {
+      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
+        doTestResourceAuthorizationProvider(CONSUMER2, Arrays.asList(host, topic2),
+            Sets.newHashSet(action), HOST_2.equals(host) && READ.equals(action));
+      }
+    }
+  }
+
+  @Test
+  public void testProducer() throws Exception {
+    for (KafkaAction action : allActions) {
+      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
+        doTestResourceAuthorizationProvider(PRODUCER0, Arrays.asList(host, topic1),
+            Sets.newHashSet(action), WRITE.equals(action));
+      }
+    }
+    for (KafkaAction action : allActions) {
+      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
+        doTestResourceAuthorizationProvider(PRODUCER1, Arrays.asList(host, topic1),
+            Sets.newHashSet(action), HOST_1.equals(host) && WRITE.equals(action));
+      }
+    }
+    for (KafkaAction action : allActions) {
+      for (Host host : Sets.newHashSet(HOST_1, HOST_2)) {
+        doTestResourceAuthorizationProvider(PRODUCER2, Arrays.asList(host, topic2),
+            Sets.newHashSet(action), HOST_2.equals(host) && WRITE.equals(action));
+      }
+    }
+  }
+
+  @Test
+  public void testConsumerProducer() throws Exception {
+    for (KafkaAction action : allActions) {
+      doTestResourceAuthorizationProvider(CONSUMER_PRODUCER0, Arrays.asList(HOST_1, topic1),
+          Sets.newHashSet(action), true);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderSpecialCases.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderSpecialCases.java
new file mode 100644
index 0000000..63d2f30
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaAuthorizationProviderSpecialCases.java
@@ -0,0 +1,90 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.kafka.KafkaActionConstant;
+import org.apache.sentry.core.model.kafka.KafkaActionFactory.KafkaAction;
+import org.apache.sentry.core.model.kafka.Host;
+import org.apache.sentry.core.model.kafka.KafkaPrivilegeModel;
+import org.apache.sentry.core.model.kafka.Topic;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.common.AuthorizationProvider;
+import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestKafkaAuthorizationProviderSpecialCases {
+  private AuthorizationProvider authzProvider;
+  private PolicyFile policyFile;
+  private File baseDir;
+  private File iniFile;
+  private String initResource;
+  @Before
+  public void setup() throws IOException {
+    baseDir = Files.createTempDir();
+    iniFile = new File(baseDir, "policy.ini");
+    initResource = "file://" + iniFile.getPath();
+    policyFile = new PolicyFile();
+  }
+
+  @After
+  public void teardown() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  @Test
+  public void testDuplicateEntries() throws Exception {
+    Subject user1 = new Subject("user1");
+    Host host1 = new Host("host1");
+    Topic topic1 = new Topic("t1");
+    Set<? extends Action> actions = Sets.newHashSet(new KafkaAction(KafkaActionConstant.READ));
+    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
+      .addRolesToGroup("group1",  true, "role1", "role1")
+      .addPermissionsToRole("role1", true, "host=host1->topic=t1->action=read",
+          "host=host1->topic=t1->action=read");
+    policyFile.write(iniFile);
+    PolicyEngine policy = KafkaPolicyTestUtil.createPolicyEngineForTest(initResource);
+    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource,
+        policy, KafkaPrivilegeModel.getInstance());
+    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(host1, topic1);
+    Assert.assertTrue(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java
new file mode 100644
index 0000000..62fbea7
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaModelAuthorizables.java
@@ -0,0 +1,87 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.fail;
+
+import org.apache.sentry.core.model.kafka.Cluster;
+import org.apache.sentry.core.model.kafka.ConsumerGroup;
+import org.apache.sentry.core.model.kafka.Host;
+import org.apache.sentry.core.model.kafka.KafkaModelAuthorizables;
+import org.apache.sentry.core.model.kafka.Topic;
+import org.apache.shiro.config.ConfigurationException;
+import org.junit.Test;
+
+public class TestKafkaModelAuthorizables {
+
+  @Test
+  public void testHost() throws Exception {
+    Host host1 = (Host) KafkaModelAuthorizables.from("HOST=host1");
+    assertEquals("host1", host1.getName());
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNoKV() throws Exception {
+    System.out.println(KafkaModelAuthorizables.from("nonsense"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(KafkaModelAuthorizables.from("=host1"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(KafkaModelAuthorizables.from("HOST="));
+  }
+
+  @Test
+  public void testNotAuthorizable() throws Exception {
+    assertNull(KafkaModelAuthorizables.from("k=v"));
+  }
+
+  @Test
+  public void testResourceNameIsCaseSensitive() throws Exception {
+    Host host1 = (Host)KafkaModelAuthorizables.from("HOST=Host1");
+    assertEquals("Host1", host1.getName());
+
+    Cluster cluster1 = (Cluster)KafkaModelAuthorizables.from("Cluster=kafka-cluster");
+    assertEquals("kafka-cluster", cluster1.getName());
+
+    Topic topic1 = (Topic)KafkaModelAuthorizables.from("topic=topiC1");
+    assertEquals("topiC1", topic1.getName());
+
+    ConsumerGroup consumergroup1 = (ConsumerGroup)KafkaModelAuthorizables.from("ConsumerGroup=CG1");
+    assertEquals("CG1", consumergroup1.getName());
+  }
+
+  @Test
+  public void testClusterResourceNameIsRestricted() throws Exception {
+    try {
+      KafkaModelAuthorizables.from("Cluster=cluster1");
+      fail("Cluster with name other than " + Cluster.NAME + " must not have been created.");
+    } catch (ConfigurationException cex) {
+      assertEquals("Exception message is not as expected.", "Kafka's cluster resource can only have name " + Cluster.NAME, cex.getMessage());
+    } catch (Exception ex) {
+      fail("Configuration exception was expected for invalid Cluster name.");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineDFS.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineDFS.java
new file mode 100644
index 0000000..4299b1f
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineDFS.java
@@ -0,0 +1,75 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class TestKafkaPolicyEngineDFS extends AbstractTestKafkaPolicyEngine {
+  private static MiniDFSCluster dfsCluster;
+  private static FileSystem fileSystem;
+  private static Path root;
+  private static Path etc;
+
+  @BeforeClass
+  public static void setupLocalClazz() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    File dfsDir = new File(baseDir, "dfs");
+    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
+    Configuration conf = new Configuration();
+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
+    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
+    fileSystem = dfsCluster.getFileSystem();
+    root = new Path(fileSystem.getUri().toString());
+    etc = new Path(root, "/etc");
+    fileSystem.mkdirs(etc);
+  }
+
+  @AfterClass
+  public static void teardownLocalClazz() {
+    if(dfsCluster != null) {
+      dfsCluster.shutdown();
+    }
+  }
+
+  @Override
+  protected void afterSetup() throws IOException {
+    fileSystem.delete(etc, true);
+    fileSystem.mkdirs(etc);
+    PolicyFiles.copyToDir(fileSystem, etc, "kafka-policy-test-authz-provider.ini");
+    setPolicy(KafkaPolicyTestUtil.createPolicyEngineForTest(new Path(etc,
+        "kafka-policy-test-authz-provider.ini").toString()));
+  }
+
+  @Override
+  protected void beforeTeardown() throws IOException {
+    fileSystem.delete(etc, true);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineLocalFS.java b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineLocalFS.java
new file mode 100644
index 0000000..9a69f1c
--- /dev/null
+++ b/sentry-binding/sentry-binding-kafka/src/test/java/org/apache/sentry/policy/kafka/TestKafkaPolicyEngineLocalFS.java
@@ -0,0 +1,47 @@
+/*
+ * 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.sentry.policy.kafka;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.provider.file.PolicyFiles;
+
+public class TestKafkaPolicyEngineLocalFS extends AbstractTestKafkaPolicyEngine {
+
+  @Override
+  protected void  afterSetup() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
+    PolicyFiles.copyToDir(baseDir, "kafka-policy-test-authz-provider.ini");
+    setPolicy(KafkaPolicyTestUtil.createPolicyEngineForTest(new File(baseDir,
+        "kafka-policy-test-authz-provider.ini").getPath()));
+  }
+
+  @Override
+  protected void beforeTeardown() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    FileUtils.deleteQuietly(baseDir);
+  }
+}


[02/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopWildcardPrivilege.java b/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopWildcardPrivilege.java
deleted file mode 100644
index ae89cf4..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/main/java/org/apache/sentry/policy/sqoop/SqoopWildcardPrivilege.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-
-import java.util.List;
-
-import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.PrivilegeFactory;
-import org.apache.sentry.policy.common.KeyValue;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class SqoopWildcardPrivilege implements Privilege {
-
-  public static class Factory implements PrivilegeFactory {
-    @Override
-    public Privilege createPrivilege(String permission) {
-      return new SqoopWildcardPrivilege(permission);
-    }
-  }
-
-  private final ImmutableList<KeyValue> parts;
-
-  public SqoopWildcardPrivilege(String permission) {
-    if (Strings.isNullOrEmpty(permission)) {
-      throw new IllegalArgumentException("permission string cannot be null or empty.");
-    }
-    List<KeyValue>parts = Lists.newArrayList();
-    for (String authorizable : AUTHORIZABLE_SPLITTER.trimResults().split(permission.trim())) {
-      if (authorizable.isEmpty()) {
-        throw new IllegalArgumentException("Privilege '" + permission + "' has an empty section");
-      }
-      parts.add(new KeyValue(authorizable));
-    }
-    if (parts.isEmpty()) {
-      throw new AssertionError("Should never occur: " + permission);
-    }
-    this.parts = ImmutableList.copyOf(parts);
-  }
-
-  @Override
-  public boolean implies(Privilege p) {
-    if (!(p instanceof SqoopWildcardPrivilege)) {
-      return false;
-    }
-    SqoopWildcardPrivilege wp = (SqoopWildcardPrivilege)p;
-    List<KeyValue> otherParts = wp.parts;
-    if(equals(wp)) {
-      return true;
-    }
-    int index = 0;
-    for (KeyValue otherPart : otherParts) {
-      // If this privilege has less parts than the other privilege, everything
-      // after the number of parts contained
-      // in this privilege is automatically implied, so return true
-      if (parts.size() - 1 < index) {
-        return true;
-      } else {
-        KeyValue part = parts.get(index);
-        // Support for action inheritance from parent to child
-        if (part.getKey().equalsIgnoreCase(SqoopActionConstant.NAME)
-            && !(otherPart.getKey().equalsIgnoreCase(SqoopActionConstant.NAME))) {
-          continue;
-        }
-        // are the keys even equal
-        if(!part.getKey().equalsIgnoreCase(otherPart.getKey())) {
-          return false;
-        }
-        if (!impliesKeyValue(part, otherPart)) {
-          return false;
-        }
-        index++;
-      }
-    }
-    // If this privilege has more parts than
-    // the other parts, only imply it if
-    // all of the other parts are "*" or "ALL"
-    for (; index < parts.size(); index++) {
-      KeyValue part = parts.get(index);
-      if (!part.getValue().equals(SqoopActionConstant.ALL)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private boolean impliesKeyValue(KeyValue policyPart, KeyValue requestPart) {
-    Preconditions.checkState(policyPart.getKey().equalsIgnoreCase(requestPart.getKey()),
-        "Please report, this method should not be called with two different keys");
-    if(policyPart.getValue().equalsIgnoreCase(SqoopActionConstant.ALL) ||
-        policyPart.getValue().equalsIgnoreCase(SqoopActionConstant.ALL_NAME) ||
-        policyPart.equals(requestPart)) {
-      return true;
-    } else if (!SqoopActionConstant.NAME.equalsIgnoreCase(policyPart.getKey())
-        && SqoopActionConstant.ALL.equalsIgnoreCase(requestPart.getValue())) {
-      /* privilege request is to match with any object of given type */
-      return true;
-    }
-    return false;
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java
deleted file mode 100644
index 49b9bc1..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public abstract class AbstractTestSqoopPolicyEngine {
-  private static final String OPERATOR_JDBC_CONNECTORS_READ = "server=server1->connector=generic-jdbc-connector->action=read";
-  private static final String OPERATOR_HDFS_CONNECTORS_READ = "server=server1->connector=hdfs-connector->action=read";
-  private static final String OPERATOR_KAFKA_CONNECTORS_READ = "server=server1->connector=kafka-connector->action=read";
-  private static final String OPERATOR_KITE_CONNECTORS_READ = "server=server1->connector=kite-connector->action=read";
-  private static final String ANALYST_JOBS_ALL = "server=server1->job=all->action=*";
-  private static final String OPERATOR_JOB1_READ = "server=server1->job=job1->action=read";
-  private static final String OPERATOR_JOB2_READ = "server=server1->job=job2->action=read";
-  private static final String ANALYST_LINKS_ALL = "server=server1->link=all->action=*";
-  private static final String OPERATOR_LINK1_READ = "server=server1->link=link1->action=read";
-  private static final String OPERATOR_LINK2_READ = "server=server1->link=link2->action=read";
-  private static final String ADMIN = "server=server1->action=*";
-
-  private PolicyEngine policy;
-  private static File baseDir;
-
-  protected String sqoopServerName = "server1";
-
-  @BeforeClass
-  public static void setupClazz() throws IOException {
-    baseDir = Files.createTempDir();
-  }
-
-  @AfterClass
-  public static void teardownClazz() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  protected void setPolicy(PolicyEngine policy) {
-    this.policy = policy;
-  }
-  protected static File getBaseDir() {
-    return baseDir;
-  }
-  @Before
-  public void setup() throws IOException {
-    afterSetup();
-  }
-  @After
-  public void teardown() throws IOException {
-    beforeTeardown();
-  }
-  protected void afterSetup() throws IOException {
-
-  }
-
-  protected void beforeTeardown() throws IOException {
-
-  }
-
-  @Test
-  public void testDeveloper() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
-        OPERATOR_JDBC_CONNECTORS_READ, OPERATOR_HDFS_CONNECTORS_READ,
-        OPERATOR_KAFKA_CONNECTORS_READ, OPERATOR_KITE_CONNECTORS_READ,
-        ANALYST_JOBS_ALL, ANALYST_LINKS_ALL));
-    Assert.assertEquals(expected.toString(),
-        Sets.newTreeSet(policy.getPrivileges(set("developer"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testAnalyst() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ANALYST_JOBS_ALL, ANALYST_LINKS_ALL));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("analyst"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testConnectorOperator() throws Exception {
-
-  }
-
-  @Test
-  public void testJobOperator() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets
-        .newHashSet(OPERATOR_JOB1_READ,OPERATOR_JOB2_READ));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("job1_2_operator"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testLinkOperator() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets
-        .newHashSet(OPERATOR_LINK1_READ, OPERATOR_LINK2_READ));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("link1_2_operator"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN));
-    Assert.assertEquals(expected.toString(),
-        new TreeSet<String>(policy.getPrivileges(set("admin"), ActiveRoleSet.ALL))
-        .toString());
-  }
-
-  private static Set<String> set(String... values) {
-    return Sets.newHashSet(values);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/MockGroupMappingServiceProvider.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/MockGroupMappingServiceProvider.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/MockGroupMappingServiceProvider.java
deleted file mode 100644
index fd577d6..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/MockGroupMappingServiceProvider.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.util.Set;
-
-import org.apache.sentry.provider.common.GroupMappingService;
-
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-public class MockGroupMappingServiceProvider implements GroupMappingService {
-  private final Multimap<String, String> userToGroupMap;
-
-  public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
-    this.userToGroupMap = userToGroupMap;
-  }
-  @Override
-  public Set<String> getGroups(String user) {
-    return Sets.newHashSet(userToGroupMap.get(user));
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyFileProviderBackend.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyFileProviderBackend.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyFileProviderBackend.java
deleted file mode 100644
index 5da63a3..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyFileProviderBackend.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.IOException;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.provider.file.SimpleFileProviderBackend;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SqoopPolicyFileProviderBackend extends SimpleSqoopPolicyEngine {
-  private static final Logger LOGGER = LoggerFactory.getLogger(SqoopPolicyFileProviderBackend.class);
-  public SqoopPolicyFileProviderBackend(String sqoopServerName,
-      String resource) throws IOException {
-    super(sqoopServerName, new SimpleFileProviderBackend(new Configuration(), resource));
-    LOGGER.warn("The DB providerbackend is the preferred option over file providerbackend as the sqoop policy engine");
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java
deleted file mode 100644
index b6e9893..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import org.junit.Assert;
-
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.shiro.config.ConfigurationException;
-import org.junit.Test;
-
-public class TestServerNameRequiredMatch {
-  @Test
-  public void testWithoutServerName() {
-    ServerNameRequiredMatch serverNameMatch = new ServerNameRequiredMatch("server1");
-    try {
-      serverNameMatch.validate(new PrivilegeValidatorContext("connector=c1->action=read"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-    }
-  }
-  @Test
-  public void testServerNameNotMatch() throws Exception {
-    ServerNameRequiredMatch serverNameMatch = new ServerNameRequiredMatch("server1");
-    try {
-      serverNameMatch.validate(new PrivilegeValidatorContext("server=server2->connector=c1->action=read"));
-      Assert.fail("Expected ConfigurationException");
-    } catch (ConfigurationException ex) {
-    }
-  }
-  @Test
-  public void testServerNameMatch() throws Exception {
-    ServerNameRequiredMatch serverNameMatch = new ServerNameRequiredMatch("server1");
-    try {
-      serverNameMatch.validate(new PrivilegeValidatorContext("server=server1->connector=c1->action=read"));
-    } catch (ConfigurationException ex) {
-      Assert.fail("Not expected ConfigurationException");
-    }
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java
deleted file mode 100644
index 3bdf6f7..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.sqoop.Connector;
-import org.apache.sentry.core.model.sqoop.Job;
-import org.apache.sentry.core.model.sqoop.Link;
-import org.apache.sentry.core.model.sqoop.Server;
-import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
-import org.apache.sentry.core.model.sqoop.SqoopActionFactory.SqoopAction;
-import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
-import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.After;
-import org.junit.Test;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestSqoopAuthorizationProviderGeneralCases {
-  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap.create();
-
-  private static final Subject SUB_ADMIN = new Subject("admin1");
-  private static final Subject SUB_DEVELOPER = new Subject("developer1");
-  private static final Subject SUB_ANALYST = new Subject("analyst1");
-  private static final Subject SUB_JOB_OPERATOR = new Subject("job_operator1");
-  private static final Subject SUB_LINK_OPERATOR = new Subject("link_operator1");
-  private static final Subject SUB_CONNECTOR_OPERATOR = new Subject("connector_operator1");
-
-
-
-  private static final Server server1 = new Server("server1");
-  private static final Connector jdbc_connector = new Connector("generic-jdbc-connector");
-  private static final Connector hdfs_connector = new Connector("hdfs-connector");
-  private static final Connector kafka_connector = new Connector("kafka-connector");
-  private static final Connector kite_connector = new Connector("kite-connector");
-  private static final Link link1 = new Link("link1");
-  private static final Link link2 = new Link("link2");
-  private static final Job job1 = new Job("job1");
-  private static final Job job2 = new Job("job2");
-
-  private static final SqoopAction ALL = new SqoopAction(SqoopActionConstant.ALL);
-  private static final SqoopAction READ = new SqoopAction(SqoopActionConstant.READ);
-  private static final SqoopAction WRITE = new SqoopAction(SqoopActionConstant.WRITE);
-
-  private static final String ADMIN = "admin";
-  private static final String DEVELOPER = "developer";
-  private static final String ANALYST = "analyst";
-  private static final String JOB_OPERATOR = "job1_2_operator";
-  private static final String LINK_OPERATOR ="link1_2_operator";
-  private static final String CONNECTOR_OPERATOR = "connectors_operator";
-
-  static {
-    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList(ADMIN));
-    USER_TO_GROUP_MAP.putAll(SUB_DEVELOPER.getName(), Arrays.asList(DEVELOPER));
-    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList(ANALYST));
-    USER_TO_GROUP_MAP.putAll(SUB_JOB_OPERATOR.getName(),Arrays.asList(JOB_OPERATOR));
-    USER_TO_GROUP_MAP.putAll(SUB_LINK_OPERATOR.getName(),Arrays.asList(LINK_OPERATOR));
-    USER_TO_GROUP_MAP.putAll(SUB_CONNECTOR_OPERATOR.getName(),Arrays.asList(CONNECTOR_OPERATOR));
-  }
-
-  private final ResourceAuthorizationProvider authzProvider;
-  private File baseDir;
-
-  public TestSqoopAuthorizationProviderGeneralCases() throws IOException {
-    baseDir = Files.createTempDir();
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    authzProvider = new HadoopGroupResourceAuthorizationProvider(
-        new SqoopPolicyFileProviderBackend(server1.getName(), new File(baseDir, "test-authz-provider.ini").getPath()),
-        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP));
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void doTestResourceAuthorizationProvider(Subject subject, List<? extends Authorizable> authorizableHierarchy,
-      Set<? extends Action> actions, boolean expected) throws Exception {
-    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
-    helper.add("Subject", subject).add("authzHierarchy", authorizableHierarchy).add("action", actions);
-    Assert.assertEquals(helper.toString(), expected,
-        authzProvider.hasAccess(subject, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-
-  @Test
-  public void testAdmin() throws Exception {
-    Set<? extends Action> allActions = Sets.newHashSet(ALL, READ, WRITE);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,hdfs_connector), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,jdbc_connector), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,kafka_connector), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,kite_connector), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,link1), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,link2), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,job1), allActions, true);
-    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,job2), allActions, true);
-  }
-
-  @Test
-  public void testDeveloper() throws Exception {
-    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
-    for (SqoopAction action : allActions) {
-      //developer only has the read action on all connectors
-      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
-        doTestResourceAuthorizationProvider(SUB_DEVELOPER, Arrays.asList(server1, connector), Sets.newHashSet(action), READ.equals(action));
-      }
-    }
-
-    for (Link link : Sets.newHashSet(link1, link2)) {
-      //developer has the all action on all links
-      doTestResourceAuthorizationProvider(SUB_DEVELOPER, Arrays.asList(server1, link), allActions, true);
-    }
-
-    for (Job job : Sets.newHashSet(job1,job2)) {
-      //developer has the all action on all jobs
-      doTestResourceAuthorizationProvider(SUB_DEVELOPER, Arrays.asList(server1, job), allActions, true);
-    }
-  }
-
-  @Test
-  public void testAnalyst() throws Exception {
-    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
-    for (SqoopAction action : allActions) {
-      //analyst has not the any action on all connectors
-      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
-        doTestResourceAuthorizationProvider(SUB_ANALYST, Arrays.asList(server1, connector), Sets.newHashSet(action), false);
-      }
-    }
-
-    for (Link link : Sets.newHashSet(link1, link2)) {
-      //analyst has the all action on all links
-      doTestResourceAuthorizationProvider(SUB_ANALYST, Arrays.asList(server1, link), allActions, true);
-    }
-
-    for (Job job : Sets.newHashSet(job1,job2)) {
-      //analyst has the all action on all jobs
-      doTestResourceAuthorizationProvider(SUB_ANALYST, Arrays.asList(server1, job), allActions, true);
-    }
-  }
-
-  @Test
-  public void testJobOperator() throws Exception {
-    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
-    for (SqoopAction action : allActions) {
-      for (Job job : Sets.newHashSet(job1,job2)) {
-        //Job operator has the read action on all jobs
-        doTestResourceAuthorizationProvider(SUB_JOB_OPERATOR, Arrays.asList(server1, job), Sets.newHashSet(action), READ.equals(action));
-      }
-      for (Link link : Sets.newHashSet(link1, link2)) {
-        doTestResourceAuthorizationProvider(SUB_JOB_OPERATOR, Arrays.asList(server1, link), Sets.newHashSet(action), false);
-      }
-      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
-        doTestResourceAuthorizationProvider(SUB_JOB_OPERATOR, Arrays.asList(server1, connector), Sets.newHashSet(action), false);
-      }
-    }
-  }
-
-  @Test
-  public void testLinkOperator() throws Exception {
-    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
-    for (SqoopAction action : allActions) {
-      for (Link link : Sets.newHashSet(link1, link2)) {
-        //Link operator has the read action on all links
-        doTestResourceAuthorizationProvider(SUB_LINK_OPERATOR, Arrays.asList(server1, link), Sets.newHashSet(action), READ.equals(action));
-      }
-      for (Job job : Sets.newHashSet(job1,job2)) {
-        doTestResourceAuthorizationProvider(SUB_LINK_OPERATOR, Arrays.asList(server1, job), Sets.newHashSet(action), false);
-      }
-      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
-        doTestResourceAuthorizationProvider(SUB_LINK_OPERATOR, Arrays.asList(server1, connector), Sets.newHashSet(action), false);
-      }
-    }
-  }
-
-  @Test
-  public void testConnectorOperator() throws Exception {
-    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
-    for (SqoopAction action : allActions) {
-      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
-        doTestResourceAuthorizationProvider(SUB_CONNECTOR_OPERATOR, Arrays.asList(server1, connector), Sets.newHashSet(action), READ.equals(action));
-      }
-      for (Job job : Sets.newHashSet(job1,job2)) {
-        doTestResourceAuthorizationProvider(SUB_CONNECTOR_OPERATOR, Arrays.asList(server1, job), Sets.newHashSet(action), false);
-      }
-      for (Link link : Sets.newHashSet(link1, link2)) {
-        doTestResourceAuthorizationProvider(SUB_CONNECTOR_OPERATOR, Arrays.asList(server1, link), Sets.newHashSet(action), false);
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java
deleted file mode 100644
index 9fee5a7..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.Action;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.core.common.Authorizable;
-import org.apache.sentry.core.common.Subject;
-import org.apache.sentry.core.model.sqoop.Connector;
-import org.apache.sentry.core.model.sqoop.Server;
-import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
-import org.apache.sentry.core.model.sqoop.SqoopActionFactory.SqoopAction;
-import org.apache.sentry.provider.common.AuthorizationProvider;
-import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
-import org.apache.sentry.provider.file.PolicyFile;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestSqoopAuthorizationProviderSpecialCases {
-  private AuthorizationProvider authzProvider;
-  private PolicyFile policyFile;
-  private File baseDir;
-  private File iniFile;
-  private String initResource;
-  @Before
-  public void setup() throws IOException {
-    baseDir = Files.createTempDir();
-    iniFile = new File(baseDir, "policy.ini");
-    initResource = "file://" + iniFile.getPath();
-    policyFile = new PolicyFile();
-  }
-
-  @After
-  public void teardown() throws IOException {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  @Test
-  public void testDuplicateEntries() throws Exception {
-    Subject user1 = new Subject("user1");
-    Server server1 = new Server("server1");
-    Connector connector1 = new Connector("c1");
-    Set<? extends Action> actions = Sets.newHashSet(new SqoopAction(SqoopActionConstant.READ));
-    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
-      .addRolesToGroup("group1",  true, "role1", "role1")
-      .addPermissionsToRole("role1", true, "server=server1->connector=c1->action=read",
-          "server=server1->connector=c1->action=read");
-    policyFile.write(iniFile);
-    SqoopPolicyFileProviderBackend policy = new SqoopPolicyFileProviderBackend(server1.getName(), initResource);
-    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy);
-    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, connector1);
-    Assert.assertTrue(authorizableHierarchy.toString(),
-        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java
deleted file mode 100644
index 99a5ae2..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.apache.sentry.core.model.sqoop.Server;
-import org.junit.Test;
-
-public class TestSqoopModelAuthorizables {
-
-  @Test
-  public void testServer() throws Exception {
-    Server server1 = (Server)SqoopModelAuthorizables.from("SERVER=server1");
-    assertEquals("server1", server1.getName());
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNoKV() throws Exception {
-    System.out.println(SqoopModelAuthorizables.from("nonsense"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(SqoopModelAuthorizables.from("=server1"));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(SqoopModelAuthorizables.from("SERVER="));
-  }
-
-  @Test
-  public void testNotAuthorizable() throws Exception {
-    assertNull(SqoopModelAuthorizables.from("k=v"));
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java
deleted file mode 100644
index ff4c9a8..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.fs.FileSystem;
-import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hdfs.MiniDFSCluster;
-import org.apache.sentry.provider.file.PolicyFiles;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-
-public class TestSqoopPolicyEngineDFS extends AbstractTestSqoopPolicyEngine {
-  private static MiniDFSCluster dfsCluster;
-  private static FileSystem fileSystem;
-  private static Path root;
-  private static Path etc;
-
-  @BeforeClass
-  public static void setupLocalClazz() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    File dfsDir = new File(baseDir, "dfs");
-    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
-    Configuration conf = new Configuration();
-    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
-    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
-    fileSystem = dfsCluster.getFileSystem();
-    root = new Path(fileSystem.getUri().toString());
-    etc = new Path(root, "/etc");
-    fileSystem.mkdirs(etc);
-  }
-
-  @AfterClass
-  public static void teardownLocalClazz() {
-    if(dfsCluster != null) {
-      dfsCluster.shutdown();
-    }
-  }
-
-  @Override
-  protected void  afterSetup() throws IOException {
-    fileSystem.delete(etc, true);
-    fileSystem.mkdirs(etc);
-    PolicyFiles.copyToDir(fileSystem, etc, "test-authz-provider.ini");
-    setPolicy(new SqoopPolicyFileProviderBackend(sqoopServerName, new Path(etc,
-        "test-authz-provider.ini").toString()));
-  }
-
-  @Override
-  protected void beforeTeardown() throws IOException {
-    fileSystem.delete(etc, true);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java
deleted file mode 100644
index ca5a198..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.provider.file.PolicyFiles;
-
-public class TestSqoopPolicyEngineLocalFS extends AbstractTestSqoopPolicyEngine {
-  @Override
-  protected void  afterSetup() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
-    PolicyFiles.copyToDir(baseDir, "test-authz-provider.ini");
-    setPolicy(new SqoopPolicyFileProviderBackend(sqoopServerName, new File(baseDir, "test-authz-provider.ini").getPath()));
-  }
-  @Override
-  protected void beforeTeardown() throws IOException {
-    File baseDir = getBaseDir();
-    Assert.assertNotNull(baseDir);
-    FileUtils.deleteQuietly(baseDir);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java
deleted file mode 100644
index da922a5..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.junit.Assert;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.sentry.core.common.ActiveRoleSet;
-import org.apache.sentry.policy.common.PolicyEngine;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-public class TestSqoopPolicyNegative {
-  @SuppressWarnings("unused")
-  private static final Logger LOGGER = LoggerFactory
-      .getLogger(TestSqoopPolicyNegative.class);
-
-  private File baseDir;
-  private File globalPolicyFile;
-
-  @Before
-  public void setup() {
-    baseDir = Files.createTempDir();
-    globalPolicyFile = new File(baseDir, "global.ini");
-  }
-
-  @After
-  public void teardown() {
-    if(baseDir != null) {
-      FileUtils.deleteQuietly(baseDir);
-    }
-  }
-
-  private void append(String from, File to) throws IOException {
-    Files.append(from + "\n", to, Charsets.UTF_8);
-  }
-
-  @Test
-  public void testauthorizedSqoopInPolicyFile() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("other_group = other_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("other_role = server=server1->connector=c1->action=read, server=server1->link=l1->action=read", globalPolicyFile);
-    PolicyEngine policy = new SqoopPolicyFileProviderBackend("server1", globalPolicyFile.getPath());
-    //malicious_group has no privilege
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("malicious_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-    //other_group has two privileges
-    permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.size() == 2);
-  }
-
-  @Test
-  public void testNoServerNameConfig() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("other_group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = connector=c1->action=read,link=l1->action=read", globalPolicyFile);
-    PolicyEngine policy = new SqoopPolicyFileProviderBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testServerAllName() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = server=*", globalPolicyFile);
-    PolicyEngine policy = new SqoopPolicyFileProviderBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testServerIncorrect() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = server=server2", globalPolicyFile);
-    PolicyEngine policy = new SqoopPolicyFileProviderBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-
-  @Test
-  public void testAll() throws Exception {
-    append("[groups]", globalPolicyFile);
-    append("group = malicious_role", globalPolicyFile);
-    append("[roles]", globalPolicyFile);
-    append("malicious_role = *", globalPolicyFile);
-    PolicyEngine policy = new SqoopPolicyFileProviderBackend("server1", globalPolicyFile.getPath());
-    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
-    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopWildcardPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopWildcardPrivilege.java b/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopWildcardPrivilege.java
deleted file mode 100644
index 84a25a7..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopWildcardPrivilege.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * 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.sentry.policy.sqoop;
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_SEPARATOR;
-
-import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
-import org.apache.sentry.policy.common.Privilege;
-import org.apache.sentry.policy.common.KeyValue;
-import org.junit.Test;
-
-public class TestSqoopWildcardPrivilege extends org.junit.Assert {
-  private static final Privilege SQOOP_SERVER1_ALL =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("action", SqoopActionConstant.ALL));
-  private static final Privilege SQOOP_SERVER1_READ =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("action", SqoopActionConstant.READ));
-  private static final Privilege SQOOP_SERVER1_WRITE =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("action", SqoopActionConstant.WRITE));
-
-  private static final Privilege SQOOP_SERVER1_JOB1_ALL =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("JOB", "job1"), new KeyValue("action", SqoopActionConstant.ALL));
-  private static final Privilege SQOOP_SERVER1_JOB1_READ =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("JOB", "job1"), new KeyValue("action", SqoopActionConstant.READ));
-  private static final Privilege SQOOP_SERVER1_JOB1_WRITE =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("JOB", "job1"), new KeyValue("action", SqoopActionConstant.WRITE));
-
-  private static final Privilege SQOOP_SERVER1_LINK1_ALL =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("LINK", "link1"), new KeyValue("action", SqoopActionConstant.ALL));
-  private static final Privilege SQOOP_SERVER1_LINK1_READ =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("LINK", "link1"), new KeyValue("action", SqoopActionConstant.READ));
-  private static final Privilege SQOOP_SERVER1_LINK1_WRITE =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("LINK", "link1"), new KeyValue("action", SqoopActionConstant.WRITE));
-
-  private static final Privilege SQOOP_SERVER1_CONNECTOR1_ALL =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("CONNECTOR", "connector1"), new KeyValue("action", SqoopActionConstant.ALL));
-  private static final Privilege SQOOP_SERVER1_CONNECTOR1_READ =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("CONNECTOR", "connector1"), new KeyValue("action", SqoopActionConstant.READ));
-  private static final Privilege SQOOP_SERVER1_CONNECTOR1_WRITE =
-      create(new KeyValue("SERVER", "server1"), new KeyValue("CONNECTOR", "connector1"), new KeyValue("action", SqoopActionConstant.WRITE));
-
-
-  @Test
-  public void testSimpleAction() throws Exception {
-    //server
-    assertFalse(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_READ));
-    assertFalse(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_WRITE));
-    //connector
-    assertFalse(SQOOP_SERVER1_CONNECTOR1_WRITE.implies(SQOOP_SERVER1_CONNECTOR1_READ));
-    assertFalse(SQOOP_SERVER1_CONNECTOR1_READ.implies(SQOOP_SERVER1_CONNECTOR1_WRITE));
-    //job
-    assertFalse(SQOOP_SERVER1_JOB1_READ.implies(SQOOP_SERVER1_JOB1_WRITE));
-    assertFalse(SQOOP_SERVER1_JOB1_WRITE.implies(SQOOP_SERVER1_JOB1_READ));
-    //link
-    assertFalse(SQOOP_SERVER1_LINK1_READ.implies(SQOOP_SERVER1_LINK1_WRITE));
-    assertFalse(SQOOP_SERVER1_LINK1_WRITE.implies(SQOOP_SERVER1_LINK1_READ));
-  }
-
-  @Test
-  public void testShorterThanRequest() throws Exception {
-    //job
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_JOB1_ALL));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_JOB1_READ));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_JOB1_WRITE));
-
-    assertFalse(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_READ));
-    assertTrue(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_JOB1_READ));
-    assertTrue(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_JOB1_WRITE));
-
-    //link
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_LINK1_ALL));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_LINK1_READ));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_LINK1_WRITE));
-
-    assertTrue(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_LINK1_READ));
-    assertTrue(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_LINK1_WRITE));
-
-    //connector
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_ALL));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_READ));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_WRITE));
-
-    assertTrue(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_CONNECTOR1_READ));
-    assertTrue(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_CONNECTOR1_WRITE));
-  }
-
-  @Test
-  public void testActionAll() throws Exception {
-    //server
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_READ));
-    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_WRITE));
-
-    //job
-    assertTrue(SQOOP_SERVER1_JOB1_ALL.implies(SQOOP_SERVER1_JOB1_READ));
-    assertTrue(SQOOP_SERVER1_JOB1_ALL.implies(SQOOP_SERVER1_JOB1_WRITE));
-
-    //link
-    assertTrue(SQOOP_SERVER1_LINK1_ALL.implies(SQOOP_SERVER1_LINK1_READ));
-    assertTrue(SQOOP_SERVER1_LINK1_ALL.implies(SQOOP_SERVER1_LINK1_WRITE));
-
-    //connector
-    assertTrue(SQOOP_SERVER1_CONNECTOR1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_READ));
-    assertTrue(SQOOP_SERVER1_CONNECTOR1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_WRITE));
-  }
-
-  @Test
-  public void testUnexpected() throws Exception {
-    Privilege p = new Privilege() {
-      @Override
-      public boolean implies(Privilege p) {
-        return false;
-      }
-    };
-    Privilege job1 = create(new KeyValue("SERVER", "server"), new KeyValue("JOB", "job1"));
-    assertFalse(job1.implies(null));
-    assertFalse(job1.implies(p));
-    assertFalse(job1.equals(null));
-    assertFalse(job1.equals(p));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testNullString() throws Exception {
-    System.out.println(create((String)null));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyString() throws Exception {
-    System.out.println(create(""));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyKey() throws Exception {
-    System.out.println(create(KV_JOINER.join("", "server1")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyValue() throws Exception {
-    System.out.println(create(KV_JOINER.join("SERVER", "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testEmptyPart() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_JOINER.join("SERVER", "server1"), "")));
-  }
-
-  @Test(expected=IllegalArgumentException.class)
-  public void testOnlySeperators() throws Exception {
-    System.out.println(create(AUTHORIZABLE_JOINER.
-        join(KV_SEPARATOR, KV_SEPARATOR, KV_SEPARATOR)));
-  }
-
-  static SqoopWildcardPrivilege create(KeyValue... keyValues) {
-    return create(AUTHORIZABLE_JOINER.join(keyValues));
-
-  }
-  static SqoopWildcardPrivilege create(String s) {
-    return new SqoopWildcardPrivilege(s);
-  }
-}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/resources/log4j.properties b/sentry-policy/sentry-policy-sqoop/src/test/resources/log4j.properties
deleted file mode 100644
index 7703069..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# 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.
-#
-
-# Define some default values that can be overridden by system properties.
-#
-# For testing, it may also be convenient to specify
-
-log4j.rootLogger=DEBUG,console
-
-log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.appender.console.target=System.err
-log4j.appender.console.layout=org.apache.log4j.PatternLayout
-log4j.appender.console.layout.ConversionPattern=%d (%t) [%p - %l] %m%n
-
-log4j.logger.org.apache.hadoop.conf.Configuration=INFO
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-policy/sentry-policy-sqoop/src/test/resources/test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-policy/sentry-policy-sqoop/src/test/resources/test-authz-provider.ini b/sentry-policy/sentry-policy-sqoop/src/test/resources/test-authz-provider.ini
deleted file mode 100644
index a4ab5d1..0000000
--- a/sentry-policy/sentry-policy-sqoop/src/test/resources/test-authz-provider.ini
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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.
-
-[groups]
-developer = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role,\
-    jobs_analyst_role,links_analyst_role
-analyst = jobs_analyst_role,links_analyst_role
-connectors_operator = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role
-jobs_analyst = jobs_analyst_role
-job1_2_operator = job1_role,job2_role
-links_analyst = links_analyst_role
-link1_2_operator = link1_role,link2_role
-admin = admin_role
-
-[roles]
-admin_role = server=server1->action=*
-jdbc_connector_role = server=server1->connector=generic-jdbc-connector->action=read
-hdfs_connector_role = server=server1->connector=hdfs-connector->action=read
-kafka_connector_role = server=server1->connector=kafka-connector->action=read
-kite_connector_role = server=server1->connector=kite-connector->action=read
-jobs_analyst_role = server=server1->job=all->action=*
-job1_role = server=server1->job=job1->action=read
-job2_role = server=server1->job=job2->action=read
-links_analyst_role = server=server1->link=all->action=*
-link1_role = server=server1->link=link1->action=read
-link2_role = server=server1->link=link2->action=read
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/HadoopGroupResourceAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/HadoopGroupResourceAuthorizationProvider.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/HadoopGroupResourceAuthorizationProvider.java
index bcd3312..e45799f 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/HadoopGroupResourceAuthorizationProvider.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/HadoopGroupResourceAuthorizationProvider.java
@@ -21,6 +21,7 @@ import java.io.IOException;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.security.Groups;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.policy.common.PolicyEngine;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -35,18 +36,20 @@ public class HadoopGroupResourceAuthorizationProvider extends
 
   // resource parameter present so that other AuthorizationProviders (e.g.
   // LocalGroupResourceAuthorizationProvider) has the same constructor params.
-  public HadoopGroupResourceAuthorizationProvider(String resource, PolicyEngine policy) throws IOException {
-    this(new Configuration(), resource, policy);
+  public HadoopGroupResourceAuthorizationProvider(String resource, PolicyEngine policy,
+      Model model) throws IOException {
+    this(new Configuration(), resource, policy, model);
   }
 
-  public HadoopGroupResourceAuthorizationProvider(Configuration conf, String resource, PolicyEngine policy) throws IOException { //NOPMD
-    this(policy, new HadoopGroupMappingService(getGroups(conf)));
+  public HadoopGroupResourceAuthorizationProvider(Configuration conf, String resource, //NOPMD
+      PolicyEngine policy, Model model) throws IOException {
+    this(policy, new HadoopGroupMappingService(getGroups(conf)), model);
   }
 
   @VisibleForTesting
   public HadoopGroupResourceAuthorizationProvider(PolicyEngine policy,
-      GroupMappingService groupService) {
-    super(policy, groupService);
+      GroupMappingService groupService, Model model) {
+    super(policy, groupService, model);
   }
 
   private static Groups getGroups(Configuration conf) {

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackendContext.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackendContext.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackendContext.java
index ae674aa..4cf629b 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackendContext.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ProviderBackendContext.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sentry.provider.common;
 
-import org.apache.sentry.policy.common.PrivilegeValidator;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
index b023c9a..95b4b98 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/common/ResourceAuthorizationProvider.java
@@ -16,10 +16,10 @@
  */
 package org.apache.sentry.provider.common;
 
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_SPLITTER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.PRIVILEGE_NAME;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_SPLITTER;
+import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.PRIVILEGE_NAME;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -29,6 +29,7 @@ import java.util.Set;
 import org.apache.sentry.core.common.Action;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.core.common.SentryConfigurationException;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.policy.common.PolicyEngine;
@@ -58,12 +59,14 @@ public abstract class ResourceAuthorizationProvider implements AuthorizationProv
   private final GroupMappingService groupService;
   private final PolicyEngine policy;
   private final PrivilegeFactory privilegeFactory;
+  private final Model model;
 
   public ResourceAuthorizationProvider(PolicyEngine policy,
-      GroupMappingService groupService) {
+      GroupMappingService groupService, Model model) {
     this.policy = policy;
     this.groupService = groupService;
     this.privilegeFactory = policy.getPrivilegeFactory();
+    this.model = model;
   }
 
   /***
@@ -110,7 +113,7 @@ public abstract class ResourceAuthorizationProvider implements AuthorizationProv
         /*
          * Does the permission granted in the policy file imply the requested action?
          */
-        boolean result = permission.implies(privilegeFactory.createPrivilege(requestPrivilege));
+        boolean result = permission.implies(privilegeFactory.createPrivilege(requestPrivilege), model);
         if (LOGGER.isDebugEnabled()) {
           LOGGER.debug("ProviderPrivilege {}, RequestPrivilege {}, RoleSet, {}, Result {}",
               new Object[]{ permission, requestPrivilege, roleSet, result});

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/file/HadoopGroupResourceAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/file/HadoopGroupResourceAuthorizationProvider.java b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/file/HadoopGroupResourceAuthorizationProvider.java
index 8674700..2214867 100644
--- a/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/file/HadoopGroupResourceAuthorizationProvider.java
+++ b/sentry-provider/sentry-provider-common/src/main/java/org/apache/sentry/provider/file/HadoopGroupResourceAuthorizationProvider.java
@@ -20,6 +20,7 @@ package org.apache.sentry.provider.file;
 import java.io.IOException;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.GroupMappingService;
 
@@ -32,18 +33,19 @@ import com.google.common.annotations.VisibleForTesting;
 public class HadoopGroupResourceAuthorizationProvider extends
   org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider {
 
-  public HadoopGroupResourceAuthorizationProvider(String resource, PolicyEngine policy) throws IOException {
-    super(resource, policy);
+  public HadoopGroupResourceAuthorizationProvider(String resource, PolicyEngine policy, Model model) throws IOException {
+    super(resource, policy, model);
   }
 
-  public HadoopGroupResourceAuthorizationProvider(Configuration conf, String resource, PolicyEngine policy) throws IOException {
-    super(conf, resource, policy);
+  public HadoopGroupResourceAuthorizationProvider(Configuration conf, String resource,
+      PolicyEngine policy, Model model) throws IOException {
+    super(conf, resource, policy, model);
   }
 
   @VisibleForTesting
   public HadoopGroupResourceAuthorizationProvider(PolicyEngine policy,
-      GroupMappingService groupService) {
-    super(policy, groupService);
+      GroupMappingService groupService, Model model) {
+    super(policy, groupService, model);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java b/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
index 402574e..2b402a0 100644
--- a/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
+++ b/sentry-provider/sentry-provider-common/src/test/java/org/apache/sentry/provider/common/TestGetGroupMapping.java
@@ -35,7 +35,7 @@ public class TestGetGroupMapping {
   private static class TestResourceAuthorizationProvider extends ResourceAuthorizationProvider {
     public TestResourceAuthorizationProvider(PolicyEngine policy,
       GroupMappingService groupService) {
-      super(policy, groupService);
+      super(policy, groupService, null);
     }
   };
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/pom.xml b/sentry-provider/sentry-provider-db/pom.xml
index eb9de88..86e27e4 100644
--- a/sentry-provider/sentry-provider-db/pom.xml
+++ b/sentry-provider/sentry-provider-db/pom.xml
@@ -104,11 +104,7 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-search</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-kafka</artifactId>
+      <artifactId>sentry-policy-engine</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.hive</groupId>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeObject.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeObject.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeObject.java
index 3c00d23..0ac39f4 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeObject.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeObject.java
@@ -17,8 +17,8 @@
  */
 package org.apache.sentry.provider.db.generic.service.persistent;
 
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_JOINER;
 
 import java.util.List;
 import org.apache.sentry.core.common.Authorizable;

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
index 58be24d..19c8dd8 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/service/thrift/SentryGenericPolicyProcessor.java
@@ -17,8 +17,8 @@
  */
 package org.apache.sentry.provider.db.generic.service.thrift;
 
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
 
 import java.lang.reflect.Constructor;
 import java.util.HashSet;
@@ -29,9 +29,9 @@ import java.util.Set;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.SentryUserException;
 import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.model.db.AccessConstants;
-import org.apache.sentry.policy.common.KeyValue;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.KeyValue;
 import org.apache.sentry.provider.common.AuthorizationComponent;
 import org.apache.sentry.provider.db.SentryAccessDeniedException;
 import org.apache.sentry.provider.db.SentryAlreadyExistsException;
@@ -271,11 +271,11 @@ public class SentryGenericPolicyProcessor implements SentryGenericPolicyService.
 
       for (Authorizable authorizable : authorizables) {
 
-        privileges.add(PolicyConstants.KV_JOINER.join(authorizable.getTypeName(),
+        privileges.add(SentryConstants.KV_JOINER.join(authorizable.getTypeName(),
             authorizable.getName()));
       }
 
-      return PolicyConstants.AUTHORIZABLE_JOINER.join(privileges);
+      return SentryConstants.AUTHORIZABLE_JOINER.join(privileges);
     } else {
       return "";
     }
@@ -307,7 +307,7 @@ public class SentryGenericPolicyProcessor implements SentryGenericPolicyService.
       return authorizables;
     }
 
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
       KeyValue tempKV = new KeyValue(authorizable);
       final String key = tempKV.getKey();
       final String value = tempKV.getValue();

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java
index ca88c25..af73755 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/KafkaTSentryPrivilegeConvertor.java
@@ -19,12 +19,12 @@
 package org.apache.sentry.provider.db.generic.tools;
 
 import com.google.common.collect.Lists;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
 import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
-import org.apache.sentry.policy.common.KeyValue;
-import org.apache.sentry.policy.common.PolicyConstants;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.sentry.policy.kafka.KafkaModelAuthorizables;
-import org.apache.sentry.policy.kafka.KafkaPrivilegeValidator;
+import org.apache.sentry.core.model.kafka.KafkaModelAuthorizables;
+import org.apache.sentry.core.model.kafka.validator.KafkaPrivilegeValidator;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
@@ -48,7 +48,7 @@ public  class KafkaTSentryPrivilegeConvertor implements TSentryPrivilegeConverto
     validatePrivilegeHierarchy(privilegeStr);
     TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
     List<TAuthorizable> authorizables = new LinkedList<TAuthorizable>();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
       KeyValue keyValue = new KeyValue(authorizable);
       String key = keyValue.getKey();
       String value = keyValue.getValue();
@@ -84,23 +84,23 @@ public  class KafkaTSentryPrivilegeConvertor implements TSentryPrivilegeConverto
       if (it != null) {
         while (it.hasNext()) {
           TAuthorizable tAuthorizable = it.next();
-          privileges.add(PolicyConstants.KV_JOINER.join(
+          privileges.add(SentryConstants.KV_JOINER.join(
               tAuthorizable.getType(), tAuthorizable.getName()));
         }
       }
 
       if (!authorizables.isEmpty()) {
-        privileges.add(PolicyConstants.KV_JOINER.join(
+        privileges.add(SentryConstants.KV_JOINER.join(
             PolicyFileConstants.PRIVILEGE_ACTION_NAME, action));
       }
 
       // only append the grant option to privilege string if it's true
       if ("true".equals(grantOption)) {
-        privileges.add(PolicyConstants.KV_JOINER.join(
+        privileges.add(SentryConstants.KV_JOINER.join(
             PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
       }
     }
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(privileges);
+    return SentryConstants.AUTHORIZABLE_JOINER.join(privileges);
   }
 
   private static void validatePrivilegeHierarchy(String privilegeStr) throws Exception {

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryConfigToolSolr.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryConfigToolSolr.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryConfigToolSolr.java
index bf91f52..d25ce4b 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryConfigToolSolr.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SentryConfigToolSolr.java
@@ -27,9 +27,9 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.sentry.core.common.Action;
 import org.apache.sentry.core.common.SentryConfigurationException;
-import org.apache.sentry.policy.common.KeyValue;
-import org.apache.sentry.policy.common.PolicyConstants;
-import org.apache.sentry.policy.search.SimpleSearchPolicyEngine;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
 import org.apache.sentry.provider.common.ProviderBackend;
 import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
@@ -88,7 +88,7 @@ public class SentryConfigToolSolr extends SentryConfigToolCommon {
     SimpleFileProviderBackend policyFileBackend =
         new SimpleFileProviderBackend(conf, policyFile);
     ProviderBackendContext context = new ProviderBackendContext();
-    context.setValidators(SimpleSearchPolicyEngine.createPrivilegeValidators());
+    context.setValidators(SearchPrivilegeModel.getInstance().getPrivilegeValidators());
     policyFileBackend.initialize(context);
     if (validate) {
       validatePolicy(policyFileBackend);
@@ -123,7 +123,7 @@ public class SentryConfigToolSolr extends SentryConfigToolCommon {
           for (String permission : privileges) {
             String action = null;
 
-            for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.
+            for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.
                 trimResults().split(permission)) {
               KeyValue kv = new KeyValue(authorizable);
               String key = kv.getKey();

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SolrTSentryPrivilegeConvertor.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SolrTSentryPrivilegeConvertor.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SolrTSentryPrivilegeConvertor.java
index 8dffe94..12c833e 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SolrTSentryPrivilegeConvertor.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/generic/tools/SolrTSentryPrivilegeConvertor.java
@@ -20,14 +20,14 @@ package org.apache.sentry.provider.db.generic.tools;
 
 import com.google.common.collect.Lists;
 
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.model.search.Collection;
 import org.apache.sentry.core.model.search.SearchModelAuthorizable;
-import org.apache.sentry.policy.common.PolicyConstants;
-import org.apache.sentry.policy.common.PrivilegeValidator;
-import org.apache.sentry.policy.common.PrivilegeValidatorContext;
-import org.apache.sentry.policy.search.SearchModelAuthorizables;
-import org.apache.sentry.policy.search.SimpleSearchPolicyEngine;
-import org.apache.sentry.policy.common.KeyValue;
+import org.apache.sentry.core.common.validator.PrivilegeValidator;
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.search.SearchModelAuthorizables;
+import org.apache.sentry.core.model.search.SearchPrivilegeModel;
+import org.apache.sentry.core.common.utils.KeyValue;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.db.generic.service.thrift.TAuthorizable;
 import org.apache.sentry.provider.db.generic.service.thrift.TSentryGrantOption;
@@ -61,7 +61,7 @@ public  class SolrTSentryPrivilegeConvertor implements TSentryPrivilegeConvertor
 
     TSentryPrivilege tSentryPrivilege = new TSentryPrivilege();
     List<TAuthorizable> authorizables = new LinkedList<TAuthorizable>();
-    for (String authorizable : PolicyConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
+    for (String authorizable : SentryConstants.AUTHORIZABLE_SPLITTER.split(privilegeStr)) {
       KeyValue keyValue = new KeyValue(authorizable);
       String key = keyValue.getKey();
       String value = keyValue.getValue();
@@ -104,27 +104,27 @@ public  class SolrTSentryPrivilegeConvertor implements TSentryPrivilegeConvertor
       if (it != null) {
         while (it.hasNext()) {
           TAuthorizable tAuthorizable = it.next();
-          privileges.add(PolicyConstants.KV_JOINER.join(
+          privileges.add(SentryConstants.KV_JOINER.join(
               tAuthorizable.getType(), tAuthorizable.getName()));
         }
       }
 
       if (!authorizables.isEmpty()) {
-        privileges.add(PolicyConstants.KV_JOINER.join(
+        privileges.add(SentryConstants.KV_JOINER.join(
             PolicyFileConstants.PRIVILEGE_ACTION_NAME, action));
       }
 
       // only append the grant option to privilege string if it's true
       if ("true".equals(grantOption)) {
-        privileges.add(PolicyConstants.KV_JOINER.join(
+        privileges.add(SentryConstants.KV_JOINER.join(
             PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME, grantOption));
       }
     }
-    return PolicyConstants.AUTHORIZABLE_JOINER.join(privileges);
+    return SentryConstants.AUTHORIZABLE_JOINER.join(privileges);
   }
 
   private static void validatePrivilegeHierarchy(String privilegeStr) throws Exception {
-    List<PrivilegeValidator> validators = SimpleSearchPolicyEngine.createPrivilegeValidators();
+    List<PrivilegeValidator> validators = SearchPrivilegeModel.getInstance().getPrivilegeValidators();
     PrivilegeValidatorContext context = new PrivilegeValidatorContext(null, privilegeStr);
     for (PrivilegeValidator validator : validators) {
       try {

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
----------------------------------------------------------------------
diff --git a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
index 13b48ea..59161f0 100644
--- a/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
+++ b/sentry-provider/sentry-provider-db/src/main/java/org/apache/sentry/provider/db/service/model/MSentryGMPrivilege.java
@@ -17,8 +17,8 @@ vim  * Licensed to the Apache Software Foundation (ASF) under one
  */
 package org.apache.sentry.provider.db.service.model;
 
-import static org.apache.sentry.policy.common.PolicyConstants.AUTHORIZABLE_JOINER;
-import static org.apache.sentry.policy.common.PolicyConstants.KV_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
 
 import java.lang.reflect.Field;
 import java.util.HashSet;


[12/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/SENTRY-999.001.patch
----------------------------------------------------------------------
diff --git a/SENTRY-999.001.patch b/SENTRY-999.001.patch
new file mode 100644
index 0000000..865a343
--- /dev/null
+++ b/SENTRY-999.001.patch
@@ -0,0 +1,18685 @@
+diff --git a/pom.xml b/pom.xml
+index e288593..914f436 100644
+--- a/pom.xml
++++ b/pom.xml
+@@ -475,7 +475,7 @@ limitations under the License.
+       </dependency>
+       <dependency>
+         <groupId>org.apache.sentry</groupId>
+-        <artifactId>sentry-policy-db</artifactId>
++        <artifactId>sentry-policy-engine</artifactId>
+         <version>${project.version}</version>
+       </dependency>
+       <dependency>
+@@ -485,21 +485,6 @@ limitations under the License.
+       </dependency>
+       <dependency>
+         <groupId>org.apache.sentry</groupId>
+-        <artifactId>sentry-policy-search</artifactId>
+-        <version>${project.version}</version>
+-      </dependency>
+-      <dependency>
+-        <groupId>org.apache.sentry</groupId>
+-        <artifactId>sentry-policy-sqoop</artifactId>
+-        <version>${project.version}</version>
+-      </dependency>
+-      <dependency>
+-        <groupId>org.apache.sentry</groupId>
+-        <artifactId>sentry-policy-kafka</artifactId>
+-        <version>${project.version}</version>
+-      </dependency>
+-      <dependency>
+-        <groupId>org.apache.sentry</groupId>
+         <artifactId>sentry-dist</artifactId>
+         <version>${project.version}</version>
+       </dependency>
+diff --git a/sentry-binding/sentry-binding-hive-common/pom.xml b/sentry-binding/sentry-binding-hive-common/pom.xml
+index 5f00dd2..18b422d 100644
+--- a/sentry-binding/sentry-binding-hive-common/pom.xml
++++ b/sentry-binding/sentry-binding-hive-common/pom.xml
+@@ -71,10 +71,6 @@ limitations under the License.
+       <dependency>
+         <groupId>org.apache.sentry</groupId>
+         <artifactId>sentry-provider-cache</artifactId>
+-      </dependency>
+-    <dependency>
+-      <groupId>org.apache.sentry</groupId>
+-      <artifactId>sentry-policy-db</artifactId>
+     </dependency>
+     <dependency>
+       <groupId>org.apache.hadoop</groupId>
+diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
+index 630bef3..06fe1fe 100644
+--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
++++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
+@@ -24,7 +24,7 @@ import java.util.Map;
+ import java.util.Set;
+ 
+ import org.apache.hadoop.conf.Configuration;
+-import org.apache.sentry.policy.common.PolicyConstants;
++import org.apache.sentry.core.common.utils.SentryConstants;
+ import org.apache.sentry.provider.common.PolicyFileConstants;
+ import org.apache.sentry.provider.common.ProviderBackendContext;
+ import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+@@ -152,8 +152,8 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
+     List<String> lines = Lists.newArrayList();
+     lines.add("[" + name + "]");
+     for (Map.Entry<String, Set<String>> entry : mappingData.entrySet()) {
+-      lines.add(PolicyConstants.KV_JOINER.join(entry.getKey(),
+-          PolicyConstants.ROLE_JOINER.join(entry.getValue())));
++      lines.add(SentryConstants.KV_JOINER.join(entry.getKey(),
++          SentryConstants.ROLE_JOINER.join(entry.getValue())));
+     }
+     return Joiner.on(NL).join(lines);
+   }
+diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
+index 0a1d0e8..775a1f5 100644
+--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
++++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
+@@ -34,11 +34,13 @@ import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+ import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
+ import org.apache.sentry.binding.hive.conf.InvalidConfigurationException;
+ import org.apache.sentry.core.common.ActiveRoleSet;
++import org.apache.sentry.core.common.Model;
+ import org.apache.sentry.core.common.Subject;
+ import org.apache.sentry.core.model.db.AccessConstants;
+ import org.apache.sentry.core.model.db.DBModelAction;
+ import org.apache.sentry.core.model.db.DBModelAuthorizable;
+ import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
++import org.apache.sentry.core.model.db.HivePrivilegeModel;
+ import org.apache.sentry.core.model.db.Server;
+ import org.apache.sentry.policy.common.PolicyEngine;
+ import org.apache.sentry.provider.cache.PrivilegeCache;
+@@ -60,6 +62,7 @@ public class HiveAuthzBinding {
+   private static final Splitter ROLE_SET_SPLITTER = Splitter.on(",").trimResults()
+       .omitEmptyStrings();
+   public static final String HIVE_BINDING_TAG = "hive.authz.bindings.tag";
++  public static final String HIVE_POLICY_ENGINE_OLD = "org.apache.sentry.policy.db.SimpleDBPolicyEngine";
+ 
+   private final HiveConf hiveConf;
+   private final Server authServer;
+@@ -206,6 +209,11 @@ public class HiveAuthzBinding {
+     String providerBackendName = authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar());
+     String policyEngineName = authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar());
+ 
++    // for the backward compatibility
++    if (HIVE_POLICY_ENGINE_OLD.equals(policyEngineName)) {
++      policyEngineName = AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault();
++    }
++
+     LOG.debug("Using authorization provider " + authProviderName +
+         " with resource " + resourceName + ", policy engine "
+         + policyEngineName + ", provider backend " + providerBackendName);
+@@ -216,19 +224,28 @@ public class HiveAuthzBinding {
+     ProviderBackend providerBackend = (ProviderBackend) providerBackendConstructor.
+         newInstance(new Object[] {authzConf, resourceName});
+ 
++    // create backendContext
++    ProviderBackendContext context = new ProviderBackendContext();
++    context.setAllowPerDatabase(true);
++    context.setValidators(HivePrivilegeModel.getInstance().getPrivilegeValidators(serverName));
++    // initialize the backend with the context
++    providerBackend.initialize(context);
++
++
+     // load the policy engine class
+     Constructor<?> policyConstructor =
+-      Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
++      Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
+     policyConstructor.setAccessible(true);
+     PolicyEngine policyEngine = (PolicyEngine) policyConstructor.
+-        newInstance(new Object[] {serverName, providerBackend});
++        newInstance(new Object[] {providerBackend});
+ 
+ 
+     // load the authz provider class
+     Constructor<?> constrctor =
+-      Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class);
++      Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class, Model.class);
+     constrctor.setAccessible(true);
+-    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine});
++    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine,
++            HivePrivilegeModel.getInstance()});
+   }
+ 
+   // Instantiate the authz provider using PrivilegeCache, this method is used for metadata filter function.
+@@ -238,7 +255,13 @@ public class HiveAuthzBinding {
+     String authProviderName = authzConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar());
+     String resourceName =
+             authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar());
+-    String policyEngineName = authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar());
++    String policyEngineName = authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(),
++            AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
++
++    // for the backward compatibility
++    if (HIVE_POLICY_ENGINE_OLD.equals(policyEngineName)) {
++      policyEngineName = AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault();
++    }
+ 
+     LOG.debug("Using authorization provider " + authProviderName +
+             " with resource " + resourceName + ", policy engine "
+@@ -251,19 +274,19 @@ public class HiveAuthzBinding {
+ 
+     // load the policy engine class
+     Constructor<?> policyConstructor =
+-            Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
++            Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
+     policyConstructor.setAccessible(true);
+     PolicyEngine policyEngine = (PolicyEngine) policyConstructor.
+-            newInstance(new Object[] {serverName, providerBackend});
++            newInstance(new Object[] {providerBackend});
+ 
+     // load the authz provider class
+     Constructor<?> constrctor =
+-            Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class);
++            Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class, Model.class);
+     constrctor.setAccessible(true);
+-    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine});
++    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine,
++            HivePrivilegeModel.getInstance()});
+   }
+ 
+-
+   /**
+    * Validate the privilege for the given operation for the given subject
+    * @param hiveOp
+diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
+index 5a89af2..ad19b37 100644
+--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
++++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
+@@ -92,7 +92,7 @@ public class HiveAuthzConf extends Configuration {
+       "org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"),
+     AUTHZ_PROVIDER_RESOURCE("sentry.hive.provider.resource", ""),
+     AUTHZ_PROVIDER_BACKEND("sentry.hive.provider.backend", "org.apache.sentry.provider.file.SimpleFileProviderBackend"),
+-    AUTHZ_POLICY_ENGINE("sentry.hive.policy.engine", "org.apache.sentry.policy.db.SimpleDBPolicyEngine"),
++    AUTHZ_POLICY_ENGINE("sentry.hive.policy.engine", "org.apache.sentry.policy.engine.common.CommonPolicyEngine"),
+     AUTHZ_POLICY_FILE_FORMATTER(
+         "sentry.hive.policy.file.formatter",
+         "org.apache.sentry.binding.hive.SentryIniPolicyFileFormatter"),
+diff --git a/sentry-binding/sentry-binding-hive/pom.xml b/sentry-binding/sentry-binding-hive/pom.xml
+index b769488..07aaae3 100644
+--- a/sentry-binding/sentry-binding-hive/pom.xml
++++ b/sentry-binding/sentry-binding-hive/pom.xml
+@@ -70,6 +70,31 @@ limitations under the License.
+       <artifactId>sentry-binding-hive-common</artifactId>
+     </dependency>
+     <dependency>
++      <groupId>org.apache.sentry</groupId>
++      <artifactId>sentry-core-common</artifactId>
++    </dependency>
++    <dependency>
++      <groupId>org.apache.sentry</groupId>
++      <artifactId>sentry-core-model-db</artifactId>
++    </dependency>
++    <dependency>
++      <groupId>org.apache.sentry</groupId>
++      <artifactId>sentry-provider-common</artifactId>
++    </dependency>
++    <!-- required for SentryGrantRevokeTask -->
++    <dependency>
++      <groupId>org.apache.sentry</groupId>
++      <artifactId>sentry-provider-db</artifactId>
++    </dependency>
++    <dependency>
++      <groupId>org.apache.sentry</groupId>
++      <artifactId>sentry-provider-file</artifactId>
++    </dependency>
++      <dependency>
++        <groupId>org.apache.sentry</groupId>
++        <artifactId>sentry-provider-cache</artifactId>
++      </dependency>
++    <dependency>
+       <groupId>org.apache.hadoop</groupId>
+       <artifactId>hadoop-common</artifactId>
+       <scope>provided</scope>
+@@ -90,6 +115,11 @@ limitations under the License.
+       <groupId>org.apache.sentry</groupId>
+       <artifactId>sentry-provider-db</artifactId>
+     </dependency>
++    <dependency>
++      <groupId>org.apache.hadoop</groupId>
++      <artifactId>hadoop-minicluster</artifactId>
++      <scope>test</scope>
++    </dependency>
+   </dependencies>
+ 
+ </project>
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
+index 2bfc339..0e7ee3d 100644
+--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
+@@ -25,7 +25,7 @@ import java.util.Map;
+ import java.util.Set;
+ 
+ import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+-import org.apache.sentry.policy.common.PolicyConstants;
++import org.apache.sentry.core.common.utils.SentryConstants;
+ import org.apache.sentry.provider.common.PolicyFileConstants;
+ import org.junit.Test;
+ 
+@@ -208,8 +208,8 @@ public class TestSentryIniPolicyFileFormatter {
+       for (String actualPrivilege : actualPrivileges) {
+         boolean isFound = exceptedPrivileges.contains(actualPrivilege);
+         if (!isFound) {
+-          String withOptionPrivilege = PolicyConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
+-              PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
++          String withOptionPrivilege = SentryConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
++              SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
+                   "false"));
+           isFound = exceptedPrivileges.contains(withOptionPrivilege);
+         }
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java
+new file mode 100644
+index 0000000..df8443c
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java
+@@ -0,0 +1,156 @@
++/*
++ * 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.sentry.policy.hive;
++
++import java.io.File;
++import java.io.IOException;
++import java.util.Set;
++import java.util.TreeSet;
++
++import org.junit.Assert;
++
++import org.apache.commons.io.FileUtils;
++import org.apache.sentry.core.common.ActiveRoleSet;
++import org.apache.sentry.policy.common.PolicyEngine;
++import org.junit.After;
++import org.junit.AfterClass;
++import org.junit.Before;
++import org.junit.BeforeClass;
++import org.junit.Test;
++
++import com.google.common.collect.Sets;
++import com.google.common.io.Files;
++
++public abstract class AbstractTestSimplePolicyEngine {
++  private static final String PERM_SERVER1_CUSTOMERS_SELECT = "server=server1->db=customers->table=purchases->action=select";
++  private static final String PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT = "server=server1->db=customers->table=purchases_partial->action=select";
++  private static final String PERM_SERVER1_ANALYST_ALL = "server=server1->db=analyst1";
++  private static final String PERM_SERVER1_JUNIOR_ANALYST_ALL = "server=server1->db=jranalyst1";
++  private static final String PERM_SERVER1_JUNIOR_ANALYST_READ = "server=server1->db=jranalyst1->table=*->action=select";
++  private static final String PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT = "server=server1->db=other_group_db->table=purchases->action=select";
++
++  private static final String PERM_SERVER1_ADMIN = "server=server1";
++  private PolicyEngine policy;
++  private static File baseDir;
++
++  @BeforeClass
++  public static void setupClazz() throws IOException {
++    baseDir = Files.createTempDir();
++  }
++
++  @AfterClass
++  public static void teardownClazz() throws IOException {
++    if(baseDir != null) {
++      FileUtils.deleteQuietly(baseDir);
++    }
++  }
++
++  protected void setPolicy(PolicyEngine policy) {
++    this.policy = policy;
++  }
++  protected static File getBaseDir() {
++    return baseDir;
++  }
++  @Before
++  public void setup() throws IOException {
++    afterSetup();
++  }
++  @After
++  public void teardown() throws IOException {
++    beforeTeardown();
++  }
++  protected void afterSetup() throws IOException {
++
++  }
++
++  protected void beforeTeardown() throws IOException {
++
++  }
++
++  @Test
++  public void testManager() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
++        PERM_SERVER1_CUSTOMERS_SELECT, PERM_SERVER1_ANALYST_ALL,
++        PERM_SERVER1_JUNIOR_ANALYST_ALL, PERM_SERVER1_JUNIOR_ANALYST_READ,
++        PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT
++        ));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("manager"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++  @Test
++  public void testAnalyst() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
++        PERM_SERVER1_CUSTOMERS_SELECT, PERM_SERVER1_ANALYST_ALL,
++        PERM_SERVER1_JUNIOR_ANALYST_READ));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("analyst"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++  @Test
++  public void testJuniorAnalyst() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets
++        .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
++            PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++  @Test
++  public void testAdmin() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PERM_SERVER1_ADMIN));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("admin"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++
++  @Test
++  public void testOtherGroup() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
++        PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("other_group"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++  @Test
++  public void testDbAll() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets
++        .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
++            PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++  @Test
++  public void testDbAllforOtherGroup() throws Exception {
++    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
++        PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
++    Assert.assertEquals(expected.toString(),
++        new TreeSet<String>(policy.getAllPrivileges(set("other_group"), ActiveRoleSet.ALL))
++        .toString());
++  }
++
++  private static Set<String> set(String... values) {
++    return Sets.newHashSet(values);
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java
+new file mode 100644
+index 0000000..854acbe
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java
+@@ -0,0 +1,45 @@
++/*
++ * 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.sentry.policy.hive;
++
++import org.apache.hadoop.conf.Configuration;
++import org.apache.sentry.core.model.db.HivePrivilegeModel;
++import org.apache.sentry.policy.common.PolicyEngine;
++import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
++import org.apache.sentry.provider.common.ProviderBackend;
++import org.apache.sentry.provider.common.ProviderBackendContext;
++import org.apache.sentry.provider.file.SimpleFileProviderBackend;
++
++import java.io.IOException;
++
++public class DBPolicyTestUtil {
++
++  public static PolicyEngine createPolicyEngineForTest(String server, String resource) throws IOException {
++
++    ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource);
++
++    // create backendContext
++    ProviderBackendContext context = new ProviderBackendContext();
++    context.setAllowPerDatabase(true);
++    context.setValidators(HivePrivilegeModel.getInstance().getPrivilegeValidators(server));
++    // initialize the backend with the context
++    providerBackend.initialize(context);
++
++
++    return new CommonPolicyEngine(providerBackend);
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java
+new file mode 100644
+index 0000000..fba2e1c
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java
+@@ -0,0 +1,77 @@
++/*
++ * 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.sentry.policy.hive;
++import static junit.framework.Assert.assertEquals;
++import static junit.framework.Assert.assertNull;
++
++import org.apache.sentry.core.model.db.AccessURI;
++import org.apache.sentry.core.model.db.DBModelAuthorizables;
++import org.apache.sentry.core.model.db.Database;
++import org.apache.sentry.core.model.db.Server;
++import org.apache.sentry.core.model.db.Table;
++import org.apache.sentry.core.model.db.View;
++import org.junit.Test;
++
++public class TestDBModelAuthorizables {
++
++  @Test
++  public void testServer() throws Exception {
++    Server server = (Server) DBModelAuthorizables.from("SeRvEr=server1");
++    assertEquals("server1", server.getName());
++  }
++  @Test
++  public void testDb() throws Exception {
++    Database db = (Database)DBModelAuthorizables.from("dB=db1");
++    assertEquals("db1", db.getName());
++  }
++  @Test
++  public void testTable() throws Exception {
++    Table table = (Table)DBModelAuthorizables.from("tAbLe=t1");
++    assertEquals("t1", table.getName());
++  }
++  @Test
++  public void testView() throws Exception {
++    View view = (View)DBModelAuthorizables.from("vIeW=v1");
++    assertEquals("v1", view.getName());
++  }
++  @Test
++  public void testURI() throws Exception {
++    AccessURI uri = (AccessURI)DBModelAuthorizables.from("UrI=hdfs://uri1:8200/blah");
++    assertEquals("hdfs://uri1:8200/blah", uri.getName());
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testNoKV() throws Exception {
++    System.out.println(DBModelAuthorizables.from("nonsense"));
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testEmptyKey() throws Exception {
++    System.out.println(DBModelAuthorizables.from("=v"));
++  }
++  @Test(expected=IllegalArgumentException.class)
++  public void testEmptyValue() throws Exception {
++    System.out.println(DBModelAuthorizables.from("k="));
++  }
++  @Test
++  public void testNotAuthorizable() throws Exception {
++    assertNull(DBModelAuthorizables.from("k=v"));
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java
+new file mode 100644
+index 0000000..24f3ae9
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java
+@@ -0,0 +1,50 @@
++/*
++ * 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.sentry.policy.hive;
++
++import org.junit.Assert;
++
++import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
++import org.apache.sentry.core.model.db.validator.DatabaseRequiredInPrivilege;
++import org.apache.shiro.config.ConfigurationException;
++import org.junit.Test;
++
++public class TestDatabaseRequiredInRole {
++
++  @Test
++  public void testURIInPerDbPolicyFile() throws Exception {
++    DatabaseRequiredInPrivilege dbRequiredInRole = new DatabaseRequiredInPrivilege();
++    System.setProperty("sentry.allow.uri.db.policyfile", "true");
++    dbRequiredInRole.validate(new PrivilegeValidatorContext("db1",
++      "server=server1->URI=file:///user/db/warehouse/tab1"));
++    System.setProperty("sentry.allow.uri.db.policyfile", "false");
++  }
++
++  @Test
++  public void testURIWithDBInPerDbPolicyFile() throws Exception {
++    DatabaseRequiredInPrivilege dbRequiredInRole = new DatabaseRequiredInPrivilege();
++    try {
++      dbRequiredInRole.validate(new PrivilegeValidatorContext("db1",
++        "server=server1->db=db1->URI=file:///user/db/warehouse/tab1"));
++      Assert.fail("Expected ConfigurationException");
++    } catch (ConfigurationException e) {
++      // expected
++    }
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java
+new file mode 100644
+index 0000000..4dc8812
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java
+@@ -0,0 +1,194 @@
++/*
++ * 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.sentry.policy.hive;
++
++import java.io.File;
++import java.io.IOException;
++
++import org.junit.Assert;
++
++import org.apache.commons.io.FileUtils;
++import org.apache.sentry.core.common.ActiveRoleSet;
++import org.apache.sentry.policy.common.PolicyEngine;
++import org.apache.sentry.provider.file.PolicyFile;
++import org.junit.After;
++import org.junit.Before;
++import org.junit.Test;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++import com.google.common.base.Charsets;
++import com.google.common.collect.ImmutableSet;
++import com.google.common.collect.Sets;
++import com.google.common.io.Files;
++
++public class TestPolicyParsingNegative {
++
++  @SuppressWarnings("unused")
++  private static final Logger LOGGER = LoggerFactory
++      .getLogger(TestPolicyParsingNegative.class);
++
++  private File baseDir;
++  private File globalPolicyFile;
++  private File otherPolicyFile;
++
++  @Before
++  public void setup() {
++    baseDir = Files.createTempDir();
++    globalPolicyFile = new File(baseDir, "global.ini");
++    otherPolicyFile = new File(baseDir, "other.ini");
++  }
++
++  @After
++  public void teardown() {
++    if(baseDir != null) {
++      FileUtils.deleteQuietly(baseDir);
++    }
++  }
++
++  private void append(String from, File to) throws IOException {
++    Files.append(from + "\n", to, Charsets.UTF_8);
++  }
++
++  @Test
++  public void testUnauthorizedDbSpecifiedInDBPolicyFile() throws Exception {
++    append("[databases]", globalPolicyFile);
++    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
++    append("[groups]", otherPolicyFile);
++    append("other_group = malicious_role", otherPolicyFile);
++    append("[roles]", otherPolicyFile);
++    append("malicious_role = server=server1->db=customers->table=purchases->action=select", otherPolicyFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
++    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
++  }
++  @Test
++  public void testPerDbFileCannotContainUsersOrDatabases() throws Exception {
++    PolicyEngine policy;
++    ImmutableSet<String> permissions;
++    PolicyFile policyFile;
++    // test sanity
++    policyFile = PolicyFile.setAdminOnServer1("admin");
++    policyFile.addGroupsToUser("admin1", "admin");
++    policyFile.write(globalPolicyFile);
++    policyFile.write(otherPolicyFile);
++    policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
++    Assert.assertEquals(permissions.toString(), "[server=server1]");
++    // test to ensure [users] fails parsing of per-db file
++    policyFile.addDatabase("other", otherPolicyFile.getPath());
++    policyFile.write(globalPolicyFile);
++    policyFile.write(otherPolicyFile);
++    policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
++    Assert.assertEquals(permissions.toString(), "[server=server1]");
++    // test to ensure [databases] fails parsing of per-db file
++    // by removing the user mapping from the per-db policy file
++    policyFile.removeGroupsFromUser("admin1", "admin")
++      .write(otherPolicyFile);
++    policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
++    Assert.assertEquals(permissions.toString(), "[server=server1]");
++  }
++
++  @Test
++  public void testDatabaseRequiredInRole() throws Exception {
++    append("[databases]", globalPolicyFile);
++    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
++    append("[groups]", otherPolicyFile);
++    append("other_group = malicious_role", otherPolicyFile);
++    append("[roles]", otherPolicyFile);
++    append("malicious_role = server=server1", otherPolicyFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
++    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
++  }
++
++  @Test
++  public void testServerAll() throws Exception {
++    append("[groups]", globalPolicyFile);
++    append("group = malicious_role", globalPolicyFile);
++    append("[roles]", globalPolicyFile);
++    append("malicious_role = server=*", globalPolicyFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
++    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
++  }
++
++  @Test
++  public void testServerIncorrect() throws Exception {
++    append("[groups]", globalPolicyFile);
++    append("group = malicious_role", globalPolicyFile);
++    append("[roles]", globalPolicyFile);
++    append("malicious_role = server=server2", globalPolicyFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
++    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
++  }
++
++  @Test
++  public void testAll() throws Exception {
++    append("[groups]", globalPolicyFile);
++    append("group = malicious_role", globalPolicyFile);
++    append("[roles]", globalPolicyFile);
++    append("malicious_role = *", globalPolicyFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
++    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
++  }
++
++  /**
++   * Create policy file with multiple per db files.
++   * Verify that a file with bad format is the only one that's ignored
++   * @throws Exception
++   */
++  @Test
++  public void testMultiDbWithErrors() throws Exception {
++    File db1PolicyFile = new File(baseDir, "db1.ini");
++    File db2PolicyFile = new File(baseDir, "db2.ini");
++
++    // global policy file
++    append("[databases]", globalPolicyFile);
++    append("db1 = " + db1PolicyFile.getPath(), globalPolicyFile);
++    append("db2 = " + db2PolicyFile.getPath(), globalPolicyFile);
++    append("[groups]", globalPolicyFile);
++    append("db3_group = db3_rule", globalPolicyFile);
++    append("[roles]", globalPolicyFile);
++    append("db3_rule = server=server1->db=db3->table=sales->action=select", globalPolicyFile);
++
++    //db1 policy file with badly formatted rule
++    append("[groups]", db1PolicyFile);
++    append("db1_group = bad_rule", db1PolicyFile);
++    append("[roles]", db1PolicyFile);
++    append("bad_rule = server=server1->db=customers->=purchases->action=", db1PolicyFile);
++
++    //db2 policy file with proper rule
++    append("[groups]", db2PolicyFile);
++    append("db2_group = db2_rule", db2PolicyFile);
++    append("[roles]", db2PolicyFile);
++    append("db2_rule = server=server1->db=db2->table=purchases->action=select", db2PolicyFile);
++
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++
++    // verify that the db1 rule is empty
++    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("db1_group"), ActiveRoleSet.ALL);
++    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
++
++    permissions = policy.getAllPrivileges(Sets.newHashSet("db2_group"), ActiveRoleSet.ALL);
++    Assert.assertEquals(permissions.toString(), 1, permissions.size());
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java
+new file mode 100644
+index 0000000..403eb6a
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java
+@@ -0,0 +1,195 @@
++/*
++ * 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.sentry.policy.hive;
++
++import java.io.File;
++import java.io.IOException;
++import java.util.Arrays;
++import java.util.EnumSet;
++import java.util.List;
++import java.util.Set;
++
++import com.google.common.collect.Sets;
++import junit.framework.Assert;
++
++import org.apache.commons.io.FileUtils;
++import org.apache.sentry.core.common.Action;
++import org.apache.sentry.core.common.ActiveRoleSet;
++import org.apache.sentry.core.common.Authorizable;
++import org.apache.sentry.core.common.Subject;
++import org.apache.sentry.core.model.db.AccessConstants;
++import org.apache.sentry.core.model.db.DBModelAction;
++import org.apache.sentry.core.model.db.Database;
++import org.apache.sentry.core.model.db.HivePrivilegeModel;
++import org.apache.sentry.core.model.db.Server;
++import org.apache.sentry.core.model.db.Table;
++import org.apache.sentry.provider.common.GroupMappingService;
++import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
++import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider;
++import org.apache.sentry.provider.file.PolicyFiles;
++import org.junit.After;
++import org.junit.Test;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++import com.google.common.base.Objects;
++import com.google.common.collect.HashMultimap;
++import com.google.common.collect.Multimap;
++import com.google.common.io.Files;
++
++
++public class TestResourceAuthorizationProviderGeneralCases {
++
++  private static final Logger LOGGER = LoggerFactory
++      .getLogger(TestResourceAuthorizationProviderGeneralCases.class);
++
++  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap
++      .create();
++
++  private static final Subject SUB_ADMIN = new Subject("admin1");
++  private static final Subject SUB_MANAGER = new Subject("manager1");
++  private static final Subject SUB_ANALYST = new Subject("analyst1");
++  private static final Subject SUB_JUNIOR_ANALYST = new Subject("jranalyst1");
++
++  private static final Server SVR_SERVER1 = new Server("server1");
++  private static final Server SVR_ALL = new Server(AccessConstants.ALL);
++
++  private static final Database DB_CUSTOMERS = new Database("customers");
++  private static final Database DB_ANALYST = new Database("analyst1");
++  private static final Database DB_JR_ANALYST = new Database("jranalyst1");
++
++  private static final Table TBL_PURCHASES = new Table("purchases");
++
++  private static final Set<? extends Action> ALL = EnumSet.of(DBModelAction.ALL);
++  private static final Set<? extends Action> SELECT = EnumSet.of(DBModelAction.SELECT);
++  private static final Set<? extends Action> INSERT = EnumSet.of(DBModelAction.INSERT);
++
++  static {
++    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList("admin"));
++    USER_TO_GROUP_MAP.putAll(SUB_MANAGER.getName(), Arrays.asList("manager"));
++    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList("analyst"));
++    USER_TO_GROUP_MAP.putAll(SUB_JUNIOR_ANALYST.getName(),
++        Arrays.asList("jranalyst"));
++  }
++
++  private final ResourceAuthorizationProvider authzProvider;
++  private File baseDir;
++
++  public TestResourceAuthorizationProviderGeneralCases() throws IOException {
++    baseDir = Files.createTempDir();
++    PolicyFiles.copyToDir(baseDir, "hive-policy-test-authz-provider.ini", "hive-policy-test-authz-provider-other-group.ini");
++    authzProvider = new HadoopGroupResourceAuthorizationProvider(
++            DBPolicyTestUtil.createPolicyEngineForTest("server1",
++        new File(baseDir, "hive-policy-test-authz-provider.ini").getPath()),
++        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), HivePrivilegeModel.getInstance());
++
++  }
++
++  @After
++  public void teardown() {
++    if(baseDir != null) {
++      FileUtils.deleteQuietly(baseDir);
++    }
++  }
++
++  private void doTestAuthorizables(
++      Subject subject, Set<? extends Action> privileges, boolean expected,
++      Authorizable... authorizables) throws Exception {
++    List<Authorizable> authzHierarchy = Arrays.asList(authorizables);
++    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
++      helper.add("authorizables", authzHierarchy).add("Privileges", privileges);
++    LOGGER.info("Running with " + helper.toString());
++    Assert.assertEquals(helper.toString(), expected,
++        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
++    LOGGER.info("Passed " + helper.toString());
++  }
++
++  private void doTestResourceAuthorizationProvider(Subject subject,
++      Server server, Database database, Table table,
++      Set<? extends Action> privileges, boolean expected) throws Exception {
++    List<Authorizable> authzHierarchy = Arrays.asList(new Authorizable[] {
++        server, database, table
++    });
++    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
++    helper.add("Subject", subject).add("Server", server).add("DB", database)
++    .add("Table", table).add("Privileges", privileges).add("authzHierarchy", authzHierarchy);
++    LOGGER.info("Running with " + helper.toString());
++    Assert.assertEquals(helper.toString(), expected,
++        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
++    LOGGER.info("Passed " + helper.toString());
++  }
++
++  @Test
++  public void testAdmin() throws Exception {
++    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, true);
++    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
++    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, true);
++    doTestAuthorizables(SUB_ADMIN, SELECT, true, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES);
++
++  }
++  @Test
++  public void testManager() throws Exception {
++    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
++    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
++    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
++    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
++  }
++  @Test
++  public void testAnalyst() throws Exception {
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
++
++    // analyst sandbox
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, ALL, true);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, SELECT, true);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, INSERT, true);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_ANALYST, TBL_PURCHASES, SELECT, true);
++
++    // jr analyst sandbox
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, ALL, false);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, INSERT, false);
++    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
++  }
++  @Test
++  public void testJuniorAnalyst() throws Exception {
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, false);
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, false);
++    // jr analyst sandbox
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, ALL, true);
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, INSERT, true);
++    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_ALL, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
++  }
++
++  public class MockGroupMappingServiceProvider implements GroupMappingService {
++    private final Multimap<String, String> userToGroupMap;
++
++    public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
++      this.userToGroupMap = userToGroupMap;
++    }
++
++    @Override
++    public Set<String> getGroups(String user) {
++      return Sets.newHashSet(userToGroupMap.get(user));
++    }
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java
+new file mode 100644
+index 0000000..6fe9e6b
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java
+@@ -0,0 +1,124 @@
++ /*
++ * 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.sentry.policy.hive;
++
++import java.io.File;
++import java.io.IOException;
++import java.util.EnumSet;
++import java.util.List;
++import java.util.Set;
++
++import org.junit.Assert;
++
++import org.apache.commons.io.FileUtils;
++import org.apache.sentry.core.common.Action;
++import org.apache.sentry.core.common.ActiveRoleSet;
++import org.apache.sentry.core.common.Authorizable;
++import org.apache.sentry.core.common.Subject;
++import org.apache.sentry.core.model.db.AccessURI;
++import org.apache.sentry.core.model.db.DBModelAction;
++import org.apache.sentry.core.model.db.HivePrivilegeModel;
++import org.apache.sentry.core.model.db.Server;
++import org.apache.sentry.policy.common.PolicyEngine;
++import org.apache.sentry.provider.common.AuthorizationProvider;
++import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
++import org.apache.sentry.provider.file.PolicyFile;
++import org.junit.After;
++import org.junit.Before;
++import org.junit.Test;
++
++import com.google.common.collect.ImmutableList;
++import com.google.common.io.Files;
++
++public class TestResourceAuthorizationProviderSpecialCases {
++  private AuthorizationProvider authzProvider;
++  private PolicyFile policyFile;
++  private File baseDir;
++  private File iniFile;
++  private String initResource;
++  @Before
++  public void setup() throws IOException {
++    baseDir = Files.createTempDir();
++    iniFile = new File(baseDir, "policy.ini");
++    initResource = "file://" + iniFile.getPath();
++    policyFile = new PolicyFile();
++  }
++
++  @After
++  public void teardown() throws IOException {
++    if(baseDir != null) {
++      FileUtils.deleteQuietly(baseDir);
++    }
++  }
++
++  @Test
++  public void testDuplicateEntries() throws Exception {
++    Subject user1 = new Subject("user1");
++    Server server1 = new Server("server1");
++    AccessURI uri = new AccessURI("file:///path/to/");
++    Set<? extends Action> actions = EnumSet.of(DBModelAction.ALL, DBModelAction.SELECT, DBModelAction.INSERT);
++    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
++      .addRolesToGroup("group1",  true, "role1", "role1")
++      .addPermissionsToRole("role1", true, "server=" + server1.getName() + "->uri=" + uri.getName(),
++          "server=" + server1.getName() + "->uri=" + uri.getName());
++    policyFile.write(iniFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest(server1.getName(), initResource);
++    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, HivePrivilegeModel.getInstance());
++    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, uri);
++    Assert.assertTrue(authorizableHierarchy.toString(),
++        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
++  }
++  @Test
++  public void testNonAbolutePath() throws Exception {
++    Subject user1 = new Subject("user1");
++    Server server1 = new Server("server1");
++    AccessURI uri = new AccessURI("file:///path/to/");
++    Set<? extends Action> actions = EnumSet.of(DBModelAction.ALL, DBModelAction.SELECT, DBModelAction.INSERT);
++    policyFile.addGroupsToUser(user1.getName(), "group1")
++      .addRolesToGroup("group1", "role1")
++      .addPermissionsToRole("role1", "server=" + server1.getName() + "->uri=" + uri.getName());
++    policyFile.write(iniFile);
++    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest(server1.getName(), initResource);
++    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, HivePrivilegeModel.getInstance());
++    // positive test
++    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, uri);
++    Assert.assertTrue(authorizableHierarchy.toString(),
++        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
++    // negative tests
++    // TODO we should support the case of /path/to/./ but let's to that later
++    uri = new AccessURI("file:///path/to/./");
++    authorizableHierarchy = ImmutableList.of(server1, uri);
++    Assert.assertFalse(authorizableHierarchy.toString(),
++        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
++    uri = new AccessURI("file:///path/to/../");
++    authorizableHierarchy = ImmutableList.of(server1, uri);
++    Assert.assertFalse(authorizableHierarchy.toString(),
++        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
++    uri = new AccessURI("file:///path/to/../../");
++    authorizableHierarchy = ImmutableList.of(server1, uri);
++    Assert.assertFalse(authorizableHierarchy.toString(),
++        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
++    uri = new AccessURI("file:///path/to/dir/../../");
++    authorizableHierarchy = ImmutableList.of(server1, uri);
++    Assert.assertFalse(authorizableHierarchy.toString(),
++        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
++  }
++  @Test(expected=IllegalArgumentException.class)
++  public void testInvalidPath() throws Exception {
++    new AccessURI(":invaliduri");
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java
+new file mode 100644
+index 0000000..97cf615
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java
+@@ -0,0 +1,115 @@
++/*
++ * 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.sentry.policy.hive;
++
++import java.io.File;
++import java.io.IOException;
++import java.util.Set;
++
++import org.junit.Assert;
++
++import org.apache.hadoop.conf.Configuration;
++import org.apache.hadoop.fs.FileSystem;
++import org.apache.hadoop.fs.Path;
++import org.apache.hadoop.hdfs.MiniDFSCluster;
++import org.apache.sentry.core.common.ActiveRoleSet;
++import org.apache.sentry.policy.common.PolicyEngine;
++import org.apache.sentry.provider.file.PolicyFile;
++import org.apache.sentry.provider.file.PolicyFiles;
++import org.junit.AfterClass;
++import org.junit.BeforeClass;
++import org.junit.Test;
++
++import com.google.common.collect.ImmutableSet;
++import com.google.common.collect.Sets;
++import com.google.common.io.Files;
++
++public class TestSimpleDBPolicyEngineDFS extends AbstractTestSimplePolicyEngine {
++
++  private static MiniDFSCluster dfsCluster;
++  private static FileSystem fileSystem;
++  private static Path root;
++  private static Path etc;
++
++  @BeforeClass
++  public static void setupLocalClazz() throws IOException {
++    File baseDir = getBaseDir();
++    Assert.assertNotNull(baseDir);
++    File dfsDir = new File(baseDir, "dfs");
++    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
++    Configuration conf = new Configuration();
++    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
++    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
++    fileSystem = dfsCluster.getFileSystem();
++    root = new Path(fileSystem.getUri().toString());
++    etc = new Path(root, "/etc");
++    fileSystem.mkdirs(etc);
++  }
++  @AfterClass
++  public static void teardownLocalClazz() {
++    if(dfsCluster != null) {
++      dfsCluster.shutdown();
++    }
++  }
++
++  @Override
++  protected void  afterSetup() throws IOException {
++    fileSystem.delete(etc, true);
++    fileSystem.mkdirs(etc);
++    PolicyFiles.copyToDir(fileSystem, etc, "hive-policy-test-authz-provider.ini", "hive-policy-test-authz-provider-other-group.ini");
++    setPolicy(DBPolicyTestUtil.createPolicyEngineForTest("server1",
++        new Path(etc, "hive-policy-test-authz-provider.ini").toString()));
++  }
++  @Override
++  protected void beforeTeardown() throws IOException {
++    fileSystem.delete(etc, true);
++  }
++
++  @Test
++  public void testMultiFSPolicy() throws Exception {
++    File globalPolicyFile = new File(Files.createTempDir(), "global-policy.ini");
++    File dbPolicyFile = new File(Files.createTempDir(), "db11-policy.ini");
++
++    // Create global policy file
++    PolicyFile dbPolicy = new PolicyFile()
++      .addPermissionsToRole("db11_role", "server=server1->db=db11")
++      .addRolesToGroup("group1", "db11_role");
++
++    dbPolicy.write(dbPolicyFile);
++    Path dbPolicyPath = new Path(etc, "db11-policy.ini");
++
++    // create per-db policy file
++    PolicyFile globalPolicy = new PolicyFile()
++      .addPermissionsToRole("admin_role", "server=server1")
++      .addRolesToGroup("admin_group", "admin_role")
++      .addGroupsToUser("db", "admin_group");
++    globalPolicy.addDatabase("db11", dbPolicyPath.toUri().toString());
++    globalPolicy.write(globalPolicyFile);
++
++
++    PolicyFiles.copyFilesToDir(fileSystem, etc, globalPolicyFile);
++    PolicyFiles.copyFilesToDir(fileSystem, etc, dbPolicyFile);
++    PolicyEngine multiFSEngine =
++            DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
++
++    Set<String> dbGroups = Sets.newHashSet();
++    dbGroups.add("group1");
++    ImmutableSet<String> dbPerms =
++        multiFSEngine.getAllPrivileges(dbGroups, ActiveRoleSet.ALL);
++    Assert.assertEquals("No DB permissions found", 1, dbPerms.size());
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java
+new file mode 100644
+index 0000000..c986d7e
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java
+@@ -0,0 +1,44 @@
++/*
++ * 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.sentry.policy.hive;
++
++import java.io.File;
++import java.io.IOException;
++
++import org.junit.Assert;
++
++import org.apache.commons.io.FileUtils;
++import org.apache.sentry.provider.file.PolicyFiles;
++
++public class TestSimpleDBPolicyEngineLocalFS extends AbstractTestSimplePolicyEngine {
++
++  @Override
++  protected void  afterSetup() throws IOException {
++    File baseDir = getBaseDir();
++    Assert.assertNotNull(baseDir);
++    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
++    PolicyFiles.copyToDir(baseDir, "hive-policy-test-authz-provider.ini", "hive-policy-test-authz-provider-other-group.ini");
++    setPolicy(DBPolicyTestUtil.createPolicyEngineForTest("server1",
++        new File(baseDir, "hive-policy-test-authz-provider.ini").getPath()));
++  }
++  @Override
++  protected void beforeTeardown() throws IOException {
++    File baseDir = getBaseDir();
++    Assert.assertNotNull(baseDir);
++    FileUtils.deleteQuietly(baseDir);
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
+new file mode 100644
+index 0000000..c719802
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
+@@ -0,0 +1,344 @@
++/*
++ * 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.sentry.privilege.hive;
++
++import junit.framework.Assert;
++import org.apache.sentry.core.common.Model;
++import org.apache.sentry.core.common.utils.KeyValue;
++import org.apache.sentry.core.common.utils.PathUtils;
++import org.apache.sentry.core.common.utils.SentryConstants;
++import org.apache.sentry.core.model.db.AccessConstants;
++import org.apache.sentry.core.model.db.HivePrivilegeModel;
++import org.apache.sentry.policy.common.CommonPrivilege;
++import org.apache.sentry.policy.common.Privilege;
++import org.junit.Before;
++import org.junit.Test;
++
++import static junit.framework.Assert.assertFalse;
++import static junit.framework.Assert.assertTrue;
++
++public class TestCommonPrivilegeForHive {
++
++  private Model hivePrivilegeModel;
++
++  private static final String ALL = AccessConstants.ALL;
++
++  private static final CommonPrivilege ROLE_SERVER_SERVER1_DB_ALL =
++          create(new KeyValue("server", "server1"), new KeyValue("db", ALL));
++  private static final CommonPrivilege ROLE_SERVER_SERVER1_DB_DB1 =
++          create(new KeyValue("server", "server1"), new KeyValue("db", "db1"));
++  private static final CommonPrivilege ROLE_SERVER_SERVER2_DB_ALL =
++          create(new KeyValue("server", "server2"), new KeyValue("db", ALL));
++  private static final CommonPrivilege ROLE_SERVER_SERVER2_DB_DB1 =
++          create(new KeyValue("server", "server2"), new KeyValue("db", "db1"));
++  private static final CommonPrivilege ROLE_SERVER_ALL_DB_ALL =
++          create(new KeyValue("server", ALL), new KeyValue("db", ALL));
++  private static final CommonPrivilege ROLE_SERVER_ALL_DB_DB1 =
++          create(new KeyValue("server", ALL), new KeyValue("db", "db1"));
++
++  private static final CommonPrivilege ROLE_SERVER_SERVER1_URI_URI1 =
++          create(new KeyValue("server", "server1"), new KeyValue("uri",
++                  "hdfs://namenode:8020/path/to/uri1"));
++  private static final CommonPrivilege ROLE_SERVER_SERVER1_URI_URI2 =
++          create(new KeyValue("server", "server1"), new KeyValue("uri",
++                  "hdfs://namenode:8020/path/to/uri2/"));
++  private static final CommonPrivilege ROLE_SERVER_SERVER1_URI_ALL =
++          create(new KeyValue("server", "server1"), new KeyValue("uri", ALL));
++
++  private static final CommonPrivilege ROLE_SERVER_SERVER1 =
++          create(new KeyValue("server", "server1"));
++
++  private static final CommonPrivilege REQUEST_SERVER1_DB1 =
++          create(new KeyValue("server", "server1"), new KeyValue("db", "db1"));
++  private static final CommonPrivilege REQUEST_SERVER2_DB1 =
++          create(new KeyValue("server", "server2"), new KeyValue("db", "db1"));
++  private static final CommonPrivilege REQUEST_SERVER1_DB2 =
++          create(new KeyValue("server", "server1"), new KeyValue("db", "db2"));
++  private static final CommonPrivilege REQUEST_SERVER2_DB2 =
++          create(new KeyValue("server", "server2"), new KeyValue("db", "db2"));
++
++  private static final CommonPrivilege REQUEST_SERVER1_URI1 =
++          create(new KeyValue("server", "server1"), new KeyValue("uri",
++                  "hdfs://namenode:8020/path/to/uri1/some/file"));
++  private static final CommonPrivilege REQUEST_SERVER1_URI2 =
++          create(new KeyValue("server", "server1"), new KeyValue("uri",
++                  "hdfs://namenode:8020/path/to/uri2/some/other/file"));
++
++  private static final CommonPrivilege REQUEST_SERVER1_OTHER =
++          create(new KeyValue("server", "server2"), new KeyValue("other", "thing"));
++
++  private static final CommonPrivilege REQUEST_SERVER1 =
++          create(new KeyValue("server", "server2"));
++
++  @Before
++  public void prepareData() {
++    hivePrivilegeModel = HivePrivilegeModel.getInstance();
++  }
++
++  @Test
++  public void testOther() throws Exception {
++    assertFalse(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_OTHER, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_OTHER.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
++  }
++
++  @Test
++  public void testRoleShorterThanRequest() throws Exception {
++    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1, hivePrivilegeModel));
++  }
++
++  @Test
++  public void testRolesAndRequests() throws Exception {
++    // ROLE_SERVER_SERVER1_DB_ALL
++    assertTrue(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    // test inverse
++    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
++
++    // ROLE_SERVER_SERVER1_DB_DB1
++    assertTrue(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    // test inverse
++    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
++
++    // ROLE_SERVER_SERVER2_DB_ALL
++    assertFalse(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    // test inverse
++    assertFalse(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
++
++    // ROLE_SERVER_SERVER2_DB_DB1
++    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    assertFalse(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
++
++    // ROLE_SERVER_ALL_DB_ALL
++    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    // test inverse
++    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
++
++    // ROLE_SERVER_ALL_DB_DB1
++    assertTrue(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
++
++    // test inverse
++    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
++
++    // uri
++    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1_URI_ALL.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1_URI_ALL.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1_URI_URI1.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_URI_URI1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
++    assertTrue(ROLE_SERVER_SERVER1_URI_URI2.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_URI_URI2.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER2_DB2.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
++    // test inverse
++    assertTrue(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_ALL, hivePrivilegeModel));
++    assertTrue(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_ALL, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_URI1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_URI1, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_URI2, hivePrivilegeModel));
++    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_URI2, hivePrivilegeModel));
++  };
++
++  @Test
++  public void testUnexpected() throws Exception {
++    Privilege p = new Privilege() {
++      @Override
++      public boolean implies(Privilege p, Model m) {
++        return false;
++      }
++    };
++    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(null, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(p, hivePrivilegeModel));
++    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(null));
++    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(p));
++
++    Assert.assertEquals(ROLE_SERVER_SERVER1_DB_ALL.hashCode(),
++            create(ROLE_SERVER_SERVER1_DB_ALL.toString()).hashCode());
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testNullString() throws Exception {
++    System.out.println(create((String)null));
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testEmptyString() throws Exception {
++    System.out.println(create(""));
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testEmptyKey() throws Exception {
++    System.out.println(create(SentryConstants.KV_JOINER.join("", "db1")));
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testEmptyValue() throws Exception {
++    System.out.println(create(SentryConstants.KV_JOINER.join("db", "")));
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testEmptyPart() throws Exception {
++    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
++            join(SentryConstants.KV_JOINER.join("server", "server1"), "")));
++  }
++
++  @Test(expected=IllegalArgumentException.class)
++  public void testOnlySeperators() throws Exception {
++    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
++            join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR,
++            SentryConstants.KV_SEPARATOR)));
++  }
++
++  @Test
++  public void testImpliesURIPositive() throws Exception {
++    assertTrue(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path/to/some/dir"));
++    assertTrue(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path"));
++    assertTrue(PathUtils.impliesURI("file:///path", "file:///path/to/some/dir"));
++    assertTrue(PathUtils.impliesURI("file:///path", "file:///path"));
++  }
++
++  @Test
++  public void testImpliesURINegative() throws Exception {
++    // relative path
++    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path/to/../../other"));
++    assertFalse(PathUtils.impliesURI("file:///path", "file:///path/to/../../other"));
++    // bad policy
++    assertFalse(PathUtils.impliesURI("blah", "hdfs://namenode:8020/path/to/some/dir"));
++    // bad request
++    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "blah"));
++    // scheme
++    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "file:///path/to/some/dir"));
++    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "file://namenode:8020/path/to/some/dir"));
++    // hostname
++    assertFalse(PathUtils.impliesURI("hdfs://namenode1:8020/path", "hdfs://namenode2:8020/path/to/some/dir"));
++    // port
++    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8021/path/to/some/dir"));
++    // mangled path
++    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/pathFooBar"));
++    // ends in /
++    assertTrue(PathUtils.impliesURI("hdfs://namenode:8020/path/", "hdfs://namenode:8020/path/FooBar"));
++  }
++
++  @Test
++  public void testActionHierarchy() throws Exception {
++    String dbName = "db1";
++    CommonPrivilege dbAll = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "ALL"));
++
++    CommonPrivilege dbSelect = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "SELECT"));
++    CommonPrivilege dbInsert = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "INSERT"));
++    CommonPrivilege dbAlter = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "ALTER"));
++    CommonPrivilege dbCreate = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "CREATE"));
++    CommonPrivilege dbDrop = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "DROP"));
++    CommonPrivilege dbIndex = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "INDEX"));
++    CommonPrivilege dbLock = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "LOCK"));
++
++    assertTrue(dbAll.implies(dbSelect, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbInsert, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbAlter, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbCreate, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbDrop, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbIndex, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbLock, hivePrivilegeModel));
++
++    dbAll = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName), new KeyValue("action", "*"));
++
++    assertTrue(dbAll.implies(dbSelect, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbInsert, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbAlter, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbCreate, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbDrop, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbIndex, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbLock, hivePrivilegeModel));
++
++    dbAll = create(new KeyValue("server", "server1"),
++            new KeyValue("db", dbName));
++
++    assertTrue(dbAll.implies(dbSelect, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbInsert, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbAlter, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbCreate, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbDrop, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbIndex, hivePrivilegeModel));
++    assertTrue(dbAll.implies(dbLock, hivePrivilegeModel));
++  }
++
++  static CommonPrivilege create(KeyValue... keyValues) {
++    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
++  }
++
++  static CommonPrivilege create(String s) {
++    return new CommonPrivilege(s);
++  }
++}
+diff --git a/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini
+new file mode 100644
+index 0000000..cd3695c
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini
+@@ -0,0 +1,22 @@
++# 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.
++
++[groups]
++other_group = analyst_role
++
++[roles]
++analyst_role = server=server1->db=other_group_db->table=purchases->action=select
+\ No newline at end of file
+diff --git a/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini
+new file mode 100644
+index 0000000..e9114ef
+--- /dev/null
++++ b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini
+@@ -0,0 +1,32 @@
++# 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.
++
++[databases]
++other_group_db = hive-policy-test-authz-provider-other-group.ini
++
++[groups]
++manager = analyst_role, junior_analyst_role
++analyst = analyst_role
++jranalyst = junior_analyst_role
++admin = admin
++
++[roles]
++analyst_role = server=server1->db=customers->table=purchases->action=select, \
++  server=server1->db=analyst1, \
++  server=server1->db=jranalyst1->table=*->action=select
++junior_analyst_role = server=server1->db=jranalyst1, server=server1->db=customers->table=purchases_partial->action=select
++admin = server=server1
+diff --git a/sentry-binding/sentry-binding-kafka/pom.xml b/sentry-binding/sentry-binding-kafka/pom.xml
+index 15d3de5..f6f212b 100644
+--- a/sentry-binding/sentry-binding-kafka/pom.xml
++++ b/sentry-binding/sentry-binding-kafka/pom.xml
+@@ -45,10 +45,6 @@ limitations under the License.
+     </dependency>
+     <dependency>
+       <groupId>org.apache.sentry</groupId>
+-      <artifactId>sentry-policy-kafka</artifactId>
+-    </dependency>
+-    <dependency>
+-      <groupId>org.apache.sentry</groupId>
+       <artifactId>sentry-provider-common</artifactId>
+     </dependency>
+     <dependency>
+@@ -73,5 +69,10 @@ limitations under the License.
+       <artifactId>kafka_2.11</artifactId>
+       <scope>provided</scope>
+     </dependency>
++    <dependency>
++      <groupId>org.apache.hadoop</groupId>
++      <artifactId>hadoop-minicluster</artifactId>
++      <scope>test</scope>
++    </dependency>
+   </dependencies>
+ </project>
+diff --git a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
+index c6600a0..15f7359 100644
+--- a/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
++++ b/sentry-binding/sentry-binding-kafka/src/main/java/org/apache/sentry/kafka/binding/KafkaAuthBinding.java
+@@ -42,16 +42,19 @@ import org.apache.kafka.common.security.auth.KafkaPrincipal;
+ import org.apache.sentry.SentryUserException;
+ import org.apache.sentry.core.common.ActiveRoleSet;
+ import org.apache.sentry.core.common.Authorizable;
++import org.apache.sentry.core.common.Model;
+ import org.apache.sentry.core.common.Subject;
+ import org.apache.sentry.core.model.kafka.KafkaActionFactory;
+ import org.apache.sentry.core.model.kafka.KafkaActionFactory.KafkaAction;
+ import org.apache.sentry.core.model.kafka.KafkaAuthorizable;
++import org.apache.sentry.core.model.kafka.KafkaPrivilegeModel;
+ import org.apache.sentry.kafka.ConvertUtil;
+ import org.apache.sentry.kafka.conf.KafkaAuthConf.AuthzConfVars;
+ import org.apache.sentry.policy.common.PolicyEngine;
+ import org.apache.sentry.provider.common.AuthorizationComponent;
+ import org.apache.sentry.provider.common.AuthorizationProvider;
+ import org.apache.sentry.provider.common.ProviderBackend;
++import org.apache.sentry.provider.common.ProviderBackendContext;
+ import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
+ import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
+ import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
+@@ -72,491 +75,497 @@ import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY
+ 
+ public class KafkaAuthBinding {
+ 
+-    private static final Logger LOG = LoggerFactory.getLogger(KafkaAuthBinding.class);
+-    private static final String COMPONENT_TYPE = AuthorizationComponent.KAFKA;
+-    private static final String COMPONENT_NAME = COMPONENT_TYPE;
++  private static final Logger LOG = LoggerFactory.getLogger(KafkaAuthBinding.class);
++  private static final String COMPONENT_TYPE = AuthorizationComponent.KAFKA;
++  private static final String COMPONENT_NAME = COMPONENT_TYPE;
+ 
+-    private static Boolean kerberosInit;
++  private static Boolean kerberosInit;
+ 
+-    private final Configuration authConf;
+-    private final AuthorizationProvider authProvider;
+-    private final KafkaActionFactory actionFactory = KafkaActionFactory.getInstance();
++  private fin

<TRUNCATED>

[08/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
index 8456031..731541d 100644
--- a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/binding/SqoopAuthBinding.java
@@ -25,14 +25,17 @@ import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.sentry.SentryUserException;
 import org.apache.sentry.core.common.ActiveRoleSet;
 import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.sqoop.Server;
 import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
 import org.apache.sentry.core.model.sqoop.SqoopActionFactory;
+import org.apache.sentry.core.model.sqoop.SqoopPrivilegeModel;
 import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.common.AuthorizationComponent;
 import org.apache.sentry.provider.common.AuthorizationProvider;
 import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.db.generic.SentryGenericProviderBackend;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClient;
 import org.apache.sentry.provider.db.generic.service.thrift.SentryGenericServiceClientFactory;
@@ -63,6 +66,7 @@ public class SqoopAuthBinding {
   private ProviderBackend providerBackend;
 
   private final SqoopActionFactory actionFactory = new SqoopActionFactory();
+  private final String SQOOP_POLICY_ENGINE_OLD = "org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine";
 
   public SqoopAuthBinding(Configuration authConf, String serverName) throws Exception {
     this.authConf = authConf;
@@ -87,6 +91,12 @@ public class SqoopAuthBinding {
     String providerBackendName = authConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar(), AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getDefault());
     String policyEngineName = authConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(), AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
     String serviceName = authConf.get(AuthzConfVars.AUTHZ_SERVER_NAME.getVar());
+
+    // for the backward compatibility
+    if (SQOOP_POLICY_ENGINE_OLD.equals(policyEngineName)) {
+      policyEngineName = AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault();
+    }
+
     if (LOG.isDebugEnabled()) {
       LOG.debug("Using authorization provider " + authProviderName +
           " with resource " + resourceName + ", policy engine "
@@ -110,18 +120,26 @@ public class SqoopAuthBinding {
       ((SentryGenericProviderBackend) providerBackend).setServiceName(serviceName);
     }
 
+    // Create backend context
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(SqoopPrivilegeModel.getInstance().getPrivilegeValidators(serviceName));
+    providerBackend.initialize(context);
+
     //Instantiate the configured policyEngine
     Constructor<?> policyConstructor =
-        Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
+        Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
     policyConstructor.setAccessible(true);
     PolicyEngine policyEngine =
-        (PolicyEngine) policyConstructor.newInstance(new Object[] {sqoopServer.getName(), providerBackend});
+        (PolicyEngine) policyConstructor.newInstance(new Object[] {providerBackend});
 
     //Instantiate the configured authProvider
     Constructor<?> constrctor =
-        Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class, PolicyEngine.class);
+        Class.forName(authProviderName).getDeclaredConstructor(Configuration.class, String.class,
+                PolicyEngine.class, Model.class);
     constrctor.setAccessible(true);
-    return (AuthorizationProvider) constrctor.newInstance(new Object[] {authConf, resourceName, policyEngine});
+    return (AuthorizationProvider) constrctor.newInstance(new Object[] {authConf, resourceName,
+            policyEngine, SqoopPrivilegeModel.getInstance()});
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
index 097e7f7..7836871 100644
--- a/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
+++ b/sentry-binding/sentry-binding-sqoop/src/main/java/org/apache/sentry/sqoop/conf/SqoopAuthConf.java
@@ -34,7 +34,7 @@ public class SqoopAuthConf extends Configuration {
     AUTHZ_PROVIDER_BACKEND(
         "sentry.sqoop.provider.backend",
         "org.apache.sentry.provider.db.generic.SentryGenericProviderBackend"),
-    AUTHZ_POLICY_ENGINE("sentry.sqoop.policy.engine","org.apache.sentry.policy.sqoop.SimpleSqoopPolicyEngine"),
+    AUTHZ_POLICY_ENGINE("sentry.sqoop.policy.engine","org.apache.sentry.policy.engine.common.CommonPolicyEngine"),
     AUTHZ_SERVER_NAME("sentry.sqoop.name", ""),
     AUTHZ_TESTING_MODE("sentry.sqoop.testing.mode", "false");
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java
new file mode 100644
index 0000000..49b9bc1
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/AbstractTestSqoopPolicyEngine.java
@@ -0,0 +1,145 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public abstract class AbstractTestSqoopPolicyEngine {
+  private static final String OPERATOR_JDBC_CONNECTORS_READ = "server=server1->connector=generic-jdbc-connector->action=read";
+  private static final String OPERATOR_HDFS_CONNECTORS_READ = "server=server1->connector=hdfs-connector->action=read";
+  private static final String OPERATOR_KAFKA_CONNECTORS_READ = "server=server1->connector=kafka-connector->action=read";
+  private static final String OPERATOR_KITE_CONNECTORS_READ = "server=server1->connector=kite-connector->action=read";
+  private static final String ANALYST_JOBS_ALL = "server=server1->job=all->action=*";
+  private static final String OPERATOR_JOB1_READ = "server=server1->job=job1->action=read";
+  private static final String OPERATOR_JOB2_READ = "server=server1->job=job2->action=read";
+  private static final String ANALYST_LINKS_ALL = "server=server1->link=all->action=*";
+  private static final String OPERATOR_LINK1_READ = "server=server1->link=link1->action=read";
+  private static final String OPERATOR_LINK2_READ = "server=server1->link=link2->action=read";
+  private static final String ADMIN = "server=server1->action=*";
+
+  private PolicyEngine policy;
+  private static File baseDir;
+
+  protected String sqoopServerName = "server1";
+
+  @BeforeClass
+  public static void setupClazz() throws IOException {
+    baseDir = Files.createTempDir();
+  }
+
+  @AfterClass
+  public static void teardownClazz() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  protected void setPolicy(PolicyEngine policy) {
+    this.policy = policy;
+  }
+  protected static File getBaseDir() {
+    return baseDir;
+  }
+  @Before
+  public void setup() throws IOException {
+    afterSetup();
+  }
+  @After
+  public void teardown() throws IOException {
+    beforeTeardown();
+  }
+  protected void afterSetup() throws IOException {
+
+  }
+
+  protected void beforeTeardown() throws IOException {
+
+  }
+
+  @Test
+  public void testDeveloper() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        OPERATOR_JDBC_CONNECTORS_READ, OPERATOR_HDFS_CONNECTORS_READ,
+        OPERATOR_KAFKA_CONNECTORS_READ, OPERATOR_KITE_CONNECTORS_READ,
+        ANALYST_JOBS_ALL, ANALYST_LINKS_ALL));
+    Assert.assertEquals(expected.toString(),
+        Sets.newTreeSet(policy.getPrivileges(set("developer"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testAnalyst() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ANALYST_JOBS_ALL, ANALYST_LINKS_ALL));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("analyst"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testConnectorOperator() throws Exception {
+
+  }
+
+  @Test
+  public void testJobOperator() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets
+        .newHashSet(OPERATOR_JOB1_READ,OPERATOR_JOB2_READ));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("job1_2_operator"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testLinkOperator() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets
+        .newHashSet(OPERATOR_LINK1_READ, OPERATOR_LINK2_READ));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("link1_2_operator"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(ADMIN));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getPrivileges(set("admin"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  private static Set<String> set(String... values) {
+    return Sets.newHashSet(values);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyTestUtil.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyTestUtil.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyTestUtil.java
new file mode 100644
index 0000000..bfd11e3
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/SqoopPolicyTestUtil.java
@@ -0,0 +1,45 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.sqoop.SqoopPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+
+import java.io.IOException;
+
+public class SqoopPolicyTestUtil {
+
+  public static PolicyEngine createPolicyEngineForTest(String server, String resource) throws IOException {
+
+    ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource);
+
+    // create backendContext
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(false);
+    context.setValidators(SqoopPrivilegeModel.getInstance().getPrivilegeValidators(server));
+    // initialize the backend with the context
+    providerBackend.initialize(context);
+
+
+    return new CommonPolicyEngine(providerBackend);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java
new file mode 100644
index 0000000..7cb0ae4
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestServerNameRequiredMatch.java
@@ -0,0 +1,57 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import org.junit.Assert;
+
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.sqoop.validator.ServerNameRequiredMatch;
+import org.apache.shiro.config.ConfigurationException;
+import org.junit.Test;
+
+public class TestServerNameRequiredMatch {
+  @Test
+  public void testWithoutServerName() {
+    ServerNameRequiredMatch serverNameMatch = new ServerNameRequiredMatch("server1");
+    try {
+      serverNameMatch.validate(new PrivilegeValidatorContext("connector=c1->action=read"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+    }
+  }
+  @Test
+  public void testServerNameNotMatch() throws Exception {
+    ServerNameRequiredMatch serverNameMatch = new ServerNameRequiredMatch("server1");
+    try {
+      serverNameMatch.validate(new PrivilegeValidatorContext("server=server2->connector=c1->action=read"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException ex) {
+    }
+  }
+  @Test
+  public void testServerNameMatch() throws Exception {
+    ServerNameRequiredMatch serverNameMatch = new ServerNameRequiredMatch("server1");
+    try {
+      serverNameMatch.validate(new PrivilegeValidatorContext("server=server1->connector=c1->action=read"));
+    } catch (ConfigurationException ex) {
+      Assert.fail("Not expected ConfigurationException");
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java
new file mode 100644
index 0000000..7ce8881
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderGeneralCases.java
@@ -0,0 +1,241 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.sqoop.Connector;
+import org.apache.sentry.core.model.sqoop.Job;
+import org.apache.sentry.core.model.sqoop.Link;
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
+import org.apache.sentry.core.model.sqoop.SqoopActionFactory.SqoopAction;
+import org.apache.sentry.core.model.sqoop.SqoopPrivilegeModel;
+import org.apache.sentry.provider.common.GroupMappingService;
+import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
+import org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.After;
+import org.junit.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestSqoopAuthorizationProviderGeneralCases {
+  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap.create();
+
+  private static final Subject SUB_ADMIN = new Subject("admin1");
+  private static final Subject SUB_DEVELOPER = new Subject("developer1");
+  private static final Subject SUB_ANALYST = new Subject("analyst1");
+  private static final Subject SUB_JOB_OPERATOR = new Subject("job_operator1");
+  private static final Subject SUB_LINK_OPERATOR = new Subject("link_operator1");
+  private static final Subject SUB_CONNECTOR_OPERATOR = new Subject("connector_operator1");
+
+
+
+  private static final Server server1 = new Server("server1");
+  private static final Connector jdbc_connector = new Connector("generic-jdbc-connector");
+  private static final Connector hdfs_connector = new Connector("hdfs-connector");
+  private static final Connector kafka_connector = new Connector("kafka-connector");
+  private static final Connector kite_connector = new Connector("kite-connector");
+  private static final Link link1 = new Link("link1");
+  private static final Link link2 = new Link("link2");
+  private static final Job job1 = new Job("job1");
+  private static final Job job2 = new Job("job2");
+
+  private static final SqoopAction ALL = new SqoopAction(SqoopActionConstant.ALL);
+  private static final SqoopAction READ = new SqoopAction(SqoopActionConstant.READ);
+  private static final SqoopAction WRITE = new SqoopAction(SqoopActionConstant.WRITE);
+
+  private static final String ADMIN = "admin";
+  private static final String DEVELOPER = "developer";
+  private static final String ANALYST = "analyst";
+  private static final String JOB_OPERATOR = "job1_2_operator";
+  private static final String LINK_OPERATOR ="link1_2_operator";
+  private static final String CONNECTOR_OPERATOR = "connectors_operator";
+
+  static {
+    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList(ADMIN));
+    USER_TO_GROUP_MAP.putAll(SUB_DEVELOPER.getName(), Arrays.asList(DEVELOPER));
+    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList(ANALYST));
+    USER_TO_GROUP_MAP.putAll(SUB_JOB_OPERATOR.getName(),Arrays.asList(JOB_OPERATOR));
+    USER_TO_GROUP_MAP.putAll(SUB_LINK_OPERATOR.getName(),Arrays.asList(LINK_OPERATOR));
+    USER_TO_GROUP_MAP.putAll(SUB_CONNECTOR_OPERATOR.getName(),Arrays.asList(CONNECTOR_OPERATOR));
+  }
+
+  private final ResourceAuthorizationProvider authzProvider;
+  private File baseDir;
+
+  public TestSqoopAuthorizationProviderGeneralCases() throws IOException {
+    baseDir = Files.createTempDir();
+    PolicyFiles.copyToDir(baseDir, "sqoop-policy-test-authz-provider.ini");
+    authzProvider = new HadoopGroupResourceAuthorizationProvider(
+        SqoopPolicyTestUtil.createPolicyEngineForTest(server1.getName(),
+        new File(baseDir, "sqoop-policy-test-authz-provider.ini").getPath()),
+        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), SqoopPrivilegeModel.getInstance());
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void doTestResourceAuthorizationProvider(Subject subject, List<? extends Authorizable> authorizableHierarchy,
+      Set<? extends Action> actions, boolean expected) throws Exception {
+    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
+    helper.add("Subject", subject).add("authzHierarchy", authorizableHierarchy).add("action", actions);
+    Assert.assertEquals(helper.toString(), expected,
+        authzProvider.hasAccess(subject, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    Set<? extends Action> allActions = Sets.newHashSet(ALL, READ, WRITE);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,hdfs_connector), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,jdbc_connector), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,kafka_connector), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,kite_connector), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,link1), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,link2), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,job1), allActions, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, Arrays.asList(server1,job2), allActions, true);
+  }
+
+  @Test
+  public void testDeveloper() throws Exception {
+    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
+    for (SqoopAction action : allActions) {
+      //developer only has the read action on all connectors
+      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
+        doTestResourceAuthorizationProvider(SUB_DEVELOPER, Arrays.asList(server1, connector), Sets.newHashSet(action), READ.equals(action));
+      }
+    }
+
+    for (Link link : Sets.newHashSet(link1, link2)) {
+      //developer has the all action on all links
+      doTestResourceAuthorizationProvider(SUB_DEVELOPER, Arrays.asList(server1, link), allActions, true);
+    }
+
+    for (Job job : Sets.newHashSet(job1,job2)) {
+      //developer has the all action on all jobs
+      doTestResourceAuthorizationProvider(SUB_DEVELOPER, Arrays.asList(server1, job), allActions, true);
+    }
+  }
+
+  @Test
+  public void testAnalyst() throws Exception {
+    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
+    for (SqoopAction action : allActions) {
+      //analyst has not the any action on all connectors
+      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
+        doTestResourceAuthorizationProvider(SUB_ANALYST, Arrays.asList(server1, connector), Sets.newHashSet(action), false);
+      }
+    }
+
+    for (Link link : Sets.newHashSet(link1, link2)) {
+      //analyst has the all action on all links
+      doTestResourceAuthorizationProvider(SUB_ANALYST, Arrays.asList(server1, link), allActions, true);
+    }
+
+    for (Job job : Sets.newHashSet(job1,job2)) {
+      //analyst has the all action on all jobs
+      doTestResourceAuthorizationProvider(SUB_ANALYST, Arrays.asList(server1, job), allActions, true);
+    }
+  }
+
+  @Test
+  public void testJobOperator() throws Exception {
+    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
+    for (SqoopAction action : allActions) {
+      for (Job job : Sets.newHashSet(job1,job2)) {
+        //Job operator has the read action on all jobs
+        doTestResourceAuthorizationProvider(SUB_JOB_OPERATOR, Arrays.asList(server1, job), Sets.newHashSet(action), READ.equals(action));
+      }
+      for (Link link : Sets.newHashSet(link1, link2)) {
+        doTestResourceAuthorizationProvider(SUB_JOB_OPERATOR, Arrays.asList(server1, link), Sets.newHashSet(action), false);
+      }
+      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
+        doTestResourceAuthorizationProvider(SUB_JOB_OPERATOR, Arrays.asList(server1, connector), Sets.newHashSet(action), false);
+      }
+    }
+  }
+
+  @Test
+  public void testLinkOperator() throws Exception {
+    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
+    for (SqoopAction action : allActions) {
+      for (Link link : Sets.newHashSet(link1, link2)) {
+        //Link operator has the read action on all links
+        doTestResourceAuthorizationProvider(SUB_LINK_OPERATOR, Arrays.asList(server1, link), Sets.newHashSet(action), READ.equals(action));
+      }
+      for (Job job : Sets.newHashSet(job1,job2)) {
+        doTestResourceAuthorizationProvider(SUB_LINK_OPERATOR, Arrays.asList(server1, job), Sets.newHashSet(action), false);
+      }
+      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
+        doTestResourceAuthorizationProvider(SUB_LINK_OPERATOR, Arrays.asList(server1, connector), Sets.newHashSet(action), false);
+      }
+    }
+  }
+
+  @Test
+  public void testConnectorOperator() throws Exception {
+    Set<SqoopAction> allActions = Sets.newHashSet(ALL, READ, WRITE);
+    for (SqoopAction action : allActions) {
+      for (Connector connector : Sets.newHashSet(jdbc_connector, hdfs_connector, kafka_connector, kite_connector)) {
+        doTestResourceAuthorizationProvider(SUB_CONNECTOR_OPERATOR, Arrays.asList(server1, connector), Sets.newHashSet(action), READ.equals(action));
+      }
+      for (Job job : Sets.newHashSet(job1,job2)) {
+        doTestResourceAuthorizationProvider(SUB_CONNECTOR_OPERATOR, Arrays.asList(server1, job), Sets.newHashSet(action), false);
+      }
+      for (Link link : Sets.newHashSet(link1, link2)) {
+        doTestResourceAuthorizationProvider(SUB_CONNECTOR_OPERATOR, Arrays.asList(server1, link), Sets.newHashSet(action), false);
+      }
+    }
+  }
+
+  public class MockGroupMappingServiceProvider implements GroupMappingService {
+    private final Multimap<String, String> userToGroupMap;
+
+    public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
+      this.userToGroupMap = userToGroupMap;
+    }
+
+    @Override
+    public Set<String> getGroups(String user) {
+      return Sets.newHashSet(userToGroupMap.get(user));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java
new file mode 100644
index 0000000..8d69402
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopAuthorizationProviderSpecialCases.java
@@ -0,0 +1,89 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.sqoop.Connector;
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
+import org.apache.sentry.core.model.sqoop.SqoopActionFactory.SqoopAction;
+import org.apache.sentry.core.model.sqoop.SqoopPrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.common.AuthorizationProvider;
+import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestSqoopAuthorizationProviderSpecialCases {
+  private AuthorizationProvider authzProvider;
+  private PolicyFile policyFile;
+  private File baseDir;
+  private File iniFile;
+  private String initResource;
+  @Before
+  public void setup() throws IOException {
+    baseDir = Files.createTempDir();
+    iniFile = new File(baseDir, "policy.ini");
+    initResource = "file://" + iniFile.getPath();
+    policyFile = new PolicyFile();
+  }
+
+  @After
+  public void teardown() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  @Test
+  public void testDuplicateEntries() throws Exception {
+    Subject user1 = new Subject("user1");
+    Server server1 = new Server("server1");
+    Connector connector1 = new Connector("c1");
+    Set<? extends Action> actions = Sets.newHashSet(new SqoopAction(SqoopActionConstant.READ));
+    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
+      .addRolesToGroup("group1",  true, "role1", "role1")
+      .addPermissionsToRole("role1", true, "server=server1->connector=c1->action=read",
+          "server=server1->connector=c1->action=read");
+    policyFile.write(iniFile);
+    PolicyEngine policy = SqoopPolicyTestUtil.createPolicyEngineForTest(server1.getName(), initResource);
+    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, SqoopPrivilegeModel.getInstance());
+    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, connector1);
+    Assert.assertTrue(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java
new file mode 100644
index 0000000..5a69f4a
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopModelAuthorizables.java
@@ -0,0 +1,54 @@
+/*
+ * 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.sentry.policy.sqoop;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.apache.sentry.core.model.sqoop.Server;
+import org.apache.sentry.core.model.sqoop.SqoopModelAuthorizables;
+import org.junit.Test;
+
+public class TestSqoopModelAuthorizables {
+
+  @Test
+  public void testServer() throws Exception {
+    Server server1 = (Server) SqoopModelAuthorizables.from("SERVER=server1");
+    assertEquals("server1", server1.getName());
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNoKV() throws Exception {
+    System.out.println(SqoopModelAuthorizables.from("nonsense"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(SqoopModelAuthorizables.from("=server1"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(SqoopModelAuthorizables.from("SERVER="));
+  }
+
+  @Test
+  public void testNotAuthorizable() throws Exception {
+    assertNull(SqoopModelAuthorizables.from("k=v"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java
new file mode 100644
index 0000000..c156ed0
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineDFS.java
@@ -0,0 +1,75 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class TestSqoopPolicyEngineDFS extends AbstractTestSqoopPolicyEngine {
+  private static MiniDFSCluster dfsCluster;
+  private static FileSystem fileSystem;
+  private static Path root;
+  private static Path etc;
+
+  @BeforeClass
+  public static void setupLocalClazz() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    File dfsDir = new File(baseDir, "dfs");
+    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
+    Configuration conf = new Configuration();
+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
+    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
+    fileSystem = dfsCluster.getFileSystem();
+    root = new Path(fileSystem.getUri().toString());
+    etc = new Path(root, "/etc");
+    fileSystem.mkdirs(etc);
+  }
+
+  @AfterClass
+  public static void teardownLocalClazz() {
+    if(dfsCluster != null) {
+      dfsCluster.shutdown();
+    }
+  }
+
+  @Override
+  protected void  afterSetup() throws IOException {
+    fileSystem.delete(etc, true);
+    fileSystem.mkdirs(etc);
+    PolicyFiles.copyToDir(fileSystem, etc, "sqoop-policy-test-authz-provider.ini");
+    setPolicy(SqoopPolicyTestUtil.createPolicyEngineForTest(sqoopServerName, new Path(etc,
+        "sqoop-policy-test-authz-provider.ini").toString()));
+  }
+
+  @Override
+  protected void beforeTeardown() throws IOException {
+    fileSystem.delete(etc, true);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java
new file mode 100644
index 0000000..b30d04b
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyEngineLocalFS.java
@@ -0,0 +1,45 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.provider.file.PolicyFiles;
+
+public class TestSqoopPolicyEngineLocalFS extends AbstractTestSqoopPolicyEngine {
+  @Override
+  protected void  afterSetup() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
+    PolicyFiles.copyToDir(baseDir, "sqoop-policy-test-authz-provider.ini");
+    setPolicy(SqoopPolicyTestUtil.createPolicyEngineForTest(sqoopServerName,
+      new File(baseDir, "sqoop-policy-test-authz-provider.ini").getPath()));
+  }
+  @Override
+  protected void beforeTeardown() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    FileUtils.deleteQuietly(baseDir);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java
new file mode 100644
index 0000000..12c68f3
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/policy/sqoop/TestSqoopPolicyNegative.java
@@ -0,0 +1,121 @@
+/*
+ * 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.sentry.policy.sqoop;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestSqoopPolicyNegative {
+  @SuppressWarnings("unused")
+  private static final Logger LOGGER = LoggerFactory
+      .getLogger(TestSqoopPolicyNegative.class);
+
+  private File baseDir;
+  private File globalPolicyFile;
+
+  @Before
+  public void setup() {
+    baseDir = Files.createTempDir();
+    globalPolicyFile = new File(baseDir, "global.ini");
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void append(String from, File to) throws IOException {
+    Files.append(from + "\n", to, Charsets.UTF_8);
+  }
+
+  @Test
+  public void testauthorizedSqoopInPolicyFile() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("other_group = other_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("other_role = server=server1->connector=c1->action=read, server=server1->link=l1->action=read", globalPolicyFile);
+    PolicyEngine policy = SqoopPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    //malicious_group has no privilege
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("malicious_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+    //other_group has two privileges
+    permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.size() == 2);
+  }
+
+  @Test
+  public void testNoServerNameConfig() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("other_group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = connector=c1->action=read,link=l1->action=read", globalPolicyFile);
+    PolicyEngine policy = SqoopPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testServerAllName() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = server=*", globalPolicyFile);
+    PolicyEngine policy = SqoopPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testServerIncorrect() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = server=server2", globalPolicyFile);
+    PolicyEngine policy = SqoopPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testAll() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = *", globalPolicyFile);
+    PolicyEngine policy = SqoopPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
new file mode 100644
index 0000000..92e9290
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/java/org/apache/sentry/privilege/sqoop/TestCommonPrivilegeForSqoop.java
@@ -0,0 +1,196 @@
+/*
+ * 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.sentry.privilege.sqoop;
+
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.sqoop.SqoopActionConstant;
+import org.apache.sentry.core.model.sqoop.SqoopPrivilegeModel;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+public class TestCommonPrivilegeForSqoop {
+
+  private Model sqoopPrivilegeModel;
+
+  private static final CommonPrivilege SQOOP_SERVER1_ALL =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("action", SqoopActionConstant.ALL));
+  private static final CommonPrivilege SQOOP_SERVER1_READ =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("action", SqoopActionConstant.READ));
+  private static final CommonPrivilege SQOOP_SERVER1_WRITE =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("action", SqoopActionConstant.WRITE));
+
+  private static final CommonPrivilege SQOOP_SERVER1_JOB1_ALL =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("JOB", "job1"),
+                  new KeyValue("action", SqoopActionConstant.ALL));
+  private static final CommonPrivilege SQOOP_SERVER1_JOB1_READ =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("JOB", "job1"),
+                  new KeyValue("action", SqoopActionConstant.READ));
+  private static final CommonPrivilege SQOOP_SERVER1_JOB1_WRITE =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("JOB", "job1"),
+                  new KeyValue("action", SqoopActionConstant.WRITE));
+
+  private static final CommonPrivilege SQOOP_SERVER1_LINK1_ALL =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("LINK", "link1"),
+                  new KeyValue("action", SqoopActionConstant.ALL));
+  private static final CommonPrivilege SQOOP_SERVER1_LINK1_READ =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("LINK", "link1"),
+                  new KeyValue("action", SqoopActionConstant.READ));
+  private static final CommonPrivilege SQOOP_SERVER1_LINK1_WRITE =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("LINK", "link1"),
+                  new KeyValue("action", SqoopActionConstant.WRITE));
+
+  private static final CommonPrivilege SQOOP_SERVER1_CONNECTOR1_ALL =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("CONNECTOR", "connector1"),
+                  new KeyValue("action", SqoopActionConstant.ALL));
+  private static final CommonPrivilege SQOOP_SERVER1_CONNECTOR1_READ =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("CONNECTOR", "connector1"),
+                  new KeyValue("action", SqoopActionConstant.READ));
+  private static final CommonPrivilege SQOOP_SERVER1_CONNECTOR1_WRITE =
+          create(new KeyValue("SERVER", "server1"), new KeyValue("CONNECTOR", "connector1"),
+                  new KeyValue("action", SqoopActionConstant.WRITE));
+
+  @Before
+  public void prepareData() {
+    sqoopPrivilegeModel = SqoopPrivilegeModel.getInstance();
+  }
+
+  @Test
+  public void testSimpleAction() throws Exception {
+    //server
+    assertFalse(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_READ, sqoopPrivilegeModel));
+    assertFalse(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_WRITE, sqoopPrivilegeModel));
+    //connector
+    assertFalse(SQOOP_SERVER1_CONNECTOR1_WRITE.implies(SQOOP_SERVER1_CONNECTOR1_READ, sqoopPrivilegeModel));
+    assertFalse(SQOOP_SERVER1_CONNECTOR1_READ.implies(SQOOP_SERVER1_CONNECTOR1_WRITE, sqoopPrivilegeModel));
+    //job
+    assertFalse(SQOOP_SERVER1_JOB1_READ.implies(SQOOP_SERVER1_JOB1_WRITE, sqoopPrivilegeModel));
+    assertFalse(SQOOP_SERVER1_JOB1_WRITE.implies(SQOOP_SERVER1_JOB1_READ, sqoopPrivilegeModel));
+    //link
+    assertFalse(SQOOP_SERVER1_LINK1_READ.implies(SQOOP_SERVER1_LINK1_WRITE, sqoopPrivilegeModel));
+    assertFalse(SQOOP_SERVER1_LINK1_WRITE.implies(SQOOP_SERVER1_LINK1_READ, sqoopPrivilegeModel));
+  }
+
+  @Test
+  public void testShorterThanRequest() throws Exception {
+    //job
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_JOB1_ALL, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_JOB1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_JOB1_WRITE, sqoopPrivilegeModel));
+
+    assertFalse(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_JOB1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_JOB1_WRITE, sqoopPrivilegeModel));
+
+    //link
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_LINK1_ALL, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_LINK1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_LINK1_WRITE, sqoopPrivilegeModel));
+
+    assertTrue(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_LINK1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_LINK1_WRITE, sqoopPrivilegeModel));
+
+    //connector
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_ALL, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_WRITE, sqoopPrivilegeModel));
+
+    assertTrue(SQOOP_SERVER1_READ.implies(SQOOP_SERVER1_CONNECTOR1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_WRITE.implies(SQOOP_SERVER1_CONNECTOR1_WRITE, sqoopPrivilegeModel));
+  }
+
+  @Test
+  public void testActionAll() throws Exception {
+    //server
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_ALL.implies(SQOOP_SERVER1_WRITE, sqoopPrivilegeModel));
+
+    //job
+    assertTrue(SQOOP_SERVER1_JOB1_ALL.implies(SQOOP_SERVER1_JOB1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_JOB1_ALL.implies(SQOOP_SERVER1_JOB1_WRITE, sqoopPrivilegeModel));
+
+    //link
+    assertTrue(SQOOP_SERVER1_LINK1_ALL.implies(SQOOP_SERVER1_LINK1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_LINK1_ALL.implies(SQOOP_SERVER1_LINK1_WRITE, sqoopPrivilegeModel));
+
+    //connector
+    assertTrue(SQOOP_SERVER1_CONNECTOR1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_READ, sqoopPrivilegeModel));
+    assertTrue(SQOOP_SERVER1_CONNECTOR1_ALL.implies(SQOOP_SERVER1_CONNECTOR1_WRITE, sqoopPrivilegeModel));
+  }
+
+  @Test
+  public void testUnexpected() throws Exception {
+    Privilege p = new Privilege() {
+      @Override
+      public boolean implies(Privilege p, Model m) {
+        return false;
+      }
+    };
+    Privilege job1 = create(new KeyValue("SERVER", "server"), new KeyValue("JOB", "job1"));
+    assertFalse(job1.implies(null, sqoopPrivilegeModel));
+    assertFalse(job1.implies(p, sqoopPrivilegeModel));
+    assertFalse(job1.equals(null));
+    assertFalse(job1.equals(p));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNullString() throws Exception {
+    System.out.println(create((String)null));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyString() throws Exception {
+    System.out.println(create(""));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("", "server1")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("SERVER", "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyPart() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_JOINER.join("SERVER", "server1"), "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testOnlySeperators() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR,
+            SentryConstants.KV_SEPARATOR)));
+  }
+
+  static CommonPrivilege create(KeyValue... keyValues) {
+    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
+  }
+
+  static CommonPrivilege create(String s) {
+    return new CommonPrivilege(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-sqoop/src/test/resources/sqoop-policy-test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-sqoop/src/test/resources/sqoop-policy-test-authz-provider.ini b/sentry-binding/sentry-binding-sqoop/src/test/resources/sqoop-policy-test-authz-provider.ini
new file mode 100644
index 0000000..a4ab5d1
--- /dev/null
+++ b/sentry-binding/sentry-binding-sqoop/src/test/resources/sqoop-policy-test-authz-provider.ini
@@ -0,0 +1,40 @@
+# 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.
+
+[groups]
+developer = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role,\
+    jobs_analyst_role,links_analyst_role
+analyst = jobs_analyst_role,links_analyst_role
+connectors_operator = jdbc_connector_role, hdfs_connector_role,kafka_connector_role,kite_connector_role
+jobs_analyst = jobs_analyst_role
+job1_2_operator = job1_role,job2_role
+links_analyst = links_analyst_role
+link1_2_operator = link1_role,link2_role
+admin = admin_role
+
+[roles]
+admin_role = server=server1->action=*
+jdbc_connector_role = server=server1->connector=generic-jdbc-connector->action=read
+hdfs_connector_role = server=server1->connector=hdfs-connector->action=read
+kafka_connector_role = server=server1->connector=kafka-connector->action=read
+kite_connector_role = server=server1->connector=kite-connector->action=read
+jobs_analyst_role = server=server1->job=all->action=*
+job1_role = server=server1->job=job1->action=read
+job2_role = server=server1->job=job2->action=read
+links_analyst_role = server=server1->link=all->action=*
+link1_role = server=server1->link=link1->action=read
+link2_role = server=server1->link=link2->action=read
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/BitFieldAction.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/BitFieldAction.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/BitFieldAction.java
index ce0e4fb..0f5b23b 100644
--- a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/BitFieldAction.java
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/BitFieldAction.java
@@ -20,7 +20,7 @@ package org.apache.sentry.core.common;
  * example, There exists three actions, UPDATE, QUERY and ALL.
  * The a bit set for UPDATE is 0x0001, QUERY is 0x0002, ALL is 0x0001|0x0002=0x0003
  */
-public abstract class BitFieldAction implements Action {
+public class BitFieldAction implements Action {
   private String name;
   private int code;
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/ImplyMethodType.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/ImplyMethodType.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/ImplyMethodType.java
new file mode 100644
index 0000000..8931989
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/ImplyMethodType.java
@@ -0,0 +1,24 @@
+/*
+ * 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.sentry.core.common;
+
+public enum ImplyMethodType {
+  STRING,
+  STRING_CASE_SENSITIVE,
+  URL,
+  ACTION,
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Model.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Model.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Model.java
new file mode 100644
index 0000000..a63cd63
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Model.java
@@ -0,0 +1,29 @@
+/*
+ * 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.sentry.core.common;
+
+import java.util.Map;
+
+// The interface is used for define the authorization model for different component
+public interface Model {
+  // The authorizableTypeName is the key of map, and the ImplyMethodType is the value.
+  Map<String, ImplyMethodType> getImplyMethodMap();
+
+  BitFieldActionFactory getBitFieldActionFactory();
+
+  // TODO: add interface to validate the hierarchy for the resources
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Resource.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Resource.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Resource.java
new file mode 100644
index 0000000..3ce52e8
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/Resource.java
@@ -0,0 +1,26 @@
+/*
+ * 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.sentry.core.common;
+
+// The interface is responsible for define the resource for every component.
+public interface Resource {
+  // Get the ResourceImplyMethodType which indicate how to compare the resource value.
+  // eg, For Hive component, it will output STRING for "db", "table", "column" and URL for "url"
+  //     in CommonPrivilege, the method imply() will compare the resource value according to the ResourceImplyMethodType.
+  //     Using String.equals() for STRING and PathUtils.impliesURI() for URL
+  ImplyMethodType getResourceImplyMethod();
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/KeyValue.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/KeyValue.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/KeyValue.java
new file mode 100644
index 0000000..4e944e5
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/KeyValue.java
@@ -0,0 +1,99 @@
+/*
+ * 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.sentry.core.common.utils;
+
+import java.util.List;
+
+import com.google.common.collect.Lists;
+
+public class KeyValue {
+  private final String key;
+  private final String value;
+
+  public KeyValue(String keyValue) {
+    List<String> kvList = Lists.newArrayList(SentryConstants.KV_SPLITTER.trimResults().limit(2).split(keyValue));
+    if (kvList.size() != 2) {
+      throw new IllegalArgumentException("Invalid key value: " + keyValue + " " + kvList);
+    }
+    key = kvList.get(0);
+    value = kvList.get(1);
+    if (key.isEmpty()) {
+      throw new IllegalArgumentException("Key cannot be empty");
+    } else if (value.isEmpty()) {
+      throw new IllegalArgumentException("Value cannot be empty");
+    }
+  }
+
+  public KeyValue(String key, String value) {
+    super();
+    this.key = key;
+    this.value = value;
+  }
+
+  public String getKey() {
+    return key;
+  }
+
+  public String getValue() {
+    return value;
+  }
+
+  @Override
+  public String toString() {
+    return SentryConstants.KV_JOINER.join(key, value);
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((key == null) ? 0 : key.hashCode());
+    result = prime * result + ((value == null) ? 0 : value.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;
+    }
+    KeyValue other = (KeyValue) obj;
+    if (key == null) {
+      if (other.key != null) {
+        return false;
+      }
+    } else if (!key.equals(other.key)) {
+      return false;
+    }
+    if (value == null) {
+      if (other.value != null) {
+        return false;
+      }
+    } else if (!value.equals(other.value)) {
+      return false;
+    }
+    return true;
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java
new file mode 100644
index 0000000..3da4906
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/utils/SentryConstants.java
@@ -0,0 +1,43 @@
+/*
+ * 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.sentry.core.common.utils;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+
+public class SentryConstants {
+
+  public static final String ROLE_SEPARATOR = ",";
+  public static final String AUTHORIZABLE_SEPARATOR = "->";
+  public static final String KV_SEPARATOR = "=";
+
+  public static final Splitter ROLE_SPLITTER = Splitter.on(ROLE_SEPARATOR);
+  public static final Splitter AUTHORIZABLE_SPLITTER = Splitter.on(AUTHORIZABLE_SEPARATOR);
+  public static final Splitter KV_SPLITTER = Splitter.on(KV_SEPARATOR);
+  public static final Joiner ROLE_JOINER = Joiner.on(ROLE_SEPARATOR);
+  public static final Joiner AUTHORIZABLE_JOINER = Joiner.on(AUTHORIZABLE_SEPARATOR);
+  public static final Joiner KV_JOINER = Joiner.on(KV_SEPARATOR);
+
+  public static final String PRIVILEGE_NAME = "action";
+  public static final String PRIVILEGE_PREFIX = (PRIVILEGE_NAME + KV_SEPARATOR).toLowerCase();
+  public static final String PRIVILEGE_WILDCARD_VALUE = "*";
+
+  public static final String RESOURCE_WILDCARD_VALUE = "*";
+  public static final String RESOURCE_WILDCARD_VALUE_ALL = "ALL";
+  public static final String RESOURCE_WILDCARD_VALUE_SOME = "+";
+  public static final String ACCESS_ALLOW_URI_PER_DB_POLICYFILE = "sentry.allow.uri.db.policyfile";
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidator.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidator.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidator.java
new file mode 100644
index 0000000..f5643ff
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidator.java
@@ -0,0 +1,24 @@
+/*
+ * 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.sentry.core.common.validator;
+
+import org.apache.shiro.config.ConfigurationException;
+
+public interface PrivilegeValidator {
+
+  void validate(PrivilegeValidatorContext context) throws ConfigurationException;
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidatorContext.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidatorContext.java b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidatorContext.java
new file mode 100644
index 0000000..ccee977
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/core/common/validator/PrivilegeValidatorContext.java
@@ -0,0 +1,38 @@
+/*
+ * 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.sentry.core.common.validator;
+
+import javax.annotation.Nullable;
+
+public class PrivilegeValidatorContext {
+  private final String database;
+  private final String privilege;
+  public PrivilegeValidatorContext(String privilege) {
+    this(null, privilege);
+  }
+  public PrivilegeValidatorContext(@Nullable String database, String privilege) {
+    super();
+    this.database = database;
+    this.privilege = privilege;
+  }
+  public @Nullable String getDatabase() {
+    return database;
+  }
+  public String getPrivilege() {
+    return privilege;
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestKeyValue.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestKeyValue.java b/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestKeyValue.java
new file mode 100644
index 0000000..ca44a24
--- /dev/null
+++ b/sentry-core/sentry-core-common/src/test/java/org/apache/sentry/core/common/utils/TestKeyValue.java
@@ -0,0 +1,74 @@
+/*
+ * 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.sentry.core.common.utils;
+
+import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
+import junit.framework.Assert;
+import org.junit.Test;
+
+public class TestKeyValue {
+
+  @Test
+  public void testWithSeparators() throws Exception {
+    KeyValue kv = new KeyValue("URI=/u/h/w/t/partition=value/");
+    Assert.assertEquals("URI", kv.getKey());
+    Assert.assertEquals("/u/h/w/t/partition=value/", kv.getValue());
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    new KeyValue(KV_JOINER.join("", "b"));
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    new KeyValue(KV_JOINER.join("a", ""));
+  }
+
+  @Test
+  public void testOneParameterConstructor() throws Exception {
+    KeyValue kv1 = new KeyValue(KV_JOINER.join("k1", "v1"));
+    KeyValue kv2 = new KeyValue(KV_JOINER.join("k1", "v1"));
+    KeyValue kv3 = new KeyValue(KV_JOINER.join("k2", "v2"));
+    doTest(kv1, kv2, kv3);
+  }
+
+  @Test
+  public void testTwoParameterConstructor() throws Exception {
+    KeyValue kv1 = new KeyValue("k1", "v1");
+    KeyValue kv2 = new KeyValue("k1", "v1");
+    KeyValue kv3 = new KeyValue("k2", "v2");
+    doTest(kv1, kv2, kv3);
+  }
+
+  private void doTest(KeyValue kv1, KeyValue kv2, KeyValue kv3) {
+    Assert.assertEquals(kv1, kv2);
+    Assert.assertFalse(kv1.equals(kv3));
+
+    Assert.assertEquals(kv1.toString(), kv2.toString());
+    Assert.assertFalse(kv1.toString().equals(kv3.toString()));
+
+    Assert.assertEquals(kv1.hashCode(), kv2.hashCode());
+    Assert.assertFalse(kv1.hashCode() == kv3.hashCode());
+
+    Assert.assertEquals(kv1.getKey(), kv2.getKey());
+    Assert.assertFalse(kv1.getKey().equals(kv3.getKey()));
+
+    Assert.assertEquals(kv1.getValue(), kv2.getValue());
+    Assert.assertFalse(kv1.getValue().equals(kv3.getValue()));
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/DBModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/DBModelAuthorizables.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/DBModelAuthorizables.java
new file mode 100644
index 0000000..3a05a3b
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/DBModelAuthorizables.java
@@ -0,0 +1,60 @@
+/*
+ * 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.sentry.core.model.db;
+
+import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+import org.apache.sentry.core.common.utils.KeyValue;
+
+public class DBModelAuthorizables {
+
+  public static DBModelAuthorizable from(KeyValue keyValue) {
+    String prefix = keyValue.getKey().toLowerCase();
+    String name = keyValue.getValue();
+    for(AuthorizableType type : AuthorizableType.values()) {
+      if(prefix.equalsIgnoreCase(type.name())) {
+        if (prefix.equalsIgnoreCase(AuthorizableType.URI.toString())) {
+          return from(type, name);
+        } else {
+          return from(type, name.toLowerCase());
+        }
+      }
+    }
+    return null;
+  }
+  public static DBModelAuthorizable from(String s) {
+    return from(new KeyValue(s));
+  }
+
+  private static DBModelAuthorizable from(AuthorizableType type, String name) {
+    switch (type) {
+    case Server:
+      return new Server(name);
+    case Db:
+      return new Database(name);
+    case Table:
+      return new Table(name);
+    case View:
+      return new View(name);
+    case Column:
+      return new Column(name);
+    case URI:
+      return new AccessURI(name);
+    default:
+      return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HiveActionFactory.java
----------------------------------------------------------------------
diff --git a/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HiveActionFactory.java b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HiveActionFactory.java
new file mode 100644
index 0000000..ad7e1c9
--- /dev/null
+++ b/sentry-core/sentry-core-model-db/src/main/java/org/apache/sentry/core/model/db/HiveActionFactory.java
@@ -0,0 +1,73 @@
+/*
+ * 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.sentry.core.model.db;
+
+import org.apache.sentry.core.common.BitFieldAction;
+import org.apache.sentry.core.common.BitFieldActionFactory;
+
+import java.util.List;
+
+// The class is used to define the privilege code for Hive
+public class HiveActionFactory extends BitFieldActionFactory {
+
+  enum ActionType {
+    SELECT(AccessConstants.SELECT, 1),    // binary: 00000001
+    INSERT(AccessConstants.INSERT, 2),    // binary: 00000010
+    ALTER(AccessConstants.ALTER, 4),      // binary: 00000100
+    CREATE(AccessConstants.CREATE, 8),    // binary: 00001000
+    DROP(AccessConstants.DROP, 16),       // binary: 00010000
+    INDEX(AccessConstants.INDEX, 32),     // binary: 00100000
+    LOCK(AccessConstants.LOCK, 64),       // binary: 01000000
+
+    // For the compatibility, ALL, ALL_STAR, SOME have the same binary value: 01111111
+    // They have the different names which are "ALL", "*", "+"
+    ALL(AccessConstants.ACTION_ALL, SELECT.getCode() | INSERT.getCode() | ALTER.getCode() | CREATE.getCode() |
+            DROP.getCode() | INDEX.getCode() | LOCK.getCode()),   // binary: 01111111
+    ALL_STAR(AccessConstants.ALL, ALL.getCode()),                 // binary: 01111111
+    SOME(AccessConstants.SOME, ALL.getCode());                    // binary: 01111111
+
+    private String name;
+    private int code;
+
+    ActionType(String name, int code) {
+      this.name = name;
+      this.code = code;
+    }
+
+    public int getCode() {
+      return code;
+    }
+
+    public String getName() {
+      return name;
+    }
+  }
+
+  public List<? extends BitFieldAction> getActionsByCode(int actionCode) {
+    return null;
+  }
+
+  public BitFieldAction getActionByName(String name) {
+    for (ActionType action : ActionType.values()) {
+      if (action.name.equalsIgnoreCase(name)) {
+        return new BitFieldAction(action.getName(), action.getCode());
+      }
+    }
+    return null;
+  }
+
+}
\ No newline at end of file


[11/13] sentry git commit: SENTRY-999: Refactor the sentry to integrate with external components quickly (Colin Ma, reviewed by Dapeng Sun)

Posted by co...@apache.org.
http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e288593..914f436 100644
--- a/pom.xml
+++ b/pom.xml
@@ -475,7 +475,7 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.sentry</groupId>
-        <artifactId>sentry-policy-db</artifactId>
+        <artifactId>sentry-policy-engine</artifactId>
         <version>${project.version}</version>
       </dependency>
       <dependency>
@@ -485,21 +485,6 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.sentry</groupId>
-        <artifactId>sentry-policy-search</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.sentry</groupId>
-        <artifactId>sentry-policy-sqoop</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.sentry</groupId>
-        <artifactId>sentry-policy-kafka</artifactId>
-        <version>${project.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.sentry</groupId>
         <artifactId>sentry-dist</artifactId>
         <version>${project.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive-common/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/pom.xml b/sentry-binding/sentry-binding-hive-common/pom.xml
index 5f00dd2..18b422d 100644
--- a/sentry-binding/sentry-binding-hive-common/pom.xml
+++ b/sentry-binding/sentry-binding-hive-common/pom.xml
@@ -71,10 +71,6 @@ limitations under the License.
       <dependency>
         <groupId>org.apache.sentry</groupId>
         <artifactId>sentry-provider-cache</artifactId>
-      </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-db</artifactId>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
index 630bef3..06fe1fe 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/SentryIniPolicyFileFormatter.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.apache.sentry.provider.common.ProviderBackendContext;
 import org.apache.sentry.provider.file.SimpleFileProviderBackend;
@@ -152,8 +152,8 @@ public class SentryIniPolicyFileFormatter implements SentryPolicyFileFormatter {
     List<String> lines = Lists.newArrayList();
     lines.add("[" + name + "]");
     for (Map.Entry<String, Set<String>> entry : mappingData.entrySet()) {
-      lines.add(PolicyConstants.KV_JOINER.join(entry.getKey(),
-          PolicyConstants.ROLE_JOINER.join(entry.getValue())));
+      lines.add(SentryConstants.KV_JOINER.join(entry.getKey(),
+          SentryConstants.ROLE_JOINER.join(entry.getValue())));
     }
     return Joiner.on(NL).join(lines);
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
index 0a1d0e8..775a1f5 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/authz/HiveAuthzBinding.java
@@ -34,11 +34,13 @@ import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
 import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
 import org.apache.sentry.binding.hive.conf.InvalidConfigurationException;
 import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Model;
 import org.apache.sentry.core.common.Subject;
 import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.core.model.db.DBModelAction;
 import org.apache.sentry.core.model.db.DBModelAuthorizable;
 import org.apache.sentry.core.model.db.DBModelAuthorizable.AuthorizableType;
+import org.apache.sentry.core.model.db.HivePrivilegeModel;
 import org.apache.sentry.core.model.db.Server;
 import org.apache.sentry.policy.common.PolicyEngine;
 import org.apache.sentry.provider.cache.PrivilegeCache;
@@ -60,6 +62,7 @@ public class HiveAuthzBinding {
   private static final Splitter ROLE_SET_SPLITTER = Splitter.on(",").trimResults()
       .omitEmptyStrings();
   public static final String HIVE_BINDING_TAG = "hive.authz.bindings.tag";
+  public static final String HIVE_POLICY_ENGINE_OLD = "org.apache.sentry.policy.db.SimpleDBPolicyEngine";
 
   private final HiveConf hiveConf;
   private final Server authServer;
@@ -206,6 +209,11 @@ public class HiveAuthzBinding {
     String providerBackendName = authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_BACKEND.getVar());
     String policyEngineName = authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar());
 
+    // for the backward compatibility
+    if (HIVE_POLICY_ENGINE_OLD.equals(policyEngineName)) {
+      policyEngineName = AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault();
+    }
+
     LOG.debug("Using authorization provider " + authProviderName +
         " with resource " + resourceName + ", policy engine "
         + policyEngineName + ", provider backend " + providerBackendName);
@@ -216,19 +224,28 @@ public class HiveAuthzBinding {
     ProviderBackend providerBackend = (ProviderBackend) providerBackendConstructor.
         newInstance(new Object[] {authzConf, resourceName});
 
+    // create backendContext
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(true);
+    context.setValidators(HivePrivilegeModel.getInstance().getPrivilegeValidators(serverName));
+    // initialize the backend with the context
+    providerBackend.initialize(context);
+
+
     // load the policy engine class
     Constructor<?> policyConstructor =
-      Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
+      Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
     policyConstructor.setAccessible(true);
     PolicyEngine policyEngine = (PolicyEngine) policyConstructor.
-        newInstance(new Object[] {serverName, providerBackend});
+        newInstance(new Object[] {providerBackend});
 
 
     // load the authz provider class
     Constructor<?> constrctor =
-      Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class);
+      Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class, Model.class);
     constrctor.setAccessible(true);
-    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine});
+    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine,
+            HivePrivilegeModel.getInstance()});
   }
 
   // Instantiate the authz provider using PrivilegeCache, this method is used for metadata filter function.
@@ -238,7 +255,13 @@ public class HiveAuthzBinding {
     String authProviderName = authzConf.get(AuthzConfVars.AUTHZ_PROVIDER.getVar());
     String resourceName =
             authzConf.get(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar());
-    String policyEngineName = authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar());
+    String policyEngineName = authzConf.get(AuthzConfVars.AUTHZ_POLICY_ENGINE.getVar(),
+            AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault());
+
+    // for the backward compatibility
+    if (HIVE_POLICY_ENGINE_OLD.equals(policyEngineName)) {
+      policyEngineName = AuthzConfVars.AUTHZ_POLICY_ENGINE.getDefault();
+    }
 
     LOG.debug("Using authorization provider " + authProviderName +
             " with resource " + resourceName + ", policy engine "
@@ -251,19 +274,19 @@ public class HiveAuthzBinding {
 
     // load the policy engine class
     Constructor<?> policyConstructor =
-            Class.forName(policyEngineName).getDeclaredConstructor(String.class, ProviderBackend.class);
+            Class.forName(policyEngineName).getDeclaredConstructor(ProviderBackend.class);
     policyConstructor.setAccessible(true);
     PolicyEngine policyEngine = (PolicyEngine) policyConstructor.
-            newInstance(new Object[] {serverName, providerBackend});
+            newInstance(new Object[] {providerBackend});
 
     // load the authz provider class
     Constructor<?> constrctor =
-            Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class);
+            Class.forName(authProviderName).getDeclaredConstructor(String.class, PolicyEngine.class, Model.class);
     constrctor.setAccessible(true);
-    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine});
+    return (AuthorizationProvider) constrctor.newInstance(new Object[] {resourceName, policyEngine,
+            HivePrivilegeModel.getInstance()});
   }
 
-
   /**
    * Validate the privilege for the given operation for the given subject
    * @param hiveOp

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
index 5a89af2..ad19b37 100644
--- a/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
+++ b/sentry-binding/sentry-binding-hive-common/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
@@ -92,7 +92,7 @@ public class HiveAuthzConf extends Configuration {
       "org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"),
     AUTHZ_PROVIDER_RESOURCE("sentry.hive.provider.resource", ""),
     AUTHZ_PROVIDER_BACKEND("sentry.hive.provider.backend", "org.apache.sentry.provider.file.SimpleFileProviderBackend"),
-    AUTHZ_POLICY_ENGINE("sentry.hive.policy.engine", "org.apache.sentry.policy.db.SimpleDBPolicyEngine"),
+    AUTHZ_POLICY_ENGINE("sentry.hive.policy.engine", "org.apache.sentry.policy.engine.common.CommonPolicyEngine"),
     AUTHZ_POLICY_FILE_FORMATTER(
         "sentry.hive.policy.file.formatter",
         "org.apache.sentry.binding.hive.SentryIniPolicyFileFormatter"),

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/pom.xml b/sentry-binding/sentry-binding-hive/pom.xml
index b769488..07aaae3 100644
--- a/sentry-binding/sentry-binding-hive/pom.xml
+++ b/sentry-binding/sentry-binding-hive/pom.xml
@@ -70,6 +70,31 @@ limitations under the License.
       <artifactId>sentry-binding-hive-common</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-core-model-db</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-common</artifactId>
+    </dependency>
+    <!-- required for SentryGrantRevokeTask -->
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-db</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-file</artifactId>
+    </dependency>
+      <dependency>
+        <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-provider-cache</artifactId>
+      </dependency>
+    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-common</artifactId>
       <scope>provided</scope>
@@ -90,6 +115,11 @@ limitations under the License.
       <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-db</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
index 2bfc339..0e7ee3d 100644
--- a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/binding/hive/TestSentryIniPolicyFileFormatter.java
@@ -25,7 +25,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
-import org.apache.sentry.policy.common.PolicyConstants;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.common.PolicyFileConstants;
 import org.junit.Test;
 
@@ -208,8 +208,8 @@ public class TestSentryIniPolicyFileFormatter {
       for (String actualPrivilege : actualPrivileges) {
         boolean isFound = exceptedPrivileges.contains(actualPrivilege);
         if (!isFound) {
-          String withOptionPrivilege = PolicyConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
-              PolicyConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
+          String withOptionPrivilege = SentryConstants.AUTHORIZABLE_JOINER.join(actualPrivilege,
+              SentryConstants.KV_JOINER.join(PolicyFileConstants.PRIVILEGE_GRANT_OPTION_NAME,
                   "false"));
           isFound = exceptedPrivileges.contains(withOptionPrivilege);
         }

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java
new file mode 100644
index 0000000..df8443c
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/AbstractTestSimplePolicyEngine.java
@@ -0,0 +1,156 @@
+/*
+ * 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.sentry.policy.hive;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public abstract class AbstractTestSimplePolicyEngine {
+  private static final String PERM_SERVER1_CUSTOMERS_SELECT = "server=server1->db=customers->table=purchases->action=select";
+  private static final String PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT = "server=server1->db=customers->table=purchases_partial->action=select";
+  private static final String PERM_SERVER1_ANALYST_ALL = "server=server1->db=analyst1";
+  private static final String PERM_SERVER1_JUNIOR_ANALYST_ALL = "server=server1->db=jranalyst1";
+  private static final String PERM_SERVER1_JUNIOR_ANALYST_READ = "server=server1->db=jranalyst1->table=*->action=select";
+  private static final String PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT = "server=server1->db=other_group_db->table=purchases->action=select";
+
+  private static final String PERM_SERVER1_ADMIN = "server=server1";
+  private PolicyEngine policy;
+  private static File baseDir;
+
+  @BeforeClass
+  public static void setupClazz() throws IOException {
+    baseDir = Files.createTempDir();
+  }
+
+  @AfterClass
+  public static void teardownClazz() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  protected void setPolicy(PolicyEngine policy) {
+    this.policy = policy;
+  }
+  protected static File getBaseDir() {
+    return baseDir;
+  }
+  @Before
+  public void setup() throws IOException {
+    afterSetup();
+  }
+  @After
+  public void teardown() throws IOException {
+    beforeTeardown();
+  }
+  protected void afterSetup() throws IOException {
+
+  }
+
+  protected void beforeTeardown() throws IOException {
+
+  }
+
+  @Test
+  public void testManager() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        PERM_SERVER1_CUSTOMERS_SELECT, PERM_SERVER1_ANALYST_ALL,
+        PERM_SERVER1_JUNIOR_ANALYST_ALL, PERM_SERVER1_JUNIOR_ANALYST_READ,
+        PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT
+        ));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("manager"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testAnalyst() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        PERM_SERVER1_CUSTOMERS_SELECT, PERM_SERVER1_ANALYST_ALL,
+        PERM_SERVER1_JUNIOR_ANALYST_READ));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("analyst"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testJuniorAnalyst() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets
+        .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
+            PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(PERM_SERVER1_ADMIN));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("admin"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+
+  @Test
+  public void testOtherGroup() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("other_group"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testDbAll() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets
+        .newHashSet(PERM_SERVER1_JUNIOR_ANALYST_ALL,
+            PERM_SERVER1_CUSTOMERS_DB_CUSTOMERS_PARTIAL_SELECT));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("jranalyst"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  @Test
+  public void testDbAllforOtherGroup() throws Exception {
+    Set<String> expected = Sets.newTreeSet(Sets.newHashSet(
+        PERM_SERVER1_OTHER_GROUP_DB_CUSTOMERS_SELECT));
+    Assert.assertEquals(expected.toString(),
+        new TreeSet<String>(policy.getAllPrivileges(set("other_group"), ActiveRoleSet.ALL))
+        .toString());
+  }
+
+  private static Set<String> set(String... values) {
+    return Sets.newHashSet(values);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java
new file mode 100644
index 0000000..854acbe
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/DBPolicyTestUtil.java
@@ -0,0 +1,45 @@
+/*
+ * 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.sentry.policy.hive;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.core.model.db.HivePrivilegeModel;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.policy.engine.common.CommonPolicyEngine;
+import org.apache.sentry.provider.common.ProviderBackend;
+import org.apache.sentry.provider.common.ProviderBackendContext;
+import org.apache.sentry.provider.file.SimpleFileProviderBackend;
+
+import java.io.IOException;
+
+public class DBPolicyTestUtil {
+
+  public static PolicyEngine createPolicyEngineForTest(String server, String resource) throws IOException {
+
+    ProviderBackend providerBackend = new SimpleFileProviderBackend(new Configuration(), resource);
+
+    // create backendContext
+    ProviderBackendContext context = new ProviderBackendContext();
+    context.setAllowPerDatabase(true);
+    context.setValidators(HivePrivilegeModel.getInstance().getPrivilegeValidators(server));
+    // initialize the backend with the context
+    providerBackend.initialize(context);
+
+
+    return new CommonPolicyEngine(providerBackend);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java
new file mode 100644
index 0000000..fba2e1c
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDBModelAuthorizables.java
@@ -0,0 +1,77 @@
+/*
+ * 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.sentry.policy.hive;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import org.apache.sentry.core.model.db.AccessURI;
+import org.apache.sentry.core.model.db.DBModelAuthorizables;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.core.model.db.Table;
+import org.apache.sentry.core.model.db.View;
+import org.junit.Test;
+
+public class TestDBModelAuthorizables {
+
+  @Test
+  public void testServer() throws Exception {
+    Server server = (Server) DBModelAuthorizables.from("SeRvEr=server1");
+    assertEquals("server1", server.getName());
+  }
+  @Test
+  public void testDb() throws Exception {
+    Database db = (Database)DBModelAuthorizables.from("dB=db1");
+    assertEquals("db1", db.getName());
+  }
+  @Test
+  public void testTable() throws Exception {
+    Table table = (Table)DBModelAuthorizables.from("tAbLe=t1");
+    assertEquals("t1", table.getName());
+  }
+  @Test
+  public void testView() throws Exception {
+    View view = (View)DBModelAuthorizables.from("vIeW=v1");
+    assertEquals("v1", view.getName());
+  }
+  @Test
+  public void testURI() throws Exception {
+    AccessURI uri = (AccessURI)DBModelAuthorizables.from("UrI=hdfs://uri1:8200/blah");
+    assertEquals("hdfs://uri1:8200/blah", uri.getName());
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNoKV() throws Exception {
+    System.out.println(DBModelAuthorizables.from("nonsense"));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(DBModelAuthorizables.from("=v"));
+  }
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(DBModelAuthorizables.from("k="));
+  }
+  @Test
+  public void testNotAuthorizable() throws Exception {
+    assertNull(DBModelAuthorizables.from("k=v"));
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java
new file mode 100644
index 0000000..24f3ae9
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestDatabaseRequiredInRole.java
@@ -0,0 +1,50 @@
+/*
+ * 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.sentry.policy.hive;
+
+import org.junit.Assert;
+
+import org.apache.sentry.core.common.validator.PrivilegeValidatorContext;
+import org.apache.sentry.core.model.db.validator.DatabaseRequiredInPrivilege;
+import org.apache.shiro.config.ConfigurationException;
+import org.junit.Test;
+
+public class TestDatabaseRequiredInRole {
+
+  @Test
+  public void testURIInPerDbPolicyFile() throws Exception {
+    DatabaseRequiredInPrivilege dbRequiredInRole = new DatabaseRequiredInPrivilege();
+    System.setProperty("sentry.allow.uri.db.policyfile", "true");
+    dbRequiredInRole.validate(new PrivilegeValidatorContext("db1",
+      "server=server1->URI=file:///user/db/warehouse/tab1"));
+    System.setProperty("sentry.allow.uri.db.policyfile", "false");
+  }
+
+  @Test
+  public void testURIWithDBInPerDbPolicyFile() throws Exception {
+    DatabaseRequiredInPrivilege dbRequiredInRole = new DatabaseRequiredInPrivilege();
+    try {
+      dbRequiredInRole.validate(new PrivilegeValidatorContext("db1",
+        "server=server1->db=db1->URI=file:///user/db/warehouse/tab1"));
+      Assert.fail("Expected ConfigurationException");
+    } catch (ConfigurationException e) {
+      // expected
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java
new file mode 100644
index 0000000..4dc8812
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestPolicyParsingNegative.java
@@ -0,0 +1,194 @@
+/*
+ * 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.sentry.policy.hive;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestPolicyParsingNegative {
+
+  @SuppressWarnings("unused")
+  private static final Logger LOGGER = LoggerFactory
+      .getLogger(TestPolicyParsingNegative.class);
+
+  private File baseDir;
+  private File globalPolicyFile;
+  private File otherPolicyFile;
+
+  @Before
+  public void setup() {
+    baseDir = Files.createTempDir();
+    globalPolicyFile = new File(baseDir, "global.ini");
+    otherPolicyFile = new File(baseDir, "other.ini");
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void append(String from, File to) throws IOException {
+    Files.append(from + "\n", to, Charsets.UTF_8);
+  }
+
+  @Test
+  public void testUnauthorizedDbSpecifiedInDBPolicyFile() throws Exception {
+    append("[databases]", globalPolicyFile);
+    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
+    append("[groups]", otherPolicyFile);
+    append("other_group = malicious_role", otherPolicyFile);
+    append("[roles]", otherPolicyFile);
+    append("malicious_role = server=server1->db=customers->table=purchases->action=select", otherPolicyFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+  @Test
+  public void testPerDbFileCannotContainUsersOrDatabases() throws Exception {
+    PolicyEngine policy;
+    ImmutableSet<String> permissions;
+    PolicyFile policyFile;
+    // test sanity
+    policyFile = PolicyFile.setAdminOnServer1("admin");
+    policyFile.addGroupsToUser("admin1", "admin");
+    policyFile.write(globalPolicyFile);
+    policyFile.write(otherPolicyFile);
+    policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
+    Assert.assertEquals(permissions.toString(), "[server=server1]");
+    // test to ensure [users] fails parsing of per-db file
+    policyFile.addDatabase("other", otherPolicyFile.getPath());
+    policyFile.write(globalPolicyFile);
+    policyFile.write(otherPolicyFile);
+    policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
+    Assert.assertEquals(permissions.toString(), "[server=server1]");
+    // test to ensure [databases] fails parsing of per-db file
+    // by removing the user mapping from the per-db policy file
+    policyFile.removeGroupsFromUser("admin1", "admin")
+      .write(otherPolicyFile);
+    policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    permissions = policy.getAllPrivileges(Sets.newHashSet("admin"), ActiveRoleSet.ALL);
+    Assert.assertEquals(permissions.toString(), "[server=server1]");
+  }
+
+  @Test
+  public void testDatabaseRequiredInRole() throws Exception {
+    append("[databases]", globalPolicyFile);
+    append("other_group_db = " + otherPolicyFile.getPath(), globalPolicyFile);
+    append("[groups]", otherPolicyFile);
+    append("other_group = malicious_role", otherPolicyFile);
+    append("[roles]", otherPolicyFile);
+    append("malicious_role = server=server1", otherPolicyFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("other_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testServerAll() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = server=*", globalPolicyFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testServerIncorrect() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = server=server2", globalPolicyFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  @Test
+  public void testAll() throws Exception {
+    append("[groups]", globalPolicyFile);
+    append("group = malicious_role", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("malicious_role = *", globalPolicyFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+  }
+
+  /**
+   * Create policy file with multiple per db files.
+   * Verify that a file with bad format is the only one that's ignored
+   * @throws Exception
+   */
+  @Test
+  public void testMultiDbWithErrors() throws Exception {
+    File db1PolicyFile = new File(baseDir, "db1.ini");
+    File db2PolicyFile = new File(baseDir, "db2.ini");
+
+    // global policy file
+    append("[databases]", globalPolicyFile);
+    append("db1 = " + db1PolicyFile.getPath(), globalPolicyFile);
+    append("db2 = " + db2PolicyFile.getPath(), globalPolicyFile);
+    append("[groups]", globalPolicyFile);
+    append("db3_group = db3_rule", globalPolicyFile);
+    append("[roles]", globalPolicyFile);
+    append("db3_rule = server=server1->db=db3->table=sales->action=select", globalPolicyFile);
+
+    //db1 policy file with badly formatted rule
+    append("[groups]", db1PolicyFile);
+    append("db1_group = bad_rule", db1PolicyFile);
+    append("[roles]", db1PolicyFile);
+    append("bad_rule = server=server1->db=customers->=purchases->action=", db1PolicyFile);
+
+    //db2 policy file with proper rule
+    append("[groups]", db2PolicyFile);
+    append("db2_group = db2_rule", db2PolicyFile);
+    append("[roles]", db2PolicyFile);
+    append("db2_rule = server=server1->db=db2->table=purchases->action=select", db2PolicyFile);
+
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+
+    // verify that the db1 rule is empty
+    ImmutableSet<String> permissions = policy.getAllPrivileges(Sets.newHashSet("db1_group"), ActiveRoleSet.ALL);
+    Assert.assertTrue(permissions.toString(), permissions.isEmpty());
+
+    permissions = policy.getAllPrivileges(Sets.newHashSet("db2_group"), ActiveRoleSet.ALL);
+    Assert.assertEquals(permissions.toString(), 1, permissions.size());
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java
new file mode 100644
index 0000000..403eb6a
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderGeneralCases.java
@@ -0,0 +1,195 @@
+/*
+ * 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.sentry.policy.hive;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+import junit.framework.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.core.model.db.DBModelAction;
+import org.apache.sentry.core.model.db.Database;
+import org.apache.sentry.core.model.db.HivePrivilegeModel;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.core.model.db.Table;
+import org.apache.sentry.provider.common.GroupMappingService;
+import org.apache.sentry.provider.common.ResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.HadoopGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.After;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.io.Files;
+
+
+public class TestResourceAuthorizationProviderGeneralCases {
+
+  private static final Logger LOGGER = LoggerFactory
+      .getLogger(TestResourceAuthorizationProviderGeneralCases.class);
+
+  private static final Multimap<String, String> USER_TO_GROUP_MAP = HashMultimap
+      .create();
+
+  private static final Subject SUB_ADMIN = new Subject("admin1");
+  private static final Subject SUB_MANAGER = new Subject("manager1");
+  private static final Subject SUB_ANALYST = new Subject("analyst1");
+  private static final Subject SUB_JUNIOR_ANALYST = new Subject("jranalyst1");
+
+  private static final Server SVR_SERVER1 = new Server("server1");
+  private static final Server SVR_ALL = new Server(AccessConstants.ALL);
+
+  private static final Database DB_CUSTOMERS = new Database("customers");
+  private static final Database DB_ANALYST = new Database("analyst1");
+  private static final Database DB_JR_ANALYST = new Database("jranalyst1");
+
+  private static final Table TBL_PURCHASES = new Table("purchases");
+
+  private static final Set<? extends Action> ALL = EnumSet.of(DBModelAction.ALL);
+  private static final Set<? extends Action> SELECT = EnumSet.of(DBModelAction.SELECT);
+  private static final Set<? extends Action> INSERT = EnumSet.of(DBModelAction.INSERT);
+
+  static {
+    USER_TO_GROUP_MAP.putAll(SUB_ADMIN.getName(), Arrays.asList("admin"));
+    USER_TO_GROUP_MAP.putAll(SUB_MANAGER.getName(), Arrays.asList("manager"));
+    USER_TO_GROUP_MAP.putAll(SUB_ANALYST.getName(), Arrays.asList("analyst"));
+    USER_TO_GROUP_MAP.putAll(SUB_JUNIOR_ANALYST.getName(),
+        Arrays.asList("jranalyst"));
+  }
+
+  private final ResourceAuthorizationProvider authzProvider;
+  private File baseDir;
+
+  public TestResourceAuthorizationProviderGeneralCases() throws IOException {
+    baseDir = Files.createTempDir();
+    PolicyFiles.copyToDir(baseDir, "hive-policy-test-authz-provider.ini", "hive-policy-test-authz-provider-other-group.ini");
+    authzProvider = new HadoopGroupResourceAuthorizationProvider(
+            DBPolicyTestUtil.createPolicyEngineForTest("server1",
+        new File(baseDir, "hive-policy-test-authz-provider.ini").getPath()),
+        new MockGroupMappingServiceProvider(USER_TO_GROUP_MAP), HivePrivilegeModel.getInstance());
+
+  }
+
+  @After
+  public void teardown() {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  private void doTestAuthorizables(
+      Subject subject, Set<? extends Action> privileges, boolean expected,
+      Authorizable... authorizables) throws Exception {
+    List<Authorizable> authzHierarchy = Arrays.asList(authorizables);
+    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
+      helper.add("authorizables", authzHierarchy).add("Privileges", privileges);
+    LOGGER.info("Running with " + helper.toString());
+    Assert.assertEquals(helper.toString(), expected,
+        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
+    LOGGER.info("Passed " + helper.toString());
+  }
+
+  private void doTestResourceAuthorizationProvider(Subject subject,
+      Server server, Database database, Table table,
+      Set<? extends Action> privileges, boolean expected) throws Exception {
+    List<Authorizable> authzHierarchy = Arrays.asList(new Authorizable[] {
+        server, database, table
+    });
+    Objects.ToStringHelper helper = Objects.toStringHelper("TestParameters");
+    helper.add("Subject", subject).add("Server", server).add("DB", database)
+    .add("Table", table).add("Privileges", privileges).add("authzHierarchy", authzHierarchy);
+    LOGGER.info("Running with " + helper.toString());
+    Assert.assertEquals(helper.toString(), expected,
+        authzProvider.hasAccess(subject, authzHierarchy, privileges, ActiveRoleSet.ALL));
+    LOGGER.info("Passed " + helper.toString());
+  }
+
+  @Test
+  public void testAdmin() throws Exception {
+    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
+    doTestResourceAuthorizationProvider(SUB_ADMIN, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, true);
+    doTestAuthorizables(SUB_ADMIN, SELECT, true, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES);
+
+  }
+  @Test
+  public void testManager() throws Exception {
+    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
+    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
+    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
+    doTestResourceAuthorizationProvider(SUB_MANAGER, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
+  }
+  @Test
+  public void testAnalyst() throws Exception {
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, true);
+
+    // analyst sandbox
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, ALL, true);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, SELECT, true);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_ANALYST, TBL_PURCHASES, INSERT, true);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_ANALYST, TBL_PURCHASES, SELECT, true);
+
+    // jr analyst sandbox
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, ALL, false);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, INSERT, false);
+    doTestResourceAuthorizationProvider(SUB_ANALYST, SVR_ALL, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
+  }
+  @Test
+  public void testJuniorAnalyst() throws Exception {
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, ALL, false);
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, SELECT, false);
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_CUSTOMERS, TBL_PURCHASES, INSERT, false);
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_ALL, DB_CUSTOMERS, TBL_PURCHASES, SELECT, false);
+    // jr analyst sandbox
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, ALL, true);
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_SERVER1, DB_JR_ANALYST, TBL_PURCHASES, INSERT, true);
+    doTestResourceAuthorizationProvider(SUB_JUNIOR_ANALYST, SVR_ALL, DB_JR_ANALYST, TBL_PURCHASES, SELECT, true);
+  }
+
+  public class MockGroupMappingServiceProvider implements GroupMappingService {
+    private final Multimap<String, String> userToGroupMap;
+
+    public MockGroupMappingServiceProvider(Multimap<String, String> userToGroupMap) {
+      this.userToGroupMap = userToGroupMap;
+    }
+
+    @Override
+    public Set<String> getGroups(String user) {
+      return Sets.newHashSet(userToGroupMap.get(user));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java
new file mode 100644
index 0000000..6fe9e6b
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestResourceAuthorizationProviderSpecialCases.java
@@ -0,0 +1,124 @@
+ /*
+ * 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.sentry.policy.hive;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.core.common.Action;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.core.common.Authorizable;
+import org.apache.sentry.core.common.Subject;
+import org.apache.sentry.core.model.db.AccessURI;
+import org.apache.sentry.core.model.db.DBModelAction;
+import org.apache.sentry.core.model.db.HivePrivilegeModel;
+import org.apache.sentry.core.model.db.Server;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.common.AuthorizationProvider;
+import org.apache.sentry.provider.file.LocalGroupResourceAuthorizationProvider;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.Files;
+
+public class TestResourceAuthorizationProviderSpecialCases {
+  private AuthorizationProvider authzProvider;
+  private PolicyFile policyFile;
+  private File baseDir;
+  private File iniFile;
+  private String initResource;
+  @Before
+  public void setup() throws IOException {
+    baseDir = Files.createTempDir();
+    iniFile = new File(baseDir, "policy.ini");
+    initResource = "file://" + iniFile.getPath();
+    policyFile = new PolicyFile();
+  }
+
+  @After
+  public void teardown() throws IOException {
+    if(baseDir != null) {
+      FileUtils.deleteQuietly(baseDir);
+    }
+  }
+
+  @Test
+  public void testDuplicateEntries() throws Exception {
+    Subject user1 = new Subject("user1");
+    Server server1 = new Server("server1");
+    AccessURI uri = new AccessURI("file:///path/to/");
+    Set<? extends Action> actions = EnumSet.of(DBModelAction.ALL, DBModelAction.SELECT, DBModelAction.INSERT);
+    policyFile.addGroupsToUser(user1.getName(), true, "group1", "group1")
+      .addRolesToGroup("group1",  true, "role1", "role1")
+      .addPermissionsToRole("role1", true, "server=" + server1.getName() + "->uri=" + uri.getName(),
+          "server=" + server1.getName() + "->uri=" + uri.getName());
+    policyFile.write(iniFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest(server1.getName(), initResource);
+    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, HivePrivilegeModel.getInstance());
+    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, uri);
+    Assert.assertTrue(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+  @Test
+  public void testNonAbolutePath() throws Exception {
+    Subject user1 = new Subject("user1");
+    Server server1 = new Server("server1");
+    AccessURI uri = new AccessURI("file:///path/to/");
+    Set<? extends Action> actions = EnumSet.of(DBModelAction.ALL, DBModelAction.SELECT, DBModelAction.INSERT);
+    policyFile.addGroupsToUser(user1.getName(), "group1")
+      .addRolesToGroup("group1", "role1")
+      .addPermissionsToRole("role1", "server=" + server1.getName() + "->uri=" + uri.getName());
+    policyFile.write(iniFile);
+    PolicyEngine policy = DBPolicyTestUtil.createPolicyEngineForTest(server1.getName(), initResource);
+    authzProvider = new LocalGroupResourceAuthorizationProvider(initResource, policy, HivePrivilegeModel.getInstance());
+    // positive test
+    List<? extends Authorizable> authorizableHierarchy = ImmutableList.of(server1, uri);
+    Assert.assertTrue(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+    // negative tests
+    // TODO we should support the case of /path/to/./ but let's to that later
+    uri = new AccessURI("file:///path/to/./");
+    authorizableHierarchy = ImmutableList.of(server1, uri);
+    Assert.assertFalse(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+    uri = new AccessURI("file:///path/to/../");
+    authorizableHierarchy = ImmutableList.of(server1, uri);
+    Assert.assertFalse(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+    uri = new AccessURI("file:///path/to/../../");
+    authorizableHierarchy = ImmutableList.of(server1, uri);
+    Assert.assertFalse(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+    uri = new AccessURI("file:///path/to/dir/../../");
+    authorizableHierarchy = ImmutableList.of(server1, uri);
+    Assert.assertFalse(authorizableHierarchy.toString(),
+        authzProvider.hasAccess(user1, authorizableHierarchy, actions, ActiveRoleSet.ALL));
+  }
+  @Test(expected=IllegalArgumentException.class)
+  public void testInvalidPath() throws Exception {
+    new AccessURI(":invaliduri");
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java
new file mode 100644
index 0000000..97cf615
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineDFS.java
@@ -0,0 +1,115 @@
+/*
+ * 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.sentry.policy.hive;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import org.junit.Assert;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.sentry.core.common.ActiveRoleSet;
+import org.apache.sentry.policy.common.PolicyEngine;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.provider.file.PolicyFiles;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
+
+public class TestSimpleDBPolicyEngineDFS extends AbstractTestSimplePolicyEngine {
+
+  private static MiniDFSCluster dfsCluster;
+  private static FileSystem fileSystem;
+  private static Path root;
+  private static Path etc;
+
+  @BeforeClass
+  public static void setupLocalClazz() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    File dfsDir = new File(baseDir, "dfs");
+    Assert.assertTrue(dfsDir.isDirectory() || dfsDir.mkdirs());
+    Configuration conf = new Configuration();
+    conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, dfsDir.getPath());
+    dfsCluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
+    fileSystem = dfsCluster.getFileSystem();
+    root = new Path(fileSystem.getUri().toString());
+    etc = new Path(root, "/etc");
+    fileSystem.mkdirs(etc);
+  }
+  @AfterClass
+  public static void teardownLocalClazz() {
+    if(dfsCluster != null) {
+      dfsCluster.shutdown();
+    }
+  }
+
+  @Override
+  protected void  afterSetup() throws IOException {
+    fileSystem.delete(etc, true);
+    fileSystem.mkdirs(etc);
+    PolicyFiles.copyToDir(fileSystem, etc, "hive-policy-test-authz-provider.ini", "hive-policy-test-authz-provider-other-group.ini");
+    setPolicy(DBPolicyTestUtil.createPolicyEngineForTest("server1",
+        new Path(etc, "hive-policy-test-authz-provider.ini").toString()));
+  }
+  @Override
+  protected void beforeTeardown() throws IOException {
+    fileSystem.delete(etc, true);
+  }
+
+  @Test
+  public void testMultiFSPolicy() throws Exception {
+    File globalPolicyFile = new File(Files.createTempDir(), "global-policy.ini");
+    File dbPolicyFile = new File(Files.createTempDir(), "db11-policy.ini");
+
+    // Create global policy file
+    PolicyFile dbPolicy = new PolicyFile()
+      .addPermissionsToRole("db11_role", "server=server1->db=db11")
+      .addRolesToGroup("group1", "db11_role");
+
+    dbPolicy.write(dbPolicyFile);
+    Path dbPolicyPath = new Path(etc, "db11-policy.ini");
+
+    // create per-db policy file
+    PolicyFile globalPolicy = new PolicyFile()
+      .addPermissionsToRole("admin_role", "server=server1")
+      .addRolesToGroup("admin_group", "admin_role")
+      .addGroupsToUser("db", "admin_group");
+    globalPolicy.addDatabase("db11", dbPolicyPath.toUri().toString());
+    globalPolicy.write(globalPolicyFile);
+
+
+    PolicyFiles.copyFilesToDir(fileSystem, etc, globalPolicyFile);
+    PolicyFiles.copyFilesToDir(fileSystem, etc, dbPolicyFile);
+    PolicyEngine multiFSEngine =
+            DBPolicyTestUtil.createPolicyEngineForTest("server1", globalPolicyFile.getPath());
+
+    Set<String> dbGroups = Sets.newHashSet();
+    dbGroups.add("group1");
+    ImmutableSet<String> dbPerms =
+        multiFSEngine.getAllPrivileges(dbGroups, ActiveRoleSet.ALL);
+    Assert.assertEquals("No DB permissions found", 1, dbPerms.size());
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java
new file mode 100644
index 0000000..c986d7e
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/policy/hive/TestSimpleDBPolicyEngineLocalFS.java
@@ -0,0 +1,44 @@
+/*
+ * 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.sentry.policy.hive;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.junit.Assert;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sentry.provider.file.PolicyFiles;
+
+public class TestSimpleDBPolicyEngineLocalFS extends AbstractTestSimplePolicyEngine {
+
+  @Override
+  protected void  afterSetup() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    Assert.assertTrue(baseDir.isDirectory() || baseDir.mkdirs());
+    PolicyFiles.copyToDir(baseDir, "hive-policy-test-authz-provider.ini", "hive-policy-test-authz-provider-other-group.ini");
+    setPolicy(DBPolicyTestUtil.createPolicyEngineForTest("server1",
+        new File(baseDir, "hive-policy-test-authz-provider.ini").getPath()));
+  }
+  @Override
+  protected void beforeTeardown() throws IOException {
+    File baseDir = getBaseDir();
+    Assert.assertNotNull(baseDir);
+    FileUtils.deleteQuietly(baseDir);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
new file mode 100644
index 0000000..c719802
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/java/org/apache/sentry/privilege/hive/TestCommonPrivilegeForHive.java
@@ -0,0 +1,344 @@
+/*
+ * 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.sentry.privilege.hive;
+
+import junit.framework.Assert;
+import org.apache.sentry.core.common.Model;
+import org.apache.sentry.core.common.utils.KeyValue;
+import org.apache.sentry.core.common.utils.PathUtils;
+import org.apache.sentry.core.common.utils.SentryConstants;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.core.model.db.HivePrivilegeModel;
+import org.apache.sentry.policy.common.CommonPrivilege;
+import org.apache.sentry.policy.common.Privilege;
+import org.junit.Before;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+public class TestCommonPrivilegeForHive {
+
+  private Model hivePrivilegeModel;
+
+  private static final String ALL = AccessConstants.ALL;
+
+  private static final CommonPrivilege ROLE_SERVER_SERVER1_DB_ALL =
+          create(new KeyValue("server", "server1"), new KeyValue("db", ALL));
+  private static final CommonPrivilege ROLE_SERVER_SERVER1_DB_DB1 =
+          create(new KeyValue("server", "server1"), new KeyValue("db", "db1"));
+  private static final CommonPrivilege ROLE_SERVER_SERVER2_DB_ALL =
+          create(new KeyValue("server", "server2"), new KeyValue("db", ALL));
+  private static final CommonPrivilege ROLE_SERVER_SERVER2_DB_DB1 =
+          create(new KeyValue("server", "server2"), new KeyValue("db", "db1"));
+  private static final CommonPrivilege ROLE_SERVER_ALL_DB_ALL =
+          create(new KeyValue("server", ALL), new KeyValue("db", ALL));
+  private static final CommonPrivilege ROLE_SERVER_ALL_DB_DB1 =
+          create(new KeyValue("server", ALL), new KeyValue("db", "db1"));
+
+  private static final CommonPrivilege ROLE_SERVER_SERVER1_URI_URI1 =
+          create(new KeyValue("server", "server1"), new KeyValue("uri",
+                  "hdfs://namenode:8020/path/to/uri1"));
+  private static final CommonPrivilege ROLE_SERVER_SERVER1_URI_URI2 =
+          create(new KeyValue("server", "server1"), new KeyValue("uri",
+                  "hdfs://namenode:8020/path/to/uri2/"));
+  private static final CommonPrivilege ROLE_SERVER_SERVER1_URI_ALL =
+          create(new KeyValue("server", "server1"), new KeyValue("uri", ALL));
+
+  private static final CommonPrivilege ROLE_SERVER_SERVER1 =
+          create(new KeyValue("server", "server1"));
+
+  private static final CommonPrivilege REQUEST_SERVER1_DB1 =
+          create(new KeyValue("server", "server1"), new KeyValue("db", "db1"));
+  private static final CommonPrivilege REQUEST_SERVER2_DB1 =
+          create(new KeyValue("server", "server2"), new KeyValue("db", "db1"));
+  private static final CommonPrivilege REQUEST_SERVER1_DB2 =
+          create(new KeyValue("server", "server1"), new KeyValue("db", "db2"));
+  private static final CommonPrivilege REQUEST_SERVER2_DB2 =
+          create(new KeyValue("server", "server2"), new KeyValue("db", "db2"));
+
+  private static final CommonPrivilege REQUEST_SERVER1_URI1 =
+          create(new KeyValue("server", "server1"), new KeyValue("uri",
+                  "hdfs://namenode:8020/path/to/uri1/some/file"));
+  private static final CommonPrivilege REQUEST_SERVER1_URI2 =
+          create(new KeyValue("server", "server1"), new KeyValue("uri",
+                  "hdfs://namenode:8020/path/to/uri2/some/other/file"));
+
+  private static final CommonPrivilege REQUEST_SERVER1_OTHER =
+          create(new KeyValue("server", "server2"), new KeyValue("other", "thing"));
+
+  private static final CommonPrivilege REQUEST_SERVER1 =
+          create(new KeyValue("server", "server2"));
+
+  @Before
+  public void prepareData() {
+    hivePrivilegeModel = HivePrivilegeModel.getInstance();
+  }
+
+  @Test
+  public void testOther() throws Exception {
+    assertFalse(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_OTHER, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_OTHER.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
+  }
+
+  @Test
+  public void testRoleShorterThanRequest() throws Exception {
+    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1, hivePrivilegeModel));
+  }
+
+  @Test
+  public void testRolesAndRequests() throws Exception {
+    // ROLE_SERVER_SERVER1_DB_ALL
+    assertTrue(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    // test inverse
+    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER1_DB_ALL, hivePrivilegeModel));
+
+    // ROLE_SERVER_SERVER1_DB_DB1
+    assertTrue(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_DB1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    // test inverse
+    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER1_DB_DB1, hivePrivilegeModel));
+
+    // ROLE_SERVER_SERVER2_DB_ALL
+    assertFalse(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER2_DB_ALL.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    // test inverse
+    assertFalse(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER2_DB_ALL, hivePrivilegeModel));
+
+    // ROLE_SERVER_SERVER2_DB_DB1
+    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER2_DB_DB1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    assertFalse(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_SERVER2_DB_DB1, hivePrivilegeModel));
+
+    // ROLE_SERVER_ALL_DB_ALL
+    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_ALL_DB_ALL.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    // test inverse
+    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_ALL_DB_ALL, hivePrivilegeModel));
+
+    // ROLE_SERVER_ALL_DB_DB1
+    assertTrue(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_DB1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER2_DB1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_DB2, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER2_DB2, hivePrivilegeModel));
+
+    // test inverse
+    assertTrue(REQUEST_SERVER1_DB1.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER2_DB1.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_DB2.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB2.implies(ROLE_SERVER_ALL_DB_DB1, hivePrivilegeModel));
+
+    // uri
+    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1_URI_ALL.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1_URI_ALL.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1_URI_URI1.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_URI_URI1.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
+    assertTrue(ROLE_SERVER_SERVER1_URI_URI2.implies(REQUEST_SERVER1_URI2, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_URI_URI2.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER2_DB2.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_ALL_DB_DB1.implies(REQUEST_SERVER1_URI1, hivePrivilegeModel));
+    // test inverse
+    assertTrue(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_ALL, hivePrivilegeModel));
+    assertTrue(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_ALL, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_URI1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_URI1, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_URI2.implies(ROLE_SERVER_SERVER1_URI_URI2, hivePrivilegeModel));
+    assertFalse(REQUEST_SERVER1_URI1.implies(ROLE_SERVER_SERVER1_URI_URI2, hivePrivilegeModel));
+  };
+
+  @Test
+  public void testUnexpected() throws Exception {
+    Privilege p = new Privilege() {
+      @Override
+      public boolean implies(Privilege p, Model m) {
+        return false;
+      }
+    };
+    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(null, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.implies(p, hivePrivilegeModel));
+    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(null));
+    assertFalse(ROLE_SERVER_SERVER1_DB_ALL.equals(p));
+
+    Assert.assertEquals(ROLE_SERVER_SERVER1_DB_ALL.hashCode(),
+            create(ROLE_SERVER_SERVER1_DB_ALL.toString()).hashCode());
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testNullString() throws Exception {
+    System.out.println(create((String)null));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyString() throws Exception {
+    System.out.println(create(""));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyKey() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("", "db1")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyValue() throws Exception {
+    System.out.println(create(SentryConstants.KV_JOINER.join("db", "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testEmptyPart() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_JOINER.join("server", "server1"), "")));
+  }
+
+  @Test(expected=IllegalArgumentException.class)
+  public void testOnlySeperators() throws Exception {
+    System.out.println(create(SentryConstants.AUTHORIZABLE_JOINER.
+            join(SentryConstants.KV_SEPARATOR, SentryConstants.KV_SEPARATOR,
+            SentryConstants.KV_SEPARATOR)));
+  }
+
+  @Test
+  public void testImpliesURIPositive() throws Exception {
+    assertTrue(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path/to/some/dir"));
+    assertTrue(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path"));
+    assertTrue(PathUtils.impliesURI("file:///path", "file:///path/to/some/dir"));
+    assertTrue(PathUtils.impliesURI("file:///path", "file:///path"));
+  }
+
+  @Test
+  public void testImpliesURINegative() throws Exception {
+    // relative path
+    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/path/to/../../other"));
+    assertFalse(PathUtils.impliesURI("file:///path", "file:///path/to/../../other"));
+    // bad policy
+    assertFalse(PathUtils.impliesURI("blah", "hdfs://namenode:8020/path/to/some/dir"));
+    // bad request
+    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "blah"));
+    // scheme
+    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "file:///path/to/some/dir"));
+    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "file://namenode:8020/path/to/some/dir"));
+    // hostname
+    assertFalse(PathUtils.impliesURI("hdfs://namenode1:8020/path", "hdfs://namenode2:8020/path/to/some/dir"));
+    // port
+    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8021/path/to/some/dir"));
+    // mangled path
+    assertFalse(PathUtils.impliesURI("hdfs://namenode:8020/path", "hdfs://namenode:8020/pathFooBar"));
+    // ends in /
+    assertTrue(PathUtils.impliesURI("hdfs://namenode:8020/path/", "hdfs://namenode:8020/path/FooBar"));
+  }
+
+  @Test
+  public void testActionHierarchy() throws Exception {
+    String dbName = "db1";
+    CommonPrivilege dbAll = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "ALL"));
+
+    CommonPrivilege dbSelect = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "SELECT"));
+    CommonPrivilege dbInsert = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "INSERT"));
+    CommonPrivilege dbAlter = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "ALTER"));
+    CommonPrivilege dbCreate = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "CREATE"));
+    CommonPrivilege dbDrop = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "DROP"));
+    CommonPrivilege dbIndex = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "INDEX"));
+    CommonPrivilege dbLock = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "LOCK"));
+
+    assertTrue(dbAll.implies(dbSelect, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbInsert, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbAlter, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbCreate, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbDrop, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbIndex, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbLock, hivePrivilegeModel));
+
+    dbAll = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName), new KeyValue("action", "*"));
+
+    assertTrue(dbAll.implies(dbSelect, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbInsert, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbAlter, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbCreate, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbDrop, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbIndex, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbLock, hivePrivilegeModel));
+
+    dbAll = create(new KeyValue("server", "server1"),
+            new KeyValue("db", dbName));
+
+    assertTrue(dbAll.implies(dbSelect, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbInsert, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbAlter, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbCreate, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbDrop, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbIndex, hivePrivilegeModel));
+    assertTrue(dbAll.implies(dbLock, hivePrivilegeModel));
+  }
+
+  static CommonPrivilege create(KeyValue... keyValues) {
+    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
+  }
+
+  static CommonPrivilege create(String s) {
+    return new CommonPrivilege(s);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini
new file mode 100644
index 0000000..cd3695c
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider-other-group.ini
@@ -0,0 +1,22 @@
+# 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.
+
+[groups]
+other_group = analyst_role
+
+[roles]
+analyst_role = server=server1->db=other_group_db->table=purchases->action=select
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini
new file mode 100644
index 0000000..e9114ef
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/test/resources/hive-policy-test-authz-provider.ini
@@ -0,0 +1,32 @@
+# 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.
+
+[databases]
+other_group_db = hive-policy-test-authz-provider-other-group.ini
+
+[groups]
+manager = analyst_role, junior_analyst_role
+analyst = analyst_role
+jranalyst = junior_analyst_role
+admin = admin
+
+[roles]
+analyst_role = server=server1->db=customers->table=purchases->action=select, \
+  server=server1->db=analyst1, \
+  server=server1->db=jranalyst1->table=*->action=select
+junior_analyst_role = server=server1->db=jranalyst1, server=server1->db=customers->table=purchases_partial->action=select
+admin = server=server1

http://git-wip-us.apache.org/repos/asf/sentry/blob/d94e900a/sentry-binding/sentry-binding-kafka/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-kafka/pom.xml b/sentry-binding/sentry-binding-kafka/pom.xml
index 15d3de5..f6f212b 100644
--- a/sentry-binding/sentry-binding-kafka/pom.xml
+++ b/sentry-binding/sentry-binding-kafka/pom.xml
@@ -45,10 +45,6 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
-      <artifactId>sentry-policy-kafka</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-common</artifactId>
     </dependency>
     <dependency>
@@ -73,5 +69,10 @@ limitations under the License.
       <artifactId>kafka_2.11</artifactId>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>