sentry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sra...@apache.org
Subject [2/4] sentry git commit: SENTRY-1329: Adapt SentryMetaStorePostEventListener to write HMS notification logs
Date Tue, 12 Jul 2016 20:06:15 GMT
SENTRY-1329: Adapt SentryMetaStorePostEventListener to write HMS notification logs

Also,
1. Implementing the SentryJSONMessageFactory to add custom information in the notification log entry message, which includes
 1.1. Implementing Message class for each message type
 1.2. Implementing a deserializer
2. Implementing JSONAlterPartitionMessage and JSONAlterTableMessage to work around the issue in Hive 1.1.0. These classes do not have required default constructor.
3. Testing:
 3.1. Sentry functionality: TestSentryListenerSentryDeserializer to verify functionality using Sentry's SentryMetastorePostEventListener and Sentry Notification log deserializer.
 3.2. TestDbNotificationListenerSentryDeserializer uses Hive's DbNotificationListener and Sentry's JSON deserializeri. This would make sure Sentry is able to read the Notification logs written by Hive's DBNotificationListener
 3.3. TestSentryListenerInBuiltDeserializer uses Sentry's SentryMetastorePostEventListener and Hive's inbuilt Notification log deserializer: This would make sure Sentry is not breaking other users of NotificationLog who might be using Hive's in built serializer

Change-Id: I680beb6db4e534bb0a9e6ee042ea0d4f33f0943f


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

Branch: refs/heads/sentry-ha-redesign
Commit: 113c5eae4ce9d3cb86ac7193731696d943fbea1f
Parents: de7c26a
Author: Sravya Tirukkovalur <sravya@apache.org>
Authored: Tue Jun 14 16:30:51 2016 -0700
Committer: Sravya Tirukkovalur <sravya@apache.org>
Committed: Tue Jul 12 12:49:02 2016 -0700

----------------------------------------------------------------------
 sentry-binding/sentry-binding-hive/pom.xml      |   6 +
 .../SentryMetastorePostEventListener.java       | 518 +++++++++----------
 .../json/JSONAlterPartitionMessage.java         |  78 +++
 .../messaging/json/JSONAlterTableMessage.java   |  68 +++
 .../json/SentryJSONAddPartitionMessage.java     |  49 ++
 .../json/SentryJSONAlterPartitionMessage.java   |  53 ++
 .../json/SentryJSONAlterTableMessage.java       |  50 ++
 .../json/SentryJSONCreateDatabaseMessage.java   |  44 ++
 .../json/SentryJSONCreateTableMessage.java      |  45 ++
 .../json/SentryJSONDropDatabaseMessage.java     |  44 ++
 .../json/SentryJSONDropPartitionMessage.java    |  49 ++
 .../json/SentryJSONDropTableMessage.java        |  45 ++
 .../json/SentryJSONMessageDeserializer.java     | 110 ++++
 .../json/SentryJSONMessageFactory.java          | 177 +++++++
 .../TestDbPrivilegeCleanupOnDrop.java           |   7 +-
 .../AbstractTestWithStaticConfiguration.java    |   3 +-
 ...actMetastoreTestWithStaticConfiguration.java |   5 +
 ...NotificationListenerInBuiltDeserializer.java | 353 +++++++++++++
 ...bNotificationListenerSentryDeserializer.java |  39 ++
 ...ificationLogUsingDBNotificationListener.java | 351 -------------
 .../TestSentryListenerInBuiltDeserializer.java  |  37 ++
 .../TestSentryListenerSentryDeserializer.java   | 375 ++++++++++++++
 22 files changed, 1886 insertions(+), 620 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/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 07aaae3..ca87836 100644
--- a/sentry-binding/sentry-binding-hive/pom.xml
+++ b/sentry-binding/sentry-binding-hive/pom.xml
@@ -106,6 +106,12 @@ limitations under the License.
       <scope>provided</scope>
     </dependency>
     <dependency>
+      <groupId>org.apache.hive.hcatalog</groupId>
+      <artifactId>hive-hcatalog-server-extensions</artifactId>
+      <version>${hive.version}</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/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 d12ac15..75190c1 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
@@ -17,15 +17,16 @@
  */
 package org.apache.sentry.binding.metastore;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 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.RawStore;
+import org.apache.hadoop.hive.metastore.RawStoreProxy;
+import org.apache.hadoop.hive.metastore.TableType;
 import org.apache.hadoop.hive.metastore.api.MetaException;
-import org.apache.hadoop.hive.metastore.api.Partition;
+import org.apache.hadoop.hive.metastore.api.NotificationEvent;
 import org.apache.hadoop.hive.metastore.events.AddPartitionEvent;
 import org.apache.hadoop.hive.metastore.events.AlterPartitionEvent;
 import org.apache.hadoop.hive.metastore.events.AlterTableEvent;
@@ -34,371 +35,360 @@ 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.core.common.exception.SentryUserException;
-import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
-import org.apache.sentry.binding.hive.conf.HiveAuthzConf.AuthzConfVars;
-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.hive.hcatalog.common.HCatConstants;
+import org.apache.sentry.binding.metastore.messaging.json.SentryJSONMessageFactory;
 import org.apache.sentry.provider.db.SentryMetastoreListenerPlugin;
