Back to home page

OSCL-LXR

 
 

    


0001 /**
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements.  See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership.  The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License.  You may obtain a copy of the License at
0009  *
0010  *     http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing, software
0013  * distributed under the License is distributed on an "AS IS" BASIS,
0014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015  * See the License for the specific language governing permissions and
0016  * limitations under the License.
0017  */
0018 
0019 package org.apache.hive.service.server;
0020 
0021 import java.util.Properties;
0022 
0023 import scala.runtime.AbstractFunction0;
0024 import scala.runtime.BoxedUnit;
0025 
0026 import org.apache.commons.cli.GnuParser;
0027 import org.apache.commons.cli.HelpFormatter;
0028 import org.apache.commons.cli.Option;
0029 import org.apache.commons.cli.OptionBuilder;
0030 import org.apache.commons.cli.Options;
0031 import org.apache.commons.cli.ParseException;
0032 import org.apache.hadoop.hive.common.JvmPauseMonitor;
0033 import org.apache.hadoop.hive.conf.HiveConf;
0034 import org.apache.hive.common.util.HiveStringUtils;
0035 import org.apache.hive.service.CompositeService;
0036 import org.apache.hive.service.cli.CLIService;
0037 import org.apache.hive.service.cli.thrift.ThriftBinaryCLIService;
0038 import org.apache.hive.service.cli.thrift.ThriftCLIService;
0039 import org.apache.hive.service.cli.thrift.ThriftHttpCLIService;
0040 import org.slf4j.Logger;
0041 import org.slf4j.LoggerFactory;
0042 
0043 import org.apache.spark.util.ShutdownHookManager;
0044 
0045 /**
0046  * HiveServer2.
0047  *
0048  */
0049 public class HiveServer2 extends CompositeService {
0050   private static final Logger LOG = LoggerFactory.getLogger(HiveServer2.class);
0051 
0052   private CLIService cliService;
0053   private ThriftCLIService thriftCLIService;
0054 
0055   public HiveServer2() {
0056     super(HiveServer2.class.getSimpleName());
0057     HiveConf.setLoadHiveServer2Config(true);
0058   }
0059 
0060   @Override
0061   public synchronized void init(HiveConf hiveConf) {
0062     cliService = new CLIService(this);
0063     addService(cliService);
0064     if (isHTTPTransportMode(hiveConf)) {
0065       thriftCLIService = new ThriftHttpCLIService(cliService);
0066     } else {
0067       thriftCLIService = new ThriftBinaryCLIService(cliService);
0068     }
0069     addService(thriftCLIService);
0070     super.init(hiveConf);
0071 
0072     // Add a shutdown hook for catching SIGTERM & SIGINT
0073     // this must be higher than the Hadoop Filesystem priority of 10,
0074     // which the default priority is.
0075     // The signature of the callback must match that of a scala () -> Unit
0076     // function
0077     ShutdownHookManager.addShutdownHook(
0078         new AbstractFunction0<BoxedUnit>() {
0079           public BoxedUnit apply() {
0080             try {
0081               LOG.info("Hive Server Shutdown hook invoked");
0082               stop();
0083             } catch (Throwable e) {
0084               LOG.warn("Ignoring Exception while stopping Hive Server from shutdown hook",
0085                   e);
0086             }
0087             return BoxedUnit.UNIT;
0088           }
0089         });
0090   }
0091 
0092   public static boolean isHTTPTransportMode(HiveConf hiveConf) {
0093     String transportMode = System.getenv("HIVE_SERVER2_TRANSPORT_MODE");
0094     if (transportMode == null) {
0095       transportMode = hiveConf.getVar(HiveConf.ConfVars.HIVE_SERVER2_TRANSPORT_MODE);
0096     }
0097     if (transportMode != null && (transportMode.equalsIgnoreCase("http"))) {
0098       return true;
0099     }
0100     return false;
0101   }
0102 
0103   @Override
0104   public synchronized void start() {
0105     super.start();
0106   }
0107 
0108   @Override
0109   public synchronized void stop() {
0110     LOG.info("Shutting down HiveServer2");
0111     super.stop();
0112   }
0113 
0114   private static void startHiveServer2() throws Throwable {
0115     long attempts = 0, maxAttempts = 1;
0116     while (true) {
0117       LOG.info("Starting HiveServer2");
0118       HiveConf hiveConf = new HiveConf();
0119       maxAttempts = hiveConf.getLongVar(HiveConf.ConfVars.HIVE_SERVER2_MAX_START_ATTEMPTS);
0120       HiveServer2 server = null;
0121       try {
0122         server = new HiveServer2();
0123         server.init(hiveConf);
0124         server.start();
0125         try {
0126           JvmPauseMonitor pauseMonitor = new JvmPauseMonitor(hiveConf);
0127           pauseMonitor.start();
0128         } catch (Throwable t) {
0129           LOG.warn("Could not initiate the JvmPauseMonitor thread.", t);
0130         }
0131         break;
0132       } catch (Throwable throwable) {
0133         if (server != null) {
0134           try {
0135             server.stop();
0136           } catch (Throwable t) {
0137             LOG.info("Exception caught when calling stop of HiveServer2 before retrying start", t);
0138           } finally {
0139             server = null;
0140           }
0141         }
0142         if (++attempts >= maxAttempts) {
0143           throw new Error("Max start attempts " + maxAttempts + " exhausted", throwable);
0144         } else {
0145           LOG.warn("Error starting HiveServer2 on attempt " + attempts
0146               + ", will retry in 60 seconds", throwable);
0147           try {
0148             Thread.sleep(60L * 1000L);
0149           } catch (InterruptedException e) {
0150             Thread.currentThread().interrupt();
0151           }
0152         }
0153       }
0154     }
0155   }
0156 
0157   public static void main(String[] args) {
0158     HiveConf.setLoadHiveServer2Config(true);
0159     ServerOptionsProcessor oproc = new ServerOptionsProcessor("hiveserver2");
0160     ServerOptionsProcessorResponse oprocResponse = oproc.parse(args);
0161 
0162     HiveStringUtils.startupShutdownMessage(HiveServer2.class, args, LOG);
0163 
0164     // Call the executor which will execute the appropriate command based on the parsed options
0165     oprocResponse.getServerOptionsExecutor().execute();
0166   }
0167 
0168   /**
0169    * ServerOptionsProcessor.
0170    * Process arguments given to HiveServer2 (-hiveconf property=value)
0171    * Set properties in System properties
0172    * Create an appropriate response object,
0173    * which has executor to execute the appropriate command based on the parsed options.
0174    */
0175   public static class ServerOptionsProcessor {
0176     private final Options options = new Options();
0177     private org.apache.commons.cli.CommandLine commandLine;
0178     private final String serverName;
0179     private final StringBuilder debugMessage = new StringBuilder();
0180 
0181     @SuppressWarnings("static-access")
0182     public ServerOptionsProcessor(String serverName) {
0183       this.serverName = serverName;
0184       // -hiveconf x=y
0185       options.addOption(OptionBuilder
0186           .withValueSeparator()
0187           .hasArgs(2)
0188           .withArgName("property=value")
0189           .withLongOpt("hiveconf")
0190           .withDescription("Use value for given property")
0191           .create());
0192       options.addOption(new Option("H", "help", false, "Print help information"));
0193     }
0194 
0195     public ServerOptionsProcessorResponse parse(String[] argv) {
0196       try {
0197         commandLine = new GnuParser().parse(options, argv);
0198         // Process --hiveconf
0199         // Get hiveconf param values and set the System property values
0200         Properties confProps = commandLine.getOptionProperties("hiveconf");
0201         for (String propKey : confProps.stringPropertyNames()) {
0202           // save logging message for log4j output latter after log4j initialize properly
0203           debugMessage.append("Setting " + propKey + "=" + confProps.getProperty(propKey) + ";\n");
0204           System.setProperty(propKey, confProps.getProperty(propKey));
0205         }
0206 
0207         // Process --help
0208         if (commandLine.hasOption('H')) {
0209           return new ServerOptionsProcessorResponse(new HelpOptionExecutor(serverName, options));
0210         }
0211       } catch (ParseException e) {
0212         // Error out & exit - we were not able to parse the args successfully
0213         System.err.println("Error starting HiveServer2 with given arguments: ");
0214         System.err.println(e.getMessage());
0215         System.exit(-1);
0216       }
0217       // Default executor, when no option is specified
0218       return new ServerOptionsProcessorResponse(new StartOptionExecutor());
0219     }
0220 
0221     StringBuilder getDebugMessage() {
0222       return debugMessage;
0223     }
0224   }
0225 
0226   /**
0227    * The response sent back from {@link ServerOptionsProcessor#parse(String[])}
0228    */
0229   static class ServerOptionsProcessorResponse {
0230     private final ServerOptionsExecutor serverOptionsExecutor;
0231 
0232     ServerOptionsProcessorResponse(ServerOptionsExecutor serverOptionsExecutor) {
0233       this.serverOptionsExecutor = serverOptionsExecutor;
0234     }
0235 
0236     ServerOptionsExecutor getServerOptionsExecutor() {
0237       return serverOptionsExecutor;
0238     }
0239   }
0240 
0241   /**
0242    * The executor interface for running the appropriate HiveServer2 command based on parsed options
0243    */
0244   interface ServerOptionsExecutor {
0245     void execute();
0246   }
0247 
0248   /**
0249    * HelpOptionExecutor: executes the --help option by printing out the usage
0250    */
0251   static class HelpOptionExecutor implements ServerOptionsExecutor {
0252     private final Options options;
0253     private final String serverName;
0254 
0255     HelpOptionExecutor(String serverName, Options options) {
0256       this.options = options;
0257       this.serverName = serverName;
0258     }
0259 
0260     @Override
0261     public void execute() {
0262       new HelpFormatter().printHelp(serverName, options);
0263       System.exit(0);
0264     }
0265   }
0266 
0267   /**
0268    * StartOptionExecutor: starts HiveServer2.
0269    * This is the default executor, when no option is specified.
0270    */
0271   static class StartOptionExecutor implements ServerOptionsExecutor {
0272     @Override
0273     public void execute() {
0274       try {
0275         startHiveServer2();
0276       } catch (Throwable t) {
0277         LOG.error("Error starting HiveServer2", t);
0278         System.exit(-1);
0279       }
0280     }
0281   }
0282 }