diff --git a/beeline/src/java/org/apache/hive/beeline/BeeLine.java b/beeline/src/java/org/apache/hive/beeline/BeeLine.java index 630ead4..c60c11d 100644 --- a/beeline/src/java/org/apache/hive/beeline/BeeLine.java +++ b/beeline/src/java/org/apache/hive/beeline/BeeLine.java @@ -39,6 +39,9 @@ import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; @@ -87,7 +90,6 @@ import org.apache.commons.cli.ParseException; import org.apache.hadoop.io.IOUtils; - /** * A console SQL shell with command completion. *

@@ -294,6 +296,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() @@ -660,7 +670,11 @@ int 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().setInitFile(cl.getOptionValue("i")); getOpts().setScriptFile(cl.getOptionValue("f")); @@ -708,6 +722,19 @@ int initArgs(String[] args) { return code; } + /** + * Obtains a password from the passed file path. + */ + private String obtainPasswordFromFile(String passwordFilePath) { + try { + Path path = Paths.get(passwordFilePath); + byte[] passwordFileContents = Files.readAllBytes(path); + return new String(passwordFileContents, "UTF-8").trim(); + } catch (Exception e) { + throw new RuntimeException("Unable to read user password from the password file: " + + passwordFilePath, e); + } + } /** * Start accepting input from stdin, and dispatch it diff --git a/beeline/src/main/resources/BeeLine.properties b/beeline/src/main/resources/BeeLine.properties index d038d46..2e987fd 100644 --- a/beeline/src/main/resources/BeeLine.properties +++ b/beeline/src/main/resources/BeeLine.properties @@ -148,6 +148,7 @@ cmd-usage: Usage: java org.apache.hive.cli.beeline.BeeLine \n \ \ -i script file for initialization\n \ \ -e query that should be executed\n \ \ -f script file that should be executed\n \ +\ -w (or) --password-file the password file to read password from\n \ \ --hiveconf property=value Use value for given property\n \ \ --hivevar name=value hive variable name and value\n \ \ This is Hive specific settings in which variables\n \ diff --git a/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java b/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java index a6ee93a..15133c1 100644 --- a/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java +++ b/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,24 @@ 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"}; + 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. */