sentry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pras...@apache.org
Subject [25/25] git commit: SENTRY-432: Synchronization of HDFS permissions with Sentry permissions. Initial patch (Arun Suresh via Prasad Mujumdar)
Date Fri, 10 Oct 2014 03:48:10 GMT
SENTRY-432: Synchronization of HDFS permissions with Sentry permissions. Initial patch (Arun Suresh via Prasad Mujumdar)


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

Branch: refs/heads/sentry-hdfs-plugin
Commit: b86a53d10b6581d9f3168794a27d9f90edb00fd0
Parents: bfd7d10
Author: Prasad Mujumdar <prasadm@cloudera.com>
Authored: Thu Oct 9 20:47:02 2014 -0700
Committer: Prasad Mujumdar <prasadm@cloudera.com>
Committed: Thu Oct 9 20:47:19 2014 -0700

----------------------------------------------------------------------
 pom.xml                                         |   26 +-
 sentry-binding/sentry-binding-hive/pom.xml      |    8 +
 .../SentryHiveAuthorizationTaskFactoryImpl.java |   16 +
 .../sentry/binding/hive/conf/HiveAuthzConf.java |    6 +-
 .../SentryMetastorePostEventListener.java       |   92 +
 sentry-dist/pom.xml                             |   12 +
 sentry-hdfs-int/pom.xml                         |   75 +
 .../hdfs/SentryAuthorizationConstants.java      |   55 +
 .../sentry/hdfs/SentryAuthorizationInfo.java    |  233 +
 .../hdfs/SentryAuthorizationProvider.java       |  278 +
 .../apache/sentry/hdfs/SentryPermissions.java   |  159 +
 .../org/apache/sentry/hdfs/SentryUpdater.java   |   60 +
 .../sentry/hdfs/UpdateableAuthzPermissions.java |  198 +
 .../hdfs/MockSentryAuthorizationProvider.java   |   26 +
 .../sentry/hdfs/SentryAuthorizationInfoX.java   |   85 +
 .../hdfs/TestSentryAuthorizationProvider.java   |  163 +
 .../src/test/resources/hdfs-sentry.xml          |   33 +
 sentry-hdfs-service/pom.xml                     |  109 +
 .../org/apache/sentry/hdfs/MetastorePlugin.java |  110 +
 .../sentry/hdfs/SentryHDFSServiceClient.java    |  210 +
 .../sentry/hdfs/SentryHDFSServiceProcessor.java |  100 +
 .../hdfs/SentryHDFSServiceProcessorFactory.java |   86 +
 .../org/apache/sentry/hdfs/SentryPlugin.java    |  238 +
 .../org/apache/sentry/hdfs/UpdateForwarder.java |  227 +
 .../sentry/hdfs/UpdateablePermissions.java      |   62 +
 .../apache/sentry/hdfs/TestUpdateForwarder.java |  278 +
 sentry-hdfs/pom.xml                             |  149 +
 .../hdfs/service/thrift/SentryHDFSService.java  | 2688 +++++
 .../service/thrift/TAuthzUpdateResponse.java    |  603 ++
 .../hdfs/service/thrift/TPathChanges.java       |  765 ++
 .../sentry/hdfs/service/thrift/TPathEntry.java  |  747 ++
 .../sentry/hdfs/service/thrift/TPathsDump.java  |  549 +
 .../hdfs/service/thrift/TPathsUpdate.java       |  748 ++
 .../hdfs/service/thrift/TPermissionsUpdate.java |  810 ++
 .../hdfs/service/thrift/TPrivilegeChanges.java  |  713 ++
 .../hdfs/service/thrift/TRoleChanges.java       |  691 ++
 .../java/org/apache/sentry/hdfs/AuthzPaths.java |   30 +
 .../apache/sentry/hdfs/AuthzPathsDumper.java    |   28 +
 .../apache/sentry/hdfs/AuthzPermissions.java    |   28 +
 .../sentry/hdfs/ExtendedMetastoreClient.java    |  104 +
 .../java/org/apache/sentry/hdfs/HMSPaths.java   |  467 +
 .../org/apache/sentry/hdfs/HMSPathsSerDe.java   |  113 +
 .../org/apache/sentry/hdfs/MetastoreClient.java |   34 +
 .../org/apache/sentry/hdfs/PathsUpdate.java     |   84 +
 .../apache/sentry/hdfs/PermissionsUpdate.java   |   93 +
 .../java/org/apache/sentry/hdfs/Updateable.java |   61 +
 .../sentry/hdfs/UpdateableAuthzPaths.java       |  130 +
 .../main/resources/sentry_hdfs_service.thrift   |   87 +
 .../org/apache/sentry/hdfs/TestHMSPaths.java    |  357 +
 .../sentry/hdfs/TestHMSPathsFullDump.java       |   97 +
 .../sentry/hdfs/TestUpdateableAuthzPaths.java   |  136 +
 sentry-hdfs/src/test/resources/hdfs-sentry.xml  |   22 +
 sentry-provider/sentry-provider-db/pom.xml      |   91 +-
 .../db/service/thrift/SentryPolicyService.java  | 9772 ------------------
 .../TAlterSentryRoleAddGroupsRequest.java       |  742 --
 .../TAlterSentryRoleAddGroupsResponse.java      |  390 -
 .../TAlterSentryRoleDeleteGroupsRequest.java    |  742 --
 .../TAlterSentryRoleDeleteGroupsResponse.java   |  390 -
 .../TAlterSentryRoleGrantPrivilegeRequest.java  |  693 --
 .../TAlterSentryRoleGrantPrivilegeResponse.java |  505 -
 .../TAlterSentryRoleRevokePrivilegeRequest.java |  693 --
 ...TAlterSentryRoleRevokePrivilegeResponse.java |  390 -
 .../thrift/TCreateSentryRoleRequest.java        |  587 --
 .../thrift/TCreateSentryRoleResponse.java       |  390 -
 .../service/thrift/TDropPrivilegesRequest.java  |  592 --
 .../service/thrift/TDropPrivilegesResponse.java |  390 -
 .../service/thrift/TDropSentryRoleRequest.java  |  587 --
 .../service/thrift/TDropSentryRoleResponse.java |  390 -
 ...TListSentryPrivilegesForProviderRequest.java |  759 --
 ...ListSentryPrivilegesForProviderResponse.java |  543 -
 .../thrift/TListSentryPrivilegesRequest.java    |  702 --
 .../thrift/TListSentryPrivilegesResponse.java   |  554 -
 .../service/thrift/TListSentryRolesRequest.java |  596 --
 .../thrift/TListSentryRolesResponse.java        |  554 -
 .../thrift/TRenamePrivilegesRequest.java        |  698 --
 .../thrift/TRenamePrivilegesResponse.java       |  390 -
 .../db/service/thrift/TSentryActiveRoleSet.java |  536 -
 .../db/service/thrift/TSentryAuthorizable.java  |  707 --
 .../db/service/thrift/TSentryGrantOption.java   |   48 -
 .../db/service/thrift/TSentryGroup.java         |  385 -
 .../db/service/thrift/TSentryPrivilege.java     | 1145 --
 .../provider/db/service/thrift/TSentryRole.java |  641 --
 .../service/thrift/TSentryResponseStatus.java   |  594 --
 .../thrift/sentry_common_serviceConstants.java  |   50 -
 .../db/SentryMetastoreListenerPlugin.java       |   41 +
 .../provider/db/SentryPolicyStorePlugin.java    |   54 +
 .../db/service/persistent/SentryStore.java      |   75 +-
 .../thrift/SentryPolicyServiceClient.java       |    4 +-
 .../thrift/SentryPolicyStoreProcessor.java      |   59 +
 .../sentry/service/thrift/SentryService.java    |    3 +-
 .../sentry/service/thrift/ServiceConstants.java |  150 -
 .../main/resources/sentry_common_service.thrift |   42 -
 .../main/resources/sentry_policy_service.thrift |  242 -
 .../thrift/TestSentryPolicyStoreProcessor.java  |    2 +
 .../thrift/TestSentryServerWithoutKerberos.java |   14 +-
 sentry-service-client/pom.xml                   |  164 +
 .../db/service/thrift/SentryPolicyService.java  | 9772 ++++++++++++++++++
 .../TAlterSentryRoleAddGroupsRequest.java       |  742 ++
 .../TAlterSentryRoleAddGroupsResponse.java      |  390 +
 .../TAlterSentryRoleDeleteGroupsRequest.java    |  742 ++
 .../TAlterSentryRoleDeleteGroupsResponse.java   |  390 +
 .../TAlterSentryRoleGrantPrivilegeRequest.java  |  693 ++
 .../TAlterSentryRoleGrantPrivilegeResponse.java |  505 +
 .../TAlterSentryRoleRevokePrivilegeRequest.java |  693 ++
 ...TAlterSentryRoleRevokePrivilegeResponse.java |  390 +
 .../thrift/TCreateSentryRoleRequest.java        |  587 ++
 .../thrift/TCreateSentryRoleResponse.java       |  390 +
 .../service/thrift/TDropPrivilegesRequest.java  |  592 ++
 .../service/thrift/TDropPrivilegesResponse.java |  390 +
 .../service/thrift/TDropSentryRoleRequest.java  |  587 ++
 .../service/thrift/TDropSentryRoleResponse.java |  390 +
 ...TListSentryPrivilegesForProviderRequest.java |  759 ++
 ...ListSentryPrivilegesForProviderResponse.java |  543 +
 .../thrift/TListSentryPrivilegesRequest.java    |  702 ++
 .../thrift/TListSentryPrivilegesResponse.java   |  554 +
 .../service/thrift/TListSentryRolesRequest.java |  596 ++
 .../thrift/TListSentryRolesResponse.java        |  554 +
 .../thrift/TRenamePrivilegesRequest.java        |  698 ++
 .../thrift/TRenamePrivilegesResponse.java       |  390 +
 .../db/service/thrift/TSentryActiveRoleSet.java |  536 +
 .../db/service/thrift/TSentryAuthorizable.java  |  707 ++
 .../db/service/thrift/TSentryGrantOption.java   |   48 +
 .../db/service/thrift/TSentryGroup.java         |  385 +
 .../db/service/thrift/TSentryPrivilege.java     | 1145 ++
 .../provider/db/service/thrift/TSentryRole.java |  641 ++
 .../service/thrift/TSentryResponseStatus.java   |  594 ++
 .../thrift/sentry_common_serviceConstants.java  |   50 +
 .../sentry/service/thrift/ServiceConstants.java |  160 +
 .../main/resources/sentry_common_service.thrift |   42 +
 .../main/resources/sentry_policy_service.thrift |  247 +
 sentry-tests/sentry-tests-hive/pom.xml          |    5 +
 ...actMetastoreTestWithStaticConfiguration.java |    3 +
 .../e2e/metastore/TestMetastoreEndToEnd.java    |   49 +-
 133 files changed, 40361 insertions(+), 26675 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e172e92..e66e790 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,7 +68,7 @@ limitations under the License.
     <derby.version>10.10.2.0</derby.version>
     <commons-cli.version>1.2</commons-cli.version>
     <hive.version>0.13.1-cdh5.2.0-SNAPSHOT</hive.version>
