You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kyuubi.apache.org by ya...@apache.org on 2021/12/29 05:10:33 UTC
[incubator-kyuubi] branch master updated: [KYUUBI #1639] Make ApiRequestContext provide KyuubiRestFrontendService directly
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 c4fd287 [KYUUBI #1639] Make ApiRequestContext provide KyuubiRestFrontendService directly
c4fd287 is described below
commit c4fd287c8bc8241c5417186136531e32345f5fc1
Author: Kent Yao <ya...@apache.org>
AuthorDate: Wed Dec 29 13:10:22 2021 +0800
[KYUUBI #1639] Make ApiRequestContext provide KyuubiRestFrontendService directly
<!--
Thanks for sending a pull request!
Here are some tips for you:
1. If this is your first time, please read our contributor guidelines: https://kyuubi.readthedocs.io/en/latest/community/contributions.html
2. If the PR is related to an issue in https://github.com/apache/incubator-kyuubi/issues, add '[KYUUBI #XXXX]' in your PR title, e.g., '[KYUUBI #XXXX] Your PR title ...'.
3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., '[WIP][KYUUBI #XXXX] Your PR title ...'.
-->
### _Why are the changes needed?_
<!--
Please clarify why the changes are needed. For instance,
1. If you add a feature, you can talk about the use case of it.
2. If you fix a bug, you can clarify why it is a bug.
-->
Make full use of KyuubiRestFrontendService without hacking, e.g. for the swagger UI base.
We can do further improvement based on this PR.
### _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 #1639 from yaooqinn/ApiRequestContext.
Closes #1639
3c0c7061 [Kent Yao] Make ApiRequestContext provides KyuubiRestFrontendService directly
10506c2c [Kent Yao] Make ApiRequestContext provides KyuubiRestFrontendService directly
1482bd78 [Kent Yao] Make ApiRequestContext provides KyuubiRestFrontendService directly
01a0b023 [Kent Yao] Make ApiRequestContext provides KyuubiRestFrontendService directly
d3119fa4 [Kent Yao] Make ApiRequestContext provides KyuubiRestFrontendService directly
0f45258c [Kent Yao] Make ApiRequestContext provides KyuubiRestFrontendService directly
Authored-by: Kent Yao <ya...@apache.org>
Signed-off-by: Kent Yao <ya...@apache.org>
---
.../kyuubi/server/KyuubiRestFrontendService.scala | 4 +-
.../scala/org/apache/kyuubi/server/api/api.scala | 41 ++++-----------------
.../kyuubi/server/api/v1/ApiRootResource.scala | 43 ++++++++++++++++------
.../kyuubi/server/api/v1/OperationsResource.scala | 10 ++---
.../kyuubi/server/api/v1/SessionsResource.scala | 35 +++++++++---------
5 files changed, 64 insertions(+), 69 deletions(-)
diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
index ea3486c..9179155 100644
--- a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
+++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
@@ -26,7 +26,7 @@ import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler
import org.apache.kyuubi.{KyuubiException, Logging, Utils}
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf.{FRONTEND_REST_BIND_HOST, FRONTEND_REST_BIND_PORT}
-import org.apache.kyuubi.server.api.ApiUtils
+import org.apache.kyuubi.server.api.v1.ApiRootResource
import org.apache.kyuubi.service.{AbstractFrontendService, Serverable, Service}
/**
@@ -56,7 +56,7 @@ class KyuubiRestFrontendService(override val serverable: Serverable)
errorHandler.setServer(jettyServer)
jettyServer.addBean(errorHandler)
- jettyServer.setHandler(ApiUtils.getServletHandler(serverable.backendService))
+ jettyServer.setHandler(ApiRootResource.getServletHandler(this))
connector = new ServerConnector(
jettyServer,
diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/api.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/api.scala
index a64934b..ec1cade 100644
--- a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/api.scala
+++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/api.scala
@@ -22,11 +22,8 @@ import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.Context
import org.eclipse.jetty.server.handler.ContextHandler
-import org.eclipse.jetty.servlet.{DefaultServlet, ServletContextHandler, ServletHolder}
-import org.glassfish.jersey.server.ResourceConfig
-import org.glassfish.jersey.servlet.ServletContainer
-import org.apache.kyuubi.service.BackendService
+import org.apache.kyuubi.server.KyuubiRestFrontendService
private[api] trait ApiRequestContext {
@@ -36,42 +33,18 @@ private[api] trait ApiRequestContext {
@Context
protected var httpRequest: HttpServletRequest = _
- def backendService: BackendService = BackendServiceProvider.getBackendService(servletContext)
-
+ final protected def fe: KyuubiRestFrontendService = FrontendServiceContext.get(servletContext)
}
-private[api] object BackendServiceProvider {
+private[api] object FrontendServiceContext {
private val attribute = getClass.getCanonicalName
- def setBackendService(contextHandler: ContextHandler, be: BackendService): Unit = {
- contextHandler.setAttribute(attribute, be)
- }
-
- def getBackendService(context: ServletContext): BackendService = {
- context.getAttribute(attribute).asInstanceOf[BackendService]
+ def set(contextHandler: ContextHandler, fe: KyuubiRestFrontendService): Unit = {
+ contextHandler.setAttribute(attribute, fe)
}
-}
-
-private[server] object ApiUtils {
-
- def getServletHandler(backendService: BackendService): ServletContextHandler = {
- val openapiConf: ResourceConfig = new OpenAPIConfig
- val servlet = new ServletHolder(new ServletContainer(openapiConf))
- val handler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS)
- BackendServiceProvider.setBackendService(handler, backendService)
- handler.addServlet(servlet, "/*")
- // install swagger-ui, these static files are copied from
- // https://github.com/swagger-api/swagger-ui/tree/master/dist
- val swaggerUI = new ServletHolder("swagger-ui", classOf[DefaultServlet])
- swaggerUI.setInitParameter(
- "resourceBase",
- getClass.getClassLoader()
- .getResource("META-INF/resources/webjars/swagger-ui/4.1.3/")
- .toExternalForm)
- swaggerUI.setInitParameter("pathInfoOnly", "true")
- handler.addServlet(swaggerUI, "/swagger-ui-redirected/*");
- handler
+ def get(context: ServletContext): KyuubiRestFrontendService = {
+ context.getAttribute(attribute).asInstanceOf[KyuubiRestFrontendService]
}
}
diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/ApiRootResource.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/ApiRootResource.scala
index c9052b8..a2eba10 100644
--- a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/ApiRootResource.scala
+++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/ApiRootResource.scala
@@ -22,9 +22,12 @@ import javax.ws.rs.{GET, Path, Produces}
import javax.ws.rs.core.{MediaType, Response}
import com.google.common.annotations.VisibleForTesting
+import org.eclipse.jetty.servlet.{DefaultServlet, ServletContextHandler, ServletHolder}
+import org.glassfish.jersey.server.ResourceConfig
+import org.glassfish.jersey.servlet.ServletContainer
-import org.apache.kyuubi.server.{KyuubiRestFrontendService, KyuubiServer}
-import org.apache.kyuubi.server.api.ApiRequestContext
+import org.apache.kyuubi.server.KyuubiRestFrontendService
+import org.apache.kyuubi.server.api.{ApiRequestContext, FrontendServiceContext, OpenAPIConfig}
@Path("/api/v1")
private[v1] class ApiRootResource extends ApiRequestContext {
@@ -52,15 +55,33 @@ private[v1] class ApiRootResource extends ApiRequestContext {
@GET
@Path("swagger-ui")
@Produces(Array(MediaType.TEXT_HTML))
- def swaggerUi(): Response = {
- val restServiceOpt = KyuubiServer.kyuubiServer
- .frontendServices
- .collectFirst { case rest: KyuubiRestFrontendService => rest }
- assert(restServiceOpt.isDefined)
- val serverIP = restServiceOpt.map(_.connectionUrl).get
- val swaggerUi =
- s"http://$serverIP/swagger-ui-redirected/index.html?url=http://$serverIP/openapi.json"
- Response.temporaryRedirect(new URI(swaggerUi)).build()
+ def swaggerUI(): Response = {
+ val swaggerUI = s"http://${fe.connectionUrl}/swagger-ui-redirected/index.html?url=" +
+ s"http://${fe.connectionUrl}/openapi.json"
+ Response.temporaryRedirect(new URI(swaggerUI)).build()
}
}
+
+private[server] object ApiRootResource {
+
+ def getServletHandler(fe: KyuubiRestFrontendService): ServletContextHandler = {
+ val openapiConf: ResourceConfig = new OpenAPIConfig
+ val servlet = new ServletHolder(new ServletContainer(openapiConf))
+ val handler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS)
+ FrontendServiceContext.set(handler, fe)
+ handler.addServlet(servlet, "/*")
+
+ // install swagger-ui, these static files are copied from
+ // https://github.com/swagger-api/swagger-ui/tree/master/dist
+ val swaggerUI = new ServletHolder("swagger-ui", classOf[DefaultServlet])
+ swaggerUI.setInitParameter(
+ "resourceBase",
+ getClass.getClassLoader()
+ .getResource("META-INF/resources/webjars/swagger-ui/4.1.3/")
+ .toExternalForm)
+ swaggerUI.setInitParameter("pathInfoOnly", "true")
+ handler.addServlet(swaggerUI, "/swagger-ui-redirected/*");
+ handler
+ }
+}
diff --git a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/OperationsResource.scala b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/OperationsResource.scala
index 66c2943..0c731a9 100644
--- a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/OperationsResource.scala
+++ b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/OperationsResource.scala
@@ -50,7 +50,7 @@ private[v1] class OperationsResource extends ApiRequestContext {
@PathParam("operationHandle") operationHandleStr: String): KyuubiOperationEvent = {
try {
val opHandle = parseOperationHandle(operationHandleStr)
- val operation = backendService.sessionManager.operationManager.getOperation(opHandle)
+ val operation = fe.be.sessionManager.operationManager.getOperation(opHandle)
KyuubiOperationEvent(operation.asInstanceOf[KyuubiOperation])
} catch {
case NonFatal(_) =>
@@ -72,8 +72,8 @@ private[v1] class OperationsResource extends ApiRequestContext {
try {
val operationHandle = parseOperationHandle(operationHandleStr)
request.action.toLowerCase() match {
- case "cancel" => backendService.cancelOperation(operationHandle)
- case "close" => backendService.closeOperation(operationHandle)
+ case "cancel" => fe.be.cancelOperation(operationHandle)
+ case "close" => fe.be.closeOperation(operationHandle)
case _ => throw KyuubiSQLException(s"Invalid action ${request.action}")
}
Response.ok().build()
@@ -97,7 +97,7 @@ private[v1] class OperationsResource extends ApiRequestContext {
try {
val operationHandle = parseOperationHandle(operationHandleStr)
ResultSetMetaData(
- backendService.getResultSetMetadata(operationHandle).getColumns.asScala.map(c => {
+ fe.be.getResultSetMetadata(operationHandle).getColumns.asScala.map(c => {
val tPrimitiveTypeEntry = c.getTypeDesc.getTypes.get(0).getPrimitiveEntry
var precision = 0
var scale = 0
@@ -134,7 +134,7 @@ private[v1] class OperationsResource extends ApiRequestContext {
@PathParam("operationHandle") operationHandleStr: String,
@QueryParam("maxrows") maxRows: Int): OperationLog = {
try {
- val rowSet = backendService.sessionManager.operationManager.getOperationLogRowSet(
+ val rowSet = fe.be.sessionManager.operationManager.getOperationLogRowSet(
parseOperationHandle(operationHandleStr),
FetchOrientation.FETCH_NEXT,
maxRows)
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 b138167..391151f 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
@@ -48,7 +48,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@GET
def sessionInfoList(): SessionList = {
SessionList(
- backendService.sessionManager.getSessionList().asScala.map {
+ fe.be.sessionManager.getSessionList().asScala.map {
case (handle, session) =>
SessionOverview(session.user, session.ipAddress, session.createTime, handle)
}.toSeq)
@@ -63,7 +63,8 @@ private[v1] class SessionsResource extends ApiRequestContext {
@Path("{sessionHandle}")
def sessionInfo(@PathParam("sessionHandle") sessionHandleStr: String): KyuubiSessionEvent = {
try {
- KyuubiSessionEvent(backendService.sessionManager.getSession(
+ // TODO: need to use KyuubiSessionEvent in session
+ KyuubiSessionEvent(fe.be.sessionManager.getSession(
parseSessionHandle(sessionHandleStr)).asInstanceOf[AbstractSession])
} catch {
case NonFatal(e) =>
@@ -85,7 +86,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@PathParam("infoType") infoType: Int): InfoDetail = {
try {
val info = TGetInfoType.findByValue(infoType)
- val infoValue = backendService.getInfo(parseSessionHandle(sessionHandleStr), info)
+ val infoValue = fe.be.getInfo(parseSessionHandle(sessionHandleStr), info)
InfoDetail(info.toString, infoValue.getStringValue)
} catch {
case NonFatal(e) =>
@@ -102,7 +103,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@GET
@Path("count")
def sessionCount(): SessionOpenCount = {
- SessionOpenCount(backendService.sessionManager.getOpenSessionCount)
+ SessionOpenCount(fe.be.sessionManager.getOpenSessionCount)
}
@ApiResponse(
@@ -114,8 +115,8 @@ private[v1] class SessionsResource extends ApiRequestContext {
@Path("execPool/statistic")
def execPoolStatistic(): ExecPoolStatistic = {
ExecPoolStatistic(
- backendService.sessionManager.getExecPoolSize,
- backendService.sessionManager.getActiveCount)
+ fe.be.sessionManager.getExecPoolSize,
+ fe.be.sessionManager.getActiveCount)
}
@ApiResponse(
@@ -126,7 +127,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@POST
@Consumes(Array(MediaType.APPLICATION_JSON))
def openSession(request: SessionOpenRequest): SessionHandle = {
- backendService.openSession(
+ fe.be.openSession(
TProtocolVersion.findByValue(request.protocolVersion),
request.user,
request.password,
@@ -142,7 +143,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@DELETE
@Path("{sessionHandle}")
def closeSession(@PathParam("sessionHandle") sessionHandleStr: String): Response = {
- backendService.closeSession(parseSessionHandle(sessionHandleStr))
+ fe.be.closeSession(parseSessionHandle(sessionHandleStr))
Response.ok().build()
}
@@ -157,7 +158,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@PathParam("sessionHandle") sessionHandleStr: String,
request: StatementRequest): OperationHandle = {
try {
- backendService.executeStatement(
+ fe.be.executeStatement(
parseSessionHandle(sessionHandleStr),
request.statement,
request.runAsync,
@@ -177,7 +178,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@Path("{sessionHandle}/operations/typeInfo")
def getTypeInfo(@PathParam("sessionHandle") sessionHandleStr: String): OperationHandle = {
try {
- backendService.getTypeInfo(parseSessionHandle(sessionHandleStr))
+ fe.be.getTypeInfo(parseSessionHandle(sessionHandleStr))
} catch {
case NonFatal(_) =>
throw new NotFoundException(s"Error getting type information")
@@ -193,7 +194,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@Path("{sessionHandle}/operations/catalogs")
def getCatalogs(@PathParam("sessionHandle") sessionHandleStr: String): OperationHandle = {
try {
- backendService.getCatalogs(parseSessionHandle(sessionHandleStr))
+ fe.be.getCatalogs(parseSessionHandle(sessionHandleStr))
} catch {
case NonFatal(_) =>
throw new NotFoundException(s"Error getting catalogs")
@@ -212,7 +213,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
request: GetSchemasRequest): OperationHandle = {
try {
val sessionHandle = parseSessionHandle(sessionHandleStr)
- val operationHandle = backendService.getSchemas(
+ val operationHandle = fe.be.getSchemas(
sessionHandle,
request.catalogName,
request.schemaName)
@@ -234,7 +235,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@PathParam("sessionHandle") sessionHandleStr: String,
request: GetTablesRequest): OperationHandle = {
try {
- backendService.getTables(
+ fe.be.getTables(
parseSessionHandle(sessionHandleStr),
request.catalogName,
request.schemaName,
@@ -255,7 +256,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@Path("{sessionHandle}/operations/tableTypes")
def getTableTypes(@PathParam("sessionHandle") sessionHandleStr: String): OperationHandle = {
try {
- backendService.getTableTypes(parseSessionHandle(sessionHandleStr))
+ fe.be.getTableTypes(parseSessionHandle(sessionHandleStr))
} catch {
case NonFatal(_) =>
throw new NotFoundException(s"Error getting table types")
@@ -273,7 +274,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@PathParam("sessionHandle") sessionHandleStr: String,
request: GetColumnsRequest): OperationHandle = {
try {
- backendService.getColumns(
+ fe.be.getColumns(
parseSessionHandle(sessionHandleStr),
request.catalogName,
request.schemaName,
@@ -296,7 +297,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
@PathParam("sessionHandle") sessionHandleStr: String,
request: GetFunctionsRequest): OperationHandle = {
try {
- backendService.getFunctions(
+ fe.be.getFunctions(
parseSessionHandle(sessionHandleStr),
request.catalogName,
request.schemaName,
@@ -320,7 +321,7 @@ private[v1] class SessionsResource extends ApiRequestContext {
try {
val operationHandle = parseOperationHandle(operationHandleStr)
- backendService.sessionManager.getSession(parseSessionHandle(sessionHandleStr))
+ fe.be.sessionManager.getSession(parseSessionHandle(sessionHandleStr))
.closeOperation(operationHandle)
operationHandle
} catch {