You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ga...@apache.org on 2017/11/02 16:23:07 UTC

[05/12] hive git commit: HIVE-17812 Move remaining classes that HiveMetaStore depends on. This closes #261. (Alan Gates, reviewed by Vihang Karajgaonkar)

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListener.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListener.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListener.java
new file mode 100644
index 0000000..fc4f4d7
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListener.java
@@ -0,0 +1,227 @@
+/*
+ * 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.hadoop.hive.metastore;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.events.AddForeignKeyEvent;
+import org.apache.hadoop.hive.metastore.events.AddIndexEvent;
+import org.apache.hadoop.hive.metastore.events.AddNotNullConstraintEvent;
+import org.apache.hadoop.hive.metastore.events.AddPrimaryKeyEvent;
+import org.apache.hadoop.hive.metastore.events.AddUniqueConstraintEvent;
+import org.apache.hadoop.hive.metastore.events.AlterIndexEvent;
+import org.apache.hadoop.hive.metastore.events.AddPartitionEvent;
+import org.apache.hadoop.hive.metastore.events.AlterPartitionEvent;
+import org.apache.hadoop.hive.metastore.events.AlterTableEvent;
+import org.apache.hadoop.hive.metastore.events.ConfigChangeEvent;
+import org.apache.hadoop.hive.metastore.events.CreateDatabaseEvent;
+import org.apache.hadoop.hive.metastore.events.CreateFunctionEvent;
+import org.apache.hadoop.hive.metastore.events.CreateTableEvent;
+import org.apache.hadoop.hive.metastore.events.DropConstraintEvent;
+import org.apache.hadoop.hive.metastore.events.DropDatabaseEvent;
+import org.apache.hadoop.hive.metastore.events.DropFunctionEvent;
+import org.apache.hadoop.hive.metastore.events.DropIndexEvent;
+import org.apache.hadoop.hive.metastore.events.DropPartitionEvent;
+import org.apache.hadoop.hive.metastore.events.DropTableEvent;
+import org.apache.hadoop.hive.metastore.events.InsertEvent;
+import org.apache.hadoop.hive.metastore.events.LoadPartitionDoneEvent;
+
+/**
+ * This abstract class needs to be extended to  provide implementation of actions that needs
+ * to be performed when a particular event occurs on a metastore. These methods
+ * are called whenever an event occurs on metastore. Status of the event whether
+ * it was successful or not is contained in container event object.
+ */
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public abstract class MetaStoreEventListener implements Configurable {
+
+  private Configuration conf;
+
+  public MetaStoreEventListener(Configuration config){
+    this.conf = config;
+  }
+
+  /**
+   * @param tableEvent table event.
+   * @throws MetaException
+   */
+  public void onConfigChange(ConfigChangeEvent tableEvent) throws MetaException {
+  }
+
+  /**
+   * @param tableEvent table event.
+   * @throws MetaException
+   */
+  public void onCreateTable (CreateTableEvent tableEvent) throws MetaException {
+  }
+
+  /**
+   * @param tableEvent table event.
+   * @throws MetaException
+   */
+  public void onDropTable (DropTableEvent tableEvent)  throws MetaException {
+  }
+
+  /**
+   * @param tableEvent alter table event
+   * @throws MetaException
+   */
+  public void onAlterTable (AlterTableEvent tableEvent) throws MetaException {
+  }
+
+  /**
+   * @param partitionEvent add partition event
+   * @throws MetaException
+   */
+  public void onAddPartition (AddPartitionEvent partitionEvent) throws MetaException {
+  }
+
+  /**
+   * @param partitionEvent partition event
+   * @throws MetaException
+   */
+  public void onDropPartition (DropPartitionEvent partitionEvent)  throws MetaException {
+  }
+
+  /**
+   * @param partitionEvent partition event
+   * @throws MetaException
+   */
+  public void onAlterPartition (AlterPartitionEvent partitionEvent)  throws MetaException {
+  }
+
+  /**
+   * @param dbEvent database event
+   * @throws MetaException
+   */
+  public void onCreateDatabase (CreateDatabaseEvent dbEvent) throws MetaException {
+  }
+
+  /**
+   * @param dbEvent database event
+   * @throws MetaException
+   */
+  public void onDropDatabase (DropDatabaseEvent dbEvent) throws MetaException {
+  }
+
+  /**
+   * @param partSetDoneEvent
+   * @throws MetaException
+   */
+  public void onLoadPartitionDone(LoadPartitionDoneEvent partSetDoneEvent) throws MetaException {
+  }
+
+  /**
+   * @param indexEvent index event
+   * @throws MetaException
+   */
+  public void onAddIndex(AddIndexEvent indexEvent) throws MetaException {
+  }
+
+  /**
+   * @param indexEvent index event
+   * @throws MetaException
+   */
+  public void onDropIndex(DropIndexEvent indexEvent) throws MetaException {
+  }
+
+  /**
+   * @param indexEvent index event
+   * @throws MetaException
+   */
+  public void onAlterIndex(AlterIndexEvent indexEvent) throws MetaException {
+  }
+
+  /**
+   * @param fnEvent function event
+   * @throws MetaException
+   */
+  public void onCreateFunction (CreateFunctionEvent fnEvent) throws MetaException {
+  }
+
+  /**
+   * @param fnEvent function event
+   * @throws MetaException
+   */
+  public void onDropFunction (DropFunctionEvent fnEvent) throws MetaException {
+  }
+
+  /**
+   * This will be called when an insert is executed that does not cause a partition to be added.
+   * If an insert causes a partition to be added it will cause {@link #onAddPartition} to be
+   * called instead.
+   * @param insertEvent
+   * @throws MetaException
+   */
+  public void onInsert(InsertEvent insertEvent) throws MetaException {
+
+  }
+
+  /**
+   * @param addPrimaryKeyEvent add primary key event
+   * @throws MetaException
+   */
+  public void onAddPrimaryKey(AddPrimaryKeyEvent addPrimaryKeyEvent) throws MetaException {
+  }
+
+  /**
+   * @param addForeignKeyEvent add foreign key event
+   * @throws MetaException
+   */
+  public void onAddForeignKey(AddForeignKeyEvent addForeignKeyEvent) throws MetaException {
+  }
+
+  /**
+   * @param addUniqueConstraintEvent add unique constraint event
+   * @throws MetaException
+   */
+  public void onAddUniqueConstraint(AddUniqueConstraintEvent addUniqueConstraintEvent) throws MetaException {
+  }
+
+  /**
+   * @param addNotNullConstraintEvent add not null constraint event
+   * @throws MetaException
+   */
+  public void onAddNotNullConstraint(AddNotNullConstraintEvent addNotNullConstraintEvent) throws MetaException {
+  }
+
+  /**
+   * @param dropConstraintEvent drop constraint event
+   * @throws MetaException
+   */
+  public void onDropConstraint(DropConstraintEvent dropConstraintEvent) throws MetaException {
+  }
+
+  @Override
+  public Configuration getConf() {
+    return this.conf;
+  }
+
+  @Override
+  public void setConf(Configuration config) {
+    this.conf = config;
+  }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListenerConstants.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListenerConstants.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListenerConstants.java
new file mode 100644
index 0000000..0b3de49
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreEventListenerConstants.java
@@ -0,0 +1,41 @@
+/*
+ * 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.hadoop.hive.metastore;
+
+/**
+ * Keeps a list of reserved keys used by Hive listeners when updating the ListenerEvent
+ * parameters.
+ */
+public class MetaStoreEventListenerConstants {
+  /*
+   * DbNotificationListener keys reserved for updating ListenerEvent parameters.
+   *
+   * DB_NOTIFICATION_EVENT_ID_KEY_NAME This key will have the event identifier that DbNotificationListener
+   *                                   processed during an event. This event identifier might be shared
+   *                                   across other MetaStoreEventListener implementations.
+   */
+  public static final String DB_NOTIFICATION_EVENT_ID_KEY_NAME = "DB_NOTIFICATION_EVENT_ID_KEY_NAME";
+
+  /*
+   * HiveMetaStore keys reserved for updating ListenerEvent parameters.
+   *
+   * HIVE_METASTORE_TRANSACTION_ACTIVE This key is used to check if a listener event is run inside a current
+   *                                   transaction. A boolean value is used for active (true) or no active (false).
+   */
+  public static final String HIVE_METASTORE_TRANSACTION_ACTIVE = "HIVE_METASTORE_TRANSACTION_ACTIVE";
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitContext.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitContext.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitContext.java
new file mode 100644
index 0000000..0968f42
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitContext.java
@@ -0,0 +1,27 @@
+/*
+ * 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.hadoop.hive.metastore;
+
+/**
+ * Base class which provides context to implementations of MetaStoreInitListener
+ */
+
+public class MetaStoreInitContext {
+
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitListener.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitListener.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitListener.java
new file mode 100644
index 0000000..12130ea
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreInitListener.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.hadoop.hive.metastore;
+
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+
+/**
+ * This abstract class needs to be extended to  provide implementation of actions
+ * that needs to be performed when HMSHandler is initialized
+ */
+
+public abstract class MetaStoreInitListener implements Configurable {
+
+  private Configuration conf;
+
+  public MetaStoreInitListener(Configuration config){
+    this.conf = config;
+  }
+
+  public abstract void onInit(MetaStoreInitContext context) throws MetaException;
+
+  @Override
+  public Configuration getConf() {
+    return this.conf;
+  }
+
+  @Override
+  public void setConf(Configuration config) {
+    this.conf = config;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreListenerNotifier.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreListenerNotifier.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreListenerNotifier.java
new file mode 100644
index 0000000..f6e25c6
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreListenerNotifier.java
@@ -0,0 +1,266 @@
+/*
+ * 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.hadoop.hive.metastore;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.hive.metastore.api.EnvironmentContext;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.events.AddForeignKeyEvent;
+import org.apache.hadoop.hive.metastore.events.AddIndexEvent;
+import org.apache.hadoop.hive.metastore.events.AddNotNullConstraintEvent;
+import org.apache.hadoop.hive.metastore.events.AddPartitionEvent;
+import org.apache.hadoop.hive.metastore.events.AddPrimaryKeyEvent;
+import org.apache.hadoop.hive.metastore.events.AddUniqueConstraintEvent;
+import org.apache.hadoop.hive.metastore.events.AlterIndexEvent;
+import org.apache.hadoop.hive.metastore.events.AlterPartitionEvent;
+import org.apache.hadoop.hive.metastore.events.AlterTableEvent;
+import org.apache.hadoop.hive.metastore.events.CreateDatabaseEvent;
+import org.apache.hadoop.hive.metastore.events.CreateFunctionEvent;
+import org.apache.hadoop.hive.metastore.events.CreateTableEvent;
+import org.apache.hadoop.hive.metastore.events.DropDatabaseEvent;
+import org.apache.hadoop.hive.metastore.events.DropFunctionEvent;
+import org.apache.hadoop.hive.metastore.events.DropIndexEvent;
+import org.apache.hadoop.hive.metastore.events.DropPartitionEvent;
+import org.apache.hadoop.hive.metastore.events.DropTableEvent;
+import org.apache.hadoop.hive.metastore.events.InsertEvent;
+import org.apache.hadoop.hive.metastore.events.ListenerEvent;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.hadoop.hive.metastore.MetaStoreEventListenerConstants.HIVE_METASTORE_TRANSACTION_ACTIVE;
+import static org.apache.hadoop.hive.metastore.messaging.EventMessage.EventType;
+
+/**
+ * This class is used to notify a list of listeners about specific MetaStore events.
+ */
+@InterfaceAudience.Private
+public class MetaStoreListenerNotifier {
+
+  private interface EventNotifier {
+    void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException;
+  }
+
+  private static Map<EventType, EventNotifier> notificationEvents = Maps.newHashMap(
+      ImmutableMap.<EventType, EventNotifier>builder()
+          .put(EventType.CREATE_DATABASE, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onCreateDatabase((CreateDatabaseEvent)event);
+            }
+          })
+          .put(EventType.DROP_DATABASE, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onDropDatabase((DropDatabaseEvent)event);
+            }
+          })
+          .put(EventType.CREATE_TABLE, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onCreateTable((CreateTableEvent)event);
+            }
+          })
+          .put(EventType.DROP_TABLE, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onDropTable((DropTableEvent)event);
+            }
+          })
+          .put(EventType.ADD_PARTITION, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAddPartition((AddPartitionEvent)event);
+            }
+          })
+          .put(EventType.DROP_PARTITION, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onDropPartition((DropPartitionEvent)event);
+            }
+          })
+          .put(EventType.ALTER_TABLE, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAlterTable((AlterTableEvent)event);
+            }
+          })
+          .put(EventType.ALTER_PARTITION, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAlterPartition((AlterPartitionEvent)event);
+            }
+          })
+          .put(EventType.INSERT, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onInsert((InsertEvent)event);
+            }
+          })
+          .put(EventType.CREATE_FUNCTION, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onCreateFunction((CreateFunctionEvent)event);
+            }
+          })
+          .put(EventType.DROP_FUNCTION, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onDropFunction((DropFunctionEvent)event);
+            }
+          })
+          .put(EventType.CREATE_INDEX, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAddIndex((AddIndexEvent)event);
+            }
+          })
+          .put(EventType.DROP_INDEX, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onDropIndex((DropIndexEvent)event);
+            }
+          })
+          .put(EventType.ALTER_INDEX, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAlterIndex((AlterIndexEvent)event);
+            }
+          })
+          .put(EventType.ADD_PRIMARYKEY, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAddPrimaryKey((AddPrimaryKeyEvent)event);
+            }
+          })
+          .put(EventType.ADD_FOREIGNKEY, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAddForeignKey((AddForeignKeyEvent)event);
+            }
+          })
+          .put(EventType.ADD_UNIQUECONSTRAINT, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAddUniqueConstraint((AddUniqueConstraintEvent)event);
+            }
+          })
+          .put(EventType.ADD_NOTNULLCONSTRAINT, new EventNotifier() {
+            @Override
+            public void notify(MetaStoreEventListener listener, ListenerEvent event) throws MetaException {
+              listener.onAddNotNullConstraint((AddNotNullConstraintEvent)event);
+            }
+          })
+          .build()
+  );
+
+  /**
+   * Notify a list of listeners about a specific metastore event. Each listener notified might update
+   * the (ListenerEvent) event by setting a parameter key/value pair. These updated parameters will
+   * be returned to the caller.
+   *
+   * @param listeners List of MetaStoreEventListener listeners.
+   * @param eventType Type of the notification event.
+   * @param event The ListenerEvent with information about the event.
+   * @return A list of key/value pair parameters that the listeners set. The returned object will return an empty
+   *         map if no parameters were updated or if no listeners were notified.
+   * @throws MetaException If an error occurred while calling the listeners.
+   */
+  public static Map<String, String> notifyEvent(List<? extends MetaStoreEventListener> listeners,
+                                                EventType eventType,
+                                                ListenerEvent event) throws MetaException {
+
+    Preconditions.checkNotNull(listeners, "Listeners must not be null.");
+    Preconditions.checkNotNull(event, "The event must not be null.");
+
+    for (MetaStoreEventListener listener : listeners) {
+        notificationEvents.get(eventType).notify(listener, event);
+    }
+
+    // Each listener called above might set a different parameter on the event.
+    // This write permission is allowed on the listener side to avoid breaking compatibility if we change the API
+    // method calls.
+    return event.getParameters();
+  }
+
+  /**
+   * Notify a list of listeners about a specific metastore event. Each listener notified might update
+   * the (ListenerEvent) event by setting a parameter key/value pair. These updated parameters will
+   * be returned to the caller.
+   *
+   * @param listeners List of MetaStoreEventListener listeners.
+   * @param eventType Type of the notification event.
+   * @param event The ListenerEvent with information about the event.
+   * @param environmentContext An EnvironmentContext object with parameters sent by the HMS client.
+   * @return A list of key/value pair parameters that the listeners set. The returned object will return an empty
+   *         map if no parameters were updated or if no listeners were notified.
+   * @throws MetaException If an error occurred while calling the listeners.
+   */
+  public static Map<String, String> notifyEvent(List<? extends MetaStoreEventListener> listeners,
+                                                EventType eventType,
+                                                ListenerEvent event,
+                                                EnvironmentContext environmentContext) throws MetaException {
+
+    Preconditions.checkNotNull(event, "The event must not be null.");
+
+    event.setEnvironmentContext(environmentContext);
+    return notifyEvent(listeners, eventType, event);
+  }
+
+  /**
+   * Notify a list of listeners about a specific metastore event. Each listener notified might update
+   * the (ListenerEvent) event by setting a parameter key/value pair. These updated parameters will
+   * be returned to the caller.
+   *
+   * Sometimes these events are run inside a DB transaction and might cause issues with the listeners,
+   * for instance, Sentry blocks the HMS until an event is seen committed on the DB. To notify the listener about this,
+   * a new parameter to verify if a transaction is active is added to the ListenerEvent, and is up to the listener
+   * to skip this notification if so.
+   *
+   * @param listeners List of MetaStoreEventListener listeners.
+   * @param eventType Type of the notification event.
+   * @param event The ListenerEvent with information about the event.
+   * @param environmentContext An EnvironmentContext object with parameters sent by the HMS client.
+   * @param parameters A list of key/value pairs with the new parameters to add.
+   * @param ms The RawStore object from where to check if a transaction is active.
+   * @return A list of key/value pair parameters that the listeners set. The returned object will return an empty
+   *         map if no parameters were updated or if no listeners were notified.
+   * @throws MetaException If an error occurred while calling the listeners.
+   */
+  public static Map<String, String> notifyEvent(List<? extends MetaStoreEventListener> listeners,
+                                                EventType eventType,
+                                                ListenerEvent event,
+                                                EnvironmentContext environmentContext,
+                                                Map<String, String> parameters,
+                                                final RawStore ms) throws MetaException {
+
+    Preconditions.checkNotNull(event, "The event must not be null.");
+
+    event.putParameters(parameters);
+
+    if (ms != null) {
+      event.putParameter(HIVE_METASTORE_TRANSACTION_ACTIVE, Boolean.toString(ms.isActiveTransaction()));
+    }
+
+    return notifyEvent(listeners, eventType, event, environmentContext);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStorePreEventListener.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStorePreEventListener.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStorePreEventListener.java
new file mode 100644
index 0000000..a757dff
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/MetaStorePreEventListener.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.InvalidOperationException;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.apache.hadoop.hive.metastore.events.PreEventContext;
+
+/**
+ * This abstract class needs to be extended to  provide implementation of actions that needs
+ * to be performed before a particular event occurs on a metastore. These methods
+ * are called before an event occurs on metastore.
+ */
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public abstract class MetaStorePreEventListener implements Configurable {
+
+  private Configuration conf;
+
+  public MetaStorePreEventListener(Configuration config){
+    this.conf = config;
+  }
+
+  public abstract void onEvent(PreEventContext context)
+      throws MetaException, NoSuchObjectException, InvalidOperationException;
+
+  @Override
+  public Configuration getConf() {
+    return this.conf;
+  }
+
+  @Override
+  public void setConf(Configuration config) {
+    this.conf = config;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RetryingHMSHandler.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RetryingHMSHandler.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RetryingHMSHandler.java
new file mode 100644
index 0000000..559ff34
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RetryingHMSHandler.java
@@ -0,0 +1,232 @@
+/*
+ * 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.hadoop.hive.metastore;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars;
+import org.apache.hadoop.hive.metastore.metrics.PerfLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.datanucleus.exceptions.NucleusException;
+
+@InterfaceAudience.Private
+@InterfaceStability.Evolving
+public class RetryingHMSHandler implements InvocationHandler {
+
+  private static final Logger LOG = LoggerFactory.getLogger(RetryingHMSHandler.class);
+  private static final String CLASS_NAME = RetryingHMSHandler.class.getName();
+
+  private static class Result {
+    private final Object result;
+    private final int numRetries;
+
+    public Result(Object result, int numRetries) {
+      this.result = result;
+      this.numRetries = numRetries;
+    }
+  }
+
+  private final IHMSHandler baseHandler;
+  private final MetaStoreInit.MetaStoreInitData metaStoreInitData =
+    new MetaStoreInit.MetaStoreInitData();
+
+  private final Configuration origConf;            // base configuration
+  private final Configuration activeConf;  // active configuration
+
+  private RetryingHMSHandler(Configuration origConf, IHMSHandler baseHandler, boolean local) throws MetaException {
+    this.origConf = origConf;
+    this.baseHandler = baseHandler;
+    if (local) {
+      baseHandler.setConf(origConf); // tests expect configuration changes applied directly to metastore
+    }
+    activeConf = baseHandler.getConf();
+    // This has to be called before initializing the instance of HMSHandler
+    // Using the hook on startup ensures that the hook always has priority
+    // over settings in *.xml.  The thread local conf needs to be used because at this point
+    // it has already been initialized using hiveConf.
+    MetaStoreInit.updateConnectionURL(origConf, getActiveConf(), null, metaStoreInitData);
+    try {
+      //invoking init method of baseHandler this way since it adds the retry logic
+      //in case of transient failures in init method
+      invoke(baseHandler, baseHandler.getClass().getDeclaredMethod("init", (Class<?>[]) null),
+          null);
+    } catch (Throwable e) {
+      LOG.error("HMSHandler Fatal error: " + ExceptionUtils.getStackTrace(e));
+      MetaException me = new MetaException(e.getMessage());
+      me.initCause(e);
+      throw me;
+    }
+  }
+
+  public static IHMSHandler getProxy(Configuration conf, IHMSHandler baseHandler, boolean local)
+      throws MetaException {
+
+    RetryingHMSHandler handler = new RetryingHMSHandler(conf, baseHandler, local);
+
+    return (IHMSHandler) Proxy.newProxyInstance(
+      RetryingHMSHandler.class.getClassLoader(),
+      new Class[] { IHMSHandler.class }, handler);
+  }
+
+  @Override
+  public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+    int retryCount = -1;
+    int threadId = baseHandler.getThreadId();
+    boolean error = true;
+    PerfLogger perfLogger = PerfLogger.getPerfLogger(false);
+    perfLogger.PerfLogBegin(CLASS_NAME, method.getName());
+    try {
+      Result result = invokeInternal(proxy, method, args);
+      retryCount = result.numRetries;
+      error = false;
+      return result.result;
+    } finally {
+      StringBuilder additionalInfo = new StringBuilder();
+      additionalInfo.append("threadId=").append(threadId).append(" retryCount=").append(retryCount)
+        .append(" error=").append(error);
+      perfLogger.PerfLogEnd(CLASS_NAME, method.getName(), additionalInfo.toString());
+    }
+  }
+
+  public Result invokeInternal(final Object proxy, final Method method, final Object[] args) throws Throwable {
+
+    boolean gotNewConnectUrl = false;
+    boolean reloadConf = MetastoreConf.getBoolVar(origConf, ConfVars.HMSHANDLERFORCERELOADCONF);
+    long retryInterval = MetastoreConf.getTimeVar(origConf,
+        ConfVars.HMSHANDLERINTERVAL, TimeUnit.MILLISECONDS);
+    int retryLimit = MetastoreConf.getIntVar(origConf, ConfVars.HMSHANDLERATTEMPTS);
+    long timeout = MetastoreConf.getTimeVar(origConf,
+        ConfVars.CLIENT_SOCKET_TIMEOUT, TimeUnit.MILLISECONDS);
+
+    Deadline.registerIfNot(timeout);
+
+    if (reloadConf) {
+      MetaStoreInit.updateConnectionURL(origConf, getActiveConf(),
+        null, metaStoreInitData);
+    }
+
+    int retryCount = 0;
+    Throwable caughtException = null;
+    while (true) {
+      try {
+        if (reloadConf || gotNewConnectUrl) {
+          baseHandler.setConf(getActiveConf());
+        }
+        Object object = null;
+        boolean isStarted = Deadline.startTimer(method.getName());
+        try {
+          object = method.invoke(baseHandler, args);
+        } finally {
+          if (isStarted) {
+            Deadline.stopTimer();
+          }
+        }
+        return new Result(object, retryCount);
+
+      } catch (UndeclaredThrowableException e) {
+        if (e.getCause() != null) {
+          if (e.getCause() instanceof javax.jdo.JDOException) {
+            // Due to reflection, the jdo exception is wrapped in
+            // invocationTargetException
+            caughtException = e.getCause();
+          } else if (e.getCause() instanceof MetaException && e.getCause().getCause() != null
+              && e.getCause().getCause() instanceof javax.jdo.JDOException) {
+            // The JDOException may be wrapped further in a MetaException
+            caughtException = e.getCause().getCause();
+          } else {
+            LOG.error(ExceptionUtils.getStackTrace(e.getCause()));
+            throw e.getCause();
+          }
+        } else {
+          LOG.error(ExceptionUtils.getStackTrace(e));
+          throw e;
+        }
+      } catch (InvocationTargetException e) {
+        if (e.getCause() instanceof javax.jdo.JDOException) {
+          // Due to reflection, the jdo exception is wrapped in
+          // invocationTargetException
+          caughtException = e.getCause();
+        } else if (e.getCause() instanceof NoSuchObjectException || e.getTargetException().getCause() instanceof NoSuchObjectException) {
+          String methodName = method.getName();
+          if (!methodName.startsWith("get_database") && !methodName.startsWith("get_table")
+              && !methodName.startsWith("get_partition") && !methodName.startsWith("get_function")) {
+            LOG.error(ExceptionUtils.getStackTrace(e.getCause()));
+          }
+          throw e.getCause();
+        } else if (e.getCause() instanceof MetaException && e.getCause().getCause() != null) {
+          if (e.getCause().getCause() instanceof javax.jdo.JDOException ||
+              e.getCause().getCause() instanceof NucleusException) {
+            // The JDOException or the Nucleus Exception may be wrapped further in a MetaException
+            caughtException = e.getCause().getCause();
+          } else if (e.getCause().getCause() instanceof DeadlineException) {
+            // The Deadline Exception needs no retry and be thrown immediately.
+            Deadline.clear();
+            LOG.error("Error happens in method " + method.getName() + ": " +
+                ExceptionUtils.getStackTrace(e.getCause()));
+            throw e.getCause();
+          } else {
+            LOG.error(ExceptionUtils.getStackTrace(e.getCause()));
+            throw e.getCause();
+          }
+        } else {
+          LOG.error(ExceptionUtils.getStackTrace(e.getCause()));
+          throw e.getCause();
+        }
+      }
+
+      if (retryCount >= retryLimit) {
+        LOG.error("HMSHandler Fatal error: " + ExceptionUtils.getStackTrace(caughtException));
+        MetaException me = new MetaException(caughtException.getMessage());
+        me.initCause(caughtException);
+        throw me;
+      }
+
+      assert (retryInterval >= 0);
+      retryCount++;
+      LOG.error(
+        String.format(
+          "Retrying HMSHandler after %d ms (attempt %d of %d)", retryInterval, retryCount, retryLimit) +
+          " with error: " + ExceptionUtils.getStackTrace(caughtException));
+
+      Thread.sleep(retryInterval);
+      // If we have a connection error, the JDO connection URL hook might
+      // provide us with a new URL to access the datastore.
+      String lastUrl = MetaStoreInit.getConnectionURL(getActiveConf());
+      gotNewConnectUrl = MetaStoreInit.updateConnectionURL(origConf, getActiveConf(),
+        lastUrl, metaStoreInitData);
+    }
+  }
+
+  public Configuration getActiveConf() {
+    return activeConf;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/SessionPropertiesListener.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/SessionPropertiesListener.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/SessionPropertiesListener.java
new file mode 100644
index 0000000..af4f0f2
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/SessionPropertiesListener.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
+import org.apache.hadoop.hive.metastore.events.ConfigChangeEvent;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * It handles the changed properties in the change event.
+ */
+public class SessionPropertiesListener extends MetaStoreEventListener {
+
+  public SessionPropertiesListener(Configuration configuration) {
+    super(configuration);
+  }
+
+  @Override
+  public void onConfigChange(ConfigChangeEvent changeEvent) throws MetaException {
+    if (changeEvent.getKey().equals(MetastoreConf.ConfVars.CLIENT_SOCKET_TIMEOUT.getVarname()) ||
+        changeEvent.getKey().equals(MetastoreConf.ConfVars.CLIENT_SOCKET_TIMEOUT.getHiveName())) {
+      // TODO: this only applies to current thread, so it's not useful at all.
+      Deadline.resetTimeout(MetastoreConf.convertTimeStr(changeEvent.getNewValue(), TimeUnit.SECONDS,
+          TimeUnit.MILLISECONDS));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalMetaStoreEventListener.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalMetaStoreEventListener.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalMetaStoreEventListener.java
new file mode 100644
index 0000000..b6a67ac
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalMetaStoreEventListener.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore;
+
+import org.apache.hadoop.conf.Configuration;
+
+/**
+ * Special type of MetaStoreEventListener which should only be called in a transactional context
+ * and only if the transaction is successful.
+ * The events are expected to have a success status.
+ */
+public abstract class TransactionalMetaStoreEventListener extends MetaStoreEventListener {
+
+  /**
+   * Constructor
+   *
+   * @param config configuration object
+   */
+  public TransactionalMetaStoreEventListener(Configuration config) {
+    super(config);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
new file mode 100644
index 0000000..f7962a4
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/TransactionalValidationListener.java
@@ -0,0 +1,360 @@
+/*
+ * 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.hadoop.hive.metastore;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LocatedFileStatus;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.RemoteIterator;
+import org.apache.hadoop.hive.metastore.api.InvalidOperationException;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
+import org.apache.hadoop.hive.metastore.events.PreAlterTableEvent;
+import org.apache.hadoop.hive.metastore.events.PreCreateTableEvent;
+import org.apache.hadoop.hive.metastore.events.PreEventContext;
+import org.apache.hadoop.hive.metastore.utils.MetaStoreUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class TransactionalValidationListener extends MetaStorePreEventListener {
+  public static final Logger LOG = LoggerFactory.getLogger(TransactionalValidationListener.class);
+
+  // These constants are also imported by org.apache.hadoop.hive.ql.io.AcidUtils.
+  public static final String DEFAULT_TRANSACTIONAL_PROPERTY = "default";
+  public static final String INSERTONLY_TRANSACTIONAL_PROPERTY = "insert_only";
+
+  TransactionalValidationListener(Configuration conf) {
+    super(conf);
+  }
+
+  @Override
+  public void onEvent(PreEventContext context) throws MetaException, NoSuchObjectException,
+      InvalidOperationException {
+    switch (context.getEventType()) {
+      case CREATE_TABLE:
+        handle((PreCreateTableEvent) context);
+        break;
+      case ALTER_TABLE:
+        handle((PreAlterTableEvent) context);
+        break;
+      default:
+        //no validation required..
+    }
+  }
+
+  private void handle(PreAlterTableEvent context) throws MetaException {
+    handleAlterTableTransactionalProp(context);
+  }
+
+  private void handle(PreCreateTableEvent context) throws MetaException {
+    handleCreateTableTransactionalProp(context);
+  }
+
+  /**
+   * once a table is marked transactional, you cannot go back.  Enforce this.
+   * Also in current version, 'transactional_properties' of the table cannot be altered after
+   * the table is created. Any attempt to alter it will throw a MetaException.
+   */
+  private void handleAlterTableTransactionalProp(PreAlterTableEvent context) throws MetaException {
+    Table newTable = context.getNewTable();
+    Map<String, String> parameters = newTable.getParameters();
+    if (parameters == null || parameters.isEmpty()) {
+      return;
+    }
+    Set<String> keys = new HashSet<>(parameters.keySet());
+    String transactionalValue = null;
+    boolean transactionalValuePresent = false;
+    boolean isTransactionalPropertiesPresent = false;
+    String transactionalPropertiesValue = null;
+    boolean hasValidTransactionalValue = false;
+
+    for (String key : keys) {
+      if(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.equalsIgnoreCase(key)) {
+        transactionalValuePresent = true;
+        transactionalValue = parameters.get(key);
+        parameters.remove(key);
+      }
+      if(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES.equalsIgnoreCase(key)) {
+        isTransactionalPropertiesPresent = true;
+        transactionalPropertiesValue = parameters.get(key);
+        // Do not remove the parameter yet, because we have separate initialization routine
+        // that will use it down below.
+      }
+    }
+    Table oldTable = context.getOldTable();
+    String oldTransactionalValue = null;
+    String oldTransactionalPropertiesValue = null;
+    for (String key : oldTable.getParameters().keySet()) {
+      if (hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.equalsIgnoreCase(key)) {
+        oldTransactionalValue = oldTable.getParameters().get(key);
+      }
+      if (hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES.equalsIgnoreCase(key)) {
+        oldTransactionalPropertiesValue = oldTable.getParameters().get(key);
+      }
+    }
+
+    if (transactionalValuePresent) {
+      //normalize prop name
+      parameters.put(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL, transactionalValue);
+    }
+    if ("true".equalsIgnoreCase(transactionalValue) && !"true".equalsIgnoreCase(oldTransactionalValue)) {
+      //only need to check conformance if alter table enabled aicd
+      if (!conformToAcid(newTable)) {
+        // INSERT_ONLY tables don't have to conform to ACID requirement like ORC or bucketing
+        if (transactionalPropertiesValue == null || !"insert_only".equalsIgnoreCase(transactionalPropertiesValue)) {
+          throw new MetaException("The table must be stored using an ACID compliant format (such as ORC)");
+        }
+      }
+
+      if (newTable.getTableType().equals(TableType.EXTERNAL_TABLE.toString())) {
+        throw new MetaException(getTableName(newTable) +
+            " cannot be declared transactional because it's an external table");
+      }
+      validateTableStructure(context.getHandler(), newTable);
+      hasValidTransactionalValue = true;
+    }
+
+
+
+    if (oldTransactionalValue == null ? transactionalValue == null
+                                     : oldTransactionalValue.equalsIgnoreCase(transactionalValue)) {
+      //this covers backward compat cases where this prop may have been set already
+      hasValidTransactionalValue = true;
+    }
+
+    if (!hasValidTransactionalValue && !MetaStoreUtils.isInsertOnlyTableParam(oldTable.getParameters())) {
+      // if here, there is attempt to set transactional to something other than 'true'
+      // and NOT the same value it was before
+      throw new MetaException("TBLPROPERTIES with 'transactional'='true' cannot be unset");
+    }
+
+    if (isTransactionalPropertiesPresent) {
+      // Now validate transactional_properties for the table.
+      if (oldTransactionalValue == null) {
+        // If this is the first time the table is being initialized to 'transactional=true',
+        // any valid value can be set for the 'transactional_properties'.
+        initializeTransactionalProperties(newTable);
+      } else {
+        // If the table was already marked as 'transactional=true', then the new value of
+        // 'transactional_properties' must match the old value. Any attempt to alter the previous
+        // value will throw an error. An exception will still be thrown if the previous value was
+        // null and an attempt is made to set it. This behaviour can be changed in the future.
+        if ((oldTransactionalPropertiesValue == null
+            || !oldTransactionalPropertiesValue.equalsIgnoreCase(transactionalPropertiesValue))
+            && !MetaStoreUtils.isInsertOnlyTableParam(oldTable.getParameters())) {
+          throw new MetaException("TBLPROPERTIES with 'transactional_properties' cannot be "
+              + "altered after the table is created");
+        }
+      }
+    }
+  }
+
+  /**
+   * Normalize case and make sure:
+   * 1. 'true' is the only value to be set for 'transactional' (if set at all)
+   * 2. If set to 'true', we should also enforce bucketing and ORC format
+   */
+  private void handleCreateTableTransactionalProp(PreCreateTableEvent context) throws MetaException {
+    Table newTable = context.getTable();
+    Map<String, String> parameters = newTable.getParameters();
+    if (parameters == null || parameters.isEmpty()) {
+      return;
+    }
+    String transactional = null;
+    String transactionalProperties = null;
+    Set<String> keys = new HashSet<>(parameters.keySet());
+    for(String key : keys) {
+      // Get the "transactional" tblproperties value
+      if (hive_metastoreConstants.TABLE_IS_TRANSACTIONAL.equalsIgnoreCase(key)) {
+        transactional = parameters.get(key);
+        parameters.remove(key);
+      }
+
+      // Get the "transactional_properties" tblproperties value
+      if (hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES.equalsIgnoreCase(key)) {
+        transactionalProperties = parameters.get(key);
+      }
+    }
+
+    if (transactional == null) {
+      return;
+    }
+
+    if ("false".equalsIgnoreCase(transactional)) {
+      // just drop transactional=false.  For backward compatibility in case someone has scripts
+      // with transactional=false
+      LOG.info("'transactional'='false' is no longer a valid property and will be ignored");
+      return;
+    }
+
+    if ("true".equalsIgnoreCase(transactional)) {
+      if (!conformToAcid(newTable)) {
+        // INSERT_ONLY tables don't have to conform to ACID requirement like ORC or bucketing
+        if (transactionalProperties == null || !"insert_only".equalsIgnoreCase(transactionalProperties)) {
+          throw new MetaException("The table must be stored using an ACID compliant format (such as ORC)");
+        }
+      }
+
+      if (newTable.getTableType().equals(TableType.EXTERNAL_TABLE.toString())) {
+        throw new MetaException(newTable.getDbName() + "." + newTable.getTableName() +
+            " cannot be declared transactional because it's an external table");
+      }
+
+      // normalize prop name
+      parameters.put(hive_metastoreConstants.TABLE_IS_TRANSACTIONAL, Boolean.TRUE.toString());
+      initializeTransactionalProperties(newTable);
+      return;
+    }
+
+    // transactional is found, but the value is not in expected range
+    throw new MetaException("'transactional' property of TBLPROPERTIES may only have value 'true'");
+  }
+
+  /**
+   * Check that InputFormatClass/OutputFormatClass should implement
+   * AcidInputFormat/AcidOutputFormat
+   */
+  private boolean conformToAcid(Table table) throws MetaException {
+    StorageDescriptor sd = table.getSd();
+    try {
+      Class inputFormatClass = Class.forName(sd.getInputFormat());
+      Class outputFormatClass = Class.forName(sd.getOutputFormat());
+
+      if (inputFormatClass == null || outputFormatClass == null ||
+          !Class.forName("org.apache.hadoop.hive.ql.io.AcidInputFormat").isAssignableFrom(inputFormatClass) ||
+          !Class.forName("org.apache.hadoop.hive.ql.io.AcidOutputFormat").isAssignableFrom(outputFormatClass)) {
+        return false;
+      }
+    } catch (ClassNotFoundException e) {
+      throw new MetaException("Invalid input/output format for table");
+    }
+
+    return true;
+  }
+
+  private void initializeTransactionalProperties(Table table) throws MetaException {
+    // All new versions of Acid tables created after the introduction of Acid version/type system
+    // can have TRANSACTIONAL_PROPERTIES property defined. This parameter can be used to change
+    // the operational behavior of ACID. However if this parameter is not defined, the new Acid
+    // tables will still behave as the old ones. This is done so to preserve the behavior
+    // in case of rolling downgrade.
+
+    // Initialize transaction table properties with default string value.
+    String tableTransactionalProperties = null;
+
+    Map<String, String> parameters = table.getParameters();
+    if (parameters != null) {
+      Set<String> keys = parameters.keySet();
+      for (String key : keys) {
+        if (hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES.equalsIgnoreCase(key)) {
+          tableTransactionalProperties = parameters.get(key).toLowerCase();
+          parameters.remove(key);
+          String validationError = validateTransactionalProperties(tableTransactionalProperties);
+          if (validationError != null) {
+            throw new MetaException("Invalid transactional properties specified for the "
+                + "table with the error " + validationError);
+          }
+          break;
+        }
+      }
+    }
+
+    if (tableTransactionalProperties != null) {
+      parameters.put(hive_metastoreConstants.TABLE_TRANSACTIONAL_PROPERTIES,
+              tableTransactionalProperties);
+    }
+  }
+
+  private String validateTransactionalProperties(String transactionalProperties) {
+    boolean isValid = false;
+    switch (transactionalProperties) {
+      case DEFAULT_TRANSACTIONAL_PROPERTY:
+      case INSERTONLY_TRANSACTIONAL_PROPERTY:
+        isValid = true;
+        break;
+      default:
+        isValid = false;
+    }
+    if (!isValid) {
+      return "unknown value " + transactionalProperties +  " for transactional_properties";
+    }
+    return null; // All checks passed, return null.
+  }
+  private final Pattern ORIGINAL_PATTERN = Pattern.compile("[0-9]+_[0-9]+");
+  /**
+   * @see org.apache.hadoop.hive.ql.exec.Utilities#COPY_KEYWORD
+   */
+  private static final Pattern ORIGINAL_PATTERN_COPY =
+    Pattern.compile("[0-9]+_[0-9]+" + "_copy_" + "[0-9]+");
+
+  /**
+   * It's assumed everywhere that original data files are named according to
+   * {@link #ORIGINAL_PATTERN} or{@link #ORIGINAL_PATTERN_COPY}
+   * This checks that when transaction=true is set and throws if it finds any files that don't
+   * follow convention.
+   */
+  private void validateTableStructure(IHMSHandler hmsHandler, Table table)
+    throws MetaException {
+    Path tablePath;
+    try {
+      Warehouse wh = hmsHandler.getWh();
+      if (table.getSd().getLocation() == null || table.getSd().getLocation().isEmpty()) {
+        tablePath = wh.getDefaultTablePath(hmsHandler.getMS().getDatabase(table.getDbName()),
+          table.getTableName());
+      } else {
+        tablePath = wh.getDnsPath(new Path(table.getSd().getLocation()));
+      }
+      FileSystem fs = wh.getFs(tablePath);
+      //FileSystem fs = FileSystem.get(getConf());
+      RemoteIterator<LocatedFileStatus> iterator = fs.listFiles(tablePath, true);
+      while (iterator.hasNext()) {
+        LocatedFileStatus fileStatus = iterator.next();
+        if (!fileStatus.isFile()) {
+          continue;
+        }
+        boolean validFile =
+          (ORIGINAL_PATTERN.matcher(fileStatus.getPath().getName()).matches() ||
+            ORIGINAL_PATTERN_COPY.matcher(fileStatus.getPath().getName()).matches()
+          );
+        if (!validFile) {
+          throw new IllegalStateException("Unexpected data file name format.  Cannot convert " +
+            getTableName(table) + " to transactional table.  File: " + fileStatus.getPath());
+        }
+      }
+    } catch (IOException|NoSuchObjectException e) {
+      String msg = "Unable to list files for " + getTableName(table);
+      LOG.error(msg, e);
+      MetaException e1 = new MetaException(msg);
+      e1.initCause(e);
+      throw e1;
+    }
+  }
+  private static String getTableName(Table table) {
+    return table.getDbName() + "." + table.getTableName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
index ac81912..f8ebc12 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java
@@ -166,6 +166,7 @@ public class MetastoreConf {
       ConfVars.AGGREGATE_STATS_CACHE_MAX_FULL,
       ConfVars.AGGREGATE_STATS_CACHE_CLEAN_UNTIL,
       ConfVars.DISALLOW_INCOMPATIBLE_COL_TYPE_CHANGES,
+      ConfVars.FILE_METADATA_THREADS
   };
 
   /**
@@ -446,6 +447,9 @@ public class MetastoreConf {
     EXPRESSION_PROXY_CLASS("metastore.expression.proxy", "hive.metastore.expression.proxy",
         "org.apache.hadoop.hive.ql.optimizer.ppr.PartitionExpressionForMetastore",
         "Class to use to process expressions in partition pruning."),
+    FILE_METADATA_THREADS("metastore.file.metadata.threads",
+        "hive.metastore.hbase.file.metadata.threads", 1,
+        "Number of threads to use to read file metadata in background to cache it."),
     FILTER_HOOK("metastore.filter.hook", "hive.metastore.filter.hook",
         "org.apache.hadoop.hive.metastore.DefaultMetaStoreFilterHookImpl",
         "Metastore hook class for filtering the metadata read results. If hive.security.authorization.manager"
@@ -501,6 +505,18 @@ public class MetastoreConf {
         "javax.jdo.PersistenceManagerFactoryClass",
         "org.datanucleus.api.jdo.JDOPersistenceManagerFactory",
         "class implementing the jdo persistence"),
+    // Parameters for exporting metadata on table drop (requires the use of the)
+    // org.apache.hadoop.hive.ql.parse.MetaDataExportListener preevent listener
+    METADATA_EXPORT_LOCATION("metastore.metadata.export.location", "hive.metadata.export.location",
+        "",
+        "When used in conjunction with the org.apache.hadoop.hive.ql.parse.MetaDataExportListener pre event listener, \n" +
+            "it is the location to which the metadata will be exported. The default is an empty string, which results in the \n" +
+            "metadata being exported to the current user's home directory on HDFS."),
+    MOVE_EXPORTED_METADATA_TO_TRASH("metastore.metadata.move.exported.metadata.to.trash",
+        "hive.metadata.move.exported.metadata.to.trash", true,
+        "When used in conjunction with the org.apache.hadoop.hive.ql.parse.MetaDataExportListener pre event listener, \n" +
+            "this setting determines if the metadata that is exported will subsequently be moved to the user's trash directory \n" +
+            "alongside the dropped table data. This ensures that the metadata will be cleaned up along with the dropped table data."),
     METRICS_ENABLED("metastore.metrics.enabled", "hive.metastore.metrics.enabled", false,
         "Enable metrics on the metastore."),
     METRICS_JSON_FILE_INTERVAL("metastore.metrics.file.frequency",

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddForeignKeyEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddForeignKeyEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddForeignKeyEvent.java
new file mode 100644
index 0000000..f9c951c
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddForeignKeyEvent.java
@@ -0,0 +1,41 @@
+/*
+ * 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.hadoop.hive.metastore.events;
+
+import java.util.List;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.SQLForeignKey;
+
+@InterfaceStability.Stable
+@InterfaceAudience.Public
+public class AddForeignKeyEvent extends ListenerEvent {
+  private final List<SQLForeignKey> fks;
+
+  public AddForeignKeyEvent(List<SQLForeignKey> fks, boolean status, IHMSHandler handler) {
+    super(status, handler);
+    this.fks = fks;
+  }
+
+  public List<SQLForeignKey> getForeignKeyCols() {
+    return fks;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddIndexEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddIndexEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddIndexEvent.java
new file mode 100644
index 0000000..0d6cb56
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddIndexEvent.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.Index;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AddIndexEvent extends ListenerEvent {
+
+  private final Index index;
+
+  public AddIndexEvent(Index index, boolean status, IHMSHandler handler) {
+    super(status, handler);
+    this.index = index;
+  }
+
+  public Index getIndex() {
+    return index;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddNotNullConstraintEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddNotNullConstraintEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddNotNullConstraintEvent.java
new file mode 100644
index 0000000..6b4cf0b
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddNotNullConstraintEvent.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import java.util.List;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.SQLNotNullConstraint;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AddNotNullConstraintEvent extends ListenerEvent {
+  private final List<SQLNotNullConstraint> nns;
+
+  public AddNotNullConstraintEvent(List<SQLNotNullConstraint> nns, boolean status,
+                                   IHMSHandler handler) {
+    super(status, handler);
+    this.nns = nns;
+  }
+
+  public List<SQLNotNullConstraint> getNotNullConstraintCols() {
+    return nns;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPartitionEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPartitionEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPartitionEvent.java
new file mode 100644
index 0000000..d4542d7
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPartitionEvent.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+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 java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AddPartitionEvent extends ListenerEvent {
+
+  private final Table table;
+  private final List<Partition> partitions;
+  private PartitionSpecProxy partitionSpecProxy;
+
+  public AddPartitionEvent(Table table, List<Partition> partitions, boolean status,
+                           IHMSHandler handler) {
+    super(status, handler);
+    this.table = table;
+    this.partitions = partitions;
+    this.partitionSpecProxy = null;
+  }
+
+  public AddPartitionEvent(Table table, Partition partition, boolean status, IHMSHandler handler) {
+    this(table, Arrays.asList(partition), status, handler);
+  }
+
+  /**
+   * Alternative constructor to use PartitionSpec APIs.
+   */
+  public AddPartitionEvent(Table table, PartitionSpecProxy partitionSpec, boolean status,
+                           IHMSHandler handler) {
+    super(status, handler);
+    this.table = table;
+    this.partitions = null;
+    this.partitionSpecProxy = partitionSpec;
+  }
+
+  /**
+   * @return The table.
+   */
+  public Table getTable() {
+    return table;
+  }
+
+
+  // Note : List<Partition> getPartitions() removed with HIVE-9609 because it will result in OOM errors with large add_partitions.
+
+  /**
+   * @return Iterator for partitions.
+   */
+  public Iterator<Partition> getPartitionIterator() {
+    if (partitions != null){
+      return partitions.iterator();
+    } else {
+      return partitionSpecProxy == null ? null : partitionSpecProxy.getPartitionIterator();
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPrimaryKeyEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPrimaryKeyEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPrimaryKeyEvent.java
new file mode 100644
index 0000000..de7978c
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddPrimaryKeyEvent.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import java.util.List;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.SQLPrimaryKey;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AddPrimaryKeyEvent extends ListenerEvent {
+
+  private final List<SQLPrimaryKey> pks;
+
+  public AddPrimaryKeyEvent(List<SQLPrimaryKey> pks, boolean status, IHMSHandler handler) {
+    super(status, handler);
+    this.pks = pks;
+  }
+
+  public List<SQLPrimaryKey> getPrimaryKeyCols() {
+    return pks;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddUniqueConstraintEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddUniqueConstraintEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddUniqueConstraintEvent.java
new file mode 100644
index 0000000..b677ee6
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AddUniqueConstraintEvent.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import java.util.List;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.SQLUniqueConstraint;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AddUniqueConstraintEvent extends ListenerEvent {
+  private final List<SQLUniqueConstraint> uks;
+
+  public AddUniqueConstraintEvent(List<SQLUniqueConstraint> uks, boolean status,
+                                  IHMSHandler handler) {
+    super(status, handler);
+    this.uks = uks;
+  }
+
+  public List<SQLUniqueConstraint> getUniqueConstraintCols() {
+    return uks;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterIndexEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterIndexEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterIndexEvent.java
new file mode 100644
index 0000000..2c72b83
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterIndexEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.Index;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AlterIndexEvent extends ListenerEvent {
+
+  private final Index newIndex;
+  private final Index oldIndex;
+
+  public AlterIndexEvent(Index oldIndex, Index newIndex, boolean status, IHMSHandler handler) {
+    super(status, handler);
+    this.oldIndex = oldIndex;
+    this.newIndex = newIndex;
+  }
+
+  public Index getOldIndex() {
+    return oldIndex;
+  }
+
+  public Index getNewIndex() {
+    return newIndex;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterPartitionEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterPartitionEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterPartitionEvent.java
new file mode 100644
index 0000000..09cad85
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterPartitionEvent.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.Partition;
+import org.apache.hadoop.hive.metastore.api.Table;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AlterPartitionEvent extends ListenerEvent {
+
+  private final Partition oldPart;
+  private final Partition newPart;
+  private final Table table;
+  private final boolean isTruncateOp;
+
+  public AlterPartitionEvent(Partition oldPart, Partition newPart, Table table, boolean isTruncateOp,
+                             boolean status, IHMSHandler handler) {
+    super(status, handler);
+    this.oldPart = oldPart;
+    this.newPart = newPart;
+    this.table = table;
+    this.isTruncateOp = isTruncateOp;
+  }
+
+  /**
+   * @return the old partition
+   */
+  public Partition getOldPartition() {
+    return oldPart;
+  }
+
+  /**
+   *
+   * @return the new partition
+   */
+  public Partition getNewPartition() {
+    return newPart;
+  }
+
+  /**
+   * Get the table this partition is in
+   * @return
+   */
+  public Table getTable() {
+    return table;
+  }
+
+  /**
+   * Get the truncate table flag
+   * @return
+   */
+  public boolean getIsTruncateOp() {
+    return isTruncateOp;
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c5a9673a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterTableEvent.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterTableEvent.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterTableEvent.java
new file mode 100644
index 0000000..2e3f6f0
--- /dev/null
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/events/AlterTableEvent.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.events;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+import org.apache.hadoop.hive.metastore.IHMSHandler;
+import org.apache.hadoop.hive.metastore.api.Table;
+
+@InterfaceAudience.Public
+@InterfaceStability.Stable
+public class AlterTableEvent extends ListenerEvent {
+
+  private final Table newTable;
+  private final Table oldTable;
+  private final boolean isTruncateOp;
+
+  public AlterTableEvent (Table oldTable, Table newTable, boolean isTruncateOp, boolean status,
+                          IHMSHandler handler) {
+    super (status, handler);
+    this.oldTable = oldTable;
+    this.newTable = newTable;
+    this.isTruncateOp = isTruncateOp;
+  }
+
+  /**
+   * @return the old table
+   */
+  public Table getOldTable() {
+    return oldTable;
+  }
+
+  /**
+   * @return the new table
+   */
+  public Table getNewTable() {
+    return newTable;
+  }
+
+  /**
+   * @return the flag for truncate
+   */
+  public boolean getIsTruncateOp() {
+    return isTruncateOp;
+  }
+}
\ No newline at end of file