-    <hadoop.version>2.3.0-cdh5.1.0-SNAPSHOT</hadoop.version>
+    <hadoop.version>2.5.0</hadoop.version>
     <fest.reflect.version>1.4.1</fest.reflect.version>
     <guava.version>11.0.2</guava.version>
     <junit.version>4.9</junit.version>
@@ -149,6 +149,12 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.hadoop</groupId>
+        <artifactId>hadoop-hdfs</artifactId>
+        <version>${hadoop.version}</version>
+        <type>test-jar</type>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hadoop</groupId>
         <artifactId>hadoop-minicluster</artifactId>
         <version>${hadoop.version}</version>
       </dependency>
@@ -324,6 +330,11 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-service-client</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sentry</groupId>
         <artifactId>sentry-provider-common</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -334,6 +345,16 @@ limitations under the License.
       </dependency>
       <dependency>
         <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-hdfs</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sentry</groupId>
+        <artifactId>sentry-hdfs-int</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.sentry</groupId>
         <artifactId>sentry-provider-cache</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -402,6 +423,9 @@ limitations under the License.
     <module>sentry-policy</module>
     <module>sentry-tests</module>
     <module>sentry-dist</module>
+    <module>sentry-service-client</module>
+    <module>sentry-hdfs</module>
+    <module>sentry-hdfs-int</module>
   </modules>
 
   <build>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/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 e72b370..aa3a8c9 100644
--- a/sentry-binding/sentry-binding-hive/pom.xml
+++ b/sentry-binding/sentry-binding-hive/pom.xml
@@ -75,6 +75,14 @@ limitations under the License.
     <!-- required for SentryGrantRevokeTask -->
     <dependency>
       <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-service-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-hdfs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-provider-db</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