-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 org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+/*
+A HMS listener class which should ideally go into the transaction which persists the Hive metadata.
+This class writes all DDL events to the NotificationLog through rawstore.addNotificationEvent(event)
+This class is very similar to DbNotificationListener, except:
+1. It uses a custom SentryJSONMessageFactory which adds additional information to the message part of the event
+ to avoid another round trip from the clients
+2. It handles the cases where actual operation has failed, and hence skips writing to the notification log.
+3. Has additional validations to make sure event has the required information.
+
+This can be replaced with DbNotificationListener in future and sentry's message factory can be plugged in if:
+- HIVE-14011 is fixed: Make MessageFactory truly pluggable
+- 2 and 3 above are handled in DbNotificationListener
+*/
+
 public class SentryMetastorePostEventListener extends MetaStoreEventListener {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(SentryMetastoreListenerPlugin.class);
-  private final HiveAuthzConf authzConf;
-  private final Server server;
+  private RawStore rs;
+  private HiveConf hiveConf;
+  SentryJSONMessageFactory messageFactory;
 
-  protected List<SentryMetastoreListenerPlugin> sentryPlugins = new ArrayList<SentryMetastoreListenerPlugin>();
+  private static SentryMetastorePostEventListener.CleanerThread cleaner = null;
 
-  public SentryMetastorePostEventListener(Configuration config) {
-    super(config);
-
-    if (!(config instanceof HiveConf)) {
-        String error = "Could not initialize Plugin - Configuration is not an instanceof HiveConf";
-        LOGGER.error(error);
-        throw new RuntimeException(error);
+  //Same as DbNotificationListener to make the transition back easy
+  private synchronized void init(HiveConf conf) {
+    try {
+      this.rs = RawStoreProxy.getProxy(conf, conf, conf.getVar(HiveConf.ConfVars.METASTORE_RAW_STORE_IMPL), 999999);
+    } catch (MetaException var3) {
+      LOGGER.error("Unable to connect to raw store, notifications will not be tracked", var3);
+      this.rs = null;
     }
 
-    authzConf = HiveAuthzConf.getAuthzConf((HiveConf)config);
-    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());
+    if(cleaner == null && this.rs != null) {
+      cleaner = new SentryMetastorePostEventListener.CleanerThread(conf, this.rs);
+      cleaner.start();
+    }
+  }
 
-    try {
-      for (String pluginClassStr : pluginClasses) {
-        Class<?> clazz = config.getClassByName(pluginClassStr);
-        if (!SentryMetastoreListenerPlugin.class.isAssignableFrom(clazz)) {
-          throw new IllegalArgumentException("Class ["
-              + pluginClassStr + "] is not a "
-              + SentryMetastoreListenerPlugin.class.getName());
-        }
-        SentryMetastoreListenerPlugin plugin = (SentryMetastoreListenerPlugin) clazz
-            .getConstructor(Configuration.class, Configuration.class)
-            .newInstance(config, authzConf);
-        sentryPlugins.add(plugin);
-      }
-    } catch (Exception e) {
-      LOGGER.error("Could not initialize Plugin !!", e);
-      throw new RuntimeException(e);
+  public SentryMetastorePostEventListener(Configuration config) {
+    super(config);
+    // The code in MetastoreUtils.getMetaStoreListeners() that calls this looks for a constructor
+    // with a Configuration parameter, so we have to declare config as Configuration.  But it
+    // actually passes a HiveConf, which we need.  So we'll do this ugly down cast.
+    if (!(config instanceof HiveConf)) {
+      String error = "Could not initialize Plugin - Configuration is not an instanceof HiveConf";
+      LOGGER.error(error);
+      throw new RuntimeException(error);
     }
+    hiveConf = (HiveConf)config;
+    messageFactory = new SentryJSONMessageFactory();
+    init(hiveConf);
   }
 
   @Override
-  public void onCreateTable (CreateTableEvent tableEvent) throws MetaException {
+  public void onCreateDatabase(CreateDatabaseEvent dbEvent)
+          throws MetaException {
 
-    // don't sync paths/privileges if the operation has failed
-    if (!tableEvent.getStatus()) {
-      LOGGER.debug("Skip sync paths/privileges with Sentry server for onCreateTable event," +
-        " since the operation failed. \n");
+    // do not write to Notification log if the operation has failed
+    if (!dbEvent.getStatus()) {
+      LOGGER.info("Skipping writing to NotificationLog as the Create database event failed");
       return;
     }
 
-    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);
-      }
+    String location = dbEvent.getDatabase().getLocationUri();
+    if (location == null || location.isEmpty()) {
+      throw new SentryMalformedEventException("CreateDatabaseEvent has invalid location", dbEvent);
     }
-
-    // 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)) {
-      return;
+    String dbName = dbEvent.getDatabase().getName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("CreateDatabaseEvent has invalid dbName", dbEvent);
     }
 
-    dropSentryTablePrivilege(tableEvent.getTable().getDbName(),
-        tableEvent.getTable().getTableName());
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_CREATE_DATABASE_EVENT,
+            messageFactory.buildCreateDatabaseMessage(dbEvent.getDatabase()).toString());
+    event.setDbName(dbName);
+    this.enqueue(event);
   }
 
   @Override
-  public void onDropTable(DropTableEvent tableEvent) throws MetaException {
-
-    // don't sync paths/privileges if the operation has failed
-    if (!tableEvent.getStatus()) {
-      LOGGER.debug("Skip syncing paths/privileges with Sentry server for onDropTable event," +
-        " since the operation failed. \n");
-      return;
-    }
+  public void onDropDatabase(DropDatabaseEvent dbEvent) throws MetaException {
 
-    if (tableEvent.getTable().getSd().getLocation() != null) {
-      String authzObj = tableEvent.getTable().getDbName() + "."
-          + tableEvent.getTable().getTableName();
-      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
-        plugin.removeAllPaths(authzObj, null);
-      }
-    }
-    // drop the privileges on the given table
-    if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_DROP_WITH_POLICY_STORE)) {
+    // do not write to Notification log if the operation has failed
+    if (!dbEvent.getStatus()) {
+      LOGGER.info("Skipping writing to NotificationLog as the Drop database event failed");
       return;
     }
 
-    if (!tableEvent.getStatus()) {
-      return;
+    String dbName = dbEvent.getDatabase().getName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("DropDatabaseEvent has invalid dbName", dbEvent);
     }
 
-    dropSentryTablePrivilege(tableEvent.getTable().getDbName(),
-        tableEvent.getTable().getTableName());
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_DROP_DATABASE_EVENT,
+            messageFactory.buildDropDatabaseMessage(dbEvent.getDatabase()).toString());
+    event.setDbName(dbName);
+    this.enqueue(event);
   }
 
   @Override
