SENTRY-2269: Make SentryStore pluggable. (Fahd Siddiqui reviewed by Kalyan 
Kumar Kalvagadda )


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

Branch: refs/heads/master
Commit: 9caa0d1d05871028ae1fc53bfc945c37e9c6eadc
Parents: 7484208
Author: Kalyan Kumar Kalvagadda <kkal...@cloudera.com>
Authored: Mon Jun 25 21:38:39 2018 -0500
Committer: Kalyan Kumar Kalvagadda <kkal...@cloudera.com>
Committed: Mon Jun 25 21:38:39 2018 -0500

----------------------------------------------------------------------
 .../core/common/utils/SentryConstants.java      |  27 +
 .../sentry/service/common/ServiceConstants.java |   3 +
 .../apache/sentry/hdfs/PathDeltaRetriever.java  |   6 +-
 .../apache/sentry/hdfs/PathImageRetriever.java  |   6 +-
 .../apache/sentry/hdfs/PermDeltaRetriever.java  |   6 +-
 .../apache/sentry/hdfs/PermImageRetriever.java  |   6 +-
 .../hdfs/SentryHDFSServiceProcessorFactory.java |   4 +-
 .../org/apache/sentry/hdfs/SentryPlugin.java    |   3 +-
 .../sentry/hdfs/TestDBUpdateForwarder.java      |  12 +-
 .../SentryGenericPolicyProcessorFactory.java    |   4 +-
 .../api/service/thrift/SentryMetrics.java       |   3 +-
 .../thrift/SentryPolicyStoreProcessor.java      |  11 +-
 .../SentryPolicyStoreProcessorFactory.java      |   4 +-
 .../provider/db/SentryPolicyStorePlugin.java    |   4 +-
 .../persistent/PrivilegeOperatePersistence.java |   3 +-
 .../classification/InterfaceAudience.java       |  47 ++
 .../db/service/persistent/HMSFollower.java      |  11 +-
 .../persistent/NotificationProcessor.java       |  11 +-
 .../service/persistent/QueryParamBuilder.java   |   6 +-
 .../db/service/persistent/SentryStore.java      |  49 +-
 .../persistent/SentryStoreInterface.java        | 785 +++++++++++++++++++
 .../sentry/service/thrift/DynamicProxy.java     |  72 ++
 .../service/thrift/HiveNotificationFetcher.java |   9 +-
 .../sentry/service/thrift/ProcessorFactory.java |   6 +-
 .../sentry/service/thrift/SentryHMSClient.java  |  16 +-
 .../sentry/service/thrift/SentryService.java    |  34 +-
 .../service/persistent/TestSentryRole.java      |  22 +-
 .../db/service/persistent/TestHMSFollower.java  |  13 +-
 .../db/service/persistent/TestSentryStore.java  |   3 +-
 .../persistent/TestSentryStoreImportExport.java |  35 +-
 30 files changed, 1093 insertions(+), 128 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/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
index a4e69b9..d8c1061 100644
--- 
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
@@ -45,4 +45,31 @@ public class SentryConstants {
 
   public static final String KERBEROS_MODE = "kerberos";
 
+  // Sentry Store constants
+
+  public static final String NULL_COL = "__NULL__";
+  public static final int INDEX_GROUP_ROLES_MAP = 0;
+  public static final int INDEX_USER_ROLES_MAP = 1;
+
+  // String constants for field names
+  public static final String SERVER_NAME = "serverName";
+  public static final String DB_NAME = "dbName";
+  public static final String TABLE_NAME = "tableName";
+  public static final String COLUMN_NAME = "columnName";
+  public static final String ACTION = "action";
+  public static final String URI = "URI";
+  public static final String GRANT_OPTION = "grantOption";
+  public static final String ROLE_NAME = "roleName";
+
+  // Initial change ID for permission/path change. Auto increment
+  // is starting from 1.
+  public static final long INIT_CHANGE_ID = 1L;
+
+  public static final long EMPTY_CHANGE_ID = 0L;
+
+  public static final long EMPTY_NOTIFICATION_ID = 0L;
+
+  // Representation for empty HMS snapshots not found on MAuthzPathsSnapshotId
+  public static final long EMPTY_PATHS_SNAPSHOT_ID = 0L;
+
 }

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
----------------------------------------------------------------------
diff --git 
a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
 
