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 2023/04/10 05:16:41 UTC
[kyuubi] branch master updated: [KYUUBI #3654][UI] Add Engine Manager Page
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/kyuubi.git
The following commit(s) were added to refs/heads/master by this push:
new f5ef4018e [KYUUBI #3654][UI] Add Engine Manager Page
f5ef4018e is described below
commit f5ef4018eeb1b6495afbc48dcfe7b2f004e8abce
Author: zwangsheng <22...@qq.com>
AuthorDate: Mon Apr 10 13:16:20 2023 +0800
[KYUUBI #3654][UI] Add Engine Manager Page
### _Why are the changes needed?_
Close #3654
Add Engine Manager Page for UI
### _How was this patch tested?_
- [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible
- [x] Add screenshots for manual tests if appropriate
- [ ] [Run test](https://kyuubi.readthedocs.io/en/master/develop_tools/testing.html#running-tests) locally before make a pull request
![popo_2023-04-07 14-19-01](https://user-images.githubusercontent.com/52876270/230553293-a935533c-792f-47e6-9c3d-e91bf469452e.jpg)
Closes #4674 from zwangsheng/KYUUBI_3654.
Closes #3654
b18c7d2d9 [zwangsheng] fix style
75b61350a [zwangsheng] fix style
a064203fc [zwangsheng] I18n
da61ea2fe [zwangsheng] [KYUUBI #3654][UI] Engine Manager Page
Authored-by: zwangsheng <22...@qq.com>
Signed-off-by: Cheng Pan <ch...@apache.org>
---
.../web-ui/src/{router => api/engine}/index.ts | 50 ++-----
.../src/{router/index.ts => api/engine/types.ts} | 42 +-----
kyuubi-server/web-ui/src/locales/en_US/index.ts | 18 ++-
kyuubi-server/web-ui/src/locales/zh_CN/index.ts | 18 ++-
.../web-ui/src/router/{ => engine}/index.ts | 35 +----
kyuubi-server/web-ui/src/router/index.ts | 2 +
.../src/{router/index.ts => utils/engine.ts} | 41 +----
kyuubi-server/web-ui/src/views/engine/index.vue | 166 +++++++++++++++++++++
.../src/views/layout/components/aside/types.ts | 10 ++
.../views/operation/operation-statistics/index.vue | 10 +-
.../src/views/session/session-statistics/index.vue | 6 +-
11 files changed, 248 insertions(+), 150 deletions(-)
diff --git a/kyuubi-server/web-ui/src/router/index.ts b/kyuubi-server/web-ui/src/api/engine/index.ts
similarity index 52%
copy from kyuubi-server/web-ui/src/router/index.ts
copy to kyuubi-server/web-ui/src/api/engine/index.ts
index 4d01da552..ff6dc038d 100644
--- a/kyuubi-server/web-ui/src/router/index.ts
+++ b/kyuubi-server/web-ui/src/api/engine/index.ts
@@ -15,39 +15,21 @@
* limitations under the License.
*/
-import { createRouter, createWebHistory } from 'vue-router'
-import overviewRoutes from './overview'
-import workloadRoutes from './workload'
-import operationRoutes from './operation'
-import contactRoutes from './contact'
-import sessionRoutes from './session'
+import request from '@/utils/request'
+import { IEngineSearch } from './types'
-const routes = [
- {
- path: '/',
- name: 'main',
- redirect: {
- name: 'layout'
- }
- },
- {
- path: '/layout',
- name: 'layout',
- component: () => import('@/views/layout/index.vue'),
- redirect: 'overview',
- children: [
- ...overviewRoutes,
- ...sessionRoutes,
- ...workloadRoutes,
- ...operationRoutes,
- ...contactRoutes
- ]
- }
-]
+export function getAllEngines(params: IEngineSearch) {
+ return request({
+ url: 'api/v1/admin/engine',
+ method: 'get',
+ params
+ })
+}
-const router = createRouter({
- history: createWebHistory('/ui'),
- routes
-})
-
-export default router
+export function deleteEngine(params: IEngineSearch) {
+ return request({
+ url: 'api/v1/admin/engine',
+ method: 'delete',
+ params
+ })
+}
diff --git a/kyuubi-server/web-ui/src/router/index.ts b/kyuubi-server/web-ui/src/api/engine/types.ts
similarity index 52%
copy from kyuubi-server/web-ui/src/router/index.ts
copy to kyuubi-server/web-ui/src/api/engine/types.ts
index 4d01da552..86a05dd29 100644
--- a/kyuubi-server/web-ui/src/router/index.ts
+++ b/kyuubi-server/web-ui/src/api/engine/types.ts
@@ -15,39 +15,11 @@
* limitations under the License.
*/
-import { createRouter, createWebHistory } from 'vue-router'
-import overviewRoutes from './overview'
-import workloadRoutes from './workload'
-import operationRoutes from './operation'
-import contactRoutes from './contact'
-import sessionRoutes from './session'
+interface IEngineSearch {
+ type: null | string
+ sharelevel: null | string
+ 'hive.server2.proxy.user': null | string
+ subdomain?: null | string
+}
-const routes = [
- {
- path: '/',
- name: 'main',
- redirect: {
- name: 'layout'
- }
- },
- {
- path: '/layout',
- name: 'layout',
- component: () => import('@/views/layout/index.vue'),
- redirect: 'overview',
- children: [
- ...overviewRoutes,
- ...sessionRoutes,
- ...workloadRoutes,
- ...operationRoutes,
- ...contactRoutes
- ]
- }
-]
-
-const router = createRouter({
- history: createWebHistory('/ui'),
- routes
-})
-
-export default router
+export { IEngineSearch }
diff --git a/kyuubi-server/web-ui/src/locales/en_US/index.ts b/kyuubi-server/web-ui/src/locales/en_US/index.ts
index d50f22915..dc1986939 100644
--- a/kyuubi-server/web-ui/src/locales/en_US/index.ts
+++ b/kyuubi-server/web-ui/src/locales/en_US/index.ts
@@ -23,15 +23,25 @@ export default {
session_id: 'Session ID',
operation_id: 'Operation ID',
create_time: 'Create Time',
- operation: 'Operation',
- delete_confirm: 'Delete Confirm',
- close_confirm: 'Close Confirm',
- cancel_confirm: 'Cancel Confirm',
start_time: 'State Time',
complete_time: 'Completed Time',
state: 'State',
duration: 'Duration',
statement: 'Statement',
+ engine_address: 'Engine Address',
+ engine_id: 'Engine ID',
+ engine_type: 'Engine Type',
+ share_level: 'Share Level',
+ version: 'Version',
+ operation: {
+ text: 'Operation',
+ delete_confirm: 'Delete Confirm',
+ close_confirm: 'Close Confirm',
+ cancel_confirm: 'Cancel Confirm',
+ close: 'Close',
+ cancel: 'Cancel',
+ delete: 'Delete'
+ },
message: {
delete_succeeded: 'Delete {name} Succeeded',
delete_failed: 'Delete {name} Failed',
diff --git a/kyuubi-server/web-ui/src/locales/zh_CN/index.ts b/kyuubi-server/web-ui/src/locales/zh_CN/index.ts
index 443d129cc..87b15cc4d 100644
--- a/kyuubi-server/web-ui/src/locales/zh_CN/index.ts
+++ b/kyuubi-server/web-ui/src/locales/zh_CN/index.ts
@@ -23,15 +23,25 @@ export default {
session_id: 'Session ID',
operation_id: 'Operation ID',
create_time: '创建时间',
- operation: '操作',
- delete_confirm: '确认删除',
- close_confirm: '确认关闭',
- cancel_confirm: '确认取消',
start_time: '开始时间',
complete_time: '完成时间',
state: '状态',
duration: '运行时间',
statement: 'Statement',
+ engine_address: 'Engine 地址',
+ engine_id: 'Engine ID',
+ engine_type: 'Engine 类型',
+ share_level: '共享级别',
+ version: '版本',
+ operation: {
+ text: '操作',
+ delete_confirm: '确认删除',
+ close_confirm: '确认关闭',
+ cancel_confirm: '确认取消',
+ close: '关闭',
+ cancel: '取消',
+ delete: '删除'
+ },
message: {
delete_succeeded: '删除 {name} 成功',
delete_failed: '删除 {name} 失败',
diff --git a/kyuubi-server/web-ui/src/router/index.ts b/kyuubi-server/web-ui/src/router/engine/index.ts
similarity index 53%
copy from kyuubi-server/web-ui/src/router/index.ts
copy to kyuubi-server/web-ui/src/router/engine/index.ts
index 4d01da552..22b056a32 100644
--- a/kyuubi-server/web-ui/src/router/index.ts
+++ b/kyuubi-server/web-ui/src/router/engine/index.ts
@@ -15,39 +15,12 @@
* limitations under the License.
*/
-import { createRouter, createWebHistory } from 'vue-router'
-import overviewRoutes from './overview'
-import workloadRoutes from './workload'
-import operationRoutes from './operation'
-import contactRoutes from './contact'
-import sessionRoutes from './session'
-
const routes = [
{
- path: '/',
- name: 'main',
- redirect: {
- name: 'layout'
- }
- },
- {
- path: '/layout',
- name: 'layout',
- component: () => import('@/views/layout/index.vue'),
- redirect: 'overview',
- children: [
- ...overviewRoutes,
- ...sessionRoutes,
- ...workloadRoutes,
- ...operationRoutes,
- ...contactRoutes
- ]
+ path: '/engine/engine-statistics',
+ name: 'engine-statistics',
+ component: () => import('@/views/engine/index.vue')
}
]
-const router = createRouter({
- history: createWebHistory('/ui'),
- routes
-})
-
-export default router
+export default routes
diff --git a/kyuubi-server/web-ui/src/router/index.ts b/kyuubi-server/web-ui/src/router/index.ts
index 4d01da552..241cdf506 100644
--- a/kyuubi-server/web-ui/src/router/index.ts
+++ b/kyuubi-server/web-ui/src/router/index.ts
@@ -21,6 +21,7 @@ import workloadRoutes from './workload'
import operationRoutes from './operation'
import contactRoutes from './contact'
import sessionRoutes from './session'
+import engineRoutes from './engine'
const routes = [
{
@@ -40,6 +41,7 @@ const routes = [
...sessionRoutes,
...workloadRoutes,
...operationRoutes,
+ ...engineRoutes,
...contactRoutes
]
}
diff --git a/kyuubi-server/web-ui/src/router/index.ts b/kyuubi-server/web-ui/src/utils/engine.ts
similarity index 52%
copy from kyuubi-server/web-ui/src/router/index.ts
copy to kyuubi-server/web-ui/src/utils/engine.ts
index 4d01da552..da6646191 100644
--- a/kyuubi-server/web-ui/src/router/index.ts
+++ b/kyuubi-server/web-ui/src/utils/engine.ts
@@ -15,39 +15,12 @@
* limitations under the License.
*/
-import { createRouter, createWebHistory } from 'vue-router'
-import overviewRoutes from './overview'
-import workloadRoutes from './workload'
-import operationRoutes from './operation'
-import contactRoutes from './contact'
-import sessionRoutes from './session'
+function getEngineType() {
+ return ['SPARK_SQL', 'FLINK_SQL', 'TRINO', 'HIVE_SQL', 'JDBC']
+}
-const routes = [
- {
- path: '/',
- name: 'main',
- redirect: {
- name: 'layout'
- }
- },
- {
- path: '/layout',
- name: 'layout',
- component: () => import('@/views/layout/index.vue'),
- redirect: 'overview',
- children: [
- ...overviewRoutes,
- ...sessionRoutes,
- ...workloadRoutes,
- ...operationRoutes,
- ...contactRoutes
- ]
- }
-]
+function getShareLevel() {
+ return ['CONNECTION', 'USER', 'GROUP', 'SERVER']
+}
-const router = createRouter({
- history: createWebHistory('/ui'),
- routes
-})
-
-export default router
+export { getEngineType, getShareLevel }
diff --git a/kyuubi-server/web-ui/src/views/engine/index.vue b/kyuubi-server/web-ui/src/views/engine/index.vue
new file mode 100644
index 000000000..cecbde709
--- /dev/null
+++ b/kyuubi-server/web-ui/src/views/engine/index.vue
@@ -0,0 +1,166 @@
+<!--
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+-->
+<template>
+ <el-card :body-style="{ padding: '10px 14px' }" class="filter_card">
+ <header>
+ <el-space class="search-box">
+ <el-select
+ v-model="searchParam.type"
+ :placeholder="$t('engine_type')"
+ clearable
+ style="width: 210px"
+ @change="getList">
+ <el-option
+ v-for="item in getEngineType()"
+ :key="item"
+ :label="item"
+ :value="item" />
+ </el-select>
+ <el-select
+ v-model="searchParam.sharelevel"
+ :placeholder="$t('share_level')"
+ clearable
+ style="width: 210px"
+ @change="getList">
+ <el-option
+ v-for="item in getShareLevel()"
+ :key="item"
+ :label="item"
+ :value="item" />
+ </el-select>
+ <el-input
+ v-model="searchParam['hive.server2.proxy.user']"
+ :placeholder="$t('user')"
+ style="width: 210px"
+ @keyup.enter="getList" />
+ <el-button type="primary" icon="Search" @click="getList" />
+ </el-space>
+ </header>
+ </el-card>
+ <el-card class="table-container">
+ <el-table v-loading="loading" :data="tableData" style="width: 100%">
+ <el-table-column
+ prop="instance"
+ :label="$t('engine_address')"
+ min-width="20%" />
+ <el-table-column :label="$t('engine_id')" min-width="20%">
+ <template #default="scope">
+ <span>{{
+ scope.row.attributes && scope.row.attributes['kyuubi.engine.id']
+ ? scope.row.attributes['kyuubi.engine.id']
+ : '-'
+ }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column
+ prop="engineType"
+ :label="$t('engine_type')"
+ min-width="20%" />
+ <el-table-column
+ prop="sharelevel"
+ :label="$t('share_level')"
+ min-width="20%" />
+
+ <el-table-column prop="user" :label="$t('user')" min-width="15%" />
+ <el-table-column prop="version" :label="$t('version')" min-width="15%" />
+ <el-table-column fixed="right" :label="$t('operation.text')" width="120">
+ <template #default="scope">
+ <el-space wrap>
+ <el-popconfirm
+ :title="$t('operation.delete_confirm')"
+ @confirm="handleDeleteEngine(scope.row)">
+ <template #reference>
+ <span>
+ <el-tooltip
+ effect="dark"
+ :content="$t('operation.delete')"
+ placement="top">
+ <template #default>
+ <el-button type="danger" icon="Delete" circle />
+ </template>
+ </el-tooltip>
+ </span>
+ </template>
+ </el-popconfirm>
+ </el-space>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-card>
+</template>
+
+<script lang="ts" setup>
+ import { reactive } from 'vue'
+ import { getAllEngines, deleteEngine } from '@/api/engine'
+ import { IEngineSearch } from '@/api/engine/types'
+ import { useTable } from '@/views/common/use-table'
+ import { ElMessage } from 'element-plus'
+ import { useI18n } from 'vue-i18n'
+ import { getEngineType, getShareLevel } from '@/utils/engine'
+
+ const { t } = useI18n()
+ const { tableData, loading, getList: _getList } = useTable()
+ // default search params
+ const searchParam: IEngineSearch = reactive({
+ type: 'SPARK_SQL',
+ sharelevel: 'USER',
+ 'hive.server2.proxy.user': 'anonymous'
+ })
+ const getList = () => {
+ _getList(getAllEngines, searchParam)
+ }
+ const init = () => {
+ getList()
+ }
+
+ function handleDeleteEngine(row: any) {
+ deleteEngine({
+ type: row?.engineType,
+ sharelevel: row?.sharelevel,
+ 'hive.server2.proxy.user': row?.user,
+ subdomain: row?.subdomain
+ })
+ .then(() => {
+ ElMessage({
+ message: t('delete_succeeded', { name: 'engine' }),
+ type: 'success'
+ })
+ })
+ .catch(() => {
+ ElMessage({
+ message: t('delete_failed', { name: 'engine' }),
+ type: 'error'
+ })
+ })
+ .finally(() => {
+ getList()
+ })
+ }
+
+ init()
+</script>
+
+<style scoped lang="scss">
+ header {
+ display: flex;
+ justify-content: flex-end;
+ }
+ .filter_card {
+ margin-bottom: 10px;
+ }
+</style>
diff --git a/kyuubi-server/web-ui/src/views/layout/components/aside/types.ts b/kyuubi-server/web-ui/src/views/layout/components/aside/types.ts
index 4772c1a4e..72b150fa8 100644
--- a/kyuubi-server/web-ui/src/views/layout/components/aside/types.ts
+++ b/kyuubi-server/web-ui/src/views/layout/components/aside/types.ts
@@ -31,6 +31,16 @@ export const MENUS = [
}
]
},
+ {
+ label: 'Engine Management',
+ icon: 'List',
+ children: [
+ {
+ label: 'Engine Statistics',
+ router: '/engine/engine-statistics'
+ }
+ ]
+ },
{
label: 'Workload',
icon: 'List',
diff --git a/kyuubi-server/web-ui/src/views/operation/operation-statistics/index.vue b/kyuubi-server/web-ui/src/views/operation/operation-statistics/index.vue
index ff6706c72..992257eb8 100644
--- a/kyuubi-server/web-ui/src/views/operation/operation-statistics/index.vue
+++ b/kyuubi-server/web-ui/src/views/operation/operation-statistics/index.vue
@@ -54,18 +54,18 @@
: '-'
}}</template>
</el-table-column>
- <el-table-column fixed="right" :label="$t('operation')" width="110">
+ <el-table-column fixed="right" :label="$t('operation.text')" width="110">
<template #default="scope">
<el-space wrap>
<el-popconfirm
v-if="!isTerminalState(scope.row.state)"
- :title="$t('cancel_confirm')"
+ :title="$t('operation.cancel_confirm')"
@confirm="handleOperate(scope.row.identifier, 'CANCEL')">
<template #reference>
<span>
<el-tooltip
effect="dark"
- :content="$t('cancel')"
+ :content="$t('operation.cancel')"
placement="top">
<template #default>
<el-button type="danger" icon="Remove" circle />
@@ -75,13 +75,13 @@
</template>
</el-popconfirm>
<el-popconfirm
- :title="$t('close_confirm')"
+ :title="$t('operation.close_confirm')"
@confirm="handleOperate(scope.row.identifier, 'CLOSE')">
<template #reference>
<span>
<el-tooltip
effect="dark"
- :content="$t('close')"
+ :content="$t('operation.close')"
placement="top">
<template #default>
<el-button type="danger" icon="CircleClose" circle />
diff --git a/kyuubi-server/web-ui/src/views/session/session-statistics/index.vue b/kyuubi-server/web-ui/src/views/session/session-statistics/index.vue
index 40a9b7568..327664dd1 100644
--- a/kyuubi-server/web-ui/src/views/session/session-statistics/index.vue
+++ b/kyuubi-server/web-ui/src/views/session/session-statistics/index.vue
@@ -46,16 +46,16 @@
}}
</template>
</el-table-column>
- <el-table-column fixed="right" :label="$t('operation')">
+ <el-table-column fixed="right" :label="$t('operation.text')">
<template #default="scope">
<el-popconfirm
- :title="$t('delete_confirm')"
+ :title="$t('operation.delete_confirm')"
@confirm="handleDeleteSession(scope.row.identifier)">
<template #reference>
<span>
<el-tooltip
effect="dark"
- :content="$t('delete')"
+ :content="$t('operation.delete')"
placement="top">
<template #default>
<el-button type="danger" icon="Delete" circle />