index f38ee91..dfcf63a 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/SentryHiveAuthorizationTaskFactoryImpl.java
@@ -50,11 +50,14 @@ import org.apache.hadoop.hive.ql.security.authorization.Privilege;
 import org.apache.hadoop.hive.ql.security.authorization.PrivilegeRegistry;
 import org.apache.hadoop.hive.ql.session.SessionState;
 import org.apache.sentry.core.model.db.AccessConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 
 public class SentryHiveAuthorizationTaskFactoryImpl implements HiveAuthorizationTaskFactory {
 
+  private static final Logger LOG = LoggerFactory.getLogger(SentryHiveAuthorizationTaskFactoryImpl.class);
 
   public SentryHiveAuthorizationTaskFactoryImpl(HiveConf conf, Hive db) {
 
@@ -236,8 +239,11 @@ public class SentryHiveAuthorizationTaskFactoryImpl implements HiveAuthorization
 
   private Task<? extends Serializable> analyzeGrantRevokeRole(boolean isGrant, ASTNode ast,
       HashSet<ReadEntity> inputs, HashSet<WriteEntity> outputs) throws SemanticException {
+    LOG.debug("## FULL AST : [" + ast.dump() + "]");
+    LOG.debug("## CHILD AST : [" + ((ASTNode)ast.getChild(0)).dump() + "]");
     List<PrincipalDesc> principalDesc = analyzePrincipalListDef(
         (ASTNode) ast.getChild(0));
+    
     List<String> roles = new ArrayList<String>();
     for (int i = 1; i < ast.getChildCount(); i++) {
       roles.add(BaseSemanticAnalyzer.unescapeIdentifier(ast.getChild(i).getText()));
@@ -314,18 +320,28 @@ public class SentryHiveAuthorizationTaskFactoryImpl implements HiveAuthorization
       ASTNode child = (ASTNode) node.getChild(i);
       PrincipalType type = null;
       switch (child.getType()) {
+      case 880:
+        type = PrincipalType.USER;
+        break;
       case HiveParser.TOK_USER:
         type = PrincipalType.USER;
         break;
+      case 685:
+        type = PrincipalType.GROUP;
+        break;
       case HiveParser.TOK_GROUP:
         type = PrincipalType.GROUP;
         break;
+      case 782:
+        type = PrincipalType.ROLE;
+        break;
       case HiveParser.TOK_ROLE:
         type = PrincipalType.ROLE;
         break;
       }
       String principalName = BaseSemanticAnalyzer.unescapeIdentifier(child.getChild(0).getText());
       PrincipalDesc principalDesc = new PrincipalDesc(principalName, type);
+      LOG.debug("## Principal : [ " + principalName + ", " + type + "]");
       principalList.add(principalDesc);
     }
     return principalList;

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
index 4d2a625..0c8778b 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/hive/conf/HiveAuthzConf.java
@@ -18,7 +18,7 @@ package org.apache.sentry.binding.hive.conf;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hive.conf.HiveConf;
-import org.mortbay.log.Log;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -203,8 +203,8 @@ public class HiveAuthzConf extends Configuration {
       if (retVal == null) {
         retVal = AuthzConfVars.getDefault(varName);
       } else {
-        Log.warn("Using the deprecated config setting " + currentToDeprecatedProps.get(varName).getVar() +
-            " instead of " + varName);
+//        Log.warn("Using the deprecated config setting " + currentToDeprecatedProps.get(varName).getVar() +
+//            " instead of " + varName);
       }
     }
     if (retVal == null) {

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetastorePostEventListener.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetastorePostEventListener.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetastorePostEventListener.java
index 38bf8b2..8983c42 100644
--- a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetastorePostEventListener.java
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/SentryMetastorePostEventListener.java
@@ -19,16 +19,22 @@ package org.apache.sentry.binding.metastore;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.metastore.MetaStoreEventListener;
 import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.Partition;
+import org.apache.hadoop.hive.metastore.events.AddPartitionEvent;
 import org.apache.hadoop.hive.metastore.events.AlterTableEvent;
 import org.apache.hadoop.hive.metastore.events.CreateDatabaseEvent;
 import org.apache.hadoop.hive.metastore.events.CreateTableEvent;
 import org.apache.hadoop.hive.metastore.events.DropDatabaseEvent;
+import org.apache.hadoop.hive.metastore.events.DropPartitionEvent;
 import org.apache.hadoop.hive.metastore.events.DropTableEvent;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.sentry.SentryUserException;
@@ -38,24 +44,58 @@ import org.apache.sentry.core.common.Authorizable;
 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.db.SentryMetastoreListenerPlugin;
+import org.apache.sentry.provider.db.SentryPolicyStorePlugin;
 import org.apache.sentry.provider.db.service.thrift.SentryPolicyServiceClient;
 import org.apache.sentry.service.thrift.SentryServiceClientFactory;
+import org.apache.sentry.service.thrift.ServiceConstants.ConfUtilties;
+import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
+
+import com.google.common.collect.Lists;
 
 public class SentryMetastorePostEventListener extends MetaStoreEventListener {
   private final SentryServiceClientFactory sentryClientFactory;
   private final HiveAuthzConf authzConf;
   private final Server server;
 
+  private List<SentryMetastoreListenerPlugin> sentryPlugins = new ArrayList<SentryMetastoreListenerPlugin>(); 
+
   public SentryMetastorePostEventListener(Configuration config) {
     super(config);
     sentryClientFactory = new SentryServiceClientFactory();
 
     authzConf = HiveAuthzConf.getAuthzConf(new HiveConf());
     server = new Server(authzConf.get(AuthzConfVars.AUTHZ_SERVER_NAME.getVar()));
+    Iterable<String> pluginClasses = ConfUtilties.CLASS_SPLITTER
+        .split(config.get(ServerConfig.SENTRY_METASTORE_PLUGINS,
+            ServerConfig.SENTRY_METASTORE_PLUGINS_DEFAULT).trim());
+    try {
+      for (String pluginClassStr : pluginClasses) {
+        Class<?> clazz = config.getClassByName(pluginClassStr);
+        if (!SentryMetastoreListenerPlugin.class.isAssignableFrom(clazz)) {
+          throw new IllegalArgumentException("Class ["
+              + pluginClassStr + "] is not a "
+              + SentryPolicyStorePlugin.class.getName());
+        }
+        SentryMetastoreListenerPlugin plugin = (SentryMetastoreListenerPlugin) clazz
+            .getConstructor(Configuration.class).newInstance(config);
+        sentryPlugins.add(plugin);
+      }
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
   }
 
   @Override
   public void onCreateTable (CreateTableEvent tableEvent) throws MetaException {
+    if (tableEvent.getTable().getSd().getLocation() != null) {
+      String authzObj = tableEvent.getTable().getDbName() + "."
+          + tableEvent.getTable().getTableName();
+      String path = tableEvent.getTable().getSd().getLocation();
+      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+        plugin.addPath(authzObj, path);
+      }
+    }
     // drop the privileges on the given table, in case if anything was left
     // behind during the drop
     if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_CREATE_WITH_POLICY_STORE)) {
@@ -71,6 +111,13 @@ public class SentryMetastorePostEventListener extends MetaStoreEventListener {
 
   @Override
   public void onDropTable(DropTableEvent tableEvent) throws MetaException {
+    if (tableEvent.getTable().getSd().getLocation() != null) {
+      String authzObj = tableEvent.getTable().getDbName() + "."
+          + tableEvent.getTable().getTableName();
+      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+        plugin.removePath(authzObj, "*");
+      }
+    }
     // drop the privileges on the given table
     if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_DROP_WITH_POLICY_STORE)) {
       return;
@@ -86,6 +133,13 @@ public class SentryMetastorePostEventListener extends MetaStoreEventListener {
   @Override
   public void onCreateDatabase(CreateDatabaseEvent dbEvent)
       throws MetaException {
+    if (dbEvent.getDatabase().getLocationUri() != null) {
+      String authzObj = dbEvent.getDatabase().getName();
+      String path = dbEvent.getDatabase().getLocationUri();
+      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+        plugin.addPath(authzObj, path);
+      }
+    }
     // drop the privileges on the database, incase anything left behind during
     // last drop db
     if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_CREATE_WITH_POLICY_STORE)) {
@@ -105,6 +159,11 @@ public class SentryMetastorePostEventListener extends MetaStoreEventListener {
    */
   @Override
   public void onDropDatabase(DropDatabaseEvent dbEvent) throws MetaException {
+    String authzObj = dbEvent.getDatabase().getName();
+    for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+      plugin.removePath(authzObj, "*");
+    }
+    dropSentryDbPrivileges(dbEvent.getDatabase().getName());
     if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_DROP_WITH_POLICY_STORE)) {
       return;
     }
@@ -121,6 +180,7 @@ public class SentryMetastorePostEventListener extends MetaStoreEventListener {
   @Override
   public void onAlterTable (AlterTableEvent tableEvent) throws MetaException {
     String oldTableName = null, newTableName = null;
+    // TODO : notify SentryHMSPathCache
     if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_ALTER_WITH_POLICY_STORE)) {
       return;
     }
@@ -141,6 +201,37 @@ public class SentryMetastorePostEventListener extends MetaStoreEventListener {
     }
   }
 
+  
+
+  @Override
+  public void onAddPartition(AddPartitionEvent partitionEvent)
+      throws MetaException {
+    for (Partition part : partitionEvent.getPartitions()) {
+      if ((part.getSd() != null) && (part.getSd().getLocation() != null)) {
+        String authzObj = part.getDbName() + "." + part.getTableName();
+        String path = part.getSd().getLocation();
+        for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+          plugin.addPath(authzObj, path);
+        }
+      }
+    }
+    // TODO Auto-generated method stub
+    super.onAddPartition(partitionEvent);
+  }
+
+  @Override
+  public void onDropPartition(DropPartitionEvent partitionEvent)
+      throws MetaException {
+    String authzObj = partitionEvent.getTable().getDbName() + "."
+        + partitionEvent.getTable().getTableName();
+    String path = partitionEvent.getPartition().getSd().getLocation();
+    for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+      plugin.removePath(authzObj, path);
+    }
+    // TODO Auto-generated method stub
+    super.onDropPartition(partitionEvent);
+  }
+
   private SentryPolicyServiceClient getSentryServiceClient()
       throws MetaException {
     try {
@@ -225,4 +316,5 @@ public class SentryMetastorePostEventListener extends MetaStoreEventListener {
     return "true"
         .equalsIgnoreCase((authzConf.get(syncConfVar.getVar(), "true")));
   }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-dist/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-dist/pom.xml b/sentry-dist/pom.xml
index cd7126b..510fd97 100644
--- a/sentry-dist/pom.xml
+++ b/sentry-dist/pom.xml
@@ -64,6 +64,18 @@ limitations under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-hdfs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-hdfs-int</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-service-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
       <artifactId>sentry-policy-common</artifactId>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/pom.xml b/sentry-hdfs-int/pom.xml
new file mode 100644
index 0000000..253d06c
--- /dev/null
+++ b/sentry-hdfs-int/pom.xml
@@ -0,0 +1,75 @@
+<?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</artifactId>
+    <version>1.5.0-incubating-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>sentry-hdfs-int</artifactId>
+  <name>Sentry HDFS Integration Plugin</name>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-hdfs</artifactId>
+      <version>1.5.0-incubating-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-service-client</artifactId>
+      <version>1.5.0-incubating-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-hdfs-service</artifactId>
+      <version>1.5.0-incubating-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <scope>provided</scope>
+    </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/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationConstants.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationConstants.java b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationConstants.java
new file mode 100644
index 0000000..9f219ce
--- /dev/null
+++ b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationConstants.java
@@ -0,0 +1,55 @@
+/**
+ * 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.hdfs;
+
+public class SentryAuthorizationConstants {
+
+  public static final String CONFIG_FILE = "hdfs-sentry.xml";
+
+  public static final String CONFIG_PREFIX = "sentry.authorization-provider.";
+
+  public static final String HDFS_USER_KEY = CONFIG_PREFIX + "hdfs-user";
+  public static final String HDFS_USER_DEFAULT = "hive";
+
+  public static final String HDFS_GROUP_KEY = CONFIG_PREFIX + "hdfs-group";
+  public static final String HDFS_GROUP_DEFAULT = "hive";
+
+  public static final String HDFS_PERMISSION_KEY = CONFIG_PREFIX + 
+      "hdfs-permission";
+  public static final long HDFS_PERMISSION_DEFAULT = 0770;
+
+  public static final String HDFS_PATH_PREFIXES_KEY = CONFIG_PREFIX + 
+      "hdfs-path-prefixes";
+  public static final String[] HDFS_PATH_PREFIXES_DEFAULT = new String[0];
+
+  public static final String CACHE_REFRESH_INTERVAL_KEY = CONFIG_PREFIX + 
+      "cache-refresh-interval.ms";
+  public static final int CACHE_REFRESH_INTERVAL_DEFAULT = 500;
+
+  public static final String CACHE_STALE_THRESHOLD_KEY = CONFIG_PREFIX + 
+      "cache-stale-threshold.ms";
+  public static final int CACHE_STALE_THRESHOLD_DEFAULT = 60 * 1000;
+
+  public static final String CACHE_REFRESH_RETRY_WAIT_KEY = CONFIG_PREFIX +
+      "cache-refresh-retry-wait.ms";
+  public static final int CACHE_REFRESH_RETRY_WAIT_DEFAULT = 30 * 1000;
+
+  public static final String INCLUDE_HDFS_AUTHZ_AS_ACL_KEY = CONFIG_PREFIX + 
+      "include-hdfs-authz-as-acl";
+  public static final boolean INCLUDE_HDFS_AUTHZ_AS_ACL_DEFAULT = true;
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java
new file mode 100644
index 0000000..23e06dd
--- /dev/null
+++ b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationInfo.java
@@ -0,0 +1,233 @@
+/**
+ * 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.hdfs;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.sentry.hdfs.SentryHDFSServiceClient.SentryAuthzUpdate;
+import org.apache.sentry.hdfs.Updateable.Update;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+
+public class SentryAuthorizationInfo implements Runnable {
+  private static Logger LOG =
+      LoggerFactory.getLogger(SentryAuthorizationInfo.class);
+
+  private SentryUpdater updater;
+  private volatile UpdateableAuthzPaths authzPaths;
+  private volatile UpdateableAuthzPermissions authzPermissions;
+
+  private int refreshIntervalMillisec;
+  private int staleThresholdMillisec;
+  private int retryWaitMillisec;
+  private ScheduledExecutorService executor;
+  private volatile long lastUpdate;
+  private volatile long waitUntil;
+  private volatile long lastStaleReport;
+  // We don't need a re-entrant lock.. but we do need a ReadWriteLock
+  // Unfortunately, the ReentrantReadWriteLick is the only available
+  // concrete implementation of a ReadWriteLock.
+  private final ReadWriteLock lock = new ReentrantReadWriteLock();
+
+  @VisibleForTesting
+  SentryAuthorizationInfo() {}
+
+  public SentryAuthorizationInfo(Configuration conf) throws Exception {
+    String[] pathPrefixes = conf.getTrimmedStrings(
+        SentryAuthorizationConstants.HDFS_PATH_PREFIXES_KEY, 
+        SentryAuthorizationConstants.HDFS_PATH_PREFIXES_DEFAULT);
+    if (pathPrefixes.length == 0) {
+      LOG.warn("There are not HDFS path prefixes configured in [{}], "
+          + "Sentry authorization won't be enforced on any HDFS location",
+          SentryAuthorizationConstants.HDFS_PATH_PREFIXES_KEY);
+    } else {
+      refreshIntervalMillisec = conf.getInt(
+          SentryAuthorizationConstants.CACHE_REFRESH_INTERVAL_KEY,
+          SentryAuthorizationConstants.CACHE_REFRESH_INTERVAL_DEFAULT);
+      staleThresholdMillisec = conf.getInt(
+          SentryAuthorizationConstants.CACHE_STALE_THRESHOLD_KEY,
+          SentryAuthorizationConstants.CACHE_STALE_THRESHOLD_DEFAULT);
+      retryWaitMillisec = conf.getInt(
+          SentryAuthorizationConstants.CACHE_REFRESH_RETRY_WAIT_KEY,
+          SentryAuthorizationConstants.CACHE_REFRESH_RETRY_WAIT_DEFAULT);
+
+      LOG.debug("Sentry authorization will enforced in the following HDFS " +
+          "locations: [{}]", StringUtils.arrayToString(pathPrefixes));
+      LOG.debug("Refresh interval [{}]ms, retry wait [{}], stale threshold " +
+              "[{}]ms", new Object[] 
+          {refreshIntervalMillisec, retryWaitMillisec, staleThresholdMillisec});
+
+      authzPaths = new UpdateableAuthzPaths(pathPrefixes);
+      authzPermissions = new UpdateableAuthzPermissions();
+      waitUntil = System.currentTimeMillis();
+      lastStaleReport = 0;
+      updater = new SentryUpdater(conf, this);
+    }
+  }
+
+  UpdateableAuthzPaths getAuthzPaths() {
+    return authzPaths;
+  }
+
+  UpdateableAuthzPermissions getAuthzPermissions() {
+    return authzPermissions;
+  }
+
+  private void update() {
+    SentryAuthzUpdate updates = updater.getUpdates();
+    UpdateableAuthzPaths newAuthzPaths = processUpdates(
+        updates.getPathUpdates(), authzPaths);
+    UpdateableAuthzPermissions newAuthzPerms = processUpdates(
+        updates.getPermUpdates(), authzPermissions);
+    // If there were any FULL updates the returned instance would be
+    // different
+    if ((newAuthzPaths != authzPaths)||(newAuthzPerms != authzPermissions)) {
+      lock.writeLock().lock();
+      try {
+        authzPaths = newAuthzPaths;
+        LOG.warn("##### FULL Updated paths seq Num [" + authzPaths.getLastUpdatedSeqNum() + "]");
+        authzPermissions = newAuthzPerms;
+        LOG.warn("##### FULL Updated perms seq Num [" + authzPermissions.getLastUpdatedSeqNum() + "]");
+      } finally {
+        lock.writeLock().unlock();
+      }
+    }
+
+  }
+
+  private <K extends Update, V extends Updateable<K>> V processUpdates(List<K> updates,
+      V updateable) {
+    // In a list of Updates, if there is a full Update, it will be the first
+    // one in the List.. all the remaining will be partial updates
+    if (updates.size() > 0) {
+      if (updates.get(0).hasFullImage()) {
+        updateable = (V)updateable.updateFull(updates.remove(0));
+      }
+      // Any more elements ?
+      if (!updates.isEmpty()) {
+        updateable.updatePartial(updates, lock);
+      }
+    }
+    return updateable;
+  }
+
+  public void run() {
+    try {
+      // In case of previous preUpdate failure, we sleep for a retry wait 
+      // interval we can do this because we are using a singledthreadedexecutor
+      // and scheduling the runs with fixed delay.
+      long currTime = System.currentTimeMillis();
+      if (waitUntil > currTime) {
+        Thread.sleep(waitUntil - currTime);
+      }
+      update();
+      // we reset lastUpdate only on successful pulling
+      lastUpdate = System.currentTimeMillis();
+      waitUntil = lastUpdate;
+    } catch (Exception ex) {
+      LOG.warn("Failed to update, will retry in [{}]ms, error: ", 
+          new Object[]{ retryWaitMillisec, ex.getMessage(), ex});
+      waitUntil = System.currentTimeMillis() + retryWaitMillisec;
+    }
+  }
+
+  public void start() {
+    if (authzPaths != null) {
+      try {
+        update();
+      } catch (Exception ex) {
+        LOG.warn("Failed to do initial update, will retry in [{}]ms, error: ",
+            new Object[]{retryWaitMillisec, ex.getMessage(), ex});
+        waitUntil = System.currentTimeMillis() + retryWaitMillisec;
+      }
+      executor = Executors.newSingleThreadScheduledExecutor(
+          new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable r) {
+              Thread t = new Thread(r, SentryAuthorizationInfo.class.getName() +
+                  "-refresher");
+              t.setDaemon(true);
+              return t;
+            }
+          }
+      );
+      executor.scheduleWithFixedDelay(this, refreshIntervalMillisec, 
+          refreshIntervalMillisec, TimeUnit.MILLISECONDS);
+    }
+  }
+
+  public void stop() {
+    if (authzPaths != null) {
+      executor.shutdownNow();
+    }
+  }
+
+  public boolean isStale() {
+    long now = System.currentTimeMillis();
+    boolean stale = now - lastUpdate > staleThresholdMillisec;
+    if (stale && now - lastStaleReport > 30 * 1000) {
+      LOG.warn("Authorization information has been stale for [{}]s", 
+          (now - lastUpdate) / 1000);
+      lastStaleReport = now;
+    }
+    return stale;
+  }
+
+  public boolean isManaged(String[] pathElements) {
+    lock.readLock().lock();
+    try {
+      return authzPaths.isUnderPrefix(pathElements);
+    } finally {
+      lock.readLock().unlock();
+    }
+  }
+
+  public boolean doesBelongToAuthzObject(String[] pathElements) {
+    lock.readLock().lock();
+    try {
+      return authzPaths.findAuthzObject(pathElements) != null;
+    } finally {
+      lock.readLock().unlock();
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public List<AclEntry> getAclEntries(String[] pathElements) {
+    lock.readLock().lock();
+    try {
+      String authzObj = authzPaths.findAuthzObject(pathElements);
+      return (authzObj != null) ? authzPermissions.getAcls(authzObj) 
+          : Collections.EMPTY_LIST;
+    } finally {
+      lock.readLock().unlock();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationProvider.java b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationProvider.java
new file mode 100644
index 0000000..ebd063f
--- /dev/null
+++ b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryAuthorizationProvider.java
@@ -0,0 +1,278 @@
+/**
+ * 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 permission and
+ * limitations under the License.
+ */
+package org.apache.sentry.hdfs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.fs.permission.AclEntryScope;
+import org.apache.hadoop.fs.permission.AclEntryType;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.apache.hadoop.hdfs.server.namenode.AclFeature;
+import org.apache.hadoop.hdfs.server.namenode.INodeAttributeProvider;
+import org.apache.hadoop.hdfs.server.namenode.INodeAttributes;
+import org.apache.hadoop.hdfs.server.namenode.XAttrFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+public class SentryAuthorizationProvider 
+    extends INodeAttributeProvider implements Configurable {
+  
+  static class SentryAclFeature extends AclFeature {
+    public SentryAclFeature(ImmutableList<AclEntry> entries) {
+      super(entries);
+    }
+  }
+
+  private static Logger LOG = 
+      LoggerFactory.getLogger(SentryAuthorizationProvider.class);
+
+  private boolean started;
+  private Configuration conf;
+  private String user;
+  private String group;
+  private short permission;
+  private boolean originalAuthzAsAcl;
+  private SentryAuthorizationInfo authzInfo;
+
+  public SentryAuthorizationProvider() {
+    this(null);
+  }
+
+  @VisibleForTesting
+  SentryAuthorizationProvider(SentryAuthorizationInfo authzInfo) {
+    this.authzInfo = authzInfo;
+  }
+  
+  @Override
+  public void setConf(Configuration conf) {
+    this.conf = conf;
+  }
+
+  @Override
+  public Configuration getConf() {
+    return conf;
+  }
+
+  @Override
+  public synchronized void start() {
+    if (started) {
+      throw new IllegalStateException("Provider already started");
+    }
+    started = true;
+    try {
+      if (!conf.getBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, false)) {
+        throw new RuntimeException("HDFS ACLs must be enabled");
+      }
+
+      // Configuration is read from hdfs-sentry.xml and NN configuration, in
+      // that order of precedence.
+      Configuration conf = new Configuration(this.conf);
+      conf.addResource(SentryAuthorizationConstants.CONFIG_FILE);
+      user = conf.get(SentryAuthorizationConstants.HDFS_USER_KEY,
+          SentryAuthorizationConstants.HDFS_USER_DEFAULT);
+      group = conf.get(SentryAuthorizationConstants.HDFS_GROUP_KEY,
+          SentryAuthorizationConstants.HDFS_GROUP_DEFAULT);
+      permission = (short) conf.getLong(
+          SentryAuthorizationConstants.HDFS_PERMISSION_KEY,
+          SentryAuthorizationConstants.HDFS_PERMISSION_DEFAULT);
+      originalAuthzAsAcl = conf.getBoolean(
+          SentryAuthorizationConstants.INCLUDE_HDFS_AUTHZ_AS_ACL_KEY,
+          SentryAuthorizationConstants.INCLUDE_HDFS_AUTHZ_AS_ACL_DEFAULT);
+
+      LOG.info("Starting");
+      LOG.info("Config: hdfs-user[{}] hdfs-group[{}] hdfs-permission[{}] " +
+          "include-hdfs-authz-as-acl[{}]", new Object[]
+          {user, group, permission, originalAuthzAsAcl});
+
+      if (authzInfo == null) {
+        authzInfo = new SentryAuthorizationInfo(conf);
+      }
+      authzInfo.start();
+    } catch (Exception ex) {
+      throw new RuntimeException(ex);
+    }
+  }
+
+  @Override
+  public synchronized void stop() {
+    LOG.debug("Stopping");
+    authzInfo.stop();
+  }
+
+  private static final AclFeature EMPTY_ACL_FEATURE =
+      new AclFeature(AclFeature.EMPTY_ENTRY_LIST);
+
+  private class INodeAttributesX implements INodeAttributes {
+    private boolean useDefault;
+    private INodeAttributes node;
+    private AclFeature aclFeature;
+    
+    public INodeAttributesX(boolean useDefault, INodeAttributes node,
+        AclFeature aclFeature) {
+      this.node = node;
+      this.useDefault = useDefault;
+      this.aclFeature = aclFeature;
+    }
+    
+    @Override
+    public boolean isDirectory() {
+      return node.isDirectory();
+    }
+
+    @Override
+    public byte[] getLocalNameBytes() {
+      return node.getLocalNameBytes();
+    }
+
+    public String getUserName() {
+      return (useDefault) ? node.getUserName() : user;
+    }
+
+    @Override
+    public String getGroupName() {
+      return (useDefault) ? node.getGroupName() : group;
+    }
+
+    @Override
+    public FsPermission getFsPermission() {
+      return (useDefault) ? node.getFsPermission()
+                          : new FsPermission(getFsPermissionShort());
+    }
+
+    @Override
+    public short getFsPermissionShort() {
+      return (useDefault) ? node.getFsPermissionShort()
+                          : (short) getPermissionLong();
+    }
+
+    @Override
+    public long getPermissionLong() {
+      return (useDefault) ? node.getPermissionLong() : permission;
+    }
+
+    @Override
+    public AclFeature getAclFeature() {
+      AclFeature feature;
+      if (useDefault) {
+        feature = node.getAclFeature();
+        if (feature == null) {
+          feature = EMPTY_ACL_FEATURE;
+        }
+      } else {
+        feature = aclFeature;
+      }
+      return feature;
+    }
+
+    @Override
+    public XAttrFeature getXAttrFeature() {
+      return node.getXAttrFeature();
+    }
+
+    @Override
+    public long getModificationTime() {
+      return node.getModificationTime();
+    }
+
+    @Override
+    public long getAccessTime() {
+      return node.getAccessTime();
+    }
+  }
+  
+  @Override
+  public INodeAttributes getAttributes(String[] pathElements,
+      INodeAttributes node) {
+    if (authzInfo.isManaged(pathElements)) {
+      boolean stale = authzInfo.isStale();
+      AclFeature aclFeature = getAclFeature(pathElements, node, stale);
+      if (!stale) {
+        if (authzInfo.doesBelongToAuthzObject(pathElements)) {
+          node = new INodeAttributesX(false, node, aclFeature);
+        }
+      } else {
+        node = new INodeAttributesX(true, node, aclFeature);
+      }
+    }
+    return node;
+  }
+
+  private List<AclEntry> createAclEntries(String user, String group,
+      FsPermission permission) {
+    List<AclEntry> list = new ArrayList<AclEntry>();
+    AclEntry.Builder builder = new AclEntry.Builder();
+    FsPermission fsPerm = new FsPermission(permission);
+    builder.setName(user);
+    builder.setType(AclEntryType.USER);
+    builder.setScope(AclEntryScope.ACCESS);
+    builder.setPermission(fsPerm.getUserAction());
+    list.add(builder.build());
+    builder.setName(group);
+    builder.setType(AclEntryType.GROUP);
+    builder.setScope(AclEntryScope.ACCESS);
+    builder.setPermission(fsPerm.getGroupAction());
+    list.add(builder.build());
+    builder.setName(null);
+    builder.setType(AclEntryType.OTHER);
+    builder.setScope(AclEntryScope.ACCESS);
+    builder.setPermission(fsPerm.getOtherAction());
+    list.add(builder.build());
+    return list;
+  }
+
+  public AclFeature getAclFeature(String[] pathElements, INodeAttributes node, 
+      boolean stale) {
+    AclFeature f = null;
+    String p = Arrays.toString(pathElements);
+    boolean hasAuthzObj = false;
+    List<AclEntry> list = new ArrayList<AclEntry>();
+    if (originalAuthzAsAcl) {
+      String user = node.getUserName();
+      String group = node.getGroupName();
+      FsPermission perm = node.getFsPermission();
+      list.addAll(createAclEntries(user, group, perm));
+    }
+    if (!stale) { 
+      if (authzInfo.doesBelongToAuthzObject(pathElements)) {
+        hasAuthzObj = true;
+        list.addAll(authzInfo.getAclEntries(pathElements));
+        f = new SentryAclFeature(ImmutableList.copyOf(list));
+      }
+    } else {
+      f = new SentryAclFeature(ImmutableList.copyOf(list));
+    }
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("### getAclEntry [" + p + "] : ["
+          + "isStale=" + stale
+          + ",hasAuthzObj=" + hasAuthzObj
+          + ",origAtuhzAsAcl=" + originalAuthzAsAcl + "]"
+          + "[" + (f == null ? "null" : f.getEntries()) + "]");
+    }
+    return f;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryPermissions.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryPermissions.java b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryPermissions.java
new file mode 100644
index 0000000..7461f89
--- /dev/null
+++ b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryPermissions.java
@@ -0,0 +1,159 @@
+/**
+ * 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.hdfs;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.fs.permission.AclEntryScope;
+import org.apache.hadoop.fs.permission.AclEntryType;
+import org.apache.hadoop.fs.permission.FsAction;
+
+import com.google.common.collect.Lists;
+
+public class SentryPermissions implements AuthzPermissions {
+  
+  public static class PrivilegeInfo {
+    private final String authzObj;
+    private final Map<String, FsAction> roleToPermission = new HashMap<String, FsAction>();
+    public PrivilegeInfo(String authzObj) {
+      this.authzObj = authzObj;
+    }
+    public PrivilegeInfo setPermission(String role, FsAction perm) {
+      roleToPermission.put(role, perm);
+      return this;
+    }
+    public PrivilegeInfo removePermission(String role) {
+      roleToPermission.remove(role);
+      return this;
+    }
+    public FsAction getPermission(String role) {
+      return roleToPermission.get(role);
+    }
+    public Map<String, FsAction> getAllPermissions() {
+      return roleToPermission;
+    }
+    public String getAuthzObj() {
+      return authzObj;
+    }
+  }
+
+  public static class RoleInfo {
+    private final String role;
+    private final Set<String> groups = new HashSet<String>();
+    public RoleInfo(String role) {
+      this.role = role;
+    }
+    public RoleInfo addGroup(String group) {
+      groups.add(group);
+      return this;
+    }
+    public RoleInfo delGroup(String group) {
+      groups.remove(group);
+      return this;
+    }
+    public String getRole() {
+      return role;
+    }
+    public Set<String> getAllGroups() {
+      return groups;
+    }
+  }
+
+  private final Map<String, PrivilegeInfo> privileges = new HashMap<String, PrivilegeInfo>();
+  private final Map<String, RoleInfo> roles = new HashMap<String, RoleInfo>();
+
+  @Override
+  public List<AclEntry> getAcls(String authzObj) {
+    PrivilegeInfo privilegeInfo = privileges.get(authzObj);
+    Map<String, FsAction> groupPerms = new HashMap<String, FsAction>();
+    if (privilegeInfo != null) {
+      for (Map.Entry<String, FsAction> privs : privilegeInfo
+          .getAllPermissions().entrySet()) {
+        constructAclEntry(privs.getKey(), privs.getValue(), groupPerms);
+      }
+    }
+    List<AclEntry> retList = new LinkedList<AclEntry>();
+    for (Map.Entry<String, FsAction> groupPerm : groupPerms.entrySet()) {
+      AclEntry.Builder builder = new AclEntry.Builder();
+      builder.setName(groupPerm.getKey());
+      builder.setType(AclEntryType.GROUP);
+      builder.setScope(AclEntryScope.ACCESS);
+      FsAction action = groupPerm.getValue(); 
+      if ((action == FsAction.READ) || (action == FsAction.WRITE)
+          || (action == FsAction.READ_WRITE)) {
+        action = action.or(FsAction.EXECUTE);
+      }
+      builder.setPermission(action);
+      retList.add(builder.build());
+    }
+    return retList;
+  }
+
+  private void constructAclEntry(String role, FsAction permission,
+      Map<String, FsAction> groupPerms) {
+    RoleInfo roleInfo = roles.get(role);
+    if (roleInfo != null) {
+      for (String group : roleInfo.groups) {
+        FsAction fsAction = groupPerms.get(group);
+        if (fsAction == null) {
+          fsAction = FsAction.NONE;
+        }
+        groupPerms.put(group, fsAction.or(permission));
+      }
+    }
+  }
+
+  public PrivilegeInfo getPrivilegeInfo(String authzObj) {
+    return privileges.get(authzObj);
+  }
+
+  Collection<PrivilegeInfo> getAllPrivileges() {
+    return privileges.values();
+  }
+
+  Collection<RoleInfo> getAllRoles() {
+    return roles.values();
+  }
+
+  public void delPrivilegeInfo(String authzObj) {
+    privileges.remove(authzObj);
+  }
+
+  public void addPrivilegeInfo(PrivilegeInfo privilegeInfo) {
+    privileges.put(privilegeInfo.authzObj, privilegeInfo);
+  }
+
+  public RoleInfo getRoleInfo(String role) {
+    return roles.get(role);
+  }
+
+  public void delRoleInfo(String role) {
+    roles.remove(role);
+  }
+
+  public void addRoleInfo(RoleInfo roleInfo) {
+    roles.put(roleInfo.role, roleInfo);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryUpdater.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryUpdater.java b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryUpdater.java
new file mode 100644
index 0000000..905553e
--- /dev/null
+++ b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/SentryUpdater.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.hdfs;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.sentry.hdfs.SentryHDFSServiceClient.SentryAuthzUpdate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SentryUpdater {
+
+  private SentryHDFSServiceClient sentryClient;
+  private final Configuration conf;
+  private final SentryAuthorizationInfo authzInfo;
+
+  private static Logger LOG = LoggerFactory.getLogger(SentryUpdater.class);
+
+  public SentryUpdater(Configuration conf, SentryAuthorizationInfo authzInfo) throws Exception {
+    this.conf = conf;
+    this.authzInfo = authzInfo;
+  }
+
+  public SentryAuthzUpdate getUpdates() {
+    if (sentryClient == null) {
+      try {
+        sentryClient = new SentryHDFSServiceClient(conf);
+      } catch (Exception e) {
+        LOG.error("Error connecting to Sentry ['{}'] !!",
+            e.getMessage());
+        return null;
+      }
+    }
+    try {
+      SentryAuthzUpdate sentryUpdates = sentryClient.getAllUpdatesFrom(
+          authzInfo.getAuthzPermissions().getLastUpdatedSeqNum() + 1,
+          authzInfo.getAuthzPaths().getLastUpdatedSeqNum() + 1);
+      return sentryUpdates;
+    } catch (Exception e)  {
+      sentryClient = null;
+      LOG.error("Error receiving updates from Sentry !!", e);
+      return null;
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/UpdateableAuthzPermissions.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/UpdateableAuthzPermissions.java b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/UpdateableAuthzPermissions.java
new file mode 100644
index 0000000..3f73f3c
--- /dev/null
+++ b/sentry-hdfs-int/src/main/java/org/apache/sentry/hdfs/UpdateableAuthzPermissions.java
@@ -0,0 +1,198 @@
+/**
+ * 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.hdfs;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReadWriteLock;
+
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.fs.permission.FsAction;
+import org.apache.sentry.core.model.db.AccessConstants;
+import org.apache.sentry.hdfs.SentryPermissions.PrivilegeInfo;
+import org.apache.sentry.hdfs.SentryPermissions.RoleInfo;
+import org.apache.sentry.hdfs.service.thrift.TPrivilegeChanges;
+import org.apache.sentry.hdfs.service.thrift.TRoleChanges;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UpdateableAuthzPermissions implements AuthzPermissions, Updateable<PermissionsUpdate> {
+  private volatile SentryPermissions perms = new SentryPermissions();
+  private final AtomicLong seqNum = new AtomicLong(0);
+  
+  private static Logger LOG = LoggerFactory.getLogger(UpdateableAuthzPermissions.class);
+
+  public static Map<String, FsAction> ACTION_MAPPING = new HashMap<String, FsAction>();
+  static {
+    ACTION_MAPPING.put("ALL", FsAction.ALL);
+    ACTION_MAPPING.put("*", FsAction.ALL);
+    ACTION_MAPPING.put(AccessConstants.SELECT.toUpperCase(), FsAction.READ_EXECUTE);
+    ACTION_MAPPING.put(AccessConstants.INSERT.toUpperCase(), FsAction.WRITE_EXECUTE);
+  }
+
+  @Override
+  public List<AclEntry> getAcls(String authzObj) {
+    return perms.getAcls(authzObj);
+  }
+
+  @Override
+  public UpdateableAuthzPermissions updateFull(PermissionsUpdate update) {
+    UpdateableAuthzPermissions other = new UpdateableAuthzPermissions();
+    other.applyPartialUpdate(update);
+    other.seqNum.set(update.getSeqNum());
+    return other;
+  }
+
+  @Override
+  public void updatePartial(Iterable<PermissionsUpdate> updates, ReadWriteLock lock) {
+    lock.writeLock().lock();
+    try {
+      int counter = 0;
+      for (PermissionsUpdate update : updates) {
+        applyPartialUpdate(update);
+        if (++counter > 99) {
+          counter = 0;
+          lock.writeLock().unlock();
+          lock.writeLock().lock();
+        }
+        seqNum.set(update.getSeqNum());
+        LOG.warn("##### Updated perms seq Num [" + seqNum.get() + "]");
+      }
+    } finally {
+      lock.writeLock().unlock();
+    }
+  }
+  
+
+  private void applyPartialUpdate(PermissionsUpdate update) {
+    applyPrivilegeUpdates(update);
+    applyRoleUpdates(update);
+  }
+
+  private void applyRoleUpdates(PermissionsUpdate update) {
+    for (TRoleChanges rUpdate : update.getRoleUpdates()) {
+      if (rUpdate.getRole().equals(PermissionsUpdate.ALL_ROLES)) {
+        // Request to remove group from all roles
+        String groupToRemove = rUpdate.getDelGroups().iterator().next();
+        for (RoleInfo rInfo : perms.getAllRoles()) {
+          rInfo.delGroup(groupToRemove);
+        }
+      }
+      RoleInfo rInfo = perms.getRoleInfo(rUpdate.getRole());
+      for (String group : rUpdate.getAddGroups()) {
+        if (rInfo == null) {
+          rInfo = new RoleInfo(rUpdate.getRole());
+        }
+        rInfo.addGroup(group);
+      }
+      if (rInfo != null) {
+        perms.addRoleInfo(rInfo);
+        for (String group : rUpdate.getDelGroups()) {
+          if (group.equals(PermissionsUpdate.ALL_GROUPS)) {
+            perms.delRoleInfo(rInfo.getRole());
+            break;
+          }
+          // If there are no groups to remove, rUpdate.getDelGroups() will
+          // return empty list and this code will not be reached
+          rInfo.delGroup(group);
+        }
+      }
+    }
+  }
+
+  private void applyPrivilegeUpdates(PermissionsUpdate update) {
+    for (TPrivilegeChanges pUpdate : update.getPrivilegeUpdates()) {
+      if (pUpdate.getAuthzObj().equals(PermissionsUpdate.ALL_PRIVS)) {
+        // Request to remove role from all Privileges
+        String roleToRemove = pUpdate.getDelPrivileges().keySet().iterator()
+            .next();
+        for (PrivilegeInfo pInfo : perms.getAllPrivileges()) {
+          pInfo.removePermission(roleToRemove);
+        }
+      }
+      PrivilegeInfo pInfo = perms.getPrivilegeInfo(pUpdate.getAuthzObj());
+      for (Map.Entry<String, String> aMap : pUpdate.getAddPrivileges().entrySet()) {
+        if (pInfo == null) {
+          pInfo = new PrivilegeInfo(pUpdate.getAuthzObj());
+        }
+        FsAction fsAction = pInfo.getPermission(aMap.getKey());
+        if (fsAction == null) {
+          fsAction = FsAction.getFsAction(aMap.getValue());
+        } else {
+          fsAction = fsAction.or(FsAction.getFsAction(aMap.getValue()));
+        }
+        pInfo.setPermission(aMap.getKey(), fsAction);
+      }
+      if (pInfo != null) {
+        perms.addPrivilegeInfo(pInfo);
+        for (Map.Entry<String, String> dMap : pUpdate.getDelPrivileges().entrySet()) {
+          if (dMap.getKey().equals(PermissionsUpdate.ALL_ROLES)) {
+            // Remove all privileges
+            perms.delPrivilegeInfo(pUpdate.getAuthzObj());
+            break;
+          }
+          FsAction fsAction = pInfo.getPermission(dMap.getKey());
+          if (fsAction != null) {
+            fsAction = fsAction.and(FsAction.getFsAction(dMap.getValue()).not());
+            if (FsAction.NONE == fsAction) {
+              pInfo.removePermission(dMap.getKey());
+            } else {
+              pInfo.setPermission(dMap.getKey(), fsAction);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  static FsAction getFAction(String sentryPriv) {
+    String[] strPrivs = sentryPriv.trim().split(",");
+    FsAction retVal = FsAction.NONE;
+    for (String strPriv : strPrivs) {
+      retVal = retVal.or(ACTION_MAPPING.get(strPriv.toUpperCase()));
+    }
+    return retVal;
+  }
+
+  @Override
+  public long getLastUpdatedSeqNum() {
+    return seqNum.get();
+  }
+
+  @Override
+  public PermissionsUpdate createFullImageUpdate(long currSeqNum) {
+    PermissionsUpdate retVal = new PermissionsUpdate(currSeqNum, true);
+    for (PrivilegeInfo pInfo : perms.getAllPrivileges()) {
+      TPrivilegeChanges pUpdate = retVal.addPrivilegeUpdate(pInfo.getAuthzObj());
+      for (Map.Entry<String, FsAction> ent : pInfo.getAllPermissions().entrySet()) {
+        pUpdate.putToAddPrivileges(ent.getKey(), ent.getValue().SYMBOL);
+      }
+    }
+    for (RoleInfo rInfo : perms.getAllRoles()) {
+      TRoleChanges rUpdate = retVal.addRoleUpdate(rInfo.getRole());
+      for (String group : rInfo.getAllGroups()) {
+        rUpdate.addToAddGroups(group);
+      }
+    }
+    return retVal;
+  }
+
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/MockSentryAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/MockSentryAuthorizationProvider.java b/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/MockSentryAuthorizationProvider.java
new file mode 100644
index 0000000..2085b52
--- /dev/null
+++ b/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/MockSentryAuthorizationProvider.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.hdfs;
+
+public class MockSentryAuthorizationProvider extends
+    SentryAuthorizationProvider {
+
+  public MockSentryAuthorizationProvider() {
+    super(new SentryAuthorizationInfoX());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/SentryAuthorizationInfoX.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/SentryAuthorizationInfoX.java b/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/SentryAuthorizationInfoX.java
new file mode 100644
index 0000000..7a1539b
--- /dev/null
+++ b/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/SentryAuthorizationInfoX.java
@@ -0,0 +1,85 @@
+/**
+ * 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.hdfs;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.fs.permission.AclEntryScope;
+import org.apache.hadoop.fs.permission.AclEntryType;
+import org.apache.hadoop.fs.permission.FsAction;
+
+public class SentryAuthorizationInfoX extends SentryAuthorizationInfo {
+
+  public SentryAuthorizationInfoX() {
+    super();
+  }
+
+  @Override
+  public void run() {
+    
+  }
+
+  @Override
+  public void start() {
+
+  }
+
+  @Override
+  public void stop() {
+
+  }
+
+  @Override
+  public boolean isStale() {
+    return false;
+  }
+
+  private static final String[] MANAGED = {"user", "authz"};
+  private static final String[] AUTHZ_OBJ = {"user", "authz", "obj"};
+
+  private boolean hasPrefix(String[] prefix, String[] pathElement) {
+    int i = 0;
+    for (; i < prefix.length && i < pathElement.length; i ++) {
+      if (!prefix[i].equals(pathElement[i])) {
+        return false;
+      }
+    }    
+    return (i == prefix.length);
+  }
+  
+  @Override
+  public boolean isManaged(String[] pathElements) {
+    return hasPrefix(MANAGED, pathElements);
+  }
+
+  @Override
+  public boolean doesBelongToAuthzObject(String[] pathElements) {
+    return hasPrefix(AUTHZ_OBJ, pathElements);
+  }
+
+  @Override
+  public List<AclEntry> getAclEntries(String[] pathElements) {
+    AclEntry acl = new AclEntry.Builder().setType(AclEntryType.USER).
+        setPermission(FsAction.ALL).setName("user-authz").
+        setScope(AclEntryScope.ACCESS).build();
+    return Arrays.asList(acl);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/TestSentryAuthorizationProvider.java
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/TestSentryAuthorizationProvider.java b/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/TestSentryAuthorizationProvider.java
new file mode 100644
index 0000000..c9bd9a3
--- /dev/null
+++ b/sentry-hdfs-int/src/test/java/org/apache/sentry/hdfs/TestSentryAuthorizationProvider.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.hdfs;
+
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.permission.AclEntry;
+import org.apache.hadoop.fs.permission.AclEntryScope;
+import org.apache.hadoop.fs.permission.AclEntryType;
+import org.apache.hadoop.fs.permission.FsAction;
+import org.apache.hadoop.fs.permission.FsPermission;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.apache.hadoop.hdfs.HdfsConfiguration;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.apache.hadoop.hdfs.server.namenode.EditLogFileOutputStream;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class TestSentryAuthorizationProvider {
+  private MiniDFSCluster miniDFS;
+  private UserGroupInformation admin;
+  
+  @Before
+  public void setUp() throws Exception {
+    admin = UserGroupInformation.createUserForTesting(
+        System.getProperty("user.name"), new String[] { "supergroup" });
+    admin.doAs(new PrivilegedExceptionAction<Void>() {
+      @Override
+      public Void run() throws Exception {
+        System.setProperty(MiniDFSCluster.PROP_TEST_BUILD_DATA, "target/test/data");
+        Configuration conf = new HdfsConfiguration();
+        conf.set(DFSConfigKeys.DFS_NAMENODE_INODE_ATTRIBUTES_PROVIDER_KEY,
+            MockSentryAuthorizationProvider.class.getName());
+        conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true);
+        EditLogFileOutputStream.setShouldSkipFsyncForTesting(true);
+        miniDFS = new MiniDFSCluster.Builder(conf).build();
+        return null;
+      }
+    });
+  }
+
+  @After
+  public void cleanUp() throws IOException {
+    if (miniDFS != null) {
+      miniDFS.shutdown();
+    }
+  }
+
+  @Test
+  public void testProvider() throws Exception {
+    admin.doAs(new PrivilegedExceptionAction<Void>() {
+      @Override
+      public Void run() throws Exception {
+        String sysUser = UserGroupInformation.getCurrentUser().getShortUserName();
+        FileSystem fs = FileSystem.get(miniDFS.getConfiguration(0));
+
+        List<AclEntry> baseAclList = new ArrayList<AclEntry>();
+        AclEntry.Builder builder = new AclEntry.Builder();
+        baseAclList.add(builder.setType(AclEntryType.USER)
+            .setScope(AclEntryScope.ACCESS).build());
+        baseAclList.add(builder.setType(AclEntryType.GROUP)
+            .setScope(AclEntryScope.ACCESS).build());
+        baseAclList.add(builder.setType(AclEntryType.OTHER)
+            .setScope(AclEntryScope.ACCESS).build());
+        Path path1 = new Path("/user/authz/obj/xxx");
+        fs.mkdirs(path1);
+        fs.setAcl(path1, baseAclList);
+
+        fs.mkdirs(new Path("/user/authz/xxx"));
+        fs.mkdirs(new Path("/user/xxx"));
+
+        // root
+        Path path = new Path("/");
+        Assert.assertEquals(sysUser, fs.getFileStatus(path).getOwner());
+        Assert.assertEquals("supergroup", fs.getFileStatus(path).getGroup());
+        Assert.assertEquals(new FsPermission((short) 0755), fs.getFileStatus(path).getPermission());
+        Assert.assertTrue(fs.getAclStatus(path).getEntries().isEmpty());
+
+        // dir before prefixes
+        path = new Path("/user");
+        Assert.assertEquals(sysUser, fs.getFileStatus(path).getOwner());
+        Assert.assertEquals("supergroup", fs.getFileStatus(path).getGroup());
+        Assert.assertEquals(new FsPermission((short) 0755), fs.getFileStatus(path).getPermission());
+        Assert.assertTrue(fs.getAclStatus(path).getEntries().isEmpty());
+
+        // prefix dir
+        path = new Path("/user/authz");
+        Assert.assertEquals(sysUser, fs.getFileStatus(path).getOwner());
+        Assert.assertEquals("supergroup", fs.getFileStatus(path).getGroup());
+        Assert.assertEquals(new FsPermission((short) 0755), fs.getFileStatus(path).getPermission());
+        Assert.assertTrue(fs.getAclStatus(path).getEntries().isEmpty());
+
+        // dir inside of prefix, no obj
+        path = new Path("/user/authz/xxx");
+        FileStatus status = fs.getFileStatus(path);
+        Assert.assertEquals(sysUser, status.getOwner());
+        Assert.assertEquals("supergroup", status.getGroup());
+        Assert.assertEquals(new FsPermission((short) 0755), status.getPermission());
+        Assert.assertTrue(fs.getAclStatus(path).getEntries().isEmpty());
+
+        // dir inside of prefix, obj
+        path = new Path("/user/authz/obj");
+        Assert.assertEquals("hive", fs.getFileStatus(path).getOwner());
+        Assert.assertEquals("hive", fs.getFileStatus(path).getGroup());
+        Assert.assertEquals(new FsPermission((short) 0770), fs.getFileStatus(path).getPermission());
+        Assert.assertFalse(fs.getAclStatus(path).getEntries().isEmpty());
+
+        List<AclEntry> acls = new ArrayList<AclEntry>();
+        acls.add(new AclEntry.Builder().setName(sysUser).setType(AclEntryType.USER).setScope(AclEntryScope.ACCESS).setPermission(FsAction.ALL).build());
+        acls.add(new AclEntry.Builder().setName("supergroup").setType(AclEntryType.GROUP).setScope(AclEntryScope.ACCESS).setPermission(FsAction.READ_EXECUTE).build());
+        acls.add(new AclEntry.Builder().setName(null).setType(AclEntryType.OTHER).setScope(AclEntryScope.ACCESS).setPermission(FsAction.READ_EXECUTE).build());
+        acls.add(new AclEntry.Builder().setName("user-authz").setType(AclEntryType.USER).setScope(AclEntryScope.ACCESS).setPermission(FsAction.ALL).build());
+        Assert.assertEquals(new LinkedHashSet<AclEntry>(acls), new LinkedHashSet<AclEntry>(fs.getAclStatus(path).getEntries()));
+
+        // dir inside of prefix, inside of obj
+        path = new Path("/user/authz/obj/xxx");
+        Assert.assertEquals("hive", fs.getFileStatus(path).getOwner());
+        Assert.assertEquals("hive", fs.getFileStatus(path).getGroup());
+        Assert.assertEquals(new FsPermission((short) 0770), fs.getFileStatus(path).getPermission());
+        Assert.assertFalse(fs.getAclStatus(path).getEntries().isEmpty());
+        
+        Path path2 = new Path("/user/authz/obj/path2");
+        fs.mkdirs(path2);
+        fs.setAcl(path2, baseAclList);
+
+        // dir outside of prefix
+        path = new Path("/user/xxx");
+        Assert.assertEquals(sysUser, fs.getFileStatus(path).getOwner());
+        Assert.assertEquals("supergroup", fs.getFileStatus(path).getGroup());
+        Assert.assertEquals(new FsPermission((short) 0755), fs.getFileStatus(path).getPermission());
+        Assert.assertTrue(fs.getAclStatus(path).getEntries().isEmpty());
+        return null;
+      }
+    });
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-int/src/test/resources/hdfs-sentry.xml
----------------------------------------------------------------------
diff --git a/sentry-hdfs-int/src/test/resources/hdfs-sentry.xml b/sentry-hdfs-int/src/test/resources/hdfs-sentry.xml
new file mode 100644
index 0000000..511bfdd
--- /dev/null
+++ b/sentry-hdfs-int/src/test/resources/hdfs-sentry.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   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.
+-->
+
+<configuration>
+  <property>
+    <name>sentry.hdfs-plugin.path-prefixes</name>
+    <value>/user/hive/dw</value>
+  </property>
+  <property>
+    <name>sentry.hdfs-plugin.sentry-uri</name>
+    <value>thrift://localhost:1234</value>
+  </property>
+  <property>
+    <name>sentry.hdfs-plugin.stale-threshold.ms</name>
+    <value>-1</value>
+  </property>
+</configuration>

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/b86a53d1/sentry-hdfs-service/pom.xml
----------------------------------------------------------------------
diff --git a/sentry-hdfs-service/pom.xml b/sentry-hdfs-service/pom.xml
new file mode 100644
index 0000000..8a9c625
--- /dev/null
+++ b/sentry-hdfs-service/pom.xml
@@ -0,0 +1,109 @@
+<?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</artifactId>
+    <version>1.5.0-incubating-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+
+  <artifactId>sentry-hdfs-service</artifactId>
+  <name>Sentry HDFS service</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <scope>provided</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.sentry</groupId>
+      <artifactId>sentry-hdfs</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-provider-db</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sentry</groupId>
+      <artifactId>sentry-service-client</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-exec</artifactId>
+      <version>${hive.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-shims</artifactId>
+      <version>${hive.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libfb303</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.thrift</groupId>
+      <artifactId>libthrift</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>ant-contrib</groupId>
+      <artifactId>ant-contrib</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minikdc</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hive</groupId>
+      <artifactId>hive-metastore</artifactId>
+      <version>${hive.version}</version>
+    </dependency>
+  </dependencies>
+
+
+</project>


Mime
View raw message