b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
index 777c262..c1beaed 100644
--- 
a/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
+++ 
b/sentry-core/sentry-core-common/src/main/java/org/apache/sentry/service/common/ServiceConstants.java
@@ -78,6 +78,9 @@ public class ServiceConstants {
     public static final String PROCESSOR_FACTORIES_DEFAULT =
         
"org.apache.sentry.api.service.thrift.SentryPolicyStoreProcessorFactory" +
             
",org.apache.sentry.api.generic.thrift.SentryGenericPolicyProcessorFactory";
+    public static final String SENTRY_STORE = "sentry.service.sentrystore";
+    public static final String SENTRY_STORE_DEFAULT =
+      "org.apache.sentry.provider.db.service.persistent.SentryStore";
     public static final String SENTRY_STORE_JDBC_URL = "sentry.store.jdbc.url";
     public static final String SENTRY_STORE_JDBC_USER = 
"sentry.store.jdbc.user";
     public static final String SENTRY_STORE_JDBC_USER_DEFAULT = "Sentry";

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathDeltaRetriever.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathDeltaRetriever.java
 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathDeltaRetriever.java
index b2e45f9..81c614a 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathDeltaRetriever.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathDeltaRetriever.java
@@ -19,7 +19,7 @@ package org.apache.sentry.hdfs;
 
 import com.codahale.metrics.Timer.Context;
 import org.apache.sentry.provider.db.service.model.MSentryPathChange;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 
 import javax.annotation.concurrent.ThreadSafe;
 import java.util.ArrayList;
@@ -37,9 +37,9 @@ import java.util.List;
 @ThreadSafe
 public class PathDeltaRetriever implements DeltaRetriever<PathsUpdate> {
 
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
 
-  PathDeltaRetriever(SentryStore sentryStore) {
+  PathDeltaRetriever(SentryStoreInterface sentryStore) {
     this.sentryStore = sentryStore;
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathImageRetriever.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathImageRetriever.java
 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathImageRetriever.java
index fd0d87b..3532ef3 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathImageRetriever.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PathImageRetriever.java
@@ -18,7 +18,7 @@
 package org.apache.sentry.hdfs;
 
 import com.codahale.metrics.Timer;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 
 import javax.annotation.concurrent.ThreadSafe;
 
@@ -32,11 +32,11 @@ import javax.annotation.concurrent.ThreadSafe;
 @ThreadSafe
 class PathImageRetriever implements ImageRetriever<PathsUpdate> {
 
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
   /** List of prefixes managed by Sentry */
   private final String[] prefixes;
 
-  PathImageRetriever(SentryStore sentryStore, String[] prefixes) {
+  PathImageRetriever(SentryStoreInterface sentryStore, String[] prefixes) {
     this.sentryStore = sentryStore;
     this.prefixes = prefixes;
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermDeltaRetriever.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermDeltaRetriever.java
 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermDeltaRetriever.java
index 7cd2c31..8d6713a 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermDeltaRetriever.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermDeltaRetriever.java
@@ -20,7 +20,7 @@ package org.apache.sentry.hdfs;
 import com.codahale.metrics.Timer.Context;
 import org.apache.sentry.hdfs.service.thrift.TPrivilegeChanges;
 import org.apache.sentry.provider.db.service.model.MSentryPermChange;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 
 import javax.annotation.concurrent.ThreadSafe;
 import java.util.ArrayList;
@@ -38,9 +38,9 @@ import java.util.List;
 @ThreadSafe
 public class PermDeltaRetriever implements DeltaRetriever<PermissionsUpdate> {
 
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
 
-  PermDeltaRetriever(SentryStore sentryStore) {
+  PermDeltaRetriever(SentryStoreInterface sentryStore) {
     this.sentryStore = sentryStore;
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermImageRetriever.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermImageRetriever.java
 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermImageRetriever.java
index ef0203f..b87d290 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermImageRetriever.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/PermImageRetriever.java
@@ -24,7 +24,7 @@ import 
org.apache.sentry.hdfs.service.thrift.TPrivilegeChanges;
 import org.apache.sentry.hdfs.service.thrift.TRoleChanges;
 import org.apache.sentry.hdfs.service.thrift.sentry_hdfs_serviceConstants;
 import org.apache.sentry.provider.db.service.persistent.PermissionsImage;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 
 import javax.annotation.concurrent.ThreadSafe;
 import java.util.ArrayList;
@@ -42,9 +42,9 @@ import java.util.Map;
 @ThreadSafe
 public class PermImageRetriever implements ImageRetriever<PermissionsUpdate> {
 
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
 
-  PermImageRetriever(SentryStore sentryStore) {
+  PermImageRetriever(SentryStoreInterface sentryStore) {
     this.sentryStore = sentryStore;
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
index 1ad9a02..0fe993c 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryHDFSServiceProcessorFactory.java
@@ -21,7 +21,7 @@ package org.apache.sentry.hdfs;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.hdfs.service.thrift.SentryHDFSService;
 import org.apache.sentry.hdfs.service.thrift.SentryHDFSService.Iface;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.sentry.core.common.utils.ThriftUtil;
 import org.apache.sentry.service.thrift.ProcessorFactory;
 import org.apache.thrift.TException;
@@ -54,7 +54,7 @@ public class SentryHDFSServiceProcessorFactory extends 
ProcessorFactory{
 
   @Override
   public boolean register(TMultiplexedProcessor multiplexedProcessor,
-                          SentryStore _) throws Exception {
+                          SentryStoreInterface _) throws Exception {
     SentryHDFSServiceProcessor sentryServiceHandler =
         new SentryHDFSServiceProcessor();
     LOGGER.info("Calling registerProcessor from 
SentryHDFSServiceProcessorFactory");

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
index 6ff3c82..6cb787b 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/main/java/org/apache/sentry/hdfs/SentryPlugin.java
@@ -35,6 +35,7 @@ import 
org.apache.sentry.hdfs.service.thrift.TPrivilegeEntityType;
 import org.apache.sentry.hdfs.service.thrift.TRoleChanges;
 import org.apache.sentry.provider.db.SentryPolicyStorePlugin;
 import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.sentry.api.common.SentryServiceUtil;
 import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddGroupsRequest;
 import 
org.apache.sentry.api.service.thrift.TAlterSentryRoleDeleteGroupsRequest;
@@ -118,7 +119,7 @@ public class SentryPlugin implements 
SentryPolicyStorePlugin, SigUtils.SigListen
   private DBUpdateForwarder<PermissionsUpdate> permsUpdater;
 
   @Override
-  public void initialize(Configuration conf, SentryStore sentryStore) throws 
SentryPluginException {
+  public void initialize(Configuration conf, SentryStoreInterface sentryStore) 
throws SentryPluginException {
     // List of paths managed by Sentry
     String[] prefixes =
             conf.getStrings(SENTRY_HDFS_INTEGRATION_PATH_PREFIXES,

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-hdfs/sentry-hdfs-service/src/test/java/org/apache/sentry/hdfs/TestDBUpdateForwarder.java
----------------------------------------------------------------------
diff --git 
a/sentry-hdfs/sentry-hdfs-service/src/test/java/org/apache/sentry/hdfs/TestDBUpdateForwarder.java
 
b/sentry-hdfs/sentry-hdfs-service/src/test/java/org/apache/sentry/hdfs/TestDBUpdateForwarder.java
index cd1ad03..f86ce6f 100644
--- 
a/sentry-hdfs/sentry-hdfs-service/src/test/java/org/apache/sentry/hdfs/TestDBUpdateForwarder.java
+++ 
b/sentry-hdfs/sentry-hdfs-service/src/test/java/org/apache/sentry/hdfs/TestDBUpdateForwarder.java
@@ -17,7 +17,7 @@
  */
 package org.apache.sentry.hdfs;
 
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.service.thrift.SentryServiceState;
 import org.apache.sentry.service.thrift.SentryStateBank;
 import org.apache.sentry.service.thrift.SentryStateBankTestHelper;
@@ -49,9 +49,9 @@ public class TestDBUpdateForwarder {
 
   @Test
   public void 
testEmptyListIsReturnedWhenImageNumIsZeroAndNoImagesArePersisted() throws 
Exception {
-    
Mockito.when(imageRetriever.getLatestImageID()).thenReturn(SentryStore.EMPTY_PATHS_SNAPSHOT_ID);
+    
Mockito.when(imageRetriever.getLatestImageID()).thenReturn(SentryConstants.EMPTY_PATHS_SNAPSHOT_ID);
 
-    List updates = updater.getAllUpdatesFrom(1, 
SentryStore.EMPTY_PATHS_SNAPSHOT_ID);
+    List updates = updater.getAllUpdatesFrom(1, 
SentryConstants.EMPTY_PATHS_SNAPSHOT_ID);
     assertTrue(updates.isEmpty());
   }
 
@@ -85,7 +85,7 @@ public class TestDBUpdateForwarder {
 
   @Test
   public void 
testEmptyListIsReturnedWhenImageIsUnusedAndNoDeltaChangesArePersisted() throws 
Exception {
-    
Mockito.when(deltaRetriever.getLatestDeltaID()).thenReturn(SentryStore.EMPTY_NOTIFICATION_ID);
+    
Mockito.when(deltaRetriever.getLatestDeltaID()).thenReturn(SentryConstants.EMPTY_NOTIFICATION_ID);
 
     List updates = updater.getAllUpdatesFrom(1, UNUSED_PATH_UPDATE_IMG_NUM);
     assertTrue(updates.isEmpty());
@@ -97,7 +97,7 @@ public class TestDBUpdateForwarder {
     Mockito.when(imageRetriever.retrieveFullImage())
         .thenReturn(new PathsUpdate(1, 1, true));
 
-    List<PathsUpdate> updates = updater.getAllUpdatesFrom(0, 
SentryStore.EMPTY_PATHS_SNAPSHOT_ID);
+    List<PathsUpdate> updates = updater.getAllUpdatesFrom(0, 
SentryConstants.EMPTY_PATHS_SNAPSHOT_ID);
     assertEquals(1, updates.size());
     assertEquals(1, updates.get(0).getSeqNum());
     assertEquals(1, updates.get(0).getImgNum());
@@ -111,7 +111,7 @@ public class TestDBUpdateForwarder {
         .thenReturn(new PathsUpdate(1, 1, true));
     SentryStateBank.enableState(SentryServiceState.COMPONENT, 
SentryServiceState.FULL_UPDATE_RUNNING);
 
-    List<PathsUpdate> updates = updater.getAllUpdatesFrom(0, 
SentryStore.EMPTY_PATHS_SNAPSHOT_ID);
+    List<PathsUpdate> updates = updater.getAllUpdatesFrom(0, 
SentryConstants.EMPTY_PATHS_SNAPSHOT_ID);
     assertTrue(updates.isEmpty());
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/generic/thrift/SentryGenericPolicyProcessorFactory.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/generic/thrift/SentryGenericPolicyProcessorFactory.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/generic/thrift/SentryGenericPolicyProcessorFactory.java
index 311b020..f9316ce 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/generic/thrift/SentryGenericPolicyProcessorFactory.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/generic/thrift/SentryGenericPolicyProcessorFactory.java
@@ -19,7 +19,7 @@ package org.apache.sentry.api.generic.thrift;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.api.common.ApiConstants.SentryPolicyServiceConstants;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.sentry.service.thrift.ProcessorFactory;
 import org.apache.thrift.TMultiplexedProcessor;
 import org.apache.thrift.TProcessor;
@@ -32,7 +32,7 @@ public class SentryGenericPolicyProcessorFactory extends 
ProcessorFactory {
 
   @Override
   public boolean register(TMultiplexedProcessor multiplexedProcessor,
-                          SentryStore _) throws Exception {
+                          SentryStoreInterface _) throws Exception {
     SentryGenericPolicyProcessor processHandler = new 
SentryGenericPolicyProcessor(conf);
     TProcessor processor = new 
SentryGenericPolicyProcessorWrapper<SentryGenericPolicyService.Iface>(
         processHandler);

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryMetrics.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryMetrics.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryMetrics.java
index 232a979..35c7d07 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryMetrics.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryMetrics.java
@@ -37,6 +37,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.sentry.service.thrift.SentryService;
 import org.apache.sentry.api.common.SentryServiceUtil;
 import org.slf4j.Logger;
@@ -155,7 +156,7 @@ public final class SentryMetrics {
     return sentryMetrics;
   }
 
-  void addSentryStoreGauges(SentryStore sentryStore) {
+  void addSentryStoreGauges(SentryStoreInterface sentryStore) {
     if (!gaugesAdded) {
       addGauge(SentryStore.class, "role_count", 
sentryStore.getRoleCountGauge());
       addGauge(SentryStore.class, "privilege_count",

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java
index 5aef620..3927150 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessor.java
@@ -39,6 +39,7 @@ import org.apache.sentry.SentryOwnerInfo;
 import org.apache.sentry.api.common.ThriftConstants;
 import org.apache.sentry.core.common.exception.SentryUserException;
 import 
org.apache.sentry.core.common.exception.SentrySiteConfigurationException;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.model.db.AccessConstants;
 import org.apache.sentry.provider.common.GroupMappingService;
 import org.apache.sentry.core.common.utils.PolicyFileConstants;
@@ -53,7 +54,7 @@ import 
org.apache.sentry.core.common.exception.SentryThriftAPIMismatchException;
 import org.apache.sentry.provider.db.log.entity.JsonLogEntity;
 import org.apache.sentry.provider.db.log.entity.JsonLogEntityFactory;
 import org.apache.sentry.provider.db.log.util.Constants;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import 
org.apache.sentry.core.common.utils.PolicyStoreConstants.PolicyStoreServerConfig;
 import 
org.apache.sentry.api.service.thrift.validator.GrantPrivilegeRequestValidator;
 import 
org.apache.sentry.api.service.thrift.validator.RevokePrivilegeRequestValidator;
@@ -93,7 +94,7 @@ public class SentryPolicyStoreProcessor implements 
SentryPolicyService.Iface {
 
   private final String name;
   private final Configuration conf;
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
   private final NotificationHandlerInvoker notificationHandlerInvoker;
   private final ImmutableSet<String> adminGroups;
   private SentryMetrics sentryMetrics;
@@ -104,7 +105,7 @@ public class SentryPolicyStoreProcessor implements 
SentryPolicyService.Iface {
   private List<SentryPolicyStorePlugin> sentryPlugins = new 
LinkedList<SentryPolicyStorePlugin>();
 
   SentryPolicyStoreProcessor(String name,
-        Configuration conf, SentryStore store) throws Exception {
+        Configuration conf, SentryStoreInterface store) throws Exception {
     super();
     this.name = name;
     this.conf = conf;
@@ -1274,8 +1275,8 @@ public class SentryPolicyStoreProcessor implements 
SentryPolicyService.Iface {
       List<Map<String, Set<String>>> mapList = 
sentryStore.getGroupUserRoleMapList(
           roleNames);
       tSentryMappingData.setGroupRolesMap(mapList.get(
-          SentryStore.INDEX_GROUP_ROLES_MAP));
-      
tSentryMappingData.setUserRolesMap(mapList.get(SentryStore.INDEX_USER_ROLES_MAP));
+          SentryConstants.INDEX_GROUP_ROLES_MAP));
+      
tSentryMappingData.setUserRolesMap(mapList.get(SentryConstants.INDEX_USER_ROLES_MAP));
 
       response.setMappingData(tSentryMappingData);
       response.setStatus(Status.OK());

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessorFactory.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessorFactory.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessorFactory.java
index fd209b7..b482146 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessorFactory.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/api/service/thrift/SentryPolicyStoreProcessorFactory.java
@@ -19,7 +19,7 @@ package org.apache.sentry.api.service.thrift;
 
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.api.common.ApiConstants.SentryPolicyServiceConstants;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.sentry.service.thrift.ProcessorFactory;
 import org.apache.thrift.TMultiplexedProcessor;
 import org.apache.thrift.TProcessor;
@@ -30,7 +30,7 @@ public class SentryPolicyStoreProcessorFactory extends 
ProcessorFactory {
   }
 
   public boolean register(TMultiplexedProcessor multiplexedProcessor,
-                          SentryStore sentryStore) throws Exception {
+                          SentryStoreInterface sentryStore) throws Exception {
     SentryPolicyStoreProcessor sentryServiceHandler =
         new 
SentryPolicyStoreProcessor(SentryPolicyServiceConstants.SENTRY_POLICY_SERVICE_NAME,
             conf, sentryStore);

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/SentryPolicyStorePlugin.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/SentryPolicyStorePlugin.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/SentryPolicyStorePlugin.java
index e27e1db..45803cc 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/SentryPolicyStorePlugin.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/SentryPolicyStorePlugin.java
@@ -21,7 +21,7 @@ package org.apache.sentry.provider.db;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.sentry.core.common.exception.SentryInvalidInputException;
 import org.apache.sentry.core.common.exception.SentryUserException;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.sentry.api.service.thrift.TAlterSentryRoleAddGroupsRequest;
 import 
org.apache.sentry.api.service.thrift.TAlterSentryRoleDeleteGroupsRequest;
 import org.apache.sentry.api.service.thrift.TDropPrivilegesRequest;
@@ -54,7 +54,7 @@ public interface SentryPolicyStorePlugin {
     }
   }
 
-  void initialize(Configuration conf, SentryStore sentryStore) throws 
SentryPluginException;
+  void initialize(Configuration conf, SentryStoreInterface sentryStore) throws 
SentryPluginException;
 
   Update onAlterSentryRoleAddGroups(TAlterSentryRoleAddGroupsRequest tRequest) 
throws SentryPluginException;
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
index 4e2290b..3256a20 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/generic/service/persistent/PrivilegeOperatePersistence.java
@@ -34,6 +34,7 @@ import org.apache.sentry.core.common.Action;
 import org.apache.sentry.core.common.Authorizable;
 import org.apache.sentry.core.common.BitFieldAction;
 import org.apache.sentry.core.common.BitFieldActionFactory;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.core.model.indexer.IndexerActionFactory;
 import org.apache.sentry.core.model.kafka.KafkaActionFactory;
 import org.apache.sentry.core.model.solr.SolrActionFactory;
@@ -91,7 +92,7 @@ public class PrivilegeOperatePersistence {
             .add(ACTION, SentryStore.toNULLCol(privilege.getAction()), true);
 
     Boolean grantOption = privilege.getGrantOption();
-    paramBuilder.addObject(SentryStore.GRANT_OPTION, grantOption);
+    paramBuilder.addObject(SentryConstants.GRANT_OPTION, grantOption);
 
     List<? extends Authorizable> authorizables = privilege.getAuthorizables();
     int nAuthorizables = authorizables.size();

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/classification/InterfaceAudience.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/classification/InterfaceAudience.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/classification/InterfaceAudience.java
new file mode 100644
index 0000000..32c09a3
--- /dev/null
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/classification/InterfaceAudience.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.provider.db.service.classification;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotation to inform users of a package, class or method's intended 
audience.
+ * Modeled like org.apache.hadoop.classification.
+ */
+@InterfaceAudience.Public
+public class InterfaceAudience {
+  /**
+   * Intended for use by any project or application.
+   */
+  @Documented
+  @Retention(RetentionPolicy.RUNTIME)
+  public @interface Public {};
+
+  /**
+   * Intended for use only within Sentry itself.
+   * No guarantee is provided as to reliability or stability across any level 
of release
+   * granularity.
+   */
+  @Documented
+  @Retention(RetentionPolicy.RUNTIME)
+  public @interface Private {};
+
+  private InterfaceAudience() {} // Audience can't exist on its own
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/HMSFollower.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/HMSFollower.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/HMSFollower.java
index 42770df..7667c47 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/HMSFollower.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/HMSFollower.java
@@ -19,6 +19,7 @@
 package org.apache.sentry.provider.db.service.persistent;
 
 import org.apache.sentry.core.common.utils.PubSub;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.hdfs.ServiceConstants.ServerConfig;
 
 import static 
org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars.AUTHZ_SERVER_NAME;
@@ -57,7 +58,7 @@ public class HMSFollower implements Runnable, AutoCloseable, 
PubSub.Subscriber {
 
   private SentryHMSClient client;
   private final Configuration authzConf;
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
   private final NotificationProcessor notificationProcessor;
   private boolean readyToServe;
   private final HiveNotificationFetcher notificationFetcher;
@@ -70,7 +71,7 @@ public class HMSFollower implements Runnable, AutoCloseable, 
PubSub.Subscriber {
    * Current generation of HMS snapshots. HMSFollower is single-threaded, so 
no need
    * to protect against concurrent modification.
    */
-  private long hmsImageId = SentryStore.EMPTY_PATHS_SNAPSHOT_ID;
+  private long hmsImageId = SentryConstants.EMPTY_PATHS_SNAPSHOT_ID;
 
   /**
    * Configuring Hms Follower thread.
@@ -79,7 +80,7 @@ public class HMSFollower implements Runnable, AutoCloseable, 
PubSub.Subscriber {
    * @param store sentry store
    * @param leaderMonitor singleton instance of LeaderStatusMonitor
    */
-  public HMSFollower(Configuration conf, SentryStore store, 
LeaderStatusMonitor leaderMonitor,
+  public HMSFollower(Configuration conf, SentryStoreInterface store, 
LeaderStatusMonitor leaderMonitor,
               HiveConnectionFactory hiveConnectionFactory) {
     this(conf, store, leaderMonitor, hiveConnectionFactory, null);
   }
@@ -93,7 +94,7 @@ public class HMSFollower implements Runnable, AutoCloseable, 
PubSub.Subscriber {
    * @param authServerName Server that sentry is Authorizing
    */
   @VisibleForTesting
-  public HMSFollower(Configuration conf, SentryStore store, 
LeaderStatusMonitor leaderMonitor,
+  public HMSFollower(Configuration conf, SentryStoreInterface store, 
LeaderStatusMonitor leaderMonitor,
               HiveConnectionFactory hiveConnectionFactory, String 
authServerName) {
     LOGGER.info("HMSFollower is being initialized");
     readyToServe = false;
@@ -390,7 +391,7 @@ public class HMSFollower implements Runnable, 
AutoCloseable, PubSub.Subscriber {
       // Check we're still the leader before persisting the new snapshot
       if (!isLeader()) {
         LOGGER.info("Not persisting full snapshot since not a leader");
-        return SentryStore.EMPTY_NOTIFICATION_ID;
+        return SentryConstants.EMPTY_NOTIFICATION_ID;
       }
       try {
         if (hdfsSyncEnabled) {

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/NotificationProcessor.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/NotificationProcessor.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/NotificationProcessor.java
index a771f4b..01899bf 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/NotificationProcessor.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/NotificationProcessor.java
@@ -40,6 +40,7 @@ import 
org.apache.sentry.core.common.exception.SentryInvalidHMSEventException;
 import org.apache.sentry.core.common.exception.SentryInvalidInputException;
 import org.apache.sentry.core.common.exception.SentryNoSuchObjectException;
 import org.apache.sentry.core.common.utils.PathUtils;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.hdfs.PathsUpdate;
 import org.apache.sentry.hdfs.PermissionsUpdate;
 import org.apache.sentry.hdfs.SentryMalformedPathException;
@@ -67,7 +68,7 @@ import static 
org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars.AU
 /**
  * NotificationProcessor processes various notification events generated from
  * the Hive MetaStore state change, and applies these changes to the complete
- * HMS Paths snapshot or delta update stored in Sentry using SentryStore.
+ * HMS Paths snapshot or delta update stored in Sentry using 
SentryStoreInterface.
  *
  * <p>NotificationProcessor should not skip processing notification events for 
any reason.
  * If some notification events are to be skipped, appropriate logic should be 
added in
@@ -76,7 +77,7 @@ import static 
org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars.AU
 final class NotificationProcessor {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(NotificationProcessor.class);
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
   private final SentryJSONMessageDeserializer deserializer;
   private final String authServerName;
   // These variables can be updated even after object is instantiated, for 
testing purposes.
@@ -91,7 +92,7 @@ final class NotificationProcessor {
    * @param authServerName Server that sentry is authorizing
    * @param conf sentry configuration
    */
-  NotificationProcessor(SentryStore sentryStore, String authServerName,
+  NotificationProcessor(SentryStoreInterface sentryStore, String 
authServerName,
       Configuration conf) {
     this.sentryStore = sentryStore;
     deserializer = new SentryJSONMessageDeserializer();
@@ -128,7 +129,7 @@ final class NotificationProcessor {
   @VisibleForTesting
   static Update getPermUpdatableOnDrop(TSentryAuthorizable authorizable)
       throws SentryInvalidInputException {
-    PermissionsUpdate update = new 
PermissionsUpdate(SentryStore.INIT_CHANGE_ID, false);
+    PermissionsUpdate update = new 
PermissionsUpdate(SentryConstants.INIT_CHANGE_ID, false);
     String authzObj = SentryServiceUtil.getAuthzObj(authorizable);
     update.addPrivilegeUpdate(authzObj)
         .putToDelPrivileges(new TPrivilegeEntity(TPrivilegeEntityType.ROLE, 
PermissionsUpdate.ALL_ROLES),
@@ -156,7 +157,7 @@ final class NotificationProcessor {
       throws SentryInvalidInputException {
     String oldAuthz = SentryServiceUtil.getAuthzObj(oldAuthorizable);
     String newAuthz = SentryServiceUtil.getAuthzObj(newAuthorizable);
-    PermissionsUpdate update = new 
PermissionsUpdate(SentryStore.INIT_CHANGE_ID, false);
+    PermissionsUpdate update = new 
PermissionsUpdate(SentryConstants.INIT_CHANGE_ID, false);
     TPrivilegeChanges privUpdate = 
update.addPrivilegeUpdate(PermissionsUpdate.RENAME_PRIVS);
     privUpdate.putToAddPrivileges(new 
TPrivilegeEntity(TPrivilegeEntityType.AUTHZ_OBJ, newAuthz), newAuthz);
     privUpdate.putToDelPrivileges(new 
TPrivilegeEntity(TPrivilegeEntityType.AUTHZ_OBJ, oldAuthz), oldAuthz);

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/QueryParamBuilder.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/QueryParamBuilder.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/QueryParamBuilder.java
index 6075e3f..f29c455 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/QueryParamBuilder.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/QueryParamBuilder.java
@@ -19,6 +19,8 @@
 package org.apache.sentry.provider.db.service.persistent;
 
 import com.google.common.base.Joiner;
+
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.provider.db.service.model.MSentryRole;
 import org.apache.sentry.provider.db.service.model.MSentryUser;
 
@@ -260,7 +262,7 @@ public class QueryParamBuilder {
    * @return this
    */
   public QueryParamBuilder addNotNull(String fieldName) {
-    queryParts.add(String.format("this.%s != \"%s\"", fieldName, 
SentryStore.NULL_COL));
+    queryParts.add(String.format("this.%s != \"%s\"", fieldName, 
SentryConstants.NULL_COL));
     return this;
   }
 
@@ -270,7 +272,7 @@ public class QueryParamBuilder {
    * @return this
    */
   public QueryParamBuilder addNull(String fieldName) {
-    queryParts.add(String.format("this.%s == \"%s\"", fieldName, 
SentryStore.NULL_COL));
+    queryParts.add(String.format("this.%s == \"%s\"", fieldName, 
SentryConstants.NULL_COL));
     return this;
   }
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
index aca5c2d..29c2176 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStore.java
@@ -18,7 +18,16 @@
 
 package org.apache.sentry.provider.db.service.persistent;
 
+import static org.apache.sentry.core.common.utils.SentryConstants.ACTION;
 import static 
org.apache.sentry.core.common.utils.SentryConstants.AUTHORIZABLE_JOINER;
+import static org.apache.sentry.core.common.utils.SentryConstants.COLUMN_NAME;
+import static org.apache.sentry.core.common.utils.SentryConstants.DB_NAME;
+import static 
org.apache.sentry.core.common.utils.SentryConstants.EMPTY_CHANGE_ID;
+import static 
org.apache.sentry.core.common.utils.SentryConstants.EMPTY_NOTIFICATION_ID;
+import static 
org.apache.sentry.core.common.utils.SentryConstants.EMPTY_PATHS_SNAPSHOT_ID;
+import static org.apache.sentry.core.common.utils.SentryConstants.GRANT_OPTION;
+import static 
org.apache.sentry.core.common.utils.SentryConstants.INDEX_GROUP_ROLES_MAP;
+import static 
org.apache.sentry.core.common.utils.SentryConstants.INDEX_USER_ROLES_MAP;
 import static org.apache.sentry.core.common.utils.SentryConstants.KV_JOINER;
 
 import java.io.IOException;
@@ -100,6 +109,10 @@ import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
+import static org.apache.sentry.core.common.utils.SentryConstants.NULL_COL;
+import static org.apache.sentry.core.common.utils.SentryConstants.SERVER_NAME;
+import static org.apache.sentry.core.common.utils.SentryConstants.TABLE_NAME;
+import static org.apache.sentry.core.common.utils.SentryConstants.URI;
 import static org.apache.sentry.hdfs.Updateable.Update;
 
 /**
@@ -125,35 +138,10 @@ import static org.apache.sentry.hdfs.Updateable.Update;
  * See <a 
href="https://issues.apache.org/jira/browse/SENTRY-1824";>SENTRY-1824</a>
  * for more detail.
  */
-public class SentryStore {
+public class SentryStore implements SentryStoreInterface {
   private static final Logger LOGGER = LoggerFactory
       .getLogger(SentryStore.class);
 
-  public static final String NULL_COL = "__NULL__";
-  public static final int INDEX_GROUP_ROLES_MAP = 0;
-  public static final int INDEX_USER_ROLES_MAP = 1;
-
-  // String constants for field names
-  public static final String SERVER_NAME = "serverName";
-  public static final String DB_NAME = "dbName";
-  public static final String TABLE_NAME = "tableName";
-  public static final String COLUMN_NAME = "columnName";
-  public static final String ACTION = "action";
-  public static final String URI = "URI";
-  public static final String GRANT_OPTION = "grantOption";
-  public static final String ROLE_NAME = "roleName";
-
-  // Initial change ID for permission/path change. Auto increment
-  // is starting from 1.
-  public static final long INIT_CHANGE_ID = 1L;
-
-  private static final long EMPTY_CHANGE_ID = 0L;
-
-  public static final long EMPTY_NOTIFICATION_ID = 0L;
-
-  // Representation for empty HMS snapshots not found on MAuthzPathsSnapshotId
-  public static final long EMPTY_PATHS_SNAPSHOT_ID = 0L;
-
   // For counters, representation of the "unknown value"
   private static final long COUNT_VALUE_UNKNOWN = -1L;
 
@@ -573,7 +561,6 @@ public class SentryStore {
   /**
    * Removes all the information related to HMS Objects from sentry store.
    */
-  @VisibleForTesting
   public void clearHmsPathInformation() throws Exception {
     tm.executeTransactionWithRetry(
             pm -> {
@@ -3065,7 +3052,9 @@ public class SentryStore {
    *
    * @return a {@link PathsImage} contains the mapping of hiveObj to
    *         &lt role, privileges &gt and the mapping of role to &lt Groups 
&gt.
-   *         For empty image returns {@link #EMPTY_CHANGE_ID} and empty maps.
+   *         For empty image returns
+   *         {@link 
org.apache.sentry.core.common.utils.SentryConstants#EMPTY_CHANGE_ID}
+   *         and empty maps.
    * @throws Exception
    */
   public PermissionsImage retrieveFullPermssionsImage() throws Exception {
@@ -3195,7 +3184,9 @@ public class SentryStore {
    *
    * @param prefixes path of Sentry managed prefixes. Ignore any path outside 
the prefix.
    * @return an up-to-date hive paths snapshot contains mapping of hiveObj to 
&lt Paths &gt.
-   *         For empty image return {@link #EMPTY_CHANGE_ID} and a empty map.
+   *         For empty image return
+   *         {@link 
org.apache.sentry.core.common.utils.SentryConstants#EMPTY_CHANGE_ID}
+   *         and a empty map.
    * @throws Exception
    */
   public PathsUpdate retrieveFullPathsImageUpdate(final String[] prefixes) 
throws Exception {

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
new file mode 100644
index 0000000..f61ae57
--- /dev/null
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/provider/db/service/persistent/SentryStoreInterface.java
@@ -0,0 +1,785 @@
+/**
+ * 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.provider.db.service.persistent;
+
+import com.codahale.metrics.Gauge;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sentry.SentryOwnerInfo;
+import org.apache.sentry.api.service.thrift.TSentryActiveRoleSet;
+import org.apache.sentry.api.service.thrift.TSentryAuthorizable;
+import org.apache.sentry.api.service.thrift.TSentryGroup;
+import org.apache.sentry.api.service.thrift.TSentryMappingData;
+import org.apache.sentry.api.service.thrift.TSentryPrivilege;
+import org.apache.sentry.api.service.thrift.TSentryPrivilegeMap;
+import org.apache.sentry.api.service.thrift.TSentryRole;
+import org.apache.sentry.core.common.exception.SentryInvalidInputException;
+import org.apache.sentry.core.common.exception.SentryNoSuchObjectException;
+import org.apache.sentry.hdfs.PathsUpdate;
+import org.apache.sentry.hdfs.UniquePathsUpdate;
+import org.apache.sentry.hdfs.Updateable.Update;
+import 
org.apache.sentry.provider.db.service.classification.InterfaceAudience.Private;
+import org.apache.sentry.provider.db.service.model.MAuthzPathsMapping;
+import org.apache.sentry.provider.db.service.model.MSentryGroup;
+import org.apache.sentry.provider.db.service.model.MSentryHmsNotification;
+import org.apache.sentry.provider.db.service.model.MSentryPathChange;
+import org.apache.sentry.provider.db.service.model.MSentryPermChange;
+import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
+import org.apache.sentry.service.common.ServiceConstants.SentryEntityType;
+
+/**
+ * Interface for backend sentry store.
+ * NOTE: No guarantee is provided as to reliability or stability across any 
level of release
+ * granularity. This interface can change any time for both major and minor 
release.
+ */
+@Private
+public interface SentryStoreInterface {
+
+  /**
+   * Assign a given role to a set of groups.
+   *
+   * @param grantorPrincipal grantorPrincipal currently is not used.
+   * @param roleName the role to be assigned to the groups.
+   * @param groupNames the list of groups to be added to the role,
+   * @throws Exception
+   */
+  void alterSentryRoleAddGroups(final String grantorPrincipal,
+                                final String roleName,
+                                final Set<TSentryGroup> groupNames) throws 
Exception;
+
+  /**
+   * Assign a given role to a set of users.
+   *
+   * @param roleName the role to be assigned to the users.
+   * @param userNames the list of users to be added to the role,
+   * @throws Exception
+   */
+  void alterSentryRoleAddUsers(final String roleName,
+                               final Set<String> userNames) throws Exception;
+
+  /**
+   * Revoke a given role to a set of groups.
+   *
+   * @param roleName the role to be assigned to the groups.
+   * @param groupNames the list of groups to be added to the role,
+   * @throws Exception
+   */
+  void alterSentryRoleDeleteGroups(final String roleName,
+                                   final Set<TSentryGroup> groupNames) throws 
Exception;
+
+  /**
+   * Revoke a given role from a set of users.
+   *
+   * @param roleName the role to be revoked from the users.
+   * @param userNames the list of users to be revoked from the role,
+   * @throws Exception
+   */
+  void alterSentryRoleDeleteUsers(final String roleName,
+                                  final Set<String> userNames) throws 
Exception;
+  /**
+   * Alter a given sentry role to grant a set of privileges.
+   * Internally calls alterSentryRoleGrantPrivilege.
+   *
+   * @param grantorPrincipal User name
+   * @param roleName Role name
+   * @param privileges Set of privileges
+   * @throws Exception
+   */
+  void alterSentryRoleGrantPrivileges(final String grantorPrincipal,
+                                      final String roleName,
+                                      final Set<TSentryPrivilege> privileges) 
throws Exception;
+
+  /**
+   * Alter a given sentry role to revoke a set of privileges.
+   * Internally calls alterSentryRoleRevokePrivilege.
+   *
+   * @param grantorPrincipal User name
+   * @param roleName the given role name
+   * @param tPrivileges a Set of privileges
+   * @throws Exception
+   *
+   */
+  void alterSentryRoleRevokePrivileges(final String grantorPrincipal,
+                                       final String roleName,
+                                       final Set<TSentryPrivilege> tPrivileges)
+    throws Exception;
+
+  /**
+   * Create a sentry role and persist it. Role name is the primary key for the
+   * role, so an attempt to create a role which exists fails with JDO 
exception.
+   *
+   * @param roleName: Name of the role being persisted.
+   *    The name is normalized.
+   * @throws Exception
+   */
+  void createSentryRole(final String roleName) throws Exception;
+
+  /**
+   * Drop the given privilege from all roles.
+   *
+   * @param tAuthorizable the given authorizable object.
+   * @throws Exception
+   */
+  void dropPrivilege(final TSentryAuthorizable tAuthorizable) throws Exception;
+
+  /**
+   * Drop a given sentry role.
+   *
+   * @param roleName the given role name
+   * @throws Exception
+   */
+  void dropSentryRole(final String roleName) throws Exception;
+
+  /**
+   * Get role names for groups.
+   * @param groups the given group names
+   * @return set of role names for the given groups.
+   * @throws Exception
+   */
+  Set<String> getRoleNamesForGroups(final Set<String> groups) throws Exception;
+
+  /**
+   * Thrift sentry privileges by authorizables.
+   * @param groups
+   * @param activeRoles
+   * @param authHierarchy
+   * @param isAdmin
+   * @return Map of thrift sentry privileges by authorizables.
+   * @throws Exception
+   */
+  TSentryPrivilegeMap listSentryPrivilegesByAuthorizable(
+    Set<String> groups, TSentryActiveRoleSet activeRoles,
+    TSentryAuthorizable authHierarchy, boolean isAdmin)
+    throws Exception;
+
+  /**
+   * Get all privileges associated with the authorizable and input users
+   * @param userNames the users to get their privileges
+   * @param authHierarchy the authorizables
+   * @param isAdmin true: user is admin; false: is not admin
+   * @return the privilege map. The key is user name
+   * @throws Exception
+   */
+  TSentryPrivilegeMap listSentryPrivilegesByAuthorizableForUser(
+    Set<String> userNames,
+    TSentryAuthorizable authHierarchy,
+    boolean isAdmin) throws Exception;
+
+  /**
+   * Gets sentry privilege objects for criteria from the persistence layer
+   * @param entityType : the type of the entity (required)
+   * @param entityNames : entity names to look up (required)
+   * @param authHierarchy : filter push down based on auth hierarchy (optional)
+   * @return : Set of thrift sentry privilege objects
+   * @throws SentryInvalidInputException
+   */
+  Set<TSentryPrivilege> getTSentryPrivileges(SentryEntityType entityType,
+                                             Set<String> entityNames,
+                                             TSentryAuthorizable authHierarchy)
+    throws Exception;
+
+  /**
+   * Gets sentry privilege objects for a given roleName from the persistence 
layer
+   * @param roleName : roleName to look up
+   * @return : Set of thrift sentry privilege objects
+   * @throws Exception
+   */
+  Set<TSentryPrivilege> getAllTSentryPrivilegesByRoleName(String roleName)
+    throws Exception;
+
+  /**
+   * Gets sentry privilege objects for a given userName from the persistence 
layer
+   * @param userName : userName to look up
+   * @return : Set of thrift sentry privilege objects
+   * @throws Exception
+   */
+  Set<TSentryPrivilege> getAllTSentryPrivilegesByUserName(String userName) 
throws Exception;
+
+  /**
+   * Set of Sentry Privileges for provider.
+   * @param groups
+   * @param users
+   * @param roleSet
+   * @param authHierarchy
+   * @return
+   * @throws Exception
+   */
+  Set<String> listSentryPrivilegesForProvider(Set<String> groups,
+                                              Set<String> users,
+                                              TSentryActiveRoleSet roleSet,
+                                              TSentryAuthorizable 
authHierarchy)
+    throws Exception;
+
+  /**
+   * True if the given set of group
+   * @param groups
+   * @param users
+   * @param roleSet
+   * @param server
+   * @return
+   * @throws Exception
+   */
+  boolean hasAnyServerPrivileges(Set<String> groups,
+                                 Set<String> users,
+                                 TSentryActiveRoleSet roleSet,
+                                 String server) throws Exception;
+
+  /**
+   * Return set of roles corresponding to the groups provided.<p>
+   *
+   * If groups contain a null group, return all available roles.<p>
+   *
+   * Everything is done in a single transaction so callers get a
+   * fully-consistent view of the roles, so this can be called at the same tie 
as
+   * some other method that modifies groups or roles.<p>
+   *
+   * <em><b>NOTE:</b> This function is performance-critical, so before you 
modify it, make
+   * sure to measure performance effect. It is called every time when 
PolicyClient
+   * (Hive or Impala) tries to get list of roles.
+   * </em>
+   *
+   * @param groupNames Set of Sentry groups. Can contain {@code null}
+   *                  in which case all roles should be returned
+   * @param checkAllGroups If false, raise SentryNoSuchObjectException
+   *                      if one of the groups is not available, otherwise
+   *                      ignore non-existent groups
+   * @return Set of TSentryRole toles corresponding to the given set of groups.
+   * @throws SentryNoSuchObjectException if one of the groups is not present 
and
+   * checkAllGroups is not set.
+   * @throws Exception if DataNucleus operation fails.
+   */
+  Set<TSentryRole> getTSentryRolesByGroupName(final Set<String> groupNames,
+                                              final boolean checkAllGroups)
+    throws Exception;
+
+
+  Set<TSentryRole> getTSentryRolesByUserNames(final Set<String> users)
+    throws Exception;
+
+  /**
+   * Rename the privilege for all roles. Drop the old privilege name and 
create the new one.
+   *
+   * @param oldTAuthorizable the old authorizable name needs to be renamed.
+   * @param newTAuthorizable the new authorizable name
+   * @throws SentryNoSuchObjectException
+   * @throws SentryInvalidInputException
+   */
+  void renamePrivilege(final TSentryAuthorizable oldTAuthorizable,
+                       final TSentryAuthorizable newTAuthorizable) throws 
Exception;
+
+
+  /**
+   * @return mapping data for [role,privilege] with the specific auth object
+   */
+  Map<String, Set<TSentryPrivilege>> getRoleNameTPrivilegesMap(final String 
dbName,
+                                                               final String 
tableName)
+    throws Exception;
+
+  /** get mapping datas for [group,role], [user,role] with the specific roles 
*/
+  List<Map<String, Set<String>>> getGroupUserRoleMapList(final 
Collection<String> roleNames)
+    throws Exception;
+
+  /**
+   * Import the sentry mapping data.
+   *
+   * @param tSentryMappingData
+   *        Include 2 maps to save the mapping data, the following is the 
example of the data
+   *        structure:
+   *        for the following mapping data:
+   *        user1=role1,role2
+   *        user2=role2,role3
+   *        group1=role1,role2
+   *        group2=role2,role3
+   *        role1=server=server1->db=db1
+   *        
role2=server=server1->db=db1->table=tbl1,server=server1->db=db1->table=tbl2
+   *        role3=server=server1->url=hdfs://localhost/path
+   *
+   *        The GroupRolesMap in TSentryMappingData will be saved as:
+   *        {
+   *        TSentryGroup(group1)={role1, role2},
+   *        TSentryGroup(group2)={role2, role3}
+   *        }
+   *        The UserRolesMap in TSentryMappingData will be saved as:
+   *        {
+   *        TSentryUser(user1)={role1, role2},
+   *        TSentryGroup(user2)={role2, role3}
+   *        }
+   *        The RolePrivilegesMap in TSentryMappingData will be saved as:
+   *        {
+   *        role1={TSentryPrivilege(server=server1->db=db1)},
+   *        role2={TSentryPrivilege(server=server1->db=db1->table=tbl1),
+   *        TSentryPrivilege(server=server1->db=db1->table=tbl2)},
+   *        role3={TSentryPrivilege(server=server1->url=hdfs://localhost/path)}
+   *        }
+   * @param isOverwriteForRole
+   *        The option for merging or overwriting the existing data during 
import, true for
+   *        overwriting, false for merging
+   */
+  void importSentryMetaData(final TSentryMappingData tSentryMappingData,
+                            final boolean isOverwriteForRole) throws Exception;
+
+  /**
+   * Removes all the information related to HMS Objects from sentry store.
+   */
+  void clearHmsPathInformation() throws Exception;
+
+  /**
+   * Stop Sentry Store
+   */
+  void stop();
+
+  /**
+   * Set the notification ID of last processed HMS notification and remove all
+   * subsequent notifications stored.
+   */
+  void setLastProcessedNotificationID(final Long notificationId) throws 
Exception;
+
+  /**
+   * Checks if a notification was already processed by searching for the hash 
value
+   * on the MSentryPathChange table.
+   *
+   * @param hash A SHA-1 hex hash that represents a unique notification
+   * @return True if the notification was already processed; False otherwise
+   */
+  boolean isNotificationProcessed(final String hash) throws Exception;
+
+  /**
+   * Tells if there are any records in MSentryHmsNotification
+   *
+   * @return true if there are no entries in 
<code>MSentryHmsNotification</code>
+   * false if there are entries
+   * @throws Exception
+   */
+  boolean isHmsNotificationEmpty() throws Exception;
+
+  /**
+   * Get the notification ID of last processed path delta change.
+   *
+   * @return the notification ID of latest path change. If no change
+   *         found then return 0.
+   */
+  Long getLastProcessedNotificationID() throws Exception;
+
+  /**
+   * Set the notification ID of last processed HMS notification.
+   */
+  void persistLastProcessedNotificationID(final Long notificationId) throws 
Exception;
+
+  /**
+   * Set persistent update deltas
+   * @param persistUpdateDeltas
+   */
+  void setPersistUpdateDeltas(boolean persistUpdateDeltas);
+
+  /**
+   * Purge delta change tables, {@link MSentryPermChange} and {@link 
MSentryPathChange}.
+   * The number of deltas to keep is configurable
+   */
+  void purgeDeltaChangeTables();
+
+  /**
+   * Purge hms notification id table , {@link MSentryHmsNotification}.
+   * The number of notifications id's to be kept is based on configuration
+   * sentry.server.delta.keep.count
+   */
+  void purgeNotificationIdTable();
+
+  /**
+   * Return counter wait
+   * @return
+   */
+  CounterWait getCounterWait();
+
+  // Metrics
+
+  /**
+   * @return number of roles
+   */
+  Gauge<Long> getRoleCountGauge();
+
+  /**
+   * @return number of groups
+   */
+  Gauge<Long> getGroupCountGauge();
+
+  /**
+   * @return number of threads waiting for HMS notifications to be processed
+   */
+  Gauge<Integer> getHMSWaitersCountGauge();
+
+  /**
+   * @return Number of privileges
+   */
+  Gauge<Long> getPrivilegeCountGauge();
+
+  /**
+   * @return current value of last processed notification ID
+   */
+  Gauge<Long> getLastNotificationIdGauge();
+
+  /**
+   * @return ID of the path snapshot
+   */
+  Gauge<Long> getLastPathsSnapshotIdGauge();
+
+  /**
+   * @return Permissions change ID
+   */
+  Gauge<Long> getPermChangeIdGauge();
+
+  /**
+   * @return Path change id
+   */
+  Gauge<Long> getPathChangeIdGauge();
+
+  /**
+   * Assign a given role to a set of groups. As well as persist the 
corresponding
+   * permission change to MSentryPermChange table in a single transaction.
+   *
+   * @param grantorPrincipal grantorPrincipal currently is not used.
+   * @param roleName the role to be assigned to the groups.
+   * @param groupNames the list of groups to be added to the role,
+   * @param update the corresponding permission delta update
+   * @throws Exception
+   */
+  void alterSentryRoleAddGroups(final String grantorPrincipal,
+                                final String roleName,
+                                final Set<TSentryGroup> groupNames,
+                                final Update update) throws Exception;
+
+  /**
+   * Revoke a given role to a set of groups. As well as persist the 
corresponding
+   * permission change to MSentryPermChange table in a single transaction.
+   *
+   * @param roleName the role to be assigned to the groups.
+   * @param groupNames the list of groups to be added to the role,
+   * @param update the corresponding permission delta update
+   * @throws Exception
+   */
+  void alterSentryRoleDeleteGroups(final String roleName,
+                                   final Set<TSentryGroup> groupNames,
+                                   final Update update) throws Exception;
+
+  /**
+   * Alter a given sentry role to grant a set of privileges, as well as 
persist the
+   * corresponding permission change to MSentryPermChange table in a single 
transaction.
+   * Internally calls alterSentryRoleGrantPrivilege.
+   *
+   * @param grantorPrincipal User name
+   * @param roleName the given role name
+   * @param privileges a Set of privileges
+   * @param privilegesUpdateMap the corresponding <privilege, 
DeltaTransactionBlock> map
+   * @throws Exception
+   *
+   */
+  void alterSentryRoleGrantPrivileges(final String grantorPrincipal,
+                                      final String roleName,
+                                      final Set<TSentryPrivilege> privileges,
+                                      final Map<TSentryPrivilege, Update> 
privilegesUpdateMap)
+    throws Exception;
+
+  /**
+   * Alter a given sentry role to revoke a set of privileges, as well as 
persist the
+   * corresponding permission change to MSentryPermChange table in a single 
transaction.
+   * Internally calls alterSentryRoleRevokePrivilege.
+   *
+   * @param grantorPrincipal User name
+   * @param roleName the given role name
+   * @param tPrivileges a Set of privileges
+   * @param privilegesUpdateMap the corresponding <privilege, Update> map
+   * @throws Exception
+   *
+   */
+  void alterSentryRoleRevokePrivileges(final String grantorPrincipal,
+                                       final String roleName, final 
Set<TSentryPrivilege> tPrivileges,
+                                       final Map<TSentryPrivilege, Update> 
privilegesUpdateMap)
+    throws Exception;
+
+  /**
+   * Drop the given privilege from all roles. As well as persist the 
corresponding
+   * permission change to MSentryPermChange table in a single transaction.
+   *
+   * @param tAuthorizable the given authorizable object.
+   * @param update the corresponding permission delta update.
+   * @throws Exception
+   */
+  void dropPrivilege(final TSentryAuthorizable tAuthorizable,
+                     final Update update) throws Exception;
+
+  /**
+   * Drop a given sentry role. As well as persist the corresponding
+   * permission change to MSentryPermChange table in a single transaction.
+   *
+   * @param roleName the given role name
+   * @param update the corresponding permission delta update
+   * @throws Exception
+   */
+  void dropSentryRole(final String roleName, final Update update) throws 
Exception;
+
+  /**
+   * Retrieves an up-to-date sentry permission snapshot.
+   * <p>
+   * It reads hiveObj to &lt role, privileges &gt mapping from {@link 
MSentryPrivilege}
+   * table and role to groups mapping from {@link MSentryGroup}.
+   * It also gets the changeID of latest delta update, from {@link 
MSentryPathChange}, that
+   * the snapshot corresponds to.
+   *
+   * @return a {@link PathsImage} contains the mapping of hiveObj to
+   *         &lt role, privileges &gt and the mapping of role to &lt Groups 
&gt.
+   *         For empty image returns
+   *         {@link 
org.apache.sentry.core.common.utils.SentryConstants#EMPTY_CHANGE_ID}
+   *         and empty maps.
+   * @throws Exception
+   */
+  PermissionsImage retrieveFullPermssionsImage() throws Exception;
+
+  /**
+   * Retrieves an up-to-date hive paths snapshot.
+   * The image only contains PathsDump in it.
+   * <p>
+   * It reads hiveObj to paths mapping from {@link MAuthzPathsMapping} table 
and
+   * gets the changeID of latest delta update, from {@link MSentryPathChange}, 
that
+   * the snapshot corresponds to.
+   *
+   * @param prefixes path of Sentry managed prefixes. Ignore any path outside 
the prefix.
+   * @return an up-to-date hive paths snapshot contains mapping of hiveObj to 
&lt Paths &gt.
+   *         For empty image return
+   *         {@link 
org.apache.sentry.core.common.utils.SentryConstants#EMPTY_CHANGE_ID}
+   *         and a empty map.
+   * @throws Exception
+   */
+  PathsUpdate retrieveFullPathsImageUpdate(final String[] prefixes) throws 
Exception;
+
+  /**
+   * Rename the privilege for all roles. Drop the old privilege name and 
create the new one.
+   * As well as persist the corresponding permission change to 
MSentryPermChange table in a
+   * single transaction.
+   *
+   * @param oldTAuthorizable the old authorizable name needs to be renamed.
+   * @param newTAuthorizable the new authorizable name
+   * @param update the corresponding permission delta update.
+   * @throws SentryNoSuchObjectException
+   * @throws SentryInvalidInputException
+   */
+  void renamePrivilege(final TSentryAuthorizable oldTAuthorizable,
+                       final TSentryAuthorizable newTAuthorizable,
+                       final Update update)
+    throws Exception;
+
+  /**
+   * Gets a list of MSentryPermChange objects greater than or equal to the 
given ChangeID.
+   * If there is any path delta missing in {@link MSentryPermChange} table, an 
empty list is returned.
+   *
+   * @param changeID Requested changeID
+   * @return a list of MSentryPathChange objects. May be empty.
+   * @throws Exception
+   */
+  List<MSentryPermChange> getMSentryPermChanges(final long changeID) throws 
Exception;
+
+  /**
+   * Checks if any MSentryPermChange object exists with the given changeID.
+   *
+   * @param changeID
+   * @return true if found the MSentryPermChange object, otherwise false.
+   * @throws Exception
+   */
+  Boolean permChangeExists(final long changeID) throws Exception;
+
+  /**
+   * Gets the last processed change ID for perm delta changes.
+   * @return latest perm change ID.
+   */
+  Long getLastProcessedPermChangeID() throws Exception;
+
+  /**
+   * Gets a list of MSentryPathChange objects greater than or equal to the 
given changeID.
+   * If there is any path delta missing in {@link MSentryPathChange} table, an 
empty list is returned.
+   *
+   * @param changeID  Requested changeID
+   * @return a list of MSentryPathChange objects. May be empty.
+   * @throws Exception
+   */
+  List<MSentryPathChange> getMSentryPathChanges(final long changeID) throws 
Exception;
+
+  /**
+   * Checks if any MSentryPathChange object exists with the given changeID.
+   *
+   * @param changeID
+   * @return true if found the MSentryPathChange object, otherwise false.
+   * @throws Exception
+   */
+  Boolean pathChangeExists(final long changeID) throws Exception;
+
+  /**
+   * Gets the last processed change ID for path delta changes.
+   *
+   * @return latest path change ID.
+   */
+  Long getLastProcessedPathChangeID() throws Exception;
+
+  /**
+   * Persist an up-to-date HMS snapshot into Sentry DB in a single transaction 
with its latest
+   * notification ID
+   *
+   * @param authzPaths paths to be be persisted
+   * @param notificationID the latest notificationID associated with the 
snapshot
+   * @throws Exception
+   */
+  void persistFullPathsImage(final Map<String, Collection<String>> authzPaths,
+                             final long notificationID) throws Exception;
+
+  /**
+   * Adds the authzObj and with a set of paths into the authzObj -> [Paths] 
mapping.
+   * As well as persist the corresponding delta path change to 
MSentryPathChange
+   * table in a single transaction.
+   *
+   * @param authzObj an authzObj
+   * @param paths a set of paths need to be added into the authzObj -> [Paths] 
mapping
+   * @param update the corresponding path delta update
+   * @throws Exception
+   */
+  void addAuthzPathsMapping(final String authzObj,
+                            final Collection<String> paths,
+                            final UniquePathsUpdate update) throws Exception;
+
+  /**
+   * Deletes all entries of the given authzObj from the authzObj -> [Paths] 
mapping.
+   * As well as persist the corresponding delta path change to 
MSentryPathChange
+   * table in a single transaction.
+   *
+   * @param authzObj an authzObj to be deleted
+   * @param update the corresponding path delta update
+   */
+  void deleteAllAuthzPathsMapping(final String authzObj, final 
UniquePathsUpdate update)
+    throws Exception;
+
+  /**
+   * Deletes a set of paths belongs to given authzObj from the authzObj -> 
[Paths] mapping.
+   * As well as persist the corresponding delta path change to 
MSentryPathChange
+   * table in a single transaction.
+   *
+   * @param authzObj an authzObj
+   * @param paths a set of paths need to be deleted from the authzObj -> 
[Paths] mapping
+   * @param update the corresponding path delta update
+   */
+  void deleteAuthzPathsMapping(final String authzObj,
+                               final Iterable<String> paths,
+                               final UniquePathsUpdate update) throws 
Exception;
+
+  /**
+   * Renames the existing authzObj to a new one in the authzObj -> [Paths] 
mapping,
+   * but keeps its paths mapping as-is. As well as persist the corresponding 
delta path
+   * change to MSentryPathChange table in a single transaction.
+   *
+   * @param oldObj the existing authzObj
+   * @param newObj the new name to be changed to
+   * @param update the corresponding path delta update
+   */
+  void renameAuthzObj(final String oldObj,
+                      final String newObj,
+                      final UniquePathsUpdate update) throws Exception;
+
+  /**
+   * Renames the existing authzObj to a new one in the authzObj -> [Paths] 
mapping.
+   * And updates its existing path with a new path, while keeps the rest of 
its paths
+   * untouched if there is any. As well as persist the corresponding delta path
+   * change to MSentryPathChange table in a single transaction.
+   *
+   * @param oldObj the existing authzObj
+   * @param newObj the new name to be changed to
+   * @param oldPath a existing path of the given authzObj
+   * @param newPath a new path to be changed to
+   * @param update the corresponding path delta update
+   */
+  void renameAuthzPathsMapping(final String oldObj, final String newObj, final 
String oldPath,
+                               final String newPath, final UniquePathsUpdate 
update)
+    throws Exception;
+
+  /**
+   * Updates authzObj -> [Paths] mapping to replace an existing path with a 
new one
+   * given an authzObj. As well as persist the corresponding delta path change 
to
+   * MSentryPathChange table in a single transaction.
+   *
+   * @param authzObj an authzObj
+   * @param oldPath the existing path maps to the given authzObj
+   * @param newPath a new path to replace the existing one
+   * @param update the corresponding path delta update
+   * @throws Exception
+   */
+  void updateAuthzPathsMapping(final String authzObj, final String oldPath,
+                               final String newPath, final UniquePathsUpdate 
update)
+    throws Exception;
+
+  /**
+   * Tells if there are any records in MAuthzPathsSnapshotId
+   *
+   * @return true if there are no entries in <code>MAuthzPathsSnapshotId</code>
+   * false if there are entries
+   * @throws Exception
+   */
+  boolean isAuthzPathsSnapshotEmpty() throws Exception;
+
+  /**
+   * Gets the last processed HMS snapshot ID for path delta changes.
+   *
+   * @return latest path change ID.
+   */
+  long getLastProcessedImageID() throws Exception;
+
+  /**
+   * Alter a give sentry user/role to set owner privilege, as well as persist 
the corresponding
+   * permission change to MSentryPermChange table in a single transaction.
+   * Creates User, if it is not already there.
+   * Internally calls alterSentryGrantPrivilege.
+   * @param entityName Entity name to which permissions should be granted.
+   * @param entityType Entity Type
+   * @param privilege Privilege to be granted
+   * @param update DeltaTransactionBlock
+   * @throws Exception
+   */
+  void alterSentryGrantOwnerPrivilege(final String entityName, 
SentryEntityType entityType,
+                                      final TSentryPrivilege privilege,
+                                      final Update update) throws Exception;
+
+  /**
+   * List the Owners for an authorizable
+   * @param authorizable Authorizable
+   * @return List of owner for an authorizable
+   * @throws Exception
+   */
+  List<SentryOwnerInfo> listOwnersByAuthorizable(TSentryAuthorizable 
authorizable)
+    throws Exception;
+
+  /**
+   * Updates the owner privileges by revoking owner privileges to an 
authorizable and adding new
+   * privilege based on the arguments provided.
+   * @param tAuthorizable Authorizable to which owner privilege should be 
granted.
+   * @param ownerName
+   * @param entityType
+   * @param updates Delta Updates.
+   * @throws Exception
+   */
+  void updateOwnerPrivilege(final TSentryAuthorizable tAuthorizable,
+                                         String ownerName,  SentryEntityType 
entityType,
+                                         final List<Update> updates) throws 
Exception;
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/DynamicProxy.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/DynamicProxy.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/DynamicProxy.java
new file mode 100644
index 0000000..9c3cf7c
--- /dev/null
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/DynamicProxy.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.service.thrift;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * This class can be used to create proxy instances for interface 
implementations that do not
+ * explicitly implement the interface.
+ * In practice, this is just a development convenience when writing pluggable 
implementations
+ * and shouldn't be encouraged to use in production, as there can be use cases 
that may result
+ * in run-time errors, for example, interface default methods are not 
supported.
+ *
+ * Other than that, this class does validate if all methods are implemented by 
the given
+ * implementation.
+ */
+public class DynamicProxy<T> implements InvocationHandler {
+  private final Object obj;
+  private final Class<T> iface;
+
+  public DynamicProxy(Object obj, Class<T> iface, String objectClassName) {
+    this.obj = checkNotNull(obj);
+    this.iface = checkNotNull(iface);
+    validateObjectImplementsInterface(objectClassName);
+  }
+
+  public Object invoke(Object proxy, Method method, Object[] args) throws 
Throwable {
+    Method proxiedMethod = findMethodBySignature(method);
+    return proxiedMethod.invoke(obj, args);
+  }
+
+  private Method findMethodBySignature(Method method) throws 
NoSuchMethodException {
+    return obj.getClass().getMethod(method.getName(),
+      method.getParameterTypes());
+  }
+
+  private void validateObjectImplementsInterface(String className) {
+    for (Method method : iface.getMethods()) {
+      try {
+        findMethodBySignature(method);
+      } catch (NoSuchMethodException e) {
+        throw new RuntimeException(
+          String.format("Class %s does not implement %s.", className, 
iface.getName()));
+      }
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  public T createProxy() {
+    return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[] 
{iface}, this);
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/HiveNotificationFetcher.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/HiveNotificationFetcher.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/HiveNotificationFetcher.java
index 93cc34f..8490d7a 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/HiveNotificationFetcher.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/HiveNotificationFetcher.java
@@ -27,8 +27,9 @@ import 
org.apache.hadoop.hive.metastore.IMetaStoreClient.NotificationFilter;
 import org.apache.hadoop.hive.metastore.api.CurrentNotificationEventId;
 import org.apache.hadoop.hive.metastore.api.NotificationEvent;
 import org.apache.hadoop.hive.metastore.api.NotificationEventResponse;
+import org.apache.sentry.core.common.utils.SentryConstants;
 import org.apache.sentry.hdfs.UniquePathsUpdate;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -38,7 +39,7 @@ import org.slf4j.LoggerFactory;
 public final class HiveNotificationFetcher implements AutoCloseable {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(HiveNotificationFetcher.class);
 
-  private final SentryStore sentryStore;
+  private final SentryStoreInterface sentryStore;
   private final HiveConnectionFactory hmsConnectionFactory;
   private HiveMetaStoreClient hmsClient;
 
@@ -46,7 +47,7 @@ public final class HiveNotificationFetcher implements 
AutoCloseable {
   private long lastIdFiltered = 0;
   private Set<String> cache = new HashSet<>();
 
-  public HiveNotificationFetcher(SentryStore sentryStore, 
HiveConnectionFactory hmsConnectionFactory) {
+  public HiveNotificationFetcher(SentryStoreInterface sentryStore, 
HiveConnectionFactory hmsConnectionFactory) {
     this.sentryStore = sentryStore;
     this.hmsConnectionFactory = hmsConnectionFactory;
   }
@@ -191,7 +192,7 @@ public final class HiveNotificationFetcher implements 
AutoCloseable {
       return eventId.getEventId();
     }
 
-    return SentryStore.EMPTY_NOTIFICATION_ID;
+    return SentryConstants.EMPTY_NOTIFICATION_ID;
   }
 
   /* AutoCloseable implementations */

http://git-wip-us.apache.org/repos/asf/sentry/blob/9caa0d1d/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
----------------------------------------------------------------------
diff --git 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
index 2a48c63..35d0e4f 100644
--- 
a/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
+++ 
b/sentry-service/sentry-service-server/src/main/java/org/apache/sentry/service/thrift/ProcessorFactory.java
@@ -18,7 +18,7 @@
 package org.apache.sentry.service.thrift;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.sentry.provider.db.service.persistent.SentryStore;
+import org.apache.sentry.provider.db.service.persistent.SentryStoreInterface;
 import org.apache.thrift.TMultiplexedProcessor;
 
 public abstract class ProcessorFactory {
@@ -31,10 +31,10 @@ public abstract class ProcessorFactory {
   /**
    * Register a Thrift processor with SentryStore.
    * @param processor a thrift processor.
-   * @param sentryStore a {@link SentryStore}
+   * @param sentryStore a {@link SentryStoreInterface}
    * @return true if success.
    * @throws Exception
    */
   public abstract boolean register(TMultiplexedProcessor processor,
-                                   SentryStore sentryStore) throws Exception;
+                                   SentryStoreInterface sentryStore) throws 
Exception;
 }

Reply via email to