diff --git beeline/src/java/org/apache/hive/beeline/BeeLine.java beeline/src/java/org/apache/hive/beeline/BeeLine.java index dcdd6f2..ed3350a 100644 --- beeline/src/java/org/apache/hive/beeline/BeeLine.java +++ beeline/src/java/org/apache/hive/beeline/BeeLine.java @@ -84,6 +84,7 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; +import org.apache.commons.io.IOUtils; /** * A console SQL shell with command completion. @@ -284,6 +285,14 @@ .withDescription("the password to connect as") .create('p')); + // -w (or) --password-file + options.addOption(OptionBuilder + .hasArg() + .withArgName("password-file") + .withDescription("the password file to read password from") + .withLongOpt("password-file") + .create('w')); + // -a options.addOption(OptionBuilder .hasArg() @@ -641,7 +650,11 @@ boolean initArgs(String[] args) { auth = cl.getOptionValue("a"); user = cl.getOptionValue("n"); getOpts().setAuthType(auth); - pass = cl.getOptionValue("p"); + if (cl.hasOption("w")) { + pass = obtainPasswordFromFile(cl.getOptionValue("w")); + } else { + pass = cl.getOptionValue("p"); + } url = cl.getOptionValue("u"); getOpts().setScriptFile(cl.getOptionValue("f")); if (cl.getOptionValues('e') != null) { @@ -690,6 +703,18 @@ boolean initArgs(String[] args) { return true; } + /** + * Obtains a password from the passed file path. + */ + private String obtainPasswordFromFile(String passwordFilePath) { + try { + InputStream passwordIs = new FileInputStream(passwordFilePath); + byte[] passwordFileContents = IOUtils.toByteArray(passwordIs); + return new String(passwordFileContents, "UTF-8").trim(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } /** * Start accepting input from stdin, and dispatch it diff --git beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java index b78b7ad..ad0ee00 100644 --- beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java +++ beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java @@ -21,6 +21,9 @@ import java.util.ArrayList; import java.util.List; +import java.io.File; +import java.io.FileOutputStream; + import junit.framework.Assert; import org.junit.Test; @@ -61,6 +64,25 @@ public void testSimpleArgs() throws Exception { Assert.assertTrue(bl.getOpts().getAuthType().equals("authType")); } + @Test + public void testPasswordFileArgs() throws Exception { + TestBeeline bl = new TestBeeline(); + File passFile = new File("file.password"); + passFile.deleteOnExit(); + FileOutputStream passFileOut = new FileOutputStream(passFile); + passFileOut.write("mypass\n".getBytes()); + passFileOut.close(); + String args[] = new String[] {"-u", "url", "-n", "name", + "-w", "file.password", "-p", "not-taken-if-w-is-present", + "-d", "driver", "-a", "authType"}; + Assert.assertTrue(bl.initArgs(args)); + System.out.println(bl.connectArgs); + // Password file contents are trimmed of trailing whitespaces and newlines + Assert.assertTrue(bl.connectArgs.equals("url name mypass driver")); + Assert.assertTrue(bl.getOpts().getAuthType().equals("authType")); + passFile.delete(); + } + /** * The first flag is taken by the parser. */