-  public void onCreateDatabase(CreateDatabaseEvent dbEvent)
-      throws MetaException {
+  public void onCreateTable (CreateTableEvent tableEvent) throws MetaException {
 
-    // don't sync paths/privileges if the operation has failed
-    if (!dbEvent.getStatus()) {
-      LOGGER.debug("Skip syncing paths/privileges with Sentry server for onCreateDatabase event," +
-        " since the operation failed. \n");
+    // do not write to Notification log if the operation has failed
+    if (!tableEvent.getStatus()) {
+      LOGGER.info("Skipping writing to NotificationLog as the Create table event failed");
       return;
     }
 
-    if (dbEvent.getDatabase().getLocationUri() != null) {
-      String authzObj = dbEvent.getDatabase().getName();
-      String path = dbEvent.getDatabase().getLocationUri();
-      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
-        plugin.addPath(authzObj, path);
-      }
+    String dbName = tableEvent.getTable().getDbName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("CreateTableEvent has invalid dbName", tableEvent);
     }
-    // drop the privileges on the database, in case anything left behind during
-    // last drop db
-    if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_CREATE_WITH_POLICY_STORE)) {
-      return;
+    String tableName = tableEvent.getTable().getTableName();
+    if (tableName == null || tableName.isEmpty()) {
+      throw new SentryMalformedEventException("CreateTableEvent has invalid tableName", tableEvent);
     }
-
-    dropSentryDbPrivileges(dbEvent.getDatabase().getName());
+    // Create table event should also contain a location.
+    // But, Create view also generates a Create table event, but it does not have a location.
+    // Create view is identified by the tableType. But turns out tableType is not set in some cases.
+    // We assume that tableType is set for all create views.
+    //TODO: Location can be null/empty, handle that in HMSFollower
+    String tableType = tableEvent.getTable().getTableType();
+    if(!(tableType != null && tableType.equals(TableType.VIRTUAL_VIEW.name()))) {
+        if (tableType == null) {
+        LOGGER.warn("TableType is null, assuming it is not TableType.VIRTUAL_VIEW: tableEvent", tableEvent);
+      }
+      String location = tableEvent.getTable().getSd().getLocation();
+      if (location == null || location.isEmpty()) {
+        throw new SentryMalformedEventException("CreateTableEvent has invalid location", tableEvent);
+      }
+    }
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_CREATE_TABLE_EVENT,
+            messageFactory.buildCreateTableMessage(tableEvent.getTable()).toString());
+    event.setDbName(dbName);
+    event.setTableName(tableName);
+    this.enqueue(event);
   }
 
-  /**
-   * Drop the privileges on the database. Note that child tables will be
-   * dropped individually by client, so we just need to handle the removing
-   * the db privileges. The table drop should cleanup the table privileges.
-   */
   @Override
-  public void onDropDatabase(DropDatabaseEvent dbEvent) throws MetaException {
+  public void onDropTable(DropTableEvent tableEvent) throws MetaException {
 
-    // don't sync paths/privileges if the operation has failed
-    if (!dbEvent.getStatus()) {
-      LOGGER.debug("Skip syncing paths/privileges with Sentry server for onDropDatabase event," +
-        " since the operation failed. \n");
+    // do not write to Notification log if the operation has failed
+    if (!tableEvent.getStatus()) {
+      LOGGER.info("Skipping writing to NotificationLog as the Drop table event failed");
       return;
     }
 
-    String authzObj = dbEvent.getDatabase().getName();
-    for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
-      List<String> tNames = dbEvent.getHandler().get_all_tables(authzObj);
-      plugin.removeAllPaths(authzObj, tNames);
+    String dbName = tableEvent.getTable().getDbName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("DropTableEvent has invalid dbName", tableEvent);
     }
-    if (!syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_DROP_WITH_POLICY_STORE)) {
-      return;
+    String tableName = tableEvent.getTable().getTableName();
+    if (tableName == null || tableName.isEmpty()) {
+      throw new SentryMalformedEventException("DropTableEvent has invalid tableName", tableEvent);
     }
 
-    dropSentryDbPrivileges(dbEvent.getDatabase().getName());
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_DROP_TABLE_EVENT,
+            messageFactory.buildDropTableMessage(tableEvent.getTable()).toString());
+    event.setDbName(dbName);
+    event.setTableName(tableName);
+    this.enqueue(event);
   }
 
-  /**
-   * Adjust the privileges when table is renamed
-   */
   @Override
   public void onAlterTable (AlterTableEvent tableEvent) throws MetaException {
 
-    // don't sync privileges if the operation has failed
+    // do not write to Notification log if the operation has failed
     if (!tableEvent.getStatus()) {
-      LOGGER.debug("Skip syncing privileges with Sentry server for onAlterTable event," +
-        " since the operation failed. \n");
+      LOGGER.info("Skipping writing to NotificationLog as the Alter table event failed");
       return;
     }
 
-    renameSentryTablePrivilege(tableEvent.getOldTable().getDbName(),
-        tableEvent.getOldTable().getTableName(), 
-        tableEvent.getOldTable().getSd().getLocation(),
-        tableEvent.getNewTable().getDbName(), 
-        tableEvent.getNewTable().getTableName(),
-        tableEvent.getNewTable().getSd().getLocation());
+    String dbName = tableEvent.getNewTable().getDbName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("AlterTableEvent's newTable has invalid dbName", tableEvent);
+    }
+    String tableName = tableEvent.getNewTable().getTableName();
+    if (tableName == null || tableName.isEmpty()) {
+      throw new SentryMalformedEventException("AlterTableEvent's newTable has invalid tableName", tableEvent);
+    }
+    dbName = tableEvent.getOldTable().getDbName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("AlterTableEvent's oldTable has invalid dbName", tableEvent);
+    }
+    tableName = tableEvent.getOldTable().getTableName();
+    if (tableName == null || tableName.isEmpty()) {
+      throw new SentryMalformedEventException("AlterTableEvent's oldTable has invalid tableName", tableEvent);
+    }
+    //Alter view also generates an alter table event, but it does not have a location
+    //TODO: Handle this case in Sentry
+    if(!tableEvent.getOldTable().getTableType().equals(TableType.VIRTUAL_VIEW.name())) {
+      String location = tableEvent.getNewTable().getSd().getLocation();
+      if (location == null || location.isEmpty()) {
+        throw new SentryMalformedEventException("AlterTableEvent's newTable has invalid location", tableEvent);
+      }
+      location = tableEvent.getOldTable().getSd().getLocation();
+      if (location == null || location.isEmpty()) {
+        throw new SentryMalformedEventException("AlterTableEvent's oldTable has invalid location", tableEvent);
+      }
+    }
+
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_ALTER_TABLE_EVENT,
+            messageFactory.buildAlterTableMessage(tableEvent.getOldTable(), tableEvent.getNewTable()).toString());
+    event.setDbName(tableEvent.getNewTable().getDbName());
+    event.setTableName(tableEvent.getNewTable().getTableName());
+    this.enqueue(event);
   }
 
   @Override
   public void onAlterPartition(AlterPartitionEvent partitionEvent)
