Repository: hive
Updated Branches:
  refs/heads/master fedefeba6 -> b0d3cb452


HIVE-18635: Generalize hook dispatch logics in Driver (Zoltan Haindrich 
reviewed by Ashutosh Chauhan)

Signed-off-by: Zoltan Haindrich <k...@rxd.hu>


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

Branch: refs/heads/master
Commit: c96c6acf6e2ef04618e2c3cb36a28fa695ae07e3
Parents: fedefeb
Author: Zoltan Haindrich <k...@rxd.hu>
Authored: Wed Feb 14 09:17:31 2018 +0100
Committer: Zoltan Haindrich <k...@rxd.hu>
Committed: Wed Feb 14 09:17:31 2018 +0100

----------------------------------------------------------------------
 .../java/org/apache/hadoop/hive/ql/Driver.java  |  85 ++---
 .../org/apache/hadoop/hive/ql/HookRunner.java   | 323 +++++++++++++++++++
 .../hadoop/hive/ql/QueryLifeTimeHookRunner.java | 189 -----------
 .../apache/hadoop/hive/ql/hooks/HookUtils.java  |  27 +-
 .../hadoop/hive/ql/hooks/HooksLoader.java       | 110 -------
 .../hadoop/hive/ql/hooks/TestQueryHooks.java    |  32 +-
 .../results/clientnegative/bad_exec_hooks.q.out |   9 +-
 .../service/cli/session/SessionManager.java     |   4 +-
 8 files changed, 397 insertions(+), 382 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java 
b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
index 8f7291d..23b209e 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
@@ -39,6 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantLock;
 
 import com.google.common.annotations.VisibleForTesting;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.hadoop.conf.Configurable;
 import org.apache.hadoop.fs.FSDataInputStream;
@@ -71,11 +72,8 @@ import org.apache.hadoop.hive.ql.exec.TaskRunner;
 import org.apache.hadoop.hive.ql.exec.Utilities;
 import org.apache.hadoop.hive.ql.history.HiveHistory.Keys;
 import org.apache.hadoop.hive.ql.hooks.Entity;
-import org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext;
-import org.apache.hadoop.hive.ql.hooks.Hook;
 import org.apache.hadoop.hive.ql.hooks.HookContext;
 import org.apache.hadoop.hive.ql.hooks.HookUtils;
-import org.apache.hadoop.hive.ql.hooks.HooksLoader;
 import org.apache.hadoop.hive.ql.hooks.ReadEntity;
 import org.apache.hadoop.hive.ql.hooks.WriteEntity;
 import org.apache.hadoop.hive.ql.lockmgr.HiveLock;
@@ -95,7 +93,6 @@ import org.apache.hadoop.hive.ql.parse.ASTNode;
 import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer;
 import org.apache.hadoop.hive.ql.parse.ColumnAccessInfo;
 import org.apache.hadoop.hive.ql.parse.ExplainConfiguration.AnalyzeState;
-import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHook;
 import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
 import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContextImpl;
 import org.apache.hadoop.hive.ql.parse.ImportSemanticAnalyzer;
