You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kyuubi.apache.org by ch...@apache.org on 2022/12/12 04:50:52 UTC

[incubator-kyuubi] branch master updated: [KYUUBI #3887] Provide kyuubiServerPrincipal as alias for principal in JDBC parameter

This is an automated email from the ASF dual-hosted git repository.

chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-kyuubi.git


The following commit(s) were added to refs/heads/master by this push:
     new 70c0451f4 [KYUUBI #3887] Provide kyuubiServerPrincipal as alias for principal in JDBC parameter
70c0451f4 is described below

commit 70c0451f4f670d50a72f093adca0b91fa49f8d1c
Author: Tianlin Liao <ti...@ebay.com>
AuthorDate: Mon Dec 12 12:50:43 2022 +0800

    [KYUUBI #3887] Provide kyuubiServerPrincipal as alias for principal in JDBC parameter
    
    ### _Why are the changes needed?_
    
    Close #3887
    
    ### _How was this patch tested?_
    - [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible
    
    - [ ] Add screenshots for manual tests if appropriate
    
    - [ ] [Run test](https://kyuubi.apache.org/docs/latest/develop_tools/testing.html#running-tests) locally before make a pull request
    
    Closes #3933 from lightning-L/kyuubi-3887.
    
    Closes #3887
    
    65566232 [Tianlin Liao] [KYUUBI #3887] Provide kyuubiServerPrincipal as alias for principal in JDBC parameter
    
    Authored-by: Tianlin Liao <ti...@ebay.com>
    Signed-off-by: Cheng Pan <ch...@apache.org>
---
 docs/client/advanced/kerberos.md                   |  7 +++-
 .../org/apache/hive/beeline/KyuubiCommands.java    | 28 ++++++-------
 .../kyuubi/jdbc/hive/JdbcConnectionParams.java     |  3 ++
 .../apache/kyuubi/jdbc/hive/KyuubiConnection.java  |  6 +++
 .../jdbc/hive/ZooKeeperHiveClientHelper.java       |  5 ++-
 .../KyuubiOperationKerberosAndPlainAuthSuite.scala | 49 +++++++++++++---------
 ...rationThriftHttpKerberosAndPlainAuthSuite.scala |  3 ++
 7 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/docs/client/advanced/kerberos.md b/docs/client/advanced/kerberos.md
index f6d71e8c7..6bdcd7659 100644
--- a/docs/client/advanced/kerberos.md
+++ b/docs/client/advanced/kerberos.md
@@ -214,10 +214,15 @@ The last step is to connect to Kyuubi with the right JDBC URL.
 The JDBC URL should be in format: 
 
 ```
-jdbc:hive2://<kyuubi_server_a ddress>:<kyuubi_server_port>/<db>;principal=<kyuubi_server_principal>
+jdbc:hive2://<kyuubi_server_address>:<kyuubi_server_port>/<db>;principal=<kyuubi_server_principal>
+```
+or
+```
+jdbc:hive2://<kyuubi_server_address>:<kyuubi_server_port>/<db>;kyuubiServerPrincipal=<kyuubi_server_principal>
 ```
 
 **Note**:  
+- `principal` is inherited from Hive JDBC Driver and is a little ambiguous, and we could use `kyuubiServerPrincipal` as its alias.
 - `kyuubi_server_principal` is the value of `kyuubi.kinit.principal` set in `kyuubi-defaults.conf`.
 - As a command line argument, JDBC URL should be quoted to avoid being split into 2 commands by ";".
 - As to DBeaver, `<db>;principal=<kyuubi_server_principal>` should be set as the `Database/Schema` argument.
diff --git a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
index 3ffe7aee7..311495212 100644
--- a/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
+++ b/kyuubi-hive-beeline/src/main/java/org/apache/hive/beeline/KyuubiCommands.java
@@ -17,11 +17,12 @@
 
 package org.apache.hive.beeline;
 
+import static org.apache.kyuubi.jdbc.hive.JdbcConnectionParams.*;
+
 import java.io.*;
 import java.sql.*;
 import java.util.*;
 import org.apache.hive.beeline.logs.KyuubiBeelineInPlaceUpdateStream;
-import org.apache.kyuubi.jdbc.hive.JdbcConnectionParams;
 import org.apache.kyuubi.jdbc.hive.KyuubiStatement;
 import org.apache.kyuubi.jdbc.hive.Utils;
 import org.apache.kyuubi.jdbc.hive.logs.InPlaceUpdateStream;
@@ -423,31 +424,25 @@ public class KyuubiCommands extends Commands {
         getProperty(
             props,
             new String[] {
-              JdbcConnectionParams.PROPERTY_URL, "javax.jdo.option.ConnectionURL", "ConnectionURL",
+              PROPERTY_URL, "javax.jdo.option.ConnectionURL", "ConnectionURL",
             });
     String driver =
         getProperty(
             props,
             new String[] {
-              JdbcConnectionParams.PROPERTY_DRIVER,
-              "javax.jdo.option.ConnectionDriverName",
-              "ConnectionDriverName",
+              PROPERTY_DRIVER, "javax.jdo.option.ConnectionDriverName", "ConnectionDriverName",
             });
     String username =
         getProperty(
             props,
             new String[] {
-              JdbcConnectionParams.AUTH_USER,
-              "javax.jdo.option.ConnectionUserName",
-              "ConnectionUserName",
+              AUTH_USER, "javax.jdo.option.ConnectionUserName", "ConnectionUserName",
             });
     String password =
         getProperty(
             props,
             new String[] {
-              JdbcConnectionParams.AUTH_PASSWD,
-              "javax.jdo.option.ConnectionPassword",
-              "ConnectionPassword",
+              AUTH_PASSWD, "javax.jdo.option.ConnectionPassword", "ConnectionPassword",
             });
 
     if (url == null || url.length() == 0) {
@@ -459,28 +454,29 @@ public class KyuubiCommands extends Commands {
       }
     }
 
-    String auth = getProperty(props, new String[] {JdbcConnectionParams.AUTH_TYPE});
+    String auth = getProperty(props, new String[] {AUTH_TYPE});
     if (auth == null) {
       auth = beeLine.getOpts().getAuthType();
       if (auth != null) {
-        props.setProperty(JdbcConnectionParams.AUTH_TYPE, auth);
+        props.setProperty(AUTH_TYPE, auth);
       }
     }
 
     beeLine.info("Connecting to " + url);
-    if (Utils.parsePropertyFromUrl(url, JdbcConnectionParams.AUTH_PRINCIPAL) == null) {
+    if (Utils.parsePropertyFromUrl(url, AUTH_PRINCIPAL) == null
+        || Utils.parsePropertyFromUrl(url, AUTH_KYUUBI_SERVER_PRINCIPAL) == null) {
       String urlForPrompt = url.substring(0, url.contains(";") ? url.indexOf(';') : url.length());
       if (username == null) {
         username = beeLine.getConsoleReader().readLine("Enter username for " + urlForPrompt + ": ");
       }
-      props.setProperty(JdbcConnectionParams.AUTH_USER, username);
+      props.setProperty(AUTH_USER, username);
       if (password == null) {
         password =
             beeLine
                 .getConsoleReader()
                 .readLine("Enter password for " + urlForPrompt + ": ", new Character('*'));
       }
-      props.setProperty(JdbcConnectionParams.AUTH_PASSWD, password);
+      props.setProperty(AUTH_PASSWD, password);
     }
 
     try {
diff --git a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/JdbcConnectionParams.java b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/JdbcConnectionParams.java
index 385a9d6d6..71949b9df 100644
--- a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/JdbcConnectionParams.java
+++ b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/JdbcConnectionParams.java
@@ -43,6 +43,9 @@ public class JdbcConnectionParams {
   public static final String AUTH_SIMPLE = "noSasl";
   public static final String AUTH_USER = "user";
   public static final String AUTH_PRINCIPAL = "principal";
+  // kyuubiServerPrincipal is alias to principal. And principal will take precedence
+  // over kyuubiServerPrincipal when both are set.
+  public static final String AUTH_KYUUBI_SERVER_PRINCIPAL = "kyuubiServerPrincipal";
   public static final String AUTH_KYUUBI_CLIENT_PRINCIPAL = "kyuubiClientPrincipal";
   public static final String AUTH_KYUUBI_CLIENT_KEYTAB = "kyuubiClientKeytab";
   public static final String AUTH_PASSWD = "password";
diff --git a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiConnection.java b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiConnection.java
index 00d561cea..2811e9d24 100644
--- a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiConnection.java
+++ b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/KyuubiConnection.java
@@ -135,6 +135,12 @@ public class KyuubiConnection implements SQLConnection, KyuubiLoggable {
     }
     jdbcUriString = connParams.getJdbcUriString();
     sessConfMap = connParams.getSessionVars();
+
+    if (!sessConfMap.containsKey(AUTH_PRINCIPAL)
+        && sessConfMap.containsKey(AUTH_KYUUBI_SERVER_PRINCIPAL)) {
+      sessConfMap.put(AUTH_PRINCIPAL, sessConfMap.get(AUTH_KYUUBI_SERVER_PRINCIPAL));
+    }
+
     // JDBC URL: jdbc:hive2://<host>:<port>/dbName;sess_var_list?hive_conf_list#hive_var_list
     // each list: <key1>=<val1>;<key2>=<val2> and so on
     // sess_var_list -> sessConfMap
diff --git a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/ZooKeeperHiveClientHelper.java b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/ZooKeeperHiveClientHelper.java
index c6aad50ae..349fc8dfb 100644
--- a/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/ZooKeeperHiveClientHelper.java
+++ b/kyuubi-hive-jdbc/src/main/java/org/apache/kyuubi/jdbc/hive/ZooKeeperHiveClientHelper.java
@@ -206,7 +206,10 @@ class ZooKeeperHiveClientHelper {
         }
         // KERBEROS
         if (matcher.group(1).equalsIgnoreCase("hive.server2.authentication.kerberos.principal")
-            && !(connParams.getSessionVars().containsKey(JdbcConnectionParams.AUTH_PRINCIPAL))) {
+            && !(connParams.getSessionVars().containsKey(JdbcConnectionParams.AUTH_PRINCIPAL)
+                && !(connParams
+                    .getSessionVars()
+                    .containsKey(JdbcConnectionParams.AUTH_KYUUBI_SERVER_PRINCIPAL)))) {
           connParams.getSessionVars().put(JdbcConnectionParams.AUTH_PRINCIPAL, matcher.group(2));
         }
       }
diff --git a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/KyuubiOperationKerberosAndPlainAuthSuite.scala b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/KyuubiOperationKerberosAndPlainAuthSuite.scala
index 4e9c5dd78..fc8e1ec70 100644
--- a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/KyuubiOperationKerberosAndPlainAuthSuite.scala
+++ b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/KyuubiOperationKerberosAndPlainAuthSuite.scala
@@ -35,8 +35,12 @@ class KyuubiOperationKerberosAndPlainAuthSuite extends WithKyuubiServer with Ker
 
   override protected def jdbcUrl: String = getJdbcUrl
   protected def kerberosTgtJdbcUrl: String = jdbcUrl.stripSuffix(";") + s";principal=$testPrincipal"
+  protected def kerberosTgtJdbcUrlUsingAlias: String =
+    jdbcUrl.stripSuffix(";") + s";kyuubiServerPrincipal=$testPrincipal"
   protected def kerberosKeytabJdbcUrl: String = kerberosTgtJdbcUrl.stripSuffix(";") +
     s";kyuubiClientPrincipal=$testPrincipal;kyuubiClientKeytab=$testKeytab"
+  protected def kerberosKeytabJdbcUrlUsingAlias: String = kerberosTgtJdbcUrlUsingAlias +
+    s";kyuubiClientPrincipal=$testPrincipal;kyuubiClientKeytab=$testKeytab"
   private val currentUser = UserGroupInformation.getCurrentUser
 
   override def beforeAll(): Unit = {
@@ -78,29 +82,34 @@ class KyuubiOperationKerberosAndPlainAuthSuite extends WithKyuubiServer with Ker
     val ret = kinitProc.start().waitFor()
     assert(ret === 0, "kinit failed")
 
-    val conn = DriverManager.getConnection(jdbcUrlWithConf(kerberosTgtJdbcUrl), user, "")
-    try {
-      val statement = conn.createStatement()
-      val resultSet = statement.executeQuery("select engine_name()")
-      assert(resultSet.next())
-      assert(resultSet.getString(1).nonEmpty)
-    } finally {
-      conn.close()
-      "kdestroy".!
-    }
+    Seq(kerberosTgtJdbcUrl, kerberosTgtJdbcUrlUsingAlias).foreach(tgtJdbcUrl => {
+      val conn = DriverManager.getConnection(jdbcUrlWithConf(tgtJdbcUrl), user, "")
+      try {
+        val statement = conn.createStatement()
+        val resultSet = statement.executeQuery("select engine_name()")
+        assert(resultSet.next())
+        assert(resultSet.getString(1).nonEmpty)
+      } finally {
+        conn.close()
+        "kdestroy".!
+      }
+    })
+
   }
 
   test("test with KERBEROS keytab authentication") {
-    val jdbcUrl = jdbcUrlWithConf(kerberosKeytabJdbcUrl)
-    val conn = DriverManager.getConnection(jdbcUrl, user, "")
-    try {
-      val statement = conn.createStatement()
-      val resultSet = statement.executeQuery("select engine_name()")
-      assert(resultSet.next())
-      assert(resultSet.getString(1).nonEmpty)
-    } finally {
-      conn.close()
-    }
+    Seq(kerberosKeytabJdbcUrl, kerberosKeytabJdbcUrlUsingAlias).foreach(keytabJdbcUrl => {
+      val jdbcUrl = jdbcUrlWithConf(keytabJdbcUrl)
+      val conn = DriverManager.getConnection(jdbcUrl, user, "")
+      try {
+        val statement = conn.createStatement()
+        val resultSet = statement.executeQuery("select engine_name()")
+        assert(resultSet.next())
+        assert(resultSet.getString(1).nonEmpty)
+      } finally {
+        conn.close()
+      }
+    })
   }
 
   test("test with LDAP authentication") {
diff --git a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/thrift/http/KyuubiOperationThriftHttpKerberosAndPlainAuthSuite.scala b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/thrift/http/KyuubiOperationThriftHttpKerberosAndPlainAuthSuite.scala
index e0f32e843..4f6ae92f1 100644
--- a/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/thrift/http/KyuubiOperationThriftHttpKerberosAndPlainAuthSuite.scala
+++ b/kyuubi-server/src/test/scala/org/apache/kyuubi/operation/thrift/http/KyuubiOperationThriftHttpKerberosAndPlainAuthSuite.scala
@@ -38,6 +38,9 @@ class KyuubiOperationThriftHttpKerberosAndPlainAuthSuite
   override protected def kerberosTgtJdbcUrl: String =
     jdbcUrl.stripSuffix(";") + s";principal=$testSpnegoPrincipal"
 
+  override protected def kerberosTgtJdbcUrlUsingAlias: String =
+    jdbcUrl.stripSuffix(";") + s";kyuubiServerPrincipal=$testSpnegoPrincipal"
+
   override protected lazy val conf: KyuubiConf = {
     val config = new Configuration()
     val authType = "hadoop.security.authentication"