-      throws MetaException {
+          throws MetaException {
 
-    // don't sync privileges if the operation has failed
+    // do not write to Notification log if the operation has failed
     if (!partitionEvent.getStatus()) {
-      LOGGER.debug("Skip syncing privileges with Sentry server for onAlterPartition event," +
-        " since the operation failed. \n");
+      LOGGER.info("Skipping writing to NotificationLog as the Alter partition event failed");
       return;
     }
 
-    String oldLoc = null, newLoc = null;
-    if (partitionEvent.getOldPartition() != null) {
-      oldLoc = partitionEvent.getOldPartition().getSd().getLocation();
+    String dbName = partitionEvent.getNewPartition().getDbName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("AlterPartitionEvent's newPartition has invalid dbName", partitionEvent);
     }
-    if (partitionEvent.getNewPartition() != null) {
-      newLoc = partitionEvent.getNewPartition().getSd().getLocation();
+    String tableName = partitionEvent.getNewPartition().getTableName();
+    if (tableName == null || tableName.isEmpty()) {
+      throw new SentryMalformedEventException("AlterPartitionEvent's newPartition has invalid tableName", partitionEvent);
     }
 
-    if (oldLoc != null && newLoc != null && !oldLoc.equals(newLoc)) {
-      String authzObj =
-          partitionEvent.getOldPartition().getDbName() + "."
-              + partitionEvent.getOldPartition().getTableName();
-      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
-        plugin.renameAuthzObject(authzObj, oldLoc,
-            authzObj, newLoc);
-      }
-    }
+    //TODO: Need more validations, but it is tricky as there are many variations and validations change for each one
+    // Alter partition Location
+    // Alter partition property
+    // Any more?
+
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_ALTER_PARTITION_EVENT,
+            messageFactory.buildAlterPartitionMessage(partitionEvent.getOldPartition(), partitionEvent.getNewPartition()).toString());
+
+    event.setDbName(partitionEvent.getNewPartition().getDbName());
+    event.setTableName(partitionEvent.getNewPartition().getTableName());
+    this.enqueue(event);
   }
 
   @Override
   public void onAddPartition(AddPartitionEvent partitionEvent)
-      throws MetaException {
+          throws MetaException {
 
-    // don't sync path if the operation has failed
+    // do not write to Notification log if the operation has failed
     if (!partitionEvent.getStatus()) {
-      LOGGER.debug("Skip syncing path with Sentry server for onAddPartition event," +
-        " since the operation failed. \n");
+      LOGGER.info("Skipping writing to NotificationLog as the Add partition event failed");
       return;
     }
 
-    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);
-        }
-      }
+    String dbName = partitionEvent.getTable().getDbName();
+    if (dbName == null || dbName.isEmpty()) {
+      throw new SentryMalformedEventException("AddPartitionEvent has invalid dbName", partitionEvent);
+    }
+    String tableName = partitionEvent.getTable().getTableName();
+    if (tableName == null || tableName.isEmpty()) {
+      throw new SentryMalformedEventException("AddPartitionEvent's newPartition has invalid tableName", partitionEvent);
     }
-    super.onAddPartition(partitionEvent);
+
+    //TODO: Need more validations?
+
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_ADD_PARTITION_EVENT,
+            messageFactory.buildAddPartitionMessage(partitionEvent.getTable(), partitionEvent.getPartitions()).toString());
+
+    event.setDbName(partitionEvent.getTable().getDbName());
+    event.setTableName(partitionEvent.getTable().getTableName());
+    this.enqueue(event);
   }
 
   @Override
   public void onDropPartition(DropPartitionEvent partitionEvent)
-      throws MetaException {
+          throws MetaException {
 
-    // don't sync path if the operation has failed
+    // do not write to Notification log if the operation has failed
     if (!partitionEvent.getStatus()) {
-      LOGGER.debug("Skip syncing path with Sentry server for onDropPartition event," +
-        " since the operation failed. \n");
+      LOGGER.info("Skipping writing to NotificationLog as the Drop partition event failed");
       return;
     }
 
-    String authzObj = partitionEvent.getTable().getDbName() + "."
-        + partitionEvent.getTable().getTableName();
-    String path = partitionEvent.getPartition().getSd().getLocation();
-    for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
-      plugin.removePath(authzObj, path);
-    }
-    super.onDropPartition(partitionEvent);
+    NotificationEvent event = new NotificationEvent(0L, now(), HCatConstants.HCAT_DROP_PARTITION_EVENT,
+            messageFactory.buildDropPartitionMessage(partitionEvent.getTable(), partitionEvent.getPartition()).toString());
+    //TODO: Why is this asymmetric with add partitions(s)?
+    // Seems like adding multiple partitions generate a single event
+    // where as single partition drop generated an event?
+
+    event.setDbName(partitionEvent.getTable().getDbName());
+    event.setTableName(partitionEvent.getTable().getTableName());
+    this.enqueue(event);
   }
 