@@ -176,8 +173,7 @@ public class Driver implements IDriver {
   private final QueryState queryState;
 
   // Query hooks that execute before compilation and after execution
-  private QueryLifeTimeHookRunner queryLifeTimeHookRunner;
-  private final HooksLoader hooksLoader;
+  private HookRunner hookRunner;
 
   // Transaction manager the Driver has been initialized with (can be null).
   // If this is set then this Transaction manager will be used during query
@@ -397,25 +393,20 @@ public class Driver implements IDriver {
   }
 
   public Driver(QueryState queryState, String userName) {
-    this(queryState, userName, new HooksLoader(queryState.getConf()), null, 
null);
+    this(queryState, userName, null, null);
   }
 
   public Driver(QueryState queryState, String userName, QueryInfo queryInfo) {
-     this(queryState, userName, new HooksLoader(queryState.getConf()), 
queryInfo, null);
+    this(queryState, userName, queryInfo, null);
   }
 
   public Driver(QueryState queryState, String userName, QueryInfo queryInfo, 
HiveTxnManager txnMgr) {
-    this(queryState, userName, new HooksLoader(queryState.getConf()), 
queryInfo, txnMgr);
-  }
-
-  public Driver(QueryState queryState, String userName, HooksLoader 
hooksLoader, QueryInfo queryInfo, HiveTxnManager txnMgr) {
     this.queryState = queryState;
     this.conf = queryState.getConf();
     isParallelEnabled = (conf != null)
         && HiveConf.getBoolVar(conf, 
ConfVars.HIVE_SERVER2_PARALLEL_COMPILATION);
     this.userName = userName;
-    this.hooksLoader = hooksLoader;
-    this.queryLifeTimeHookRunner = new QueryLifeTimeHookRunner(conf, 
hooksLoader, console);
+    this.hookRunner = new HookRunner(conf, console);
     this.queryInfo = queryInfo;
     this.initTxnMgr = txnMgr;
   }
@@ -568,7 +559,7 @@ public class Driver implements IDriver {
       perfLogger.PerfLogBegin(CLASS_NAME, PerfLogger.PARSE);
 
       // Trigger query hook before compilation
-      queryLifeTimeHookRunner.runBeforeParseHook(command);
+      hookRunner.runBeforeParseHook(command);
 
       ASTNode tree;
       try {
@@ -577,16 +568,14 @@ public class Driver implements IDriver {
         parseError = true;
         throw e;
       } finally {
-        queryLifeTimeHookRunner.runAfterParseHook(command, parseError);
+        hookRunner.runAfterParseHook(command, parseError);
       }
       perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.PARSE);
 
-      queryLifeTimeHookRunner.runBeforeCompileHook(command);
+      hookRunner.runBeforeCompileHook(command);
 
       perfLogger.PerfLogBegin(CLASS_NAME, PerfLogger.ANALYZE);
       BaseSemanticAnalyzer sem = SemanticAnalyzerFactory.get(queryState, tree);
-      List<HiveSemanticAnalyzerHook> saHooks =
-          hooksLoader.getHooks(HiveConf.ConfVars.SEMANTIC_ANALYZER_HOOK, 
console, HiveSemanticAnalyzerHook.class);
 
       // Flush the metastore cache.  This assures that we don't pick up 
objects from a previous
       // query running in this same thread.  This has to be done after we get 
our semantic
@@ -604,21 +593,20 @@ public class Driver implements IDriver {
         }
       }
       // Do semantic analysis and plan generation
-      if (saHooks != null && !saHooks.isEmpty()) {
+      if (hookRunner.hasPreAnalyzeHooks()) {
         HiveSemanticAnalyzerHookContext hookCtx = new 
HiveSemanticAnalyzerHookContextImpl();
         hookCtx.setConf(conf);
         hookCtx.setUserName(userName);
         hookCtx.setIpAddress(SessionState.get().getUserIpAddress());
         hookCtx.setCommand(command);
         hookCtx.setHiveOperation(queryState.getHiveOperation());
-        for (HiveSemanticAnalyzerHook hook : saHooks) {
-          tree = hook.preAnalyze(hookCtx, tree);
-        }
+
+        tree =  hookRunner.runPreAnalyzeHooks(hookCtx, tree);
+
         sem.analyze(tree, ctx);
         hookCtx.update(sem);
-        for (HiveSemanticAnalyzerHook hook : saHooks) {
-          hook.postAnalyze(hookCtx, sem.getAllRootTasks());
-        }
+
+        hookRunner.runPostAnalyzeHooks(hookCtx, sem.getAllRootTasks());
       } else {
         sem.analyze(tree, ctx);
       }
@@ -710,7 +698,7 @@ public class Driver implements IDriver {
       // before/after execution hook will never be executed.
       if (!parseError) {
         try {
-          queryLifeTimeHookRunner.runAfterCompilationHook(command, 
compileError);
+          hookRunner.runAfterCompilationHook(command, compileError);
         } catch (Exception e) {
           LOG.warn("Failed when invoking query after-compilation hook.", e);
         }
@@ -1599,12 +1587,8 @@ public class Driver implements IDriver {
       HiveDriverRunHookContext hookContext = new 
HiveDriverRunHookContextImpl(conf,
           alreadyCompiled ? ctx.getCmd() : command);
       // Get all the driver run hooks and pre-execute them.
-      List<HiveDriverRunHook> driverRunHooks;
       try {
-        driverRunHooks = 
hooksLoader.getHooks(HiveConf.ConfVars.HIVE_DRIVER_RUN_HOOKS, console, 
HiveDriverRunHook.class);
-        for (HiveDriverRunHook driverRunHook : driverRunHooks) {
-            driverRunHook.preDriverRun(hookContext);
-        }
+        hookRunner.runPreDriverHooks(hookContext);
       } catch (Exception e) {
         errorMessage = "FAILED: Hive Internal Error: " + 
Utilities.getNameMessage(e);
         SQLState = ErrorMsg.findSQLState(e.getMessage());
@@ -1666,9 +1650,7 @@ public class Driver implements IDriver {
 
       // Take all the driver run hooks and post-execute them.
       try {
-        for (HiveDriverRunHook driverRunHook : driverRunHooks) {
-            driverRunHook.postDriverRun(hookContext);
-        }
+        hookRunner.runPostDriverHooks(hookContext);
       } catch (Exception e) {
         errorMessage = "FAILED: Hive Internal Error: " + 
Utilities.getNameMessage(e);
         SQLState = ErrorMsg.findSQLState(e.getMessage());
@@ -1880,16 +1862,10 @@ public class Driver implements IDriver {
           ss.getSessionId(), Thread.currentThread().getName(), 
ss.isHiveServerQuery(), perfLogger, queryInfo);
       hookContext.setHookType(HookContext.HookType.PRE_EXEC_HOOK);
 
-      for (Hook peh : hooksLoader.getHooks(HiveConf.ConfVars.PREEXECHOOKS, 
console, ExecuteWithHookContext.class)) {
-        perfLogger.PerfLogBegin(CLASS_NAME, PerfLogger.PRE_HOOK + 
peh.getClass().getName());
-
-        ((ExecuteWithHookContext) peh).run(hookContext);
-
-        perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.PRE_HOOK + 
peh.getClass().getName());
-      }
+      hookRunner.runPreHooks(hookContext);
 
       // Trigger query hooks before query execution.
-      queryLifeTimeHookRunner.runBeforeExecutionHook(queryStr, hookContext);
+      hookRunner.runBeforeExecutionHook(queryStr, hookContext);
 
       setQueryDisplays(plan.getRootTasks());
       int mrJobs = Utilities.getMRTasks(plan.getRootTasks()).size();
@@ -2064,15 +2040,10 @@ public class Driver implements IDriver {
         plan.getOutputs().remove(output);
       }
 
-      hookContext.setHookType(HookContext.HookType.POST_EXEC_HOOK);
-      // Get all the post execution hooks and execute them.
-      for (Hook peh : hooksLoader.getHooks(HiveConf.ConfVars.POSTEXECHOOKS, 
console, ExecuteWithHookContext.class)) {
-        perfLogger.PerfLogBegin(CLASS_NAME, PerfLogger.POST_HOOK + 
peh.getClass().getName());
 
-        ((ExecuteWithHookContext) peh).run(hookContext);
+      hookContext.setHookType(HookContext.HookType.POST_EXEC_HOOK);
 
-        perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.POST_HOOK + 
peh.getClass().getName());
-      }
+      hookRunner.runPostExecHooks(hookContext);
 
       if (SessionState.get() != null) {
         SessionState.get().getHiveHistory().setQueryProperty(queryId, 
Keys.QUERY_RET_CODE,
@@ -2110,7 +2081,7 @@ public class Driver implements IDriver {
     } finally {
       // Trigger query hooks after query completes its execution.
       try {
-        queryLifeTimeHookRunner.runAfterExecutionHook(queryStr, hookContext, 
executionError);
+        hookRunner.runAfterExecutionHook(queryStr, hookContext, 
executionError);
       } catch (Exception e) {
         LOG.warn("Failed when invoking query after execution hook", e);
       }
@@ -2230,13 +2201,7 @@ public class Driver implements IDriver {
     hookContext.setErrorMessage(errorMessage);
     hookContext.setException(exception);
     // Get all the failure execution hooks and execute them.
-    for (Hook ofh : hooksLoader.getHooks(HiveConf.ConfVars.ONFAILUREHOOKS, 
console, ExecuteWithHookContext.class)) {
-      perfLogger.PerfLogBegin(CLASS_NAME, PerfLogger.FAILURE_HOOK + 
ofh.getClass().getName());
-
-      ((ExecuteWithHookContext) ofh).run(hookContext);
-
-      perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.FAILURE_HOOK + 
ofh.getClass().getName());
-    }
+    hookRunner.runFailureHooks(hookContext);
   }
 
   /**
@@ -2557,4 +2522,8 @@ public class Driver implements IDriver {
   public QueryState getQueryState() {
     return queryState;
   }
+
+  public HookRunner getHookRunner() {
+    return hookRunner;
+  }
 }

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/java/org/apache/hadoop/hive/ql/HookRunner.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/HookRunner.java 
b/ql/src/java/org/apache/hadoop/hive/ql/HookRunner.java
new file mode 100644
index 0000000..52e99f9
--- /dev/null
+++ b/ql/src/java/org/apache/hadoop/hive/ql/HookRunner.java
@@ -0,0 +1,323 @@
+/*
+ * 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.ql;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.hadoop.hive.ql.exec.Task;
+import org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext;
+import org.apache.hadoop.hive.ql.hooks.Hook;
+import org.apache.hadoop.hive.ql.hooks.HookContext;
+import org.apache.hadoop.hive.ql.hooks.HookUtils;
+import org.apache.hadoop.hive.ql.hooks.MaterializedViewRegistryUpdateHook;
+import org.apache.hadoop.hive.ql.hooks.MetricsQueryLifeTimeHook;
+import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHook;
+import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHookContext;
+import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHookContextImpl;
+import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHookWithParseHooks;
+import org.apache.hadoop.hive.ql.log.PerfLogger;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
+import org.apache.hadoop.hive.ql.parse.ASTNode;
+import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHook;
+import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.apache.hadoop.hive.ql.session.SessionState.LogHelper;
+import org.apache.hive.common.util.HiveStringUtils;
+
+/**
+ * Handles hook executions for {@link Driver}.
+ */
+public class HookRunner {
+
+  private static final String CLASS_NAME = Driver.class.getName();
+  private final HiveConf conf;
+  private LogHelper console;
+  private List<QueryLifeTimeHook> queryHooks = new ArrayList<>();
+  private List<HiveSemanticAnalyzerHook> saHooks = new ArrayList<>();
+  private List<HiveDriverRunHook> driverRunHooks = new ArrayList<>();
+  private List<ExecuteWithHookContext> preExecHooks = new ArrayList<>();
+  private List<ExecuteWithHookContext> postExecHooks = new ArrayList<>();
+  private List<ExecuteWithHookContext> onFailureHooks = new ArrayList<>();
+  private boolean initialized = false;
+
+  /**
+   * Constructs a {@link HookRunner} that loads all hooks to be run via a 
{@link HooksLoader}.
+   */
+  HookRunner(HiveConf conf, SessionState.LogHelper console) {
+    this.conf = conf;
+    this.console = console;
+  }
+
+  public void initialize() {
+    if (initialized) {
+      return;
+    }
+    initialized = true;
+    
queryHooks.addAll(loadHooksFromConf(HiveConf.ConfVars.HIVE_QUERY_LIFETIME_HOOKS,
 QueryLifeTimeHook.class));
+    saHooks.addAll(loadHooksFromConf(HiveConf.ConfVars.SEMANTIC_ANALYZER_HOOK, 
HiveSemanticAnalyzerHook.class));
+    
driverRunHooks.addAll(loadHooksFromConf(HiveConf.ConfVars.HIVE_DRIVER_RUN_HOOKS,
 HiveDriverRunHook.class));
+    preExecHooks.addAll(loadHooksFromConf(HiveConf.ConfVars.PREEXECHOOKS, 
ExecuteWithHookContext.class));
+    postExecHooks.addAll(loadHooksFromConf(HiveConf.ConfVars.POSTEXECHOOKS, 
ExecuteWithHookContext.class));
+    onFailureHooks.addAll(loadHooksFromConf(HiveConf.ConfVars.ONFAILUREHOOKS, 
ExecuteWithHookContext.class));
+
+    if (conf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_METRICS_ENABLED)) {
+      queryHooks.add(new MetricsQueryLifeTimeHook());
+    }
+    queryHooks.add(new MaterializedViewRegistryUpdateHook());
+  }
+
+
+  private <T extends Hook> List<T> loadHooksFromConf(ConfVars hookConfVar, 
Class<T> clazz) {
+    try {
+      return HookUtils.readHooksFromConf(conf, hookConfVar);
+    } catch (InstantiationException | IllegalAccessException | 
ClassNotFoundException e) {
+      String message = "Error loading hooks(" + hookConfVar + "): " + 
HiveStringUtils.stringifyException(e);
+      throw new RuntimeException(message, e);
+    }
+  }
+
+  /**
+   * If {@link QueryLifeTimeHookWithParseHooks} have been loaded via the 
{@link HooksLoader} then invoke the
+   * {@link 
QueryLifeTimeHookWithParseHooks#beforeParse(QueryLifeTimeHookContext)} method 
for each
+   * {@link QueryLifeTimeHookWithParseHooks}.
+   *
+   * @param command the Hive command that is being run
+   */
+  void runBeforeParseHook(String command) {
+    initialize();
+    if (!queryHooks.isEmpty()) {
+      QueryLifeTimeHookContext qhc =
+          new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(command).build();
+
+      for (QueryLifeTimeHook hook : queryHooks) {
+        if (hook instanceof QueryLifeTimeHookWithParseHooks) {
+          ((QueryLifeTimeHookWithParseHooks) hook).beforeParse(qhc);
+        }
+      }
+    }
+  }
+
+  /**
+   * If {@link QueryLifeTimeHookWithParseHooks} have been loaded via the 
{@link HooksLoader} then invoke the
+   * {@link 
QueryLifeTimeHookWithParseHooks#afterParse(QueryLifeTimeHookContext, boolean)} 
method for each
+   * {@link QueryLifeTimeHookWithParseHooks}.
+   *
+   * @param command the Hive command that is being run
+   * @param parseError true if there was an error while parsing the command, 
false otherwise
+   */
+  void runAfterParseHook(String command, boolean parseError) {
+    initialize();
+    if (!queryHooks.isEmpty()) {
+      QueryLifeTimeHookContext qhc =
+          new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(command).build();
+
+      for (QueryLifeTimeHook hook : queryHooks) {
+        if (hook instanceof QueryLifeTimeHookWithParseHooks) {
+          ((QueryLifeTimeHookWithParseHooks) hook).afterParse(qhc, parseError);
+        }
+      }
+    }
+  }
+
+  /**
+   * Dispatches {@link 
QueryLifeTimeHook#beforeCompile(QueryLifeTimeHookContext)}.
+   *
+   * @param command the Hive command that is being run
+   */
+  void runBeforeCompileHook(String command) {
+    initialize();
+    if (!queryHooks.isEmpty()) {
+      QueryLifeTimeHookContext qhc =
+          new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(command).build();
+
+      for (QueryLifeTimeHook hook : queryHooks) {
+        hook.beforeCompile(qhc);
+      }
+    }
+  }
+
+  /**
+  * Dispatches {@link QueryLifeTimeHook#afterCompile(QueryLifeTimeHookContext, 
boolean)}.
+  *
+  * @param command the Hive command that is being run
+  * @param compileError true if there was an error while compiling the 
command, false otherwise
+  */
+  void runAfterCompilationHook(String command, boolean compileError) {
+    initialize();
+    if (!queryHooks.isEmpty()) {
+      QueryLifeTimeHookContext qhc =
+          new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(command).build();
+
+      for (QueryLifeTimeHook hook : queryHooks) {
+        hook.afterCompile(qhc, compileError);
+      }
+    }
+  }
+
+  /**
+   * Dispatches {@link 
QueryLifeTimeHook#beforeExecution(QueryLifeTimeHookContext)}.
+   *
+   * @param command the Hive command that is being run
+   * @param hookContext the {@link HookContext} of the command being run
+   */
+  void runBeforeExecutionHook(String command, HookContext hookContext) {
+    initialize();
+    if (!queryHooks.isEmpty()) {
+      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(command)
+          .withHookContext(hookContext).build();
+
+      for (QueryLifeTimeHook hook : queryHooks) {
+        hook.beforeExecution(qhc);
+      }
+    }
+  }
+
+  /**
+   * Dispatches {@link 
QueryLifeTimeHook#afterExecution(QueryLifeTimeHookContext, boolean)}.
+   *
+   * @param command the Hive command that is being run
+   * @param hookContext the {@link HookContext} of the command being run
+   * @param executionError true if there was an error while executing the 
command, false otherwise
+   */
+  void runAfterExecutionHook(String command, HookContext hookContext, boolean 
executionError) {
+    initialize();
+    if (!queryHooks.isEmpty()) {
+      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(command)
+          .withHookContext(hookContext).build();
+
+      for (QueryLifeTimeHook hook : queryHooks) {
+        hook.afterExecution(qhc, executionError);
+      }
+    }
+  }
+
+  public ASTNode runPreAnalyzeHooks(HiveSemanticAnalyzerHookContext hookCtx, 
ASTNode tree) throws HiveException {
+    initialize();
+    try {
+      for (HiveSemanticAnalyzerHook hook : saHooks) {
+        tree = hook.preAnalyze(hookCtx, tree);
+      }
+      return tree;
+    } catch (HiveException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new HiveException("Error while invoking PreAnalyzeHooks:" + 
HiveStringUtils.stringifyException(e), e);
+    }
+  }
+
+  public boolean hasPreAnalyzeHooks() {
+    return !saHooks.isEmpty();
+  }
+
+  public void runPostAnalyzeHooks(HiveSemanticAnalyzerHookContext hookCtx,
+      List<Task<? extends Serializable>> allRootTasks) throws HiveException {
+    initialize();
+    try {
+      for (HiveSemanticAnalyzerHook hook : saHooks) {
+        hook.postAnalyze(hookCtx, allRootTasks);
+      }
+    } catch (HiveException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new HiveException("Error while invoking PostAnalyzeHooks:" + 
HiveStringUtils.stringifyException(e), e);
+    }
+
+  }
+
+  public void runPreDriverHooks(HiveDriverRunHookContext hookContext) throws 
HiveException {
+    initialize();
+    try {
+      for (HiveDriverRunHook driverRunHook : driverRunHooks) {
+        driverRunHook.preDriverRun(hookContext);
+      }
+    } catch (HiveException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new HiveException("Error while invoking PreDriverHooks:" + 
HiveStringUtils.stringifyException(e), e);
+    }
+  }
+
+  public void runPostDriverHooks(HiveDriverRunHookContext hookContext) throws 
HiveException {
+    initialize();
+    try {
+      for (HiveDriverRunHook driverRunHook : driverRunHooks) {
+        driverRunHook.postDriverRun(hookContext);
+      }
+    } catch (HiveException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new HiveException("Error while invoking PostDriverHooks:" + 
HiveStringUtils.stringifyException(e), e);
+    }
+  }
+
+  public void runPreHooks(HookContext hookContext) throws HiveException {
+    initialize();
+    invokeGeneralHook(preExecHooks, PerfLogger.PRE_HOOK, hookContext);
+  }
+
+  public void runPostExecHooks(HookContext hookContext) throws HiveException {
+    initialize();
+    invokeGeneralHook(postExecHooks, PerfLogger.POST_HOOK, hookContext);
+  }
+
+  public void runFailureHooks(HookContext hookContext) throws HiveException {
+    initialize();
+    invokeGeneralHook(onFailureHooks, PerfLogger.FAILURE_HOOK, hookContext);
+  }
+
+  private static void invokeGeneralHook(List<ExecuteWithHookContext> hooks, 
String prefix, HookContext hookContext)
+      throws HiveException {
+    if (hooks.isEmpty()) {
+      return;
+    }
+    try {
+      PerfLogger perfLogger = SessionState.getPerfLogger();
+
+      for (ExecuteWithHookContext hook : hooks) {
+        perfLogger.PerfLogBegin(CLASS_NAME, prefix + 
hook.getClass().getName());
+        hook.run(hookContext);
+        perfLogger.PerfLogEnd(CLASS_NAME, prefix + hook.getClass().getName());
+      }
+    } catch (HiveException e) {
+      throw e;
+    } catch (Exception e) {
+      throw new HiveException("Error while invoking " + prefix + " hooks: " + 
HiveStringUtils.stringifyException(e), e);
+    }
+  }
+
+  public void addLifeTimeHook(QueryLifeTimeHook hook) {
+    queryHooks.add(hook);
+  }
+
+  public void addPreHook(ExecuteWithHookContext hook) {
+    preExecHooks.add(hook);
+  }
+
+  public void addPostHook(ExecuteWithHookContext hook) {
+    postExecHooks.add(hook);
+  }
+
+  public void addOnFailureHook(ExecuteWithHookContext hook) {
+    onFailureHooks.add(hook);
+  }
+}

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/java/org/apache/hadoop/hive/ql/QueryLifeTimeHookRunner.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/QueryLifeTimeHookRunner.java 
b/ql/src/java/org/apache/hadoop/hive/ql/QueryLifeTimeHookRunner.java
deleted file mode 100644
index 53d716b..0000000
--- a/ql/src/java/org/apache/hadoop/hive/ql/QueryLifeTimeHookRunner.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.ql;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.google.common.collect.Iterables;
-
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.ql.hooks.HookContext;
-import org.apache.hadoop.hive.ql.hooks.HooksLoader;
-import org.apache.hadoop.hive.ql.hooks.MaterializedViewRegistryUpdateHook;
-import org.apache.hadoop.hive.ql.hooks.MetricsQueryLifeTimeHook;
-import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHook;
-import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHookContext;
-import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHookContextImpl;
-import org.apache.hadoop.hive.ql.hooks.QueryLifeTimeHookWithParseHooks;
-import org.apache.hadoop.hive.ql.session.SessionState;
-
-
-/**
- * A runner class for {@link QueryLifeTimeHook}s and {@link 
QueryLifeTimeHookWithParseHooks}. The class has run methods
- * for each phase of a {@link QueryLifeTimeHook} and {@link 
QueryLifeTimeHookWithParseHooks}. Each run method checks if
- * a list of hooks has be specified, and if so invokes the appropriate 
callback method of each hook. Each method
- * constructs a {@link QueryLifeTimeHookContext} object and pass it to the 
callback functions.
- */
-class QueryLifeTimeHookRunner {
-
-  private final HiveConf conf;
-  private final List<QueryLifeTimeHook> queryHooks;
-
-  /**
-   * Constructs a {@link QueryLifeTimeHookRunner} that loads all hooks to be 
run via a {@link HooksLoader}.
-   *
-   * @param conf the {@link HiveConf} to use when creating {@link 
QueryLifeTimeHookContext} objects
-   * @param hooksLoader the {@link HooksLoader} to use when loading all hooks 
to be run
-   * @param console the {@link SessionState.LogHelper} to use when running 
{@link HooksLoader#getHooks(HiveConf.ConfVars)}
-   */
-  QueryLifeTimeHookRunner(HiveConf conf, HooksLoader hooksLoader, 
SessionState.LogHelper console) {
-    this.conf = conf;
-    this.queryHooks = new ArrayList<>();
-
-    if (conf.getBoolVar(HiveConf.ConfVars.HIVE_SERVER2_METRICS_ENABLED)) {
-      queryHooks.add(new MetricsQueryLifeTimeHook());
-    }
-    queryHooks.add(new MaterializedViewRegistryUpdateHook());
-
-    List<QueryLifeTimeHook> propertyDefinedHoooks;
-    try {
-      propertyDefinedHoooks = hooksLoader.getHooks(
-          HiveConf.ConfVars.HIVE_QUERY_LIFETIME_HOOKS, console, 
QueryLifeTimeHook.class);
-    } catch (IllegalAccessException | InstantiationException | 
ClassNotFoundException e) {
-      throw new IllegalArgumentException(e);
-    }
-    if (propertyDefinedHoooks != null) {
-      Iterables.addAll(queryHooks, propertyDefinedHoooks);
-    }
-  }
-
-  /**
-   * If {@link QueryLifeTimeHookWithParseHooks} have been loaded via the 
{@link HooksLoader} then invoke the
-   * {@link 
QueryLifeTimeHookWithParseHooks#beforeParse(QueryLifeTimeHookContext)} method 
for each
-   * {@link QueryLifeTimeHookWithParseHooks}.
-   *
-   * @param command the Hive command that is being run
-   */
-  void runBeforeParseHook(String command) {
-    if (containsHooks()) {
-      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(
-              command).build();
-
-      for (QueryLifeTimeHook hook : queryHooks) {
-        if (hook instanceof QueryLifeTimeHookWithParseHooks) {
-          ((QueryLifeTimeHookWithParseHooks) hook).beforeParse(qhc);
-        }
-      }
-    }
-  }
-
-  /**
-   * If {@link QueryLifeTimeHookWithParseHooks} have been loaded via the 
{@link HooksLoader} then invoke the
-   * {@link 
QueryLifeTimeHookWithParseHooks#afterParse(QueryLifeTimeHookContext, boolean)} 
method for each
-   * {@link QueryLifeTimeHookWithParseHooks}.
-   *
-   * @param command the Hive command that is being run
-   * @param parseError true if there was an error while parsing the command, 
false otherwise
-   */
-  void runAfterParseHook(String command, boolean parseError) {
-    if (containsHooks()) {
-      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(
-              command).build();
-
-      for (QueryLifeTimeHook hook : queryHooks) {
-        if (hook instanceof QueryLifeTimeHookWithParseHooks) {
-          ((QueryLifeTimeHookWithParseHooks) hook).afterParse(qhc, parseError);
-        }
-      }
-    }
-  }
-
-  /**
-   * Invoke the {@link 
QueryLifeTimeHook#beforeCompile(QueryLifeTimeHookContext)} method for each 
{@link QueryLifeTimeHook}
-   *
-   * @param command the Hive command that is being run
-   */
-  void runBeforeCompileHook(String command) {
-    if (containsHooks()) {
-      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(
-              command).build();
-
-      for (QueryLifeTimeHook hook : queryHooks) {
-        hook.beforeCompile(qhc);
-      }
-    }
-  }
-
-   /**
-   * Invoke the {@link 
QueryLifeTimeHook#afterCompile(QueryLifeTimeHookContext, boolean)} method for 
each {@link QueryLifeTimeHook}
-   *
-   * @param command the Hive command that is being run
-   * @param compileError true if there was an error while compiling the 
command, false otherwise
-   */
-  void runAfterCompilationHook(String command, boolean compileError) {
-    if (containsHooks()) {
-      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(
-              command).build();
-
-      for (QueryLifeTimeHook hook : queryHooks) {
-        hook.afterCompile(qhc, compileError);
-      }
-    }
-  }
-
-  /**
-   * Invoke the {@link 
QueryLifeTimeHook#beforeExecution(QueryLifeTimeHookContext)} method for each 
{@link QueryLifeTimeHook}
-   *
-   * @param command the Hive command that is being run
-   * @param hookContext the {@link HookContext} of the command being run
-   */
-  void runBeforeExecutionHook(String command, HookContext hookContext) {
-    if (containsHooks()) {
-      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(
-              command).withHookContext(hookContext).build();
-
-      for (QueryLifeTimeHook hook : queryHooks) {
-        hook.beforeExecution(qhc);
-      }
-    }
-  }
-
-  /**
-   * Invoke the {@link 
QueryLifeTimeHook#afterExecution(QueryLifeTimeHookContext, boolean)} method for 
each {@link QueryLifeTimeHook}
-   *
-   * @param command the Hive command that is being run
-   * @param hookContext the {@link HookContext} of the command being run
-   * @param executionError true if there was an error while executing the 
command, false otherwise
-   */
-  void runAfterExecutionHook(String command, HookContext hookContext, boolean 
executionError) {
-    if (containsHooks()) {
-      QueryLifeTimeHookContext qhc = new 
QueryLifeTimeHookContextImpl.Builder().withHiveConf(conf).withCommand(
-              command).withHookContext(hookContext).build();
-
-      for (QueryLifeTimeHook hook : queryHooks) {
-        hook.afterExecution(qhc, executionError);
-      }
-    }
-  }
-
-  private boolean containsHooks() {
-    return queryHooks != null && !queryHooks.isEmpty();
-  }
-}

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/java/org/apache/hadoop/hive/ql/hooks/HookUtils.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/hooks/HookUtils.java 
b/ql/src/java/org/apache/hadoop/hive/ql/hooks/HookUtils.java
index dbd258a..0841d67 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/hooks/HookUtils.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/hooks/HookUtils.java
@@ -6,9 +6,9 @@
  * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+ *
+ *     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.
@@ -18,11 +18,13 @@
 
 package org.apache.hadoop.hive.ql.hooks;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-
+import org.apache.hadoop.hive.ql.exec.Utilities;
+import org.apache.logging.log4j.util.Strings;
 
 public class HookUtils {
 
@@ -32,7 +34,7 @@ public class HookUtils {
     String redactedString = logString;
 
     if (conf != null && logString != null) {
-      List<Redactor> queryRedactors = new 
HooksLoader(conf).getHooks(ConfVars.QUERYREDACTORHOOKS, Redactor.class);
+      List<Redactor> queryRedactors = readHooksFromConf(conf, 
ConfVars.QUERYREDACTORHOOKS);
       for (Redactor redactor : queryRedactors) {
         redactor.setConf(conf);
         redactedString = redactor.redactQuery(redactedString);
@@ -40,4 +42,19 @@ public class HookUtils {
     }
     return redactedString;
   }
+
+  public static <T extends Hook> List<T> readHooksFromConf(HiveConf conf, 
HiveConf.ConfVars hookConfVar)
+      throws InstantiationException, IllegalAccessException, 
ClassNotFoundException {
+    String csHooks = conf.getVar(hookConfVar);
+    List<T> hooks = new ArrayList<>();
+    if (Strings.isBlank(csHooks)) {
+      return hooks;
+    }
+    String[] hookClasses = csHooks.split(",");
+    for (String hookClass : hookClasses) {
+      T hook = (T) Class.forName(hookClass.trim(), true, 
Utilities.getSessionSpecifiedClassLoader()).newInstance();
+      hooks.add(hook);
+    }
+    return hooks;
+  }
 }

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/java/org/apache/hadoop/hive/ql/hooks/HooksLoader.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/hooks/HooksLoader.java 
b/ql/src/java/org/apache/hadoop/hive/ql/hooks/HooksLoader.java
deleted file mode 100644
index 8c19338..0000000
--- a/ql/src/java/org/apache/hadoop/hive/ql/hooks/HooksLoader.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.ql.hooks;
-
-import java.util.List;
-
-import com.google.common.collect.ImmutableList;
-
-import org.apache.hadoop.hive.conf.HiveConf;
-import org.apache.hadoop.hive.ql.exec.Utilities;
-import org.apache.hadoop.hive.ql.session.SessionState;
-
-
-/**
- * A loader class for {@link Hook}s. The class provides a way to create and 
instantiate {@link Hook} objects. The
- * methodology for how hooks are loaded is left up to the individual methods.
- */
-public class HooksLoader {
-
-  private final HiveConf conf;
-
-  /**
-   * Creates a new {@link HooksLoader} that uses the specified {@link 
HiveConf} to load the {@link Hook}s.
-   *
-   * @param conf the {@link HiveConf} to use when loading the {@link Hook}s
-   */
-  public HooksLoader(HiveConf conf) {
-    this.conf = conf;
-  }
-
-  /**
-   * Delegates to {@link #getHooks(HiveConf.ConfVars)} and prints the to the 
specified {@link SessionState.LogHelper} if
-   * a {@link ClassNotFoundException} is thrown.
-   *
-   * @param hookConfVar the configuration variable specifying a comma 
separated list of the hook class names
-   * @param console the {@link SessionState.LogHelper} to print to if a {@link 
ClassNotFoundException} is thrown by the
-   *                {@link #getHooks(HiveConf.ConfVars)} method
-   *
-   * @return a list of the hooks objects, in the order they are listed in the 
value of hookConfVar
-   *
-   * @throws ClassNotFoundException if the specified class names could not be 
found
-   * @throws IllegalAccessException if the specified class names could not be 
accessed
-   * @throws InstantiationException if the specified class names could not be 
instantiated
-   */
-  public final <T extends Hook> List<T> getHooks(HiveConf.ConfVars 
hookConfVar, SessionState.LogHelper console,
-      Class<T> clazz) throws IllegalAccessException, InstantiationException, 
ClassNotFoundException {
-    try {
-      return getHooks(hookConfVar, clazz);
-    } catch (ClassNotFoundException e) {
-      console.printError(hookConfVar.varname + " Class not found: " + 
e.getMessage());
-      throw e;
-    }
-  }
-
-  /**
-   * Returns the hooks specified in a configuration variable. The hooks are 
returned in a list in the order they were
-   * specified in the configuration variable. The value of the specified conf 
variable should be a comma separated list
-   * of class names where each class implements the {@link Hook} interface. 
The method uses reflection to an instance
-   * of each class and then returns them in a {@link List}.
-   *
-   * @param hookConfVar The configuration variable specifying a comma 
separated list of the hook class names
-   * @param class2
-   * @param class1
-   * @param console
-   *
-   * @return a list of the hooks objects, in the order they are listed in the 
value of hookConfVar
-   *
-   * @throws ClassNotFoundException if the specified class names could not be 
found
-   * @throws IllegalAccessException if the specified class names could not be 
accessed
-   * @throws InstantiationException if the specified class names could not be 
instantiated
-   */
-  public <T extends Hook> List<T> getHooks(HiveConf.ConfVars hookConfVar, 
Class<T> clazz)
-      throws InstantiationException, IllegalAccessException, 
ClassNotFoundException {
-    String csHooks = conf.getVar(hookConfVar);
-    ImmutableList.Builder<T> hooks = ImmutableList.builder();
-    if (csHooks == null) {
-      return ImmutableList.of();
-    }
-
-    csHooks = csHooks.trim();
-    if (csHooks.isEmpty()) {
-      return ImmutableList.of();
-    }
-
-    String[] hookClasses = csHooks.split(",");
-    for (String hookClass : hookClasses) {
-      T hook = (T) Class.forName(hookClass.trim(), true,
-              Utilities.getSessionSpecifiedClassLoader()).newInstance();
-      hooks.add(hook);
-    }
-
-    return hooks.build();
-  }
-}

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/test/org/apache/hadoop/hive/ql/hooks/TestQueryHooks.java
----------------------------------------------------------------------
diff --git a/ql/src/test/org/apache/hadoop/hive/ql/hooks/TestQueryHooks.java 
b/ql/src/test/org/apache/hadoop/hive/ql/hooks/TestQueryHooks.java
index 492b63d..5b4b42b 100644
--- a/ql/src/test/org/apache/hadoop/hive/ql/hooks/TestQueryHooks.java
+++ b/ql/src/test/org/apache/hadoop/hive/ql/hooks/TestQueryHooks.java
@@ -18,8 +18,6 @@
 
 package org.apache.hadoop.hive.ql.hooks;
 
-import com.google.common.collect.Lists;
-
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.ql.Driver;
 import org.apache.hadoop.hive.ql.QueryState;
@@ -39,7 +37,6 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 
 public class TestQueryHooks {
@@ -59,7 +56,9 @@ public class TestQueryHooks {
     String query = "select 1";
     ArgumentMatcher<QueryLifeTimeHookContext> argMatcher = new 
QueryLifeTimeHookContextMatcher(query);
     QueryLifeTimeHookWithParseHooks mockHook = 
mock(QueryLifeTimeHookWithParseHooks.class);
-    int ret = createDriver(mockHook).run(query).getResponseCode();
+    Driver driver = createDriver();
+    driver.getHookRunner().addLifeTimeHook(mockHook);
+    int ret = driver.run(query).getResponseCode();
     assertEquals("Expected query to succeed", 0, ret);
 
     verify(mockHook).beforeParse(argThat(argMatcher));
@@ -75,7 +74,9 @@ public class TestQueryHooks {
     String query = "invalidquery";
     ArgumentMatcher<QueryLifeTimeHookContext> argMatcher = new 
QueryLifeTimeHookContextMatcher(query);
     QueryLifeTimeHookWithParseHooks mockHook = 
mock(QueryLifeTimeHookWithParseHooks.class);
-    int ret = createDriver(mockHook).run(query).getResponseCode();
+    Driver driver = createDriver();
+    driver.getHookRunner().addLifeTimeHook(mockHook);
+    int ret = driver.run(query).getResponseCode();
     assertNotEquals("Expected parsing to fail", 0, ret);
 
     verify(mockHook).beforeParse(argThat(argMatcher));
@@ -91,7 +92,9 @@ public class TestQueryHooks {
     String query = "select * from foo";
     ArgumentMatcher<QueryLifeTimeHookContext> argMatcher = new 
QueryLifeTimeHookContextMatcher(query);
     QueryLifeTimeHookWithParseHooks mockHook = 
mock(QueryLifeTimeHookWithParseHooks.class);
-    int ret = createDriver(mockHook).run(query).getResponseCode();
+    Driver driver = createDriver();
+    driver.getHookRunner().addLifeTimeHook(mockHook);
+    int ret = driver.run(query).getResponseCode();
     assertNotEquals("Expected compilation to fail", 0, ret);
 
     verify(mockHook).beforeParse(argThat(argMatcher));
@@ -107,7 +110,9 @@ public class TestQueryHooks {
     String query = "select 1";
     ArgumentMatcher<QueryLifeTimeHookContext> argMatcher = new 
QueryLifeTimeHookContextMatcher(query);
     QueryLifeTimeHook mockHook = mock(QueryLifeTimeHook.class);
-    int ret = createDriver(mockHook).run(query).getResponseCode();
+    Driver driver = createDriver();
+    driver.getHookRunner().addLifeTimeHook(mockHook);
+    int ret = driver.run(query).getResponseCode();
     assertEquals("Expected query to succeed", 0, ret);
 
     verify(mockHook).beforeCompile(argThat(argMatcher));
@@ -121,7 +126,9 @@ public class TestQueryHooks {
     String query = "select * from foo";
     ArgumentMatcher<QueryLifeTimeHookContext> argMatcher = new 
QueryLifeTimeHookContextMatcher(query);
     QueryLifeTimeHook mockHook = mock(QueryLifeTimeHook.class);
-    int ret = createDriver(mockHook).run(query).getResponseCode();
+    Driver driver = createDriver();
+    driver.getHookRunner().addLifeTimeHook(mockHook);
+    int ret = driver.run(query).getResponseCode();
     assertNotEquals("Expected compilation to fail", 0, ret);
 
     verify(mockHook).beforeCompile(argThat(argMatcher));
@@ -130,14 +137,9 @@ public class TestQueryHooks {
     verify(mockHook, never()).afterExecution(any(), anyBoolean());
   }
 
-  private Driver createDriver(QueryLifeTimeHook mockHook) throws 
IllegalAccessException, ClassNotFoundException, InstantiationException {
-    HooksLoader mockLoader = mock(HooksLoader.class);
-    when(mockLoader.getHooks(eq(HiveConf.ConfVars.HIVE_QUERY_LIFETIME_HOOKS), 
any())).thenReturn(
-            Lists.newArrayList(mockHook));
-
+  private Driver createDriver() throws IllegalAccessException, 
ClassNotFoundException, InstantiationException {
     SessionState.start(conf);
-
-    Driver driver = new Driver(new 
QueryState.Builder().withGenerateNewQueryId(true).withHiveConf(conf).build(), 
null, mockLoader, null, null);
+    Driver driver = new Driver(conf);
     return driver;
   }
 

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/ql/src/test/results/clientnegative/bad_exec_hooks.q.out
----------------------------------------------------------------------
diff --git a/ql/src/test/results/clientnegative/bad_exec_hooks.q.out 
b/ql/src/test/results/clientnegative/bad_exec_hooks.q.out
index 6f2ee5c..d0b47b7 100644
--- a/ql/src/test/results/clientnegative/bad_exec_hooks.q.out
+++ b/ql/src/test/results/clientnegative/bad_exec_hooks.q.out
@@ -1,5 +1,8 @@
-hive.exec.pre.hooks Class not found: "org.this.is.a.bad.class"
-FAILED: Hive Internal Error: 
java.lang.ClassNotFoundException("org.this.is.a.bad.class")
-java.lang.ClassNotFoundException: "org.this.is.a.bad.class"
+FAILED: Hive Internal Error: java.lang.RuntimeException(Error loading 
hooks(hive.exec.pre.hooks): java.lang.ClassNotFoundException: 
"org.this.is.a.bad.class"
+#### A masked pattern was here ####
+)
+java.lang.RuntimeException: Error loading hooks(hive.exec.pre.hooks): 
java.lang.ClassNotFoundException: "org.this.is.a.bad.class"
+#### A masked pattern was here ####
+
 #### A masked pattern was here ####
 

http://git-wip-us.apache.org/repos/asf/hive/blob/c96c6acf/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
----------------------------------------------------------------------
diff --git 
a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java 
b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
index f3e08a9..e964982 100644
--- a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
+++ b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
@@ -44,7 +44,7 @@ import 
org.apache.hadoop.hive.common.metrics.common.MetricsFactory;
 import org.apache.hadoop.hive.common.metrics.common.MetricsVariable;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
-import org.apache.hadoop.hive.ql.hooks.HooksLoader;
+import org.apache.hadoop.hive.ql.hooks.HookUtils;
 import org.apache.hive.service.CompositeService;
 import org.apache.hive.service.cli.HiveSQLException;
 import org.apache.hive.service.cli.SessionHandle;
@@ -655,7 +655,7 @@ public class SessionManager extends CompositeService {
   // execute session hooks
   private void executeSessionHooks(HiveSession session) throws Exception {
     List<HiveSessionHook> sessionHooks =
-        new 
HooksLoader(hiveConf).getHooks(HiveConf.ConfVars.HIVE_SERVER2_SESSION_HOOK, 
HiveSessionHook.class);
+        HookUtils.readHooksFromConf(hiveConf, 
HiveConf.ConfVars.HIVE_SERVER2_SESSION_HOOK);
     for (HiveSessionHook sessionHook : sessionHooks) {
       sessionHook.run(new HiveSessionHookContextImpl(session));
     }

Reply via email to