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

yao 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 8f3cca9  [KYUUBI #1106] Implement 
/sessions/${identifier}/info/${infotype}
8f3cca9 is described below

commit 8f3cca9f97ca053f8c9b3936e0e6f7286777a58a
Author: simon <[email protected]>
AuthorDate: Thu Nov 4 18:56:44 2021 +0800

    [KYUUBI #1106] Implement /sessions/${identifier}/info/${infotype}
    
    ### _Why are the changes needed?_
    This is a subtask of umbrella issue #KPIP-1
    
    ### _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.readthedocs.io/en/latest/develop_tools/testing.html#running-tests)
 locally before make a pull request
    
    Closes #1317 from simon824/getinfo.
    
    Closes #1106
    
    d00b05f9 [simon] fix codestyle
    312726a5 [simon] fix
    0e7a2ce7 [simon] negativetest
    6bb9b6f0 [simon] codestyle
    24ca381a [simon] rename InfoDetail
    32a836ee [Simon] Merge branch 'apache:master' into getinfo
    474d858b [simon] getinfo
    4f26c59a [simon] reduce sleep time
    ebb6afb5 [simon] fixut
    6c366c0b [simon] init
    
    Lead-authored-by: simon <[email protected]>
    Co-authored-by: Simon <[email protected]>
    Signed-off-by: Kent Yao <[email protected]>
---
 .../kyuubi/server/api/v1/SessionsResource.scala    | 59 +++++++++++++++++-----
 .../org/apache/kyuubi/server/api/v1/dto.scala      |  5 ++
 .../server/api/v1/SessionsResourceSuite.scala      | 42 +++++++++++++--
 3 files changed, 89 insertions(+), 17 deletions(-)

diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/SessionsResource.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/SessionsResource.scala
index ab14c34..e39e647 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/SessionsResource.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/SessionsResource.scala
@@ -22,9 +22,11 @@ import javax.ws.rs._
 import javax.ws.rs.core.{MediaType, Response}
 
 import scala.collection.JavaConverters._
+import scala.util.control.NonFatal
 
-import org.apache.hive.service.rpc.thrift.TProtocolVersion
+import org.apache.hive.service.rpc.thrift.{TGetInfoType, TProtocolVersion}
 
+import org.apache.kyuubi.Utils.error
 import org.apache.kyuubi.cli.HandleIdentifier
 import org.apache.kyuubi.server.api.ApiRequestContext
 import org.apache.kyuubi.session.SessionHandle
@@ -45,19 +47,33 @@ private[v1] class SessionsResource extends 
ApiRequestContext {
   @GET
   @Path("{sessionHandle}")
   def sessionInfo(@PathParam("sessionHandle") sessionHandleStr: String): 
SessionDetail = {
-    val splitSessionHandle = sessionHandleStr.split("\\|")
-    val handleIdentifier = new HandleIdentifier(
-      UUID.fromString(splitSessionHandle(0)), 
UUID.fromString(splitSessionHandle(1)))
-    val protocolVersion = 
TProtocolVersion.findByValue(splitSessionHandle(2).toInt)
-    val sessionHandle = new SessionHandle(handleIdentifier, protocolVersion)
+    val sessionHandle = getSessionHandle(sessionHandleStr)
 
     try {
       val session = backendService.sessionManager.getSession(sessionHandle)
       SessionDetail(session.user, session.ipAddress, session.createTime, 
sessionHandle,
         session.lastAccessTime, session.lastIdleTime, 
session.getNoOperationTime, session.conf)
     } catch {
-      case _: Throwable =>
-        throw new NotFoundException()
+      case NonFatal(e) =>
+        error(s"Invalid $sessionHandle", e)
+        throw new NotFoundException(s"Invalid $sessionHandle")
+    }
+  }
+
+  @GET
+  @Path("{sessionHandle}/info/{infoType}")
+  def getInfo(@PathParam("sessionHandle") sessionHandleStr: String,
+              @PathParam("infoType") infoType: Int): InfoDetail = {
+    val sessionHandle = getSessionHandle(sessionHandleStr)
+    val info = TGetInfoType.findByValue(infoType)
+
+    try {
+      val infoValue = backendService.getInfo(sessionHandle, info)
+      InfoDetail(info.toString, infoValue.getStringValue)
+    } catch {
+      case NonFatal(e) =>
+        error(s"Unrecognized GetInfoType value: $infoType", e)
+        throw new NotFoundException(s"Unrecognized GetInfoType value: 
$infoType")
     }
   }
 
@@ -68,7 +84,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
   }
 
   @GET
-  @Path("execpool/statistic")
+  @Path("execPool/statistic")
   def execPoolStatistic(): ExecPoolStatistic = {
     ExecPoolStatistic(backendService.sessionManager.getExecPoolSize,
       backendService.sessionManager.getActiveCount)
@@ -88,12 +104,27 @@ private[v1] class SessionsResource extends 
ApiRequestContext {
   @DELETE
   @Path("{sessionHandle}")
   def closeSession(@PathParam("sessionHandle") sessionHandleStr: String): 
Response = {
-    val splitSessionHandle = sessionHandleStr.split("\\|")
-    val handleIdentifier = new HandleIdentifier(
-      UUID.fromString(splitSessionHandle(0)), 
UUID.fromString(splitSessionHandle(1)))
-    val protocolVersion = 
TProtocolVersion.findByValue(splitSessionHandle(2).toInt)
-    val sessionHandle = new SessionHandle(handleIdentifier, protocolVersion)
+    val sessionHandle = getSessionHandle(sessionHandleStr)
     backendService.closeSession(sessionHandle)
     Response.ok().build()
   }
+
+  def getSessionHandle(sessionHandleStr: String): SessionHandle = {
+    try {
+      val splitSessionHandle = sessionHandleStr.split("\\|")
+      val handleIdentifier = new HandleIdentifier(
+        UUID.fromString(splitSessionHandle(0)), 
UUID.fromString(splitSessionHandle(1)))
+      val protocolVersion = 
TProtocolVersion.findByValue(splitSessionHandle(2).toInt)
+      val sessionHandle = new SessionHandle(handleIdentifier, protocolVersion)
+
+      // if the sessionHandle is invalid, KyuubiSQLException will be thrown 
here.
+      backendService.sessionManager.getSession(sessionHandle)
+      sessionHandle
+    } catch {
+      case NonFatal(e) =>
+        error(s"Error getting sessionHandle by $sessionHandleStr.", e)
+        throw new NotFoundException(s"Error getting sessionHandle by 
$sessionHandleStr.")
+    }
+
+  }
 }
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/dto.scala 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/dto.scala
index 7b84821..e3c2a8d 100644
--- a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/dto.scala
+++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/dto.scala
@@ -32,6 +32,11 @@ case class SessionOverview(
   sessionHandle: SessionHandle
 )
 
+case class InfoDetail(
+  infoType: String,
+  infoValue: String
+)
+
 case class SessionDetail(
   user: String,
   ipAddr: String,
diff --git 
a/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/SessionsResourceSuite.scala
 
b/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/SessionsResourceSuite.scala
index 2a2ed5b..ef5853b 100644
--- 
a/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/SessionsResourceSuite.scala
+++ 
b/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/SessionsResourceSuite.scala
@@ -92,19 +92,19 @@ class SessionsResourceSuite extends KyuubiFunSuite {
         })
 
         // verify the exec pool statistic
-        var response = 
webTarget.path("api/v1/sessions/execpool/statistic").request().get()
+        var response = 
webTarget.path("api/v1/sessions/execPool/statistic").request().get()
         val execPoolStatistic1 = 
response.readEntity(classOf[ExecPoolStatistic])
         assert(execPoolStatistic1.execPoolSize == 1 && 
execPoolStatistic1.execPoolActiveCount == 1)
 
         future.cancel(true)
         eventually(timeout(3.seconds), interval(200.milliseconds)) {
-          response = 
webTarget.path("api/v1/sessions/execpool/statistic").request().get()
+          response = 
webTarget.path("api/v1/sessions/execPool/statistic").request().get()
           val statistic = response.readEntity(classOf[ExecPoolStatistic])
           assert(statistic.execPoolSize == 1 && statistic.execPoolActiveCount 
== 0)
         }
 
         sessionManager.stop()
-        response = 
webTarget.path("api/v1/sessions/execpool/statistic").request().get()
+        response = 
webTarget.path("api/v1/sessions/execPool/statistic").request().get()
         val execPoolStatistic3 = 
response.readEntity(classOf[ExecPoolStatistic])
         assert(execPoolStatistic3.execPoolSize == 0 && 
execPoolStatistic3.execPoolActiveCount == 0)
 
@@ -171,4 +171,40 @@ class SessionsResourceSuite extends KyuubiFunSuite {
         assert(404 == response.getStatus)
     }
   }
+
+  test("test get infoType") {
+    val requestObj = SessionOpenRequest(
+      1, "admin", "123456", "localhost", Map("testConfig" -> "testValue"))
+
+    RestFrontendServiceSuite.withKyuubiRestServer {
+      (_, _, _, webTarget) =>
+        var response: Response = webTarget.path("api/v1/sessions")
+          .request(MediaType.APPLICATION_JSON_TYPE)
+          .post(Entity.entity(requestObj, MediaType.APPLICATION_JSON_TYPE))
+
+        val sessionHandle = response.readEntity(classOf[SessionHandle])
+        val serializedSessionHandle = s"${sessionHandle.identifier.publicId}|" 
+
+          
s"${sessionHandle.identifier.secretId}|${sessionHandle.protocol.getValue}"
+
+        response = 
webTarget.path(s"api/v1/sessions/$serializedSessionHandle/info/13")
+          .request().get()
+        assert(200 == response.getStatus)
+        val sessions = response.readEntity(classOf[InfoDetail])
+        assert(sessions.infoType.equals("CLI_SERVER_NAME") && 
sessions.infoValue.equals("Kyuubi"))
+        // Invalid sessionHandleStr
+        val handle = 
"b88d6b56-d200-4bb6-bf0a-5da0ea572e11|0c4aad4e-ccf7-4abd-9305-943d4bfd2d9a|0"
+        response = 
webTarget.path(s"api/v1/sessions/$handle/info/13").request().get()
+        assert(404 == response.getStatus)
+        response = webTarget.path(s"api/v1/sessions/0/info/13").request().get()
+        assert(404 == response.getStatus)
+
+        // Invalid infoType
+        response = 
webTarget.path(s"api/v1/sessions/$serializedSessionHandle/info/0")
+          .request().get()
+        assert(404 == response.getStatus)
+        response = 
webTarget.path(s"api/v1/sessions/$serializedSessionHandle/info/str")
+          .request().get()
+        assert(404 == response.getStatus)
+    }
+  }
 }

Reply via email to