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

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


The following commit(s) were added to refs/heads/master by this push:
     new cb689b66b [KYUUBI #4914] [AUTHZ] Reuse extractor singleton instance 
with generalized getter for supported extractor types
cb689b66b is described below

commit cb689b66b1ed745a5e38dea37a2b0f1d9e7f1aca
Author: liangbowen <[email protected]>
AuthorDate: Mon Jun 5 13:11:34 2023 +0800

    [KYUUBI #4914] [AUTHZ] Reuse extractor singleton instance with generalized 
getter for supported extractor types
    
    ### _Why are the changes needed?_
    
    - Reuse extractor singleton instance for less memory footprint, as Authz's 
extractors are stateless and ready for sharing
    - Reneralized getter crossing supported extractor types
       - get extractor by class type
       - get extractor by explicit class name
    
    ### _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
    
    - [x] [Run 
test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests)
 locally before make a pull request
    
    Closes #4914 from bowenliang123/authz-get-extractor.
    
    Closes #4914
    
    11dde777f [liangbowen] update
    77ce00276 [liangbowen] make extractorKey of lookupExtractor not null by 
default
    5f5b6e580 [liangbowen] Revert "extractorKey: String = null => extractorKey: 
Option[String] = None"
    400c3b054 [liangbowen] extractorKey: String = null => extractorKey: 
Option[String] = None
    60acd27ec [liangbowen] rename `getExtractor` to `lookupExtractor`
    e6fbb450f [liangbowen] generalize getExtractor for getting instance of 
supported types of extractors
    
    Authored-by: liangbowen <[email protected]>
    Signed-off-by: liangbowen <[email protected]>
---
 .../plugin/spark/authz/serde/Descriptor.scala      | 33 +++++++------------
 .../spark/authz/serde/catalogExtractors.scala      |  2 +-
 .../spark/authz/serde/databaseExtractors.scala     |  4 +--
 .../spark/authz/serde/functionTypeExtractors.scala |  4 +--
 .../kyuubi/plugin/spark/authz/serde/package.scala  | 38 ++++++++++++++++++++++
 .../plugin/spark/authz/serde/tableExtractors.scala | 18 +++++-----
 6 files changed, 64 insertions(+), 35 deletions(-)

diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/Descriptor.scala
 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/Descriptor.scala
index b72f3296b..3eb3fecea 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/Descriptor.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/Descriptor.scala
@@ -23,17 +23,8 @@ import 
org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
 
 import org.apache.kyuubi.plugin.spark.authz.PrivilegeObjectActionType
 import 
org.apache.kyuubi.plugin.spark.authz.PrivilegeObjectActionType.PrivilegeObjectActionType
-import 
org.apache.kyuubi.plugin.spark.authz.serde.ActionTypeExtractor.actionTypeExtractors
-import 
org.apache.kyuubi.plugin.spark.authz.serde.CatalogExtractor.catalogExtractors
-import 
org.apache.kyuubi.plugin.spark.authz.serde.ColumnExtractor.columnExtractors
-import 
org.apache.kyuubi.plugin.spark.authz.serde.DatabaseExtractor.dbExtractors
-import 
org.apache.kyuubi.plugin.spark.authz.serde.FunctionExtractor.functionExtractors
 import org.apache.kyuubi.plugin.spark.authz.serde.FunctionType.FunctionType
-import 
org.apache.kyuubi.plugin.spark.authz.serde.FunctionTypeExtractor.functionTypeExtractors
-import 
org.apache.kyuubi.plugin.spark.authz.serde.QueryExtractor.queryExtractors
-import 
org.apache.kyuubi.plugin.spark.authz.serde.TableExtractor.tableExtractors
 import org.apache.kyuubi.plugin.spark.authz.serde.TableType.TableType
-import 
org.apache.kyuubi.plugin.spark.authz.serde.TableTypeExtractor.tableTypeExtractors
 import org.apache.kyuubi.util.reflect.ReflectUtils._
 
 /**
@@ -82,7 +73,7 @@ case class ColumnDesc(
     fieldExtractor: String) extends Descriptor {
   override def extract(v: AnyRef): Seq[String] = {
     val columnsVal = invoke(v, fieldName)
-    val columnExtractor = columnExtractors(fieldExtractor)
+    val columnExtractor = lookupExtractor[ColumnExtractor](fieldExtractor)
     columnExtractor(columnsVal)
   }
 }
@@ -101,7 +92,7 @@ case class DatabaseDesc(
     isInput: Boolean = false) extends Descriptor {
   override def extract(v: AnyRef): Database = {
     val databaseVal = invoke(v, fieldName)
-    val databaseExtractor = dbExtractors(fieldExtractor)
+    val databaseExtractor = lookupExtractor[DatabaseExtractor](fieldExtractor)
     val db = databaseExtractor(databaseVal)
     if (db.catalog.isEmpty && catalogDesc.nonEmpty) {
       val maybeCatalog = catalogDesc.get.extract(v)
@@ -129,7 +120,7 @@ case class FunctionTypeDesc(
 
   def extract(v: AnyRef, spark: SparkSession): FunctionType = {
     val functionTypeVal = invoke(v, fieldName)
-    val functionTypeExtractor = functionTypeExtractors(fieldExtractor)
+    val functionTypeExtractor = 
lookupExtractor[FunctionTypeExtractor](fieldExtractor)
     functionTypeExtractor(functionTypeVal, spark)
   }
 
@@ -155,7 +146,7 @@ case class FunctionDesc(
     isInput: Boolean = false) extends Descriptor {
   override def extract(v: AnyRef): Function = {
     val functionVal = invoke(v, fieldName)
-    val functionExtractor = functionExtractors(fieldExtractor)
+    val functionExtractor = lookupExtractor[FunctionExtractor](fieldExtractor)
     var function = functionExtractor(functionVal)
     if (function.database.isEmpty) {
       val maybeDatabase = databaseDesc.map(_.extract(v))
@@ -180,7 +171,7 @@ case class QueryDesc(
     fieldExtractor: String = "LogicalPlanQueryExtractor") extends Descriptor {
   override def extract(v: AnyRef): Option[LogicalPlan] = {
     val queryVal = invoke(v, fieldName)
-    val queryExtractor = queryExtractors(fieldExtractor)
+    val queryExtractor = lookupExtractor[QueryExtractor](fieldExtractor)
     queryExtractor(queryVal)
   }
 }
@@ -202,7 +193,7 @@ case class TableTypeDesc(
 
   def extract(v: AnyRef, spark: SparkSession): TableType = {
     val tableTypeVal = invoke(v, fieldName)
-    val tableTypeExtractor = tableTypeExtractors(fieldExtractor)
+    val tableTypeExtractor = 
lookupExtractor[TableTypeExtractor](fieldExtractor)
     tableTypeExtractor(tableTypeVal, spark)
   }
 
@@ -240,7 +231,7 @@ case class TableDesc(
 
   def extract(v: AnyRef, spark: SparkSession): Option[Table] = {
     val tableVal = invoke(v, fieldName)
-    val tableExtractor = tableExtractors(fieldExtractor)
+    val tableExtractor = lookupExtractor[TableExtractor](fieldExtractor)
     val maybeTable = tableExtractor(spark, tableVal)
     maybeTable.map { t =>
       if (t.catalog.isEmpty && catalogDesc.nonEmpty) {
@@ -267,8 +258,8 @@ case class ActionTypeDesc(
   override def extract(v: AnyRef): PrivilegeObjectActionType = {
     actionType.map(PrivilegeObjectActionType.withName).getOrElse {
       val actionTypeVal = invoke(v, fieldName)
-      val extractor = actionTypeExtractors(fieldExtractor)
-      extractor(actionTypeVal)
+      val actionTypeExtractor = 
lookupExtractor[ActionTypeExtractor](fieldExtractor)
+      actionTypeExtractor(actionTypeVal)
     }
   }
 }
@@ -284,8 +275,8 @@ case class CatalogDesc(
     fieldExtractor: String = "CatalogPluginCatalogExtractor") extends 
Descriptor {
   override def extract(v: AnyRef): Option[String] = {
     val catalogVal = invoke(v, fieldName)
-    val extractor = catalogExtractors(fieldExtractor)
-    extractor(catalogVal)
+    val catalogExtractor = lookupExtractor[CatalogExtractor](fieldExtractor)
+    catalogExtractor(catalogVal)
   }
 }
 
@@ -303,7 +294,7 @@ case class ScanDesc(
     } else {
       invoke(v, fieldName)
     }
-    val tableExtractor = tableExtractors(fieldExtractor)
+    val tableExtractor = lookupExtractor[TableExtractor](fieldExtractor)
     val maybeTable = tableExtractor(spark, tableVal)
     maybeTable.map { t =>
       if (t.catalog.isEmpty && catalogDesc.nonEmpty) {
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/catalogExtractors.scala
 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/catalogExtractors.scala
index f87943943..e48becb32 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/catalogExtractors.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/catalogExtractors.scala
@@ -43,7 +43,7 @@ class CatalogPluginOptionCatalogExtractor extends 
CatalogExtractor {
   override def apply(v1: AnyRef): Option[String] = {
     v1 match {
       case Some(catalogPlugin: AnyRef) =>
-        new CatalogPluginCatalogExtractor().apply(catalogPlugin)
+        lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogPlugin)
       case _ => None
     }
   }
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/databaseExtractors.scala
 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/databaseExtractors.scala
index d14ba7805..f952c816e 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/databaseExtractors.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/databaseExtractors.scala
@@ -70,7 +70,7 @@ class StringSeqOptionDatabaseExtractor extends 
DatabaseExtractor {
 class ResolvedNamespaceDatabaseExtractor extends DatabaseExtractor {
   override def apply(v1: AnyRef): Database = {
     val catalogVal = invoke(v1, "catalog")
-    val catalog = new CatalogPluginCatalogExtractor().apply(catalogVal)
+    val catalog = 
lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogVal)
     val namespace = getFieldVal[Seq[String]](v1, "namespace")
     Database(catalog, quote(namespace))
   }
@@ -82,7 +82,7 @@ class ResolvedNamespaceDatabaseExtractor extends 
DatabaseExtractor {
 class ResolvedDBObjectNameDatabaseExtractor extends DatabaseExtractor {
   override def apply(v1: AnyRef): Database = {
     val catalogVal = invoke(v1, "catalog")
-    val catalog = new CatalogPluginCatalogExtractor().apply(catalogVal)
+    val catalog = 
lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogVal)
     val namespace = getFieldVal[Seq[String]](v1, "nameParts")
     Database(catalog, quote(namespace))
   }
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/functionTypeExtractors.scala
 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/functionTypeExtractors.scala
index 4c5e9dc84..b70410342 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/functionTypeExtractors.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/functionTypeExtractors.scala
@@ -53,9 +53,9 @@ class TempMarkerFunctionTypeExtractor extends 
FunctionTypeExtractor {
  */
 class ExpressionInfoFunctionTypeExtractor extends FunctionTypeExtractor {
   override def apply(v1: AnyRef, spark: SparkSession): FunctionType = {
-    val function = new ExpressionInfoFunctionExtractor().apply(v1)
+    val function = lookupExtractor[ExpressionInfoFunctionExtractor].apply(v1)
     val fi = FunctionIdentifier(function.functionName, function.database)
-    new FunctionIdentifierFunctionTypeExtractor().apply(fi, spark)
+    lookupExtractor[FunctionIdentifierFunctionTypeExtractor].apply(fi, spark)
   }
 }
 
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/package.scala
 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/package.scala
index d9f646900..c992a231a 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/package.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/package.scala
@@ -25,6 +25,15 @@ import com.fasterxml.jackson.module.scala.DefaultScalaModule
 import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
 
 import org.apache.kyuubi.plugin.spark.authz.OperationType.{OperationType, 
QUERY}
+import 
org.apache.kyuubi.plugin.spark.authz.serde.ActionTypeExtractor.actionTypeExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.CatalogExtractor.catalogExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.ColumnExtractor.columnExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.DatabaseExtractor.dbExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.FunctionExtractor.functionExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.FunctionTypeExtractor.functionTypeExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.QueryExtractor.queryExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.TableExtractor.tableExtractors
+import 
org.apache.kyuubi.plugin.spark.authz.serde.TableTypeExtractor.tableTypeExtractors
 import org.apache.kyuubi.util.reflect.ReflectUtils._
 
 package object serde {
@@ -82,4 +91,33 @@ package object serde {
       .map(s => s.operationType)
       .getOrElse(QUERY)
   }
+
+  /**
+   * get extractor instance by extractor class name
+   * @param extractorKey explicitly load extractor by its simple class name.
+   *                           null by default means get extractor by 
extractor class.
+   * @param ct class tag of extractor class type
+   * @tparam T extractor class type
+   * @return
+   */
+  def lookupExtractor[T <: Extractor](extractorKey: String)(
+      implicit ct: ClassTag[T]): T = {
+    val extractorClass = ct.runtimeClass
+    val extractors: Map[String, Extractor] = extractorClass match {
+      case c if classOf[CatalogExtractor].isAssignableFrom(c) => 
catalogExtractors
+      case c if classOf[DatabaseExtractor].isAssignableFrom(c) => dbExtractors
+      case c if classOf[TableExtractor].isAssignableFrom(c) => tableExtractors
+      case c if classOf[TableTypeExtractor].isAssignableFrom(c) => 
tableTypeExtractors
+      case c if classOf[ColumnExtractor].isAssignableFrom(c) => 
columnExtractors
+      case c if classOf[QueryExtractor].isAssignableFrom(c) => queryExtractors
+      case c if classOf[FunctionExtractor].isAssignableFrom(c) => 
functionExtractors
+      case c if classOf[FunctionTypeExtractor].isAssignableFrom(c) => 
functionTypeExtractors
+      case c if classOf[ActionTypeExtractor].isAssignableFrom(c) => 
actionTypeExtractors
+      case _ => throw new IllegalArgumentException(s"Unknown extractor type: 
$ct")
+    }
+    extractors(extractorKey).asInstanceOf[T]
+  }
+
+  def lookupExtractor[T <: Extractor](implicit ct: ClassTag[T]): T =
+    lookupExtractor[T](ct.runtimeClass.getSimpleName)(ct)
 }
diff --git 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/tableExtractors.scala
 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/tableExtractors.scala
index 8743f054d..4579349ee 100644
--- 
a/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/tableExtractors.scala
+++ 
b/extensions/spark/kyuubi-spark-authz/src/main/scala/org/apache/kyuubi/plugin/spark/authz/serde/tableExtractors.scala
@@ -88,7 +88,7 @@ class CatalogTableTableExtractor extends TableExtractor {
 class CatalogTableOptionTableExtractor extends TableExtractor {
   override def apply(spark: SparkSession, v1: AnyRef): Option[Table] = {
     val catalogTable = v1.asInstanceOf[Option[CatalogTable]]
-    catalogTable.flatMap(new CatalogTableTableExtractor().apply(spark, _))
+    
catalogTable.flatMap(lookupExtractor[CatalogTableTableExtractor].apply(spark, 
_))
   }
 }
 
@@ -98,9 +98,9 @@ class CatalogTableOptionTableExtractor extends TableExtractor 
{
 class ResolvedTableTableExtractor extends TableExtractor {
   override def apply(spark: SparkSession, v1: AnyRef): Option[Table] = {
     val catalogVal = invoke(v1, "catalog")
-    val catalog = new CatalogPluginCatalogExtractor().apply(catalogVal)
+    val catalog = 
lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogVal)
     val identifier = invoke(v1, "identifier")
-    val maybeTable = new IdentifierTableExtractor().apply(spark, identifier)
+    val maybeTable = lookupExtractor[IdentifierTableExtractor].apply(spark, 
identifier)
     val maybeOwner = TableExtractor.getOwner(v1)
     maybeTable.map(_.copy(catalog = catalog, owner = maybeOwner))
   }
@@ -129,10 +129,10 @@ class DataSourceV2RelationTableExtractor extends 
TableExtractor {
       case Some(v2Relation) =>
         val maybeCatalogPlugin = invokeAs[Option[AnyRef]](v2Relation, 
"catalog")
         val maybeCatalog = maybeCatalogPlugin.flatMap(catalogPlugin =>
-          new CatalogPluginCatalogExtractor().apply(catalogPlugin))
+          lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogPlugin))
         val maybeIdentifier = invokeAs[Option[AnyRef]](v2Relation, 
"identifier")
         maybeIdentifier.flatMap { id =>
-          val maybeTable = new IdentifierTableExtractor().apply(spark, id)
+          val maybeTable = 
lookupExtractor[IdentifierTableExtractor].apply(spark, id)
           val maybeOwner = TableExtractor.getOwner(v2Relation)
           maybeTable.map(_.copy(catalog = maybeCatalog, owner = maybeOwner))
         }
@@ -147,7 +147,7 @@ class LogicalRelationTableExtractor extends TableExtractor {
   override def apply(spark: SparkSession, v1: AnyRef): Option[Table] = {
     val maybeCatalogTable = invokeAs[Option[AnyRef]](v1, "catalogTable")
     maybeCatalogTable.flatMap { ct =>
-      new CatalogTableTableExtractor().apply(spark, ct)
+      lookupExtractor[CatalogTableTableExtractor].apply(spark, ct)
     }
   }
 }
@@ -158,7 +158,7 @@ class LogicalRelationTableExtractor extends TableExtractor {
 class ResolvedDbObjectNameTableExtractor extends TableExtractor {
   override def apply(spark: SparkSession, v1: AnyRef): Option[Table] = {
     val catalogVal = invoke(v1, "catalog")
-    val catalog = new CatalogPluginCatalogExtractor().apply(catalogVal)
+    val catalog = 
lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogVal)
     val nameParts = invokeAs[Seq[String]](v1, "nameParts")
     val namespace = nameParts.init.toArray
     val table = nameParts.last
@@ -174,9 +174,9 @@ class ResolvedIdentifierTableExtractor extends 
TableExtractor {
     v1.getClass.getName match {
       case "org.apache.spark.sql.catalyst.analysis.ResolvedIdentifier" =>
         val catalogVal = invoke(v1, "catalog")
-        val catalog = new CatalogPluginCatalogExtractor().apply(catalogVal)
+        val catalog = 
lookupExtractor[CatalogPluginCatalogExtractor].apply(catalogVal)
         val identifier = invoke(v1, "identifier")
-        val maybeTable = new IdentifierTableExtractor().apply(spark, 
identifier)
+        val maybeTable = 
lookupExtractor[IdentifierTableExtractor].apply(spark, identifier)
         maybeTable.map(_.copy(catalog = catalog))
       case _ => None
     }

Reply via email to