diff --git a/beeline/src/java/org/apache/hive/beeline/BeeLine.java b/beeline/src/java/org/apache/hive/beeline/BeeLine.java index 402fadddde..208256a00c 100644 --- a/beeline/src/java/org/apache/hive/beeline/BeeLine.java +++ b/beeline/src/java/org/apache/hive/beeline/BeeLine.java @@ -35,7 +35,6 @@ import java.io.SequenceInputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; @@ -75,9 +74,6 @@ import java.util.TreeSet; import java.util.jar.Attributes; import java.util.jar.Manifest; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - import jline.console.completer.Completer; import jline.console.completer.StringsCompleter; import jline.console.completer.FileNameCompleter; @@ -319,6 +315,14 @@ .withDescription("the JDBC URL to connect to") .create('u')); + // -c + options.addOption(OptionBuilder + .hasArg() + .withArgName("named url in beeline-hs2-connection.xml") + .withDescription("the named JDBC URL to connect to which should be present in " + + "beeline-hs2-connection.xml as the value of beeline.hs2.hosts.") + .create('c')); + // -r options.addOption(OptionBuilder .withLongOpt("reconnect") @@ -789,7 +793,7 @@ int initArgs(String[] args) { // and uses it to connect if found // no-op if the file is not present if(!connSuccessful && !exit) { - connSuccessful = defaultBeelineConnect(); + connSuccessful = defaultBeelineConnect(cl); } int code = 0; @@ -1062,10 +1066,10 @@ public int begin(String[] args, InputStream inputStream) throws IOException { * if there connection is not made return false * */ - private boolean defaultBeelineConnect() { + private boolean defaultBeelineConnect(CommandLine cl) { String url; try { - url = getDefaultConnectionUrl(); + url = getDefaultConnectionUrl(cl); if (url == null) { debug("Default hs2 connection config file not found"); return false; @@ -1078,14 +1082,24 @@ private boolean defaultBeelineConnect() { } - private String getDefaultConnectionUrl() throws BeelineHS2ConnectionFileParseException { - HS2ConnectionFileParser userHS2ConnFileParser = getUserHS2ConnFileParser(); + private String getDefaultConnectionUrl(CommandLine cl) throws BeelineHS2ConnectionFileParseException { + UserHS2ConnectionFileParser userHS2ConnFileParser = getUserHS2ConnFileParser(); if (!userHS2ConnFileParser.configExists()) { // nothing to do if there is no user HS2 connection configuration file return null; } + // Get the named url from user specific config file if present + Properties userNamedConnectionURLs = userHS2ConnFileParser.getNamedConnectionURLs(); + if (!userNamedConnectionURLs.isEmpty()) { + String urlName = cl.getOptionValue("c"); + String jdbcURL = HS2ConnectionFileUtils.getNamedUrl(userNamedConnectionURLs, urlName); + if (jdbcURL != null) { + return jdbcURL; + } + } // get the connection properties from user specific config file Properties userConnectionProperties = userHS2ConnFileParser.getConnectionProperties(); + // load the HS2 connection url properties from hive-site.xml if it is present in the classpath HS2ConnectionFileParser hiveSiteParser = getHiveSiteHS2ConnectionFileParser(); Properties hiveSiteConnectionProperties = hiveSiteParser.getConnectionProperties(); @@ -1105,7 +1119,7 @@ private String getDefaultConnectionUrl() throws BeelineHS2ConnectionFileParseExc * Increased visibility of this method is only for providing better test coverage */ @VisibleForTesting - public HS2ConnectionFileParser getUserHS2ConnFileParser() { + public UserHS2ConnectionFileParser getUserHS2ConnFileParser() { return new UserHS2ConnectionFileParser(); } diff --git a/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileParser.java b/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileParser.java index b769e8581f..470d3fac8f 100644 --- a/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileParser.java +++ b/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileParser.java @@ -42,6 +42,14 @@ */ public static final String HOST_PROPERTY_KEY = "hosts"; /** + * Prefix string used for named jdbc uri configs + */ + public static final String BEELINE_CONNECTION_NAMED_JDBC_URL_PREFIX = "beeline.hs2.jdbc.url."; + /** + * Property key used to provide the default named jdbc uri in the config file + */ + public static final String DEFAULT_NAMED_JDBC_URL_PROPERTY_KEY = "default"; + /** * Property key used to provide the hive configuration key value pairs in the connection URL */ public static final String HIVE_CONF_PROPERTY_KEY = "hiveconf"; diff --git a/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileUtils.java b/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileUtils.java index f635b40633..9372a1a7c7 100644 --- a/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileUtils.java +++ b/beeline/src/java/org/apache/hive/beeline/hs2connection/HS2ConnectionFileUtils.java @@ -23,6 +23,8 @@ import java.util.List; import java.util.Properties; +import org.apache.commons.cli.CommandLine; + public class HS2ConnectionFileUtils { public static String getUrl(Properties props) throws BeelineHS2ConnectionFileParseException { @@ -116,4 +118,26 @@ private static void addPropertyValues(String value, StringBuilder hiveProperties hivePropertiesList.append(keyValue[1].trim()); } } + + public static String getNamedUrl(Properties userNamedConnectionURLs, String urlName) + throws BeelineHS2ConnectionFileParseException { + String jdbcURL = null; + if ((urlName != null) && !urlName.isEmpty()) { + // Try to read the given named url from the connection configuration file + jdbcURL = userNamedConnectionURLs.getProperty(urlName); + if (jdbcURL == null) { + throw new BeelineHS2ConnectionFileParseException( + "The named url: " + urlName + " is not specified in the connection configuration file"); + } + return jdbcURL; + } else { + // Try to read the default named url from the connection configuration file + jdbcURL = userNamedConnectionURLs + .getProperty(HS2ConnectionFileParser.DEFAULT_NAMED_JDBC_URL_PROPERTY_KEY); + if (jdbcURL != null) { + return jdbcURL; + } + } + return null; + } } diff --git a/beeline/src/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java b/beeline/src/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java index 2801ebee09..ad1fa8554a 100644 --- a/beeline/src/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java +++ b/beeline/src/java/org/apache/hive/beeline/hs2connection/UserHS2ConnectionFileParser.java @@ -86,9 +86,6 @@ public Properties getConnectionProperties() throws BeelineHS2ConnectionFileParse if (key.startsWith(BEELINE_CONNECTION_PROPERTY_PREFIX)) { props.setProperty(key.substring(BEELINE_CONNECTION_PROPERTY_PREFIX.length()), kv.getValue()); - } else { - log.warn("Ignoring " + key + " since it does not start with " - + BEELINE_CONNECTION_PROPERTY_PREFIX); } } } catch (Exception ex) { @@ -114,4 +111,30 @@ String getFileLocation() { } return null; } + + public Properties getNamedConnectionURLs() throws BeelineHS2ConnectionFileParseException { + Properties props = new Properties(); + String fileLocation = getFileLocation(); + if (fileLocation == null) { + log.debug("User connection configuration file not found"); + return props; + } + log.info("Using connection configuration file at " + fileLocation); + // load the properties from config file + Configuration conf = new Configuration(false); + conf.addResource(new Path(new File(fileLocation).toURI())); + try { + for (Entry kv : conf) { + String key = kv.getKey(); + if (key.startsWith(BEELINE_CONNECTION_NAMED_JDBC_URL_PREFIX)) { + props.setProperty(key.substring(BEELINE_CONNECTION_NAMED_JDBC_URL_PREFIX.length()), + kv.getValue()); + } + } + } catch (Exception ex) { + throw new BeelineHS2ConnectionFileParseException(ex.getMessage(), ex); + } + + return props; + } } \ No newline at end of file diff --git a/beeline/src/main/resources/BeeLine.properties b/beeline/src/main/resources/BeeLine.properties index 6fca953836..c560e4f937 100644 --- a/beeline/src/main/resources/BeeLine.properties +++ b/beeline/src/main/resources/BeeLine.properties @@ -157,6 +157,9 @@ interrupt-ctrl-c: Interrupting... Please be patient this may take some time. cmd-usage: Usage: java org.apache.hive.cli.beeline.BeeLine \n \ \ -u the JDBC URL to connect to\n \ +\ -c the named JDBC URL to connect to,\n \ +\ which should be present in beeline-hs2-connection.xml\n \ +\ as the value of beeline.hs2.jdbc.url.\n \ \ -r reconnect to last saved connect url (in conjunction with !save)\n \ \ -n the username to connect as\n \ \ -p the password to connect as\n \ diff --git a/beeline/src/test/org/apache/hive/beeline/hs2connection/TestUserHS2ConnectionFileParser.java b/beeline/src/test/org/apache/hive/beeline/hs2connection/TestUserHS2ConnectionFileParser.java index 1d17887417..3e76cccf60 100644 --- a/beeline/src/test/org/apache/hive/beeline/hs2connection/TestUserHS2ConnectionFileParser.java +++ b/beeline/src/test/org/apache/hive/beeline/hs2connection/TestUserHS2ConnectionFileParser.java @@ -55,14 +55,14 @@ public void cleanUp() { @Test public void testParseNoAuthentication() throws BeelineHS2ConnectionFileParseException { - String url = getParsedUrlFromConfigFile("test-hs2-connection-config-noauth.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-connection-config-noauth.xml", null); String expectedUrl = "jdbc:hive2://localhost:10000/default;user=hive"; Assert.assertTrue("Expected " + expectedUrl + " got " + url, expectedUrl.equals(url)); } @Test public void testParseZookeeper() throws BeelineHS2ConnectionFileParseException { - String url = getParsedUrlFromConfigFile("test-hs2-connection-zookeeper-config.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-connection-zookeeper-config.xml", null); String expectedUrl = "jdbc:hive2://zk-node-1:10000,zk-node-2:10001,zk-node-3:10004/default;serviceDiscoveryMode=zookeeper;zooKeeperNamespace=hiveserver2"; Assert.assertTrue("Expected " + expectedUrl + " got " + url, expectedUrl.equals(url)); @@ -70,7 +70,7 @@ public void testParseZookeeper() throws BeelineHS2ConnectionFileParseException { @Test public void testParseWithKerberosNoSSL() throws BeelineHS2ConnectionFileParseException { - String url = getParsedUrlFromConfigFile("test-hs2-conn-conf-kerberos-nossl.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-conn-conf-kerberos-nossl.xml", null); String expectedUrl = "jdbc:hive2://localhost:10000/default;principal=hive/dummy-hostname@domain.com;ssl=false"; Assert.assertTrue("Expected " + expectedUrl + " got " + url, expectedUrl.equals(url)); @@ -78,7 +78,7 @@ public void testParseWithKerberosNoSSL() throws BeelineHS2ConnectionFileParseExc @Test public void testParseWithKerberosSSL() throws BeelineHS2ConnectionFileParseException { - String url = getParsedUrlFromConfigFile("test-hs2-conn-conf-kerberos-ssl.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-conn-conf-kerberos-ssl.xml", null); String expectedUrl = "jdbc:hive2://localhost:10000/default;principal=hive/dummy-hostname@domain.com;ssl=true;" + "sslTrustStore=test/truststore;trustStorePassword=testTruststorePassword"; @@ -87,7 +87,7 @@ public void testParseWithKerberosSSL() throws BeelineHS2ConnectionFileParseExcep @Test public void testParseWithSSLAndHttpMode() throws BeelineHS2ConnectionFileParseException { - String url = getParsedUrlFromConfigFile("test-hs2-conn-conf-kerberos-http.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-conn-conf-kerberos-http.xml", null); String expectedUrl = "jdbc:hive2://localhost:10000/default;httpPath=testHTTPPath;principal=hive/dummy-hostname@domain.com;" + "ssl=true;sslTrustStore=test/truststore;transportMode=http;trustStorePassword=testTruststorePassword"; @@ -96,7 +96,7 @@ public void testParseWithSSLAndHttpMode() throws BeelineHS2ConnectionFileParseEx @Test public void testUrlWithHiveConfValues() throws Exception { - String url = getParsedUrlFromConfigFile("test-hs2-connection-conf-list.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-connection-conf-list.xml", null); String expectedUrl = "jdbc:hive2://localhost:10000/default;user=hive?hive.cli.print.current.db=false#testVarName1=value1"; Assert.assertTrue("Expected " + expectedUrl + " got " + url, expectedUrl.equals(url)); @@ -104,7 +104,7 @@ public void testUrlWithHiveConfValues() throws Exception { @Test public void testUrlWithMultipleHiveConfValues() throws Exception { - String url = getParsedUrlFromConfigFile("test-hs2-connection-multi-conf-list.xml"); + String url = getParsedUrlFromConfigFile("test-hs2-connection-multi-conf-list.xml", null); String expectedUrl = "jdbc:hive2://localhost:10000/default;user=hive?hive.cli.print.current.db=true;" + "hive.cli.print.header=true#testVarName1=value1;testVarName2=value2"; @@ -171,14 +171,33 @@ public void testGetLocationOrder() throws Exception { LOCATION_2.equals(testHS2ConfigManager.getFileLocation())); } - private String getParsedUrlFromConfigFile(String filename) + @Test + public void testParseWithNamedUrl() throws BeelineHS2ConnectionFileParseException { + String urlName = HS2ConnectionFileParser.DEFAULT_NAMED_JDBC_URL_PROPERTY_KEY; + String url = getParsedUrlFromConfigFile("test-hs2-named-connection-config.xml", urlName); + String expectedUrl = "jdbc:hive2://localhost:10000"; + Assert.assertTrue("Expected " + expectedUrl + " got " + url, expectedUrl.equals(url)); + urlName = "httpHS2"; + url = getParsedUrlFromConfigFile("test-hs2-named-connection-config.xml", urlName); + expectedUrl = + "jdbc:hive2://localhost:10000/default;httpPath=testHTTPPath;principal=hive/dummy-hostname@domain.com;" + + "ssl=true;sslTrustStore=test/truststore;transportMode=http;trustStorePassword=testTruststorePassword"; + Assert.assertTrue("Expected " + expectedUrl + " got " + url, expectedUrl.equals(url)); + } + + private String getParsedUrlFromConfigFile(String filename, String urlName) throws BeelineHS2ConnectionFileParseException { String path = HiveTestUtils.getFileFromClasspath(filename); testLocations.add(path); UserHS2ConnectionFileParser testHS2ConfigManager = new UserHS2ConnectionFileParser(testLocations); - - String url = HS2ConnectionFileUtils.getUrl(testHS2ConfigManager.getConnectionProperties()); + String url; + if (urlName != null) { + url = HS2ConnectionFileUtils.getNamedUrl(testHS2ConfigManager.getNamedConnectionURLs(), + urlName); + } else { + url = HS2ConnectionFileUtils.getUrl(testHS2ConfigManager.getConnectionProperties()); + } return url; } diff --git a/beeline/src/test/resources/test-hs2-named-connection-config.xml b/beeline/src/test/resources/test-hs2-named-connection-config.xml new file mode 100644 index 0000000000..5c158930e0 --- /dev/null +++ b/beeline/src/test/resources/test-hs2-named-connection-config.xml @@ -0,0 +1,28 @@ + + + + + + beeline.hs2.jdbc.url.default + jdbc:hive2://localhost:10000 + + + beeline.hs2.jdbc.url.httpHS2 + jdbc:hive2://localhost:10000/default;httpPath=testHTTPPath;principal=hive/dummy-hostname@domain.com;ssl=true;sslTrustStore=test/truststore;transportMode=http;trustStorePassword=testTruststorePassword + + \ No newline at end of file diff --git a/itests/hive-unit/src/test/java/org/apache/hive/beeline/hs2connection/BeelineWithHS2ConnectionFileTestBase.java b/itests/hive-unit/src/test/java/org/apache/hive/beeline/hs2connection/BeelineWithHS2ConnectionFileTestBase.java index 3da31ad8a9..2ed631ab70 100644 --- a/itests/hive-unit/src/test/java/org/apache/hive/beeline/hs2connection/BeelineWithHS2ConnectionFileTestBase.java +++ b/itests/hive-unit/src/test/java/org/apache/hive/beeline/hs2connection/BeelineWithHS2ConnectionFileTestBase.java @@ -89,7 +89,7 @@ public String getOutput() throws UnsupportedEncodingException { } @Override - public HS2ConnectionFileParser getUserHS2ConnFileParser() { + public UserHS2ConnectionFileParser getUserHS2ConnFileParser() { return testHs2ConfigFileManager; }