diff --git a/bin/ext/hiveserver2.cmd b/bin/ext/hiveserver2.cmd index a5f3bb5..7275708 100644 --- a/bin/ext/hiveserver2.cmd +++ b/bin/ext/hiveserver2.cmd @@ -62,7 +62,6 @@ if [%1]==[hiveserver2_catservice] goto :hiveserver2_catservice if [%1]==[hiveserver2_catcmd] goto :hiveserver2_catcmd :hiveserver2 - echo "Starting Hive Thrift Server" @rem hadoop 20 or newer - skip the aux_jars option and hiveconf call %HIVE_BIN_PATH%\ext\util\execHiveCmd.cmd %CLASS% diff --git a/bin/ext/hiveserver2.sh b/bin/ext/hiveserver2.sh index 45d7893..42d3d79 100644 --- a/bin/ext/hiveserver2.sh +++ b/bin/ext/hiveserver2.sh @@ -17,7 +17,6 @@ THISSERVICE=hiveserver2 export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} " hiveserver2() { - echo "Starting HiveServer2" CLASS=org.apache.hive.service.server.HiveServer2 if $cygwin; then HIVE_LIB=`cygpath -w "$HIVE_LIB"` diff --git a/service/src/java/org/apache/hive/service/server/HiveServer2.java b/service/src/java/org/apache/hive/service/server/HiveServer2.java index c667533..eb57fb6 100644 --- a/service/src/java/org/apache/hive/service/server/HiveServer2.java +++ b/service/src/java/org/apache/hive/service/server/HiveServer2.java @@ -18,7 +18,11 @@ package org.apache.hive.service.server; +import java.io.IOException; import java.nio.charset.Charset; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -31,11 +35,11 @@ import org.apache.hive.common.util.HiveStringUtils; import org.apache.hive.common.util.HiveVersionInfo; import org.apache.hive.service.CompositeService; -import org.apache.hive.service.ServiceException; import org.apache.hive.service.cli.CLIService; import org.apache.hive.service.cli.thrift.ThriftBinaryCLIService; import org.apache.hive.service.cli.thrift.ThriftCLIService; import org.apache.hive.service.cli.thrift.ThriftHttpCLIService; +import org.apache.hive.service.server.ServerOptionsProcessor.ServerOptionsProcessorResponse; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; @@ -125,12 +129,12 @@ private void addServerInstanceToZooKeeper(HiveConf hiveConf) throws Exception { } } // Create a znode under the rootNamespace parent for this instance of the server - // Znode name: server-host:port-versionInfo-sequence + // Znode name: serverUri=host:port;version=versionInfo;sequence=sequenceNumber try { String znodePath = ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + rootNamespace - + ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + "server-" + instanceURI + "-" - + HiveVersionInfo.getVersion() + "-"; + + ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + "serverUri=" + instanceURI + ";" + + "version=" + HiveVersionInfo.getVersion() + ";" + "sequence="; znodePath = zooKeeperClient.create(znodePath, znodeDataUTF8, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); @@ -267,15 +271,47 @@ private static void startHiveServer2() throws Throwable { } } + /** + * Remove all znodes corresponding to the given version number from ZooKeeper + * + * @param versionNumber + * @throws Exception + */ + static void deleteServerInstancesFromZooKeeper(String versionNumber) throws Exception { + HiveConf hiveConf = new HiveConf(); + int zooKeeperSessionTimeout = + hiveConf.getIntVar(HiveConf.ConfVars.HIVE_ZOOKEEPER_SESSION_TIMEOUT); + String zooKeeperEnsemble = ZooKeeperHiveHelper.getQuorumServers(hiveConf); + String rootNamespace = hiveConf.getVar(HiveConf.ConfVars.HIVE_SERVER2_ZOOKEEPER_NAMESPACE); + ZooKeeper zooKeeperClient = + new ZooKeeper(zooKeeperEnsemble, zooKeeperSessionTimeout, + new ZooKeeperHiveHelper.DummyWatcher()); + // Get all znode paths + List znodePaths = + zooKeeperClient.getChildren(ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + rootNamespace, + false); + // Now for each path that is for the given versionNumber, delete the znode from ZooKeeper + for (String znodePath : znodePaths) { + if (znodePath.contains(versionNumber)) { + zooKeeperClient.delete(ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + rootNamespace + + ZooKeeperHiveHelper.ZOOKEEPER_PATH_SEPARATOR + znodePath, -1); + } + } + } + public static void main(String[] args) { HiveConf.setLoadHiveServer2Config(true); try { ServerOptionsProcessor oproc = new ServerOptionsProcessor("hiveserver2"); - if (!oproc.process(args)) { - System.err.println("Error starting HiveServer2 with given arguments"); + ServerOptionsProcessorResponse oprocResponse = oproc.process(args); + // Error out & exit - we were not able to process the args successfully + if (!oprocResponse.isSuccess()) { System.exit(-1); } - + // Clean exit + if (oprocResponse.shouldExit()) { + System.exit(0); + } // NOTE: It is critical to do this here so that log4j is reinitialized // before any of the other core hive classes are loaded String initLog4jMessage = LogUtils.initHiveLog4j(); diff --git a/service/src/java/org/apache/hive/service/server/ServerOptionsProcessor.java b/service/src/java/org/apache/hive/service/server/ServerOptionsProcessor.java index bbb2a42..cf02580 100644 --- a/service/src/java/org/apache/hive/service/server/ServerOptionsProcessor.java +++ b/service/src/java/org/apache/hive/service/server/ServerOptionsProcessor.java @@ -53,31 +53,50 @@ public ServerOptionsProcessor(String serverName) { .withLongOpt("hiveconf") .withDescription("Use value for given property") .create()); - + // -deregister + options.addOption(OptionBuilder + .hasArgs(1) + .withArgName("versionNumber") + .withLongOpt("deregister") + .withDescription("Deregister all instances of given version from dynamic service discovery") + .create()); options.addOption(new Option("H", "help", false, "Print help information")); - } - public boolean process(String[] argv) { + public ServerOptionsProcessorResponse process(String[] argv) { try { commandLine = new GnuParser().parse(options, argv); + // Process -help if (commandLine.hasOption('H')) { printUsage(); - return false; + return new ServerOptionsProcessorResponse(ServerOptionsProcessorResponse.SUCCESS, true); } - //get hiveconf param values and set the System property values + // Process -deregister + if (commandLine.hasOption("deregister")) { + try { + HiveServer2.deleteServerInstancesFromZooKeeper(commandLine.getOptionValue("deregister")); + return new ServerOptionsProcessorResponse(ServerOptionsProcessorResponse.SUCCESS, true); + } catch (Exception e) { + System.err.println("Error deregistering HiveServer2 instances from ZooKeeper: "); + System.err.println(e.getMessage()); + return new ServerOptionsProcessorResponse(ServerOptionsProcessorResponse.FAILURE, true); + } + } + // Process -hiveconf + // get hiveconf param values and set the System property values Properties confProps = commandLine.getOptionProperties("hiveconf"); for (String propKey : confProps.stringPropertyNames()) { - //save logging message for log4j output latter after log4j initialize properly + // save logging message for log4j output latter after log4j initialize properly debugMessage.append("Setting " + propKey + "=" + confProps.getProperty(propKey) + ";\n"); System.setProperty(propKey, confProps.getProperty(propKey)); } } catch (ParseException e) { - System.err.println(e.getMessage()); printUsage(); - return false; + System.err.println("Error starting HiveServer2 with given arguments: "); + System.err.println(e.getMessage()); + return new ServerOptionsProcessorResponse(ServerOptionsProcessorResponse.FAILURE, true); } - return true; + return new ServerOptionsProcessorResponse(ServerOptionsProcessorResponse.SUCCESS, false); } public StringBuilder getDebugMessage() { @@ -88,4 +107,30 @@ private void printUsage() { new HelpFormatter().printHelp(serverName, options); } + /** + * The response sent back from {@link ServerOptionsProcessor#process(String[])} + */ + class ServerOptionsProcessorResponse { + static final boolean SUCCESS = true; + static final boolean FAILURE = false; + + private boolean success = false; + private boolean exit = false; + + ServerOptionsProcessorResponse(boolean isSuccessful, boolean shouldExit) { + this.success = isSuccessful; + this.exit = shouldExit; + } + + // Options processing successful or not + boolean isSuccess() { + return success; + } + + // Should the JVM exit after options processing (non-error exit) + boolean shouldExit() { + return exit; + } + } + } diff --git a/service/src/test/org/apache/hive/service/server/TestServerOptionsProcessor.java b/service/src/test/org/apache/hive/service/server/TestServerOptionsProcessor.java index 1aea0b8..9c76077 100644 --- a/service/src/test/org/apache/hive/service/server/TestServerOptionsProcessor.java +++ b/service/src/test/org/apache/hive/service/server/TestServerOptionsProcessor.java @@ -39,17 +39,12 @@ public void test() { null, System.getProperty(key)); - - boolean isSuccess = optProcessor.process(args); + boolean isSuccess = optProcessor.process(args).isSuccess(); Assert.assertTrue("options processor result", isSuccess); Assert.assertEquals( "checking system property after processing options", value, System.getProperty(key)); - - - - } }