| /** |
| * 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.hcatalog.cli; |
| |
| import java.io.BufferedReader; |
| import java.io.FileNotFoundException; |
| import java.io.FileReader; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.PrintStream; |
| import java.io.PrintWriter; |
| import java.io.UnsupportedEncodingException; |
| import java.util.ArrayList; |
| import java.util.Properties; |
| |
| import org.apache.commons.cli.CommandLine; |
| import org.apache.commons.cli.GnuParser; |
| import org.apache.commons.cli.HelpFormatter; |
| import org.apache.commons.cli.Option; |
| import org.apache.commons.cli.OptionBuilder; |
| import org.apache.commons.cli.Options; |
| import org.apache.commons.cli.ParseException; |
| import org.apache.commons.cli.Parser; |
| import org.apache.commons.lang.StringUtils; |
| import org.apache.hadoop.fs.permission.FsPermission; |
| import org.apache.hadoop.hive.cli.CliSessionState; |
| import org.apache.hadoop.hive.common.LogUtils; |
| import org.apache.hadoop.hive.common.LogUtils.LogInitializationException; |
| import org.apache.hadoop.hive.conf.HiveConf; |
| import org.apache.hadoop.hive.conf.HiveConf.ConfVars; |
| import org.apache.hadoop.hive.ql.CommandNeedRetryException; |
| import org.apache.hadoop.hive.ql.processors.DfsProcessor; |
| import org.apache.hadoop.hive.ql.processors.SetProcessor; |
| import org.apache.hadoop.hive.ql.session.SessionState; |
| import org.apache.hcatalog.cli.SemanticAnalysis.HCatSemanticAnalyzer; |
| import org.apache.hcatalog.common.HCatConstants; |
| import org.apache.hcatalog.common.HCatUtil; |
| |
| public class HCatCli { |
| |
| @SuppressWarnings("static-access") |
| public static void main(String[] args) { |
| |
| try { |
| LogUtils.initHiveLog4j(); |
| } catch (LogInitializationException e) { |
| |
| } |
| |
| CliSessionState ss = new CliSessionState(new HiveConf(SessionState.class)); |
| ss.in = System.in; |
| try { |
| ss.out = new PrintStream(System.out, true, "UTF-8"); |
| ss.err = new PrintStream(System.err, true, "UTF-8"); |
| } catch (UnsupportedEncodingException e) { |
| System.exit(1); |
| } |
| |
| HiveConf conf = ss.getConf(); |
| |
| HiveConf.setVar(conf, ConfVars.SEMANTIC_ANALYZER_HOOK, HCatSemanticAnalyzer.class.getName()); |
| |
| SessionState.start(ss); |
| |
| Options options = new Options(); |
| |
| // -e 'quoted-query-string' |
| options.addOption(OptionBuilder |
| .hasArg() |
| .withArgName("exec") |
| .withDescription("hcat command given from command line") |
| .create('e')); |
| |
| // -f <query-file> |
| options.addOption(OptionBuilder |
| .hasArg() |
| .withArgName("file") |
| .withDescription("hcat commands in file") |
| .create('f')); |
| |
| // -g |
| options.addOption(OptionBuilder |
| .hasArg(). |
| withArgName("group"). |
| withDescription("group for the db/table specified in CREATE statement"). |
| create('g')); |
| |
| // -p |
| options.addOption(OptionBuilder |
| .hasArg() |
| .withArgName("perms") |
| .withDescription("permissions for the db/table specified in CREATE statement") |
| .create('p')); |
| |
| // -D |
| options.addOption(OptionBuilder |
| .hasArgs(2) |
| .withArgName("property=value") |
| .withValueSeparator() |
| .withDescription("use hadoop value for given property") |
| .create('D')); |
| |
| // [-h|--help] |
| options.addOption(new Option("h", "help", false, "Print help information")); |
| |
| Parser parser = new GnuParser(); |
| CommandLine cmdLine = null; |
| |
| try { |
| cmdLine = parser.parse(options, args); |
| |
| } catch (ParseException e) { |
| printUsage(options, ss.err); |
| System.exit(1); |
| } |
| // -e |
| String execString = (String) cmdLine.getOptionValue('e'); |
| // -f |
| String fileName = (String) cmdLine.getOptionValue('f'); |
| // -h |
| if (cmdLine.hasOption('h')) { |
| printUsage(options, ss.out); |
| System.exit(0); |
| } |
| |
| if (execString != null && fileName != null) { |
| ss.err.println("The '-e' and '-f' options cannot be specified simultaneously"); |
| printUsage(options, ss.err); |
| System.exit(1); |
| } |
| |
| // -p |
| String perms = (String) cmdLine.getOptionValue('p'); |
| if (perms != null) { |
| validatePermissions(ss, conf, perms); |
| } |
| |
| // -g |
| String grp = (String) cmdLine.getOptionValue('g'); |
| if (grp != null) { |
| conf.set(HCatConstants.HCAT_GROUP, grp); |
| } |
| |
| // -D |
| setConfProperties(conf, cmdLine.getOptionProperties("D")); |
| |
| if (execString != null) { |
| System.exit(processLine(execString)); |
| } |
| |
| try { |
| if (fileName != null) { |
| System.exit(processFile(fileName)); |
| } |
| } catch (FileNotFoundException e) { |
| ss.err.println("Input file not found. (" + e.getMessage() + ")"); |
| System.exit(1); |
| } catch (IOException e) { |
| ss.err.println("Could not open input file for reading. (" + e.getMessage() + ")"); |
| System.exit(1); |
| } |
| |
| // -h |
| printUsage(options, ss.err); |
| System.exit(1); |
| } |
| |
| private static void setConfProperties(HiveConf conf, Properties props) { |
| for (java.util.Map.Entry<Object, Object> e : props.entrySet()) |
| conf.set((String) e.getKey(), (String) e.getValue()); |
| } |
| |
| private static int processLine(String line) { |
| int ret = 0; |
| |
| String command = ""; |
| for (String oneCmd : line.split(";")) { |
| |
| if (StringUtils.endsWith(oneCmd, "\\")) { |
| command += StringUtils.chop(oneCmd) + ";"; |
| continue; |
| } else { |
| command += oneCmd; |
| } |
| if (StringUtils.isBlank(command)) { |
| continue; |
| } |
| |
| ret = processCmd(command); |
| command = ""; |
| } |
| return ret; |
| } |
| |
| private static int processFile(String fileName) throws IOException { |
| FileReader fileReader = null; |
| BufferedReader reader = null; |
| try { |
| fileReader = new FileReader(fileName); |
| reader = new BufferedReader(fileReader); |
| String line; |
| StringBuilder qsb = new StringBuilder(); |
| |
| while ((line = reader.readLine()) != null) { |
| qsb.append(line + "\n"); |
| } |
| |
| return (processLine(qsb.toString())); |
| } finally { |
| if (fileReader != null) { |
| fileReader.close(); |
| } |
| if (reader != null) { |
| reader.close(); |
| } |
| } |
| } |
| |
| private static int processCmd(String cmd) { |
| |
| SessionState ss = SessionState.get(); |
| long start = System.currentTimeMillis(); |
| |
| cmd = cmd.trim(); |
| String firstToken = cmd.split("\\s+")[0].trim(); |
| |
| if (firstToken.equalsIgnoreCase("set")) { |
| return new SetProcessor().run(cmd.substring(firstToken.length()).trim()).getResponseCode(); |
| } else if (firstToken.equalsIgnoreCase("dfs")) { |
| return new DfsProcessor(ss.getConf()).run(cmd.substring(firstToken.length()).trim()).getResponseCode(); |
| } |
| |
| HCatDriver driver = new HCatDriver(); |
| |
| int ret = driver.run(cmd).getResponseCode(); |
| |
| if (ret != 0) { |
| driver.close(); |
| System.exit(ret); |
| } |
| |
| ArrayList<String> res = new ArrayList<String>(); |
| try { |
| while (driver.getResults(res)) { |
| for (String r : res) { |
| ss.out.println(r); |
| } |
| res.clear(); |
| } |
| } catch (IOException e) { |
| ss.err.println("Failed with exception " + e.getClass().getName() + ":" |
| + e.getMessage() + "\n" + org.apache.hadoop.util.StringUtils.stringifyException(e)); |
| ret = 1; |
| } catch (CommandNeedRetryException e) { |
| ss.err.println("Failed with exception " + e.getClass().getName() + ":" |
| + e.getMessage() + "\n" + org.apache.hadoop.util.StringUtils.stringifyException(e)); |
| ret = 1; |
| } |
| |
| int cret = driver.close(); |
| if (ret == 0) { |
| ret = cret; |
| } |
| |
| long end = System.currentTimeMillis(); |
| if (end > start) { |
| double timeTaken = (end - start) / 1000.0; |
| ss.err.println("Time taken: " + timeTaken + " seconds"); |
| } |
| return ret; |
| } |
| |
| private static void printUsage(Options options, OutputStream os) { |
| PrintWriter pw = new PrintWriter(os); |
| new HelpFormatter().printHelp(pw, 2 * HelpFormatter.DEFAULT_WIDTH, |
| "hcat { -e \"<query>\" | -f \"<filepath>\" } [ -g \"<group>\" ] [ -p \"<perms>\" ] [ -D\"<name>=<value>\" ]", |
| null, options, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, |
| null, false); |
| pw.flush(); |
| } |
| |
| private static void validatePermissions(CliSessionState ss, HiveConf conf, String perms) { |
| perms = perms.trim(); |
| FsPermission fp = null; |
| |
| if (perms.matches("^\\s*([r,w,x,-]{9})\\s*$")) { |
| fp = FsPermission.valueOf("d" + perms); |
| } else if (perms.matches("^\\s*([0-7]{3})\\s*$")) { |
| fp = new FsPermission(Short.decode("0" + perms)); |
| } else { |
| ss.err.println("Invalid permission specification: " + perms); |
| System.exit(1); |
| } |
| |
| if (!HCatUtil.validateMorePermissive(fp.getUserAction(), fp.getGroupAction())) { |
| ss.err.println("Invalid permission specification: " + perms + " : user permissions must be more permissive than group permission "); |
| System.exit(1); |
| } |
| if (!HCatUtil.validateMorePermissive(fp.getGroupAction(), fp.getOtherAction())) { |
| ss.err.println("Invalid permission specification: " + perms + " : group permissions must be more permissive than other permission "); |
| System.exit(1); |
| } |
| if ((!HCatUtil.validateExecuteBitPresentIfReadOrWrite(fp.getUserAction())) || |
| (!HCatUtil.validateExecuteBitPresentIfReadOrWrite(fp.getGroupAction())) || |
| (!HCatUtil.validateExecuteBitPresentIfReadOrWrite(fp.getOtherAction()))) { |
| ss.err.println("Invalid permission specification: " + perms + " : permissions must have execute permissions if read or write permissions are specified "); |
| System.exit(1); |
| } |
| |
| conf.set(HCatConstants.HCAT_PERMS, "d" + fp.toString()); |
| |
| } |
| |
| |
| } |