-  private SentryPolicyServiceClient getSentryServiceClient()
-      throws MetaException {
-    try {
-      return SentryServiceClientFactory.create(authzConf);
-    } catch (Exception e) {
-      throw new MetaException("Failed to connect to Sentry service "
-          + e.getMessage());
+  private int now() {
+    long millis = System.currentTimeMillis();
+    millis /= 1000;
+    if (millis > Integer.MAX_VALUE) {
+      LOGGER.warn("We've passed max int value in seconds since the epoch, " +
+          "all notification times will be the same!");
+      return Integer.MAX_VALUE;
     }
+    return (int)millis;
   }
 
-  private void dropSentryDbPrivileges(String dbName) throws MetaException {
-    List<Authorizable> authorizableTable = new ArrayList<Authorizable>();
-    authorizableTable.add(server);
-    authorizableTable.add(new Database(dbName));
-    try {
-      dropSentryPrivileges(authorizableTable);
-    } catch (SentryUserException e) {
-      throw new MetaException("Failed to remove Sentry policies for drop DB "
-          + dbName + " Error: " + e.getMessage());
-    } catch (IOException e) {
-      throw new MetaException("Failed to find local user " + e.getMessage());
+  //Same as DbNotificationListener to make the transition back easy
+  private void enqueue(NotificationEvent event) {
+    if(this.rs != null) {
+      this.rs.addNotificationEvent(event);
+    } else {
+      LOGGER.warn("Dropping event " + event + " since notification is not running.");
     }
-
   }
 
-  private void dropSentryTablePrivilege(String dbName, String tabName)
-      throws MetaException {
-    List<Authorizable> authorizableTable = new ArrayList<Authorizable>();
-    authorizableTable.add(server);
-    authorizableTable.add(new Database(dbName));
-    authorizableTable.add(new Table(tabName));
+  //Same as DbNotificationListener to make the transition back easy
+  private static class CleanerThread extends Thread {
+    private RawStore rs;
+    private int ttl;
 
-    try {
-      dropSentryPrivileges(authorizableTable);
-    } catch (SentryUserException e) {
-      throw new MetaException(
-          "Failed to remove Sentry policies for drop table " + dbName + "."
-              + tabName + " Error: " + e.getMessage());
-    } catch (IOException e) {
-      throw new MetaException("Failed to find local user " + e.getMessage());
+    CleanerThread(HiveConf conf, RawStore rs) {
+      super("CleanerThread");
+      this.rs = rs;
+      this.setTimeToLive(conf.getTimeVar(HiveConf.ConfVars.METASTORE_EVENT_DB_LISTENER_TTL, TimeUnit.SECONDS));
+      this.setDaemon(true);
     }
 
-  }
-  private void dropSentryPrivileges(
-      List<? extends Authorizable> authorizableTable)
-      throws SentryUserException, IOException, MetaException {
-    String requestorUserName = UserGroupInformation.getCurrentUser()
-        .getShortUserName();
-    SentryPolicyServiceClient sentryClient = getSentryServiceClient();
-    sentryClient.dropPrivileges(requestorUserName, authorizableTable);
-
-    // Close the connection after dropping privileges is done.
-    sentryClient.close();
-  }
+    public void run() {
+      while(true) {
+        this.rs.cleanNotificationEvents(this.ttl);
 
-  private void renameSentryTablePrivilege(String oldDbName, String oldTabName,
-      String oldPath, String newDbName, String newTabName, String newPath)
-      throws MetaException {
-    List<Authorizable> oldAuthorizableTable = new ArrayList<Authorizable>();
-    oldAuthorizableTable.add(server);
-    oldAuthorizableTable.add(new Database(oldDbName));
-    oldAuthorizableTable.add(new Table(oldTabName));
-
-    List<Authorizable> newAuthorizableTable = new ArrayList<Authorizable>();
-    newAuthorizableTable.add(server);
-    newAuthorizableTable.add(new Database(newDbName));
-    newAuthorizableTable.add(new Table(newTabName));
-
-    if (!oldTabName.equalsIgnoreCase(newTabName)
-        && syncWithPolicyStore(AuthzConfVars.AUTHZ_SYNC_ALTER_WITH_POLICY_STORE)) {
-
-      SentryPolicyServiceClient sentryClient = getSentryServiceClient();
-
-      try {
-        String requestorUserName = UserGroupInformation.getCurrentUser()
-            .getShortUserName();
-        sentryClient.renamePrivileges(requestorUserName, oldAuthorizableTable, newAuthorizableTable);
-      } catch (SentryUserException e) {
-        throw new MetaException(
-            "Failed to remove Sentry policies for rename table " + oldDbName
-            + "." + oldTabName + "to " + newDbName + "." + newTabName
-            + " Error: " + e.getMessage());
-      } catch (IOException e) {
-        throw new MetaException("Failed to find local user " + e.getMessage());
-      } finally {
-
-        // Close the connection after renaming privileges is done.
-        sentryClient.close();
+        try {
+          Thread.sleep(60000L);
+        } catch (InterruptedException var2) {
+          LOGGER.info("Cleaner thread sleep interupted", var2);
+        }
       }
     }
-    // The HDFS plugin needs to know if it's a path change (set location)
-    for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
-      plugin.renameAuthzObject(oldDbName + "." + oldTabName, oldPath,
-          newDbName + "." + newTabName, newPath);
+
+    public void setTimeToLive(long configTtl) {
+      if(configTtl > 2147483647L) {
+        this.ttl = 2147483647;
+      } else {
+        this.ttl = (int)configTtl;
+      }
+
     }
   }
-
-  private boolean syncWithPolicyStore(AuthzConfVars syncConfVar) {
-    return "true"
-        .equalsIgnoreCase(authzConf.get(syncConfVar.getVar(), "true"));
+  private class SentryMalformedEventException extends MetaException {
+    SentryMalformedEventException(String msg, Object event) {
+      //toString is not implemented in Event classes,
+      // hence using reflection to print the details of the Event object.
+      super(msg + "Event: " + ToStringBuilder.reflectionToString(event));
+    }
   }
-
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterPartitionMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterPartitionMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterPartitionMessage.java
new file mode 100644
index 0000000..890186b
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterPartitionMessage.java
@@ -0,0 +1,78 @@
+/**
+ * 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.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.AlterPartitionMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.List;
+
+/*
+* This is only needed as corresponding class in Hive 1.1.0 does not have a default constructor
+ */
+public class JSONAlterPartitionMessage extends AlterPartitionMessage {
+    @JsonProperty
+    String server;
+    @JsonProperty
+    String servicePrincipal;
+    @JsonProperty
+    String db;
+    @JsonProperty
+    String table;
+    @JsonProperty
+    Long timestamp;
+    @JsonProperty
+    List<String> values;
+
+    public JSONAlterPartitionMessage() {}
+    public JSONAlterPartitionMessage(String server, String servicePrincipal, String db, String table, List<String> values, Long timestamp) {
+        this.server = server;
+        this.servicePrincipal = servicePrincipal;
+        this.db = db;
+        this.table = table;
+        this.timestamp = timestamp;
+        this.values = values;
+        this.checkValid();
+    }
+
+    public String getServer() {
+        return this.server;
+    }
+
+    public String getServicePrincipal() {
+        return this.servicePrincipal;
+    }
+
+    public String getDB() {
+        return this.db;
+    }
+
+    public Long getTimestamp() {
+        return this.timestamp;
+    }
+
+    public String getTable() {
+        return this.table;
+    }
+
+    public List<String> getValues() {
+        return this.values;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterTableMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterTableMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterTableMessage.java
new file mode 100644
index 0000000..76211c3
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/JSONAlterTableMessage.java
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.AlterTableMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * This class is required as this class does not have a default contructor in Hive 1.1.0
+ */
+public class JSONAlterTableMessage extends AlterTableMessage {
+    @JsonProperty
+    String server;
+    @JsonProperty
+    String servicePrincipal;
+    @JsonProperty
+    String db;
+    @JsonProperty
+    String table;
+    @JsonProperty
+    Long timestamp;
+
+    public JSONAlterTableMessage() {}
+    public JSONAlterTableMessage(String server, String servicePrincipal, String db, String table, Long timestamp) {
+        this.server = server;
+        this.servicePrincipal = servicePrincipal;
+        this.db = db;
+        this.table = table;
+        this.timestamp = timestamp;
+        this.checkValid();
+    }
+
+    public String getServer() {
+        return this.server;
+    }
+
+    public String getServicePrincipal() {
+        return this.servicePrincipal;
+    }
+
+    public String getDB() {
+        return this.db;
+    }
+
+    public Long getTimestamp() {
+        return this.timestamp;
+    }
+
+    public String getTable() {
+        return this.table;
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAddPartitionMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAddPartitionMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAddPartitionMessage.java
new file mode 100644
index 0000000..c0c469c
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAddPartitionMessage.java
@@ -0,0 +1,49 @@
+/**
+ * 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.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.json.JSONAddPartitionMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.List;
+import java.util.Map;
+
+public class SentryJSONAddPartitionMessage extends JSONAddPartitionMessage {
+    @JsonProperty
+    List<String> locations;
+
+    public SentryJSONAddPartitionMessage() {
+    }
+
+    public SentryJSONAddPartitionMessage(String server, String servicePrincipal, String db, String table,
+                                         List<Map<String, String>> partitions, Long timestamp, List<String> locations) {
+        super(server, servicePrincipal, db, table, partitions, timestamp);
+        this.locations = locations;
+    }
+
+    public List<String> getLocations() {
+        return locations;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterPartitionMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterPartitionMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterPartitionMessage.java
new file mode 100644
index 0000000..99eb67a
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterPartitionMessage.java
@@ -0,0 +1,53 @@
+/**
+ * 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.binding.metastore.messaging.json;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.List;
+
+public class SentryJSONAlterPartitionMessage extends JSONAlterPartitionMessage{
+    @JsonProperty
+    String location;
+    @JsonProperty
+    String oldLocation;
+
+    public SentryJSONAlterPartitionMessage() {
+    }
+
+    public SentryJSONAlterPartitionMessage(String server, String servicePrincipal, String db, String table,
+                                           List<String> values, Long timestamp, String oldlocation, String newLocation) {
+        super(server, servicePrincipal, db, table, values, timestamp);
+        this.location = newLocation;
+        this.oldLocation = oldlocation;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public String getOldLocation() {
+        return oldLocation;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterTableMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterTableMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterTableMessage.java
new file mode 100644
index 0000000..6e59e25
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONAlterTableMessage.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.binding.metastore.messaging.json;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class SentryJSONAlterTableMessage extends JSONAlterTableMessage {
+    @JsonProperty
+    String location; //newLocation
+    @JsonProperty
+    String oldLocation;
+
+    public SentryJSONAlterTableMessage() {
+    }
+
+    public SentryJSONAlterTableMessage(String server, String servicePrincipal, String db, String table,
+                                       Long timestamp, String oldLocation, String location) {
+        super(server, servicePrincipal, db, table, timestamp);
+        this.location = location;
+        this.oldLocation = oldLocation;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+    public String getOldLocation() {
+        return oldLocation;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateDatabaseMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateDatabaseMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateDatabaseMessage.java
new file mode 100644
index 0000000..ba19cbe
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateDatabaseMessage.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.json.JSONCreateDatabaseMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class SentryJSONCreateDatabaseMessage extends JSONCreateDatabaseMessage {
+    @JsonProperty
+    String location;
+
+    public SentryJSONCreateDatabaseMessage() {
+    }
+
+    public SentryJSONCreateDatabaseMessage(String server, String servicePrincipal, String db, Long timestamp, String location) {
+        super(server, servicePrincipal, db, timestamp);
+        this.location = location;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateTableMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateTableMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateTableMessage.java
new file mode 100644
index 0000000..57d11d2
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONCreateTableMessage.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.json.JSONCreateTableMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class SentryJSONCreateTableMessage extends JSONCreateTableMessage {
+    @JsonProperty
+    String location;
+
+    public SentryJSONCreateTableMessage() {
+    }
+
+    public SentryJSONCreateTableMessage(String server, String servicePrincipal, String db, String table, Long timestamp, String location) {
+        super(server, servicePrincipal, db, table, timestamp);
+        this.location = location;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropDatabaseMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropDatabaseMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropDatabaseMessage.java
new file mode 100644
index 0000000..05f83f7
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropDatabaseMessage.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.json.JSONDropDatabaseMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class SentryJSONDropDatabaseMessage extends JSONDropDatabaseMessage{
+    @JsonProperty
+    String location;
+
+    public SentryJSONDropDatabaseMessage() {
+    }
+
+    public SentryJSONDropDatabaseMessage(String server, String servicePrincipal, String db, Long timestamp, String location) {
+        super(server, servicePrincipal, db, timestamp);
+        this.location = location;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropPartitionMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropPartitionMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropPartitionMessage.java
new file mode 100644
index 0000000..2ab61f7
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropPartitionMessage.java
@@ -0,0 +1,49 @@
+/**
+ * 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.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.json.JSONDropPartitionMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.List;
+import java.util.Map;
+
+public class SentryJSONDropPartitionMessage extends JSONDropPartitionMessage {
+    @JsonProperty
+    String location;
+
+    public SentryJSONDropPartitionMessage() {
+    }
+
+    public SentryJSONDropPartitionMessage(String server, String servicePrincipal, String db, String table,
+                                          List<Map<String, String>> partitions, Long timestamp, String location) {
+        super(server, servicePrincipal, db, table, partitions, timestamp);
+        this.location = location;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropTableMessage.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropTableMessage.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropTableMessage.java
new file mode 100644
index 0000000..7005776
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONDropTableMessage.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.sentry.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.json.JSONDropTableMessage;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+
+public class SentryJSONDropTableMessage extends JSONDropTableMessage {
+    @JsonProperty
+    String location;
+
+    public SentryJSONDropTableMessage() {
+    }
+
+    public SentryJSONDropTableMessage(String server, String servicePrincipal, String db, String table, Long timestamp, String location) {
+        super(server, servicePrincipal, db, table, timestamp);
+        this.location = location;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    @Override
+    public String toString() {
+        return SentryJSONMessageDeserializer.serialize(this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageDeserializer.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageDeserializer.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageDeserializer.java
new file mode 100644
index 0000000..b645c45
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageDeserializer.java
@@ -0,0 +1,110 @@
+/**
+ * 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.binding.metastore.messaging.json;
+
+import org.apache.hive.hcatalog.messaging.*;
+import org.codehaus.jackson.map.DeserializationConfig;
+import org.codehaus.jackson.map.ObjectMapper;
+
+public class SentryJSONMessageDeserializer extends MessageDeserializer {
+    static ObjectMapper mapper = new ObjectMapper();
+
+    public SentryJSONMessageDeserializer() {
+    }
+
+    /**
+     * Method to de-serialize CreateDatabaseMessage instance.
+     */
+    public SentryJSONCreateDatabaseMessage getCreateDatabaseMessage(String messageBody) {
+        try {
+            return (SentryJSONCreateDatabaseMessage)mapper.readValue(messageBody, SentryJSONCreateDatabaseMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONCreateDatabaseMessage.", var3);
+        }
+    }
+
+    public SentryJSONDropDatabaseMessage getDropDatabaseMessage(String messageBody) {
+        try {
+            return (SentryJSONDropDatabaseMessage)mapper.readValue(messageBody, SentryJSONDropDatabaseMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONDropDatabaseMessage.", var3);
+        }
+    }
+
+    public SentryJSONCreateTableMessage getCreateTableMessage(String messageBody) {
+        try {
+            return (SentryJSONCreateTableMessage)mapper.readValue(messageBody, SentryJSONCreateTableMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONCreateTableMessage.", var3);
+        }
+    }
+
+    public SentryJSONAlterTableMessage getAlterTableMessage(String messageBody) {
+        try {
+            return (SentryJSONAlterTableMessage)mapper.readValue(messageBody, SentryJSONAlterTableMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONAlterTableMessage.", var3);
+        }
+    }
+
+    public SentryJSONDropTableMessage getDropTableMessage(String messageBody) {
+        try {
+            return (SentryJSONDropTableMessage)mapper.readValue(messageBody, SentryJSONDropTableMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONDropTableMessage.", var3);
+        }
+    }
+
+    public SentryJSONAddPartitionMessage getAddPartitionMessage(String messageBody) {
+        try {
+            return (SentryJSONAddPartitionMessage)mapper.readValue(messageBody, SentryJSONAddPartitionMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONAddPartitionMessage.", var3);
+        }
+    }
+
+    public SentryJSONAlterPartitionMessage getAlterPartitionMessage(String messageBody) {
+        try {
+            return (SentryJSONAlterPartitionMessage)mapper.readValue(messageBody, SentryJSONAlterPartitionMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONAlterPartitionMessage.", var3);
+        }
+    }
+
+    public SentryJSONDropPartitionMessage getDropPartitionMessage(String messageBody) {
+        try {
+            return (SentryJSONDropPartitionMessage)mapper.readValue(messageBody, SentryJSONDropPartitionMessage.class);
+        } catch (Exception var3) {
+            throw new IllegalArgumentException("Could not construct SentryJSONDropPartitionMessage.", var3);
+        }
+    }
+
+    static {
+        mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+    }
+
+    public static String serialize(Object object) {
+        try {
+            return mapper.writeValueAsString(object);
+        }
+        catch (Exception exception) {
+            throw new IllegalArgumentException("Could not serialize: ", exception);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageFactory.java
----------------------------------------------------------------------
diff --git a/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageFactory.java b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageFactory.java
new file mode 100644
index 0000000..00e7db8
--- /dev/null
+++ b/sentry-binding/sentry-binding-hive/src/main/java/org/apache/sentry/binding/metastore/messaging/json/SentryJSONMessageFactory.java
@@ -0,0 +1,177 @@
+/**
+ * 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.binding.metastore.messaging.json;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hive.common.classification.InterfaceAudience;
+import org.apache.hadoop.hive.common.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.api.Database;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.Partition;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.partition.spec.PartitionSpecProxy;
+import org.apache.hive.hcatalog.messaging.*;
+
+import java.util.*;
+
+public class SentryJSONMessageFactory extends MessageFactory {
+    private static final Log LOG = LogFactory.getLog(SentryJSONMessageFactory.class.getName());
+    private static SentryJSONMessageDeserializer deserializer = new SentryJSONMessageDeserializer();
+    public SentryJSONMessageFactory() {
+        LOG.info("Using SentryJSONMessageFactory for building Notification log messages ");
+
+    }
+    public MessageDeserializer getDeserializer() {
+        return deserializer;
+    }
+
+    public String getVersion() {
+        return "0.1";
+    }
+
+    public String getMessageFormat() {
+        return "json";
+    }
+
+    public SentryJSONCreateDatabaseMessage buildCreateDatabaseMessage(Database db) {
+        return new SentryJSONCreateDatabaseMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, db.getName(),
+                Long.valueOf(this.now()), db.getLocationUri());
+    }
+    public SentryJSONDropDatabaseMessage buildDropDatabaseMessage(Database db) {
+        return new SentryJSONDropDatabaseMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, db.getName(),
+                Long.valueOf(this.now()), db.getLocationUri());
+    }
+
+    public SentryJSONCreateTableMessage buildCreateTableMessage(Table table) {
+        return new SentryJSONCreateTableMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, table.getDbName(),
+                table.getTableName(), Long.valueOf(this.now()), table.getSd().getLocation());
+    }
+
+    public SentryJSONAlterTableMessage buildAlterTableMessage(Table before, Table after) {
+        return new SentryJSONAlterTableMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, before.getDbName(),
+                before.getTableName(), Long.valueOf(this.now()), before.getSd().getLocation(), after.getSd().getLocation());
+    }
+
+    public SentryJSONDropTableMessage buildDropTableMessage(Table table) {
+        return new SentryJSONDropTableMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, table.getDbName(),
+                table.getTableName(), Long.valueOf(this.now()), table.getSd().getLocation());
+    }
+
+    public SentryJSONAddPartitionMessage buildAddPartitionMessage(Table table, List<Partition> partitions) {
+        return new SentryJSONAddPartitionMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, table.getDbName(),
+                table.getTableName(), getPartitionKeyValues(table, partitions), Long.valueOf(this.now()),
+                getPartitionLocations(partitions));
+    }
+
+    private List<String> getPartitionLocations(List<Partition> partitions) {
+        List<String> paths = new ArrayList<String>();
+        for(Partition partition:partitions) {
+            paths.add(partition.getSd().getLocation());
+        }
+        return paths;
+    }
+
+    //TODO: Not sure what is this used for. Need to investigate
+    private List<String> getPartitionLocations(PartitionSpecProxy partitionSpec) {
+        Iterator<Partition> iterator = partitionSpec.getPartitionIterator();
+        List<String> locations = new ArrayList<String>();
+        while(iterator.hasNext()) {
+            locations.add(iterator.next().getSd().getLocation());
+        }
+        return locations;
+    }
+
+    @InterfaceAudience.LimitedPrivate({"Hive"})
+    @InterfaceStability.Evolving
+    public SentryJSONAddPartitionMessage buildAddPartitionMessage(Table table, PartitionSpecProxy partitionSpec) {
+        return new SentryJSONAddPartitionMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, table.getDbName(),
+                table.getTableName(), getPartitionKeyValues(table, partitionSpec), Long.valueOf(this.now()),
+                getPartitionLocations(partitionSpec));
+    }
+
+    public SentryJSONAlterPartitionMessage buildAlterPartitionMessage(Partition before, Partition after) {
+        /*
+     f (partitionEvent.getOldPartition() != null) {
+      oldLoc = partitionEvent.getOldPartition().getSd().getLocation();
+    }
+    if (partitionEvent.getNewPartition() != null) {
+      newLoc = partitionEvent.getNewPartition().getSd().getLocation();
+    }
+
+    if ((oldLoc != null) && (newLoc != null) && (!oldLoc.equals(newLoc))) {
+      String authzObj =
+              partitionEvent.getOldPartition().getDbName() + "."
+                      + partitionEvent.getOldPartition().getTableName();
+      for (SentryMetastoreListenerPlugin plugin : sentryPlugins) {
+        plugin.renameAuthzObject(authzObj, oldLoc,
+                authzObj, newLoc);
+      }
+    }
+        * */
+        return new SentryJSONAlterPartitionMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, before.getDbName(),
+                before.getTableName(), before.getValues(), Long.valueOf(this.now()), before.getSd().getLocation(),
+                after.getSd().getLocation());
+    }
+
+    public SentryJSONDropPartitionMessage buildDropPartitionMessage(Table table, Partition partition) {
+        return new SentryJSONDropPartitionMessage(HCAT_SERVER_URL, HCAT_SERVICE_PRINCIPAL, partition.getDbName(),
+                partition.getTableName(), Arrays.asList(getPartitionKeyValues(table, partition)),
+                Long.valueOf(this.now()), partition.getSd().getLocation());
+    }
+
+    private static Map<String, String> getPartitionKeyValues(Table table, Partition partition) {
+        LinkedHashMap partitionKeys = new LinkedHashMap();
+
+        for(int i = 0; i < table.getPartitionKeysSize(); ++i) {
+            partitionKeys.put(((FieldSchema)table.getPartitionKeys().get(i)).getName(), partition.getValues().get(i));
+        }
+
+        return partitionKeys;
+    }
+
+    private static List<Map<String, String>> getPartitionKeyValues(Table table, List<Partition> partitions) {
+        ArrayList partitionList = new ArrayList(partitions.size());
+        Iterator i$ = partitions.iterator();
+
+        while(i$.hasNext()) {
+            Partition partition = (Partition)i$.next();
+            partitionList.add(getPartitionKeyValues(table, partition));
+        }
+
+        return partitionList;
+    }
+
+    @InterfaceAudience.LimitedPrivate({"Hive"})
+    @InterfaceStability.Evolving
+    private static List<Map<String, String>> getPartitionKeyValues(Table table, PartitionSpecProxy partitionSpec) {
+        ArrayList partitionList = new ArrayList();
+        PartitionSpecProxy.PartitionIterator iterator = partitionSpec.getPartitionIterator();
+
+        while(iterator.hasNext()) {
+            Partition partition = (Partition)iterator.next();
+            partitionList.add(getPartitionKeyValues(table, partition));
+        }
+
+        return partitionList;
+    }
+    //This is private in parent class
+    private long now() {
+        return System.currentTimeMillis() / 1000L;
+    }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
index 767bcbe..439b9de 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
@@ -32,14 +32,13 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.*;
 
 import com.google.common.collect.Lists;
 import com.google.common.io.Resources;
 
+
+@Ignore("Ignoring until SENTRY-1321 is complete")
 public class TestDbPrivilegeCleanupOnDrop extends
     AbstractTestWithStaticConfiguration {
 

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
index 2c4948e..7dc3d0f 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -515,7 +515,8 @@ public abstract class AbstractTestWithStaticConfiguration {
       } else {
         properties.put(HiveConf.ConfVars.METASTORE_EVENT_LISTENERS.varname,
                 SentryMetastorePostEventListener.class.getName());
-
+        properties.put("hcatalog.message.factory.impl.json",
+            "org.apache.sentry.binding.metastore.messaging.json.SentryJSONMessageFactory");
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/sentry/blob/113c5eae/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
index b72e317..567b4c8 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
@@ -200,6 +200,11 @@ public abstract class AbstractMetastoreTestWithStaticConfiguration extends
     client.createDatabase(db);
   }
 
+  public void dropMetastoreDBIfExists(HiveMetaStoreClient client, String dbName)
+      throws Exception {
+    client.dropDatabase(dbName, true, true, true);
+  }
+
   public void execHiveSQLwithOverlay(final String sqlStmt,
       final String userName, Map<String, String> overLay) throws Exception {
     final HiveConf hiveConf = new HiveConf();


Mime
View raw message