You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by zi...@apache.org on 2023/07/26 03:53:03 UTC
[dolphinscheduler] branch dev updated: [Improvement-4375][api] cannot delete yarn queue (#13046)
This is an automated email from the ASF dual-hosted git repository.
zihaoxiang pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 5ccc4cc889 [Improvement-4375][api] cannot delete yarn queue (#13046)
5ccc4cc889 is described below
commit 5ccc4cc889309ea2ae949b09cc7ecbb1d941ec67
Author: amao <56...@users.noreply.github.com>
AuthorDate: Wed Jul 26 11:52:57 2023 +0800
[Improvement-4375][api] cannot delete yarn queue (#13046)
* [Bug-12833][api]
delete api
* [Bug-12833][api]
delete yarn queue
* [Bug-12833][api]
add Unit Test
* Repair the failed CI
* Repair the failed UT
* Repair the failed Docs
* Repair the failed Doc
---------
Co-authored-by: amao <Gu...@Yumchina.com>
Co-authored-by: xiangzihao <46...@qq.com>
---
.../api/controller/QueueController.java | 25 +++++
.../apache/dolphinscheduler/api/enums/Status.java | 7 +-
.../dolphinscheduler/api/service/QueueService.java | 12 +++
.../api/service/impl/QueueServiceImpl.java | 56 +++++++++++
.../api/controller/QueueControllerTest.java | 18 ++++
.../dolphinscheduler/dao/mapper/TenantMapper.java | 7 ++
.../dolphinscheduler/dao/mapper/TenantMapper.xml | 7 ++
dolphinscheduler-ui/src/locales/en_US/security.ts | 2 +
dolphinscheduler-ui/src/locales/zh_CN/security.ts | 2 +
.../src/service/modules/queues/index.ts | 7 ++
.../views/security/yarn-queue-manage/use-table.ts | 102 ++++++++++++++++-----
11 files changed, 220 insertions(+), 25 deletions(-)
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
index e13e23a1df..0527ce77ae 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
@@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.api.controller;
import static org.apache.dolphinscheduler.api.enums.Status.CREATE_QUEUE_ERROR;
+import static org.apache.dolphinscheduler.api.enums.Status.DELETE_QUEUE_BY_ID_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_QUEUE_LIST_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_QUEUE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.VERIFY_QUEUE_ERROR;
@@ -30,8 +31,11 @@ import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
+import java.util.Map;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -156,6 +160,27 @@ public class QueueController extends BaseController {
return queueService.updateQueue(loginUser, id, queue, queueName);
}
+ /**
+ * delete queue by id
+ *
+ * @param loginUser login user
+ * @param id queue id
+ * @return update result code
+ */
+ @Operation(summary = "deleteQueueById", description = "DELETE_QUEUE_NOTES")
+ @Parameters({
+ @Parameter(name = "id", description = "QUEUE_ID", required = true, schema = @Schema(implementation = int.class, example = "100"))
+ })
+ @DeleteMapping(value = "/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ @ApiException(DELETE_QUEUE_BY_ID_ERROR)
+ @AccessLogAnnotation(ignoreRequestArgs = "loginUser")
+ public Result deleteQueueById(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @PathVariable(value = "id") int id) throws Exception {
+ Map<String, Object> result = queueService.deleteQueueById(loginUser, id);
+ return returnDataList(result);
+ }
+
/**
* verify queue and queue name
*
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
index 8176a2ff89..f4622b5c9f 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
@@ -263,6 +263,12 @@ public enum Status {
QUERY_TASK_INSTANCE_ERROR(10205, "query task instance error", "查询任务实例错误"),
EXECUTE_NOT_DEFINE_TASK(10206, "please save and try again",
"请先保存后再执行"),
+
+ DELETE_QUEUE_BY_ID_ERROR(10307, "delete queue by id error", "删除队列错误"),
+ DELETE_QUEUE_BY_ID_FAIL_USERS(10308, "delete queue by id fail, for there are {0} users using it",
+ "删除队列失败,有[{0}]个用户正在使用"),
+ DELETE_TENANT_BY_ID_FAIL_TENANTS(10309, "delete queue by id fail, for there are {0} tenants using it",
+ "删除队列失败,有[{0}]个租户正在使用"),
START_NODE_NOT_EXIST_IN_LAST_PROCESS(10207, "this node {0} does not exist in the latest process definition",
"该节点 {0} 不存在于最新的流程定义中"),
LIST_AZURE_DATA_FACTORY_ERROR(10208, "list azure data factory error", "查询AZURE数据工厂列表错误"),
@@ -286,7 +292,6 @@ public enum Status {
PROJECT_PARAMETER_NOT_EXISTS(10219, "project parameter {0} not exists", "项目参数[{0}]不存在"),
PROJECT_PARAMETER_CODE_EMPTY(10220, "project parameter code empty", "项目参数code为空"),
-
CREATE_PROJECT_PREFERENCE_ERROR(10300, "create project preference error", "创建项目偏好设置错误"),
UPDATE_PROJECT_PREFERENCE_ERROR(10301, "update project preference error", "更新项目偏好设置错误"),
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java
index 0f62ea9028..69ed518445 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java
@@ -21,6 +21,8 @@ import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.dao.entity.Queue;
import org.apache.dolphinscheduler.dao.entity.User;
+import java.util.Map;
+
/**
* queue service
*/
@@ -66,6 +68,16 @@ public interface QueueService {
*/
Result updateQueue(User loginUser, int id, String queue, String queueName);
+ /**
+ * delete queue
+ *
+ * @param loginUser login user
+ * @param id queue id
+ * @return delete result code
+ * @throws Exception exception
+ */
+ Map<String, Object> deleteQueueById(User loginUser, int id) throws Exception;
+
/**
* verify queue and queueName
*
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java
index ecdb3773ed..723c3010c5 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java
@@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.service.impl;
+import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.TENANT_DELETE;
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.YARN_QUEUE_CREATE;
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.YARN_QUEUE_UPDATE;
@@ -29,16 +30,21 @@ import org.apache.dolphinscheduler.common.constants.Constants;
import org.apache.dolphinscheduler.common.enums.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.Queue;
+import org.apache.dolphinscheduler.dao.entity.Tenant;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.QueueMapper;
+import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -64,6 +70,9 @@ public class QueueServiceImpl extends BaseServiceImpl implements QueueService {
@Autowired
private UserMapper userMapper;
+ @Autowired
+ private TenantMapper tenantMapper;
+
/**
* Check the queue new object valid or not
*
@@ -223,6 +232,53 @@ public class QueueServiceImpl extends BaseServiceImpl implements QueueService {
return result;
}
+ /**
+ * delete queue
+ *
+ * @param loginUser login user
+ * @param id queue id
+ * @return delete result code
+ * @throws Exception exception
+ */
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Map<String, Object> deleteQueueById(User loginUser, int id) throws Exception {
+ Map<String, Object> result = new HashMap<>();
+
+ if (!canOperatorPermissions(loginUser, null, AuthorizationType.TENANT, TENANT_DELETE)) {
+ throw new ServiceException(Status.USER_NO_OPERATION_PERM);
+ }
+
+ Queue queue = queueMapper.selectById(id);
+ if (Objects.isNull(queue)) {
+ log.error("Queue does not exist");
+ throw new ServiceException(Status.QUEUE_NOT_EXIST);
+ }
+
+ List<Tenant> tenantList = tenantMapper.queryTenantListByQueueId(queue.getId());
+ if (CollectionUtils.isNotEmpty(tenantList)) {
+ log.warn("Delete queue failed, because there are {} tenants using it.", tenantList.size());
+ throw new ServiceException(Status.DELETE_TENANT_BY_ID_FAIL_TENANTS, tenantList.size());
+ }
+
+ List<User> userList = userMapper.queryUserListByQueue(queue.getQueueName());
+ if (CollectionUtils.isNotEmpty(userList)) {
+ log.warn("Delete queue failed, because there are {} users using it.", userList.size());
+ throw new ServiceException(Status.DELETE_QUEUE_BY_ID_FAIL_USERS, userList.size());
+ }
+
+ int delete = queueMapper.deleteById(id);
+ if (delete > 0) {
+ log.info("Queue is deleted and id is {}.", id);
+ putMsg(result, Status.SUCCESS);
+ } else {
+ log.error("Queue delete failed, queueId:{}.", id);
+ putMsg(result, Status.DELETE_QUEUE_BY_ID_ERROR);
+ }
+
+ return result;
+ }
+
/**
* verify queue and queueName
*
diff --git a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java
index e2311a25ae..0ddd7ad84b 100644
--- a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java
+++ b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java
@@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.controller;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
@@ -177,4 +178,21 @@ public class QueueControllerTest extends AbstractControllerTest {
logger.info(mvcResult.getResponse().getContentAsString());
logger.info("verify queue return result:{}", mvcResult.getResponse().getContentAsString());
}
+ @Test
+ public void testDeleteQueueById() throws Exception {
+ MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
+ paramsMap.add("id", "64");
+
+ MvcResult mvcResult = mockMvc.perform(delete("/queues/{id}", 64)
+ .header(SESSION_ID, sessionId)
+ .params(paramsMap))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andReturn();
+ Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
+
+ Assertions.assertNotNull(result);
+ Assertions.assertEquals(Status.QUEUE_NOT_EXIST.getCode(), result.getCode().intValue());
+ logger.info("delete queue return result:{}", mvcResult.getResponse().getContentAsString());
+ }
}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TenantMapper.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TenantMapper.java
index 623c1f8a8d..90fee2ef5a 100644
--- a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TenantMapper.java
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TenantMapper.java
@@ -66,6 +66,13 @@ public interface TenantMapper extends BaseMapper<Tenant> {
*/
Tenant queryByTenantCode(@Param("tenantCode") String tenantCode);
+ /**
+ * query tenants by queue id
+ *
+ * @param queueId queue id
+ * @return tenant list
+ */
+ List<Tenant> queryTenantListByQueueId(@Param("queueId") Integer queueId);
/**
* tenant page
*
diff --git a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TenantMapper.xml b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TenantMapper.xml
index 60fe3a45ef..a941db420b 100644
--- a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TenantMapper.xml
+++ b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TenantMapper.xml
@@ -42,6 +42,13 @@
where tenant_code = #{tenantCode}
</select>
+ <select id="queryTenantListByQueueId" resultType="org.apache.dolphinscheduler.dao.entity.Tenant">
+ select
+ <include refid="baseSql"/>
+ from t_ds_tenant
+ where queue_id = #{queueId}
+ </select>
+
<select id="queryAll" resultType="org.apache.dolphinscheduler.dao.entity.Tenant">
select
<include refid="baseSql"/>
diff --git a/dolphinscheduler-ui/src/locales/en_US/security.ts b/dolphinscheduler-ui/src/locales/en_US/security.ts
index 44536982b2..3b8e47586d 100644
--- a/dolphinscheduler-ui/src/locales/en_US/security.ts
+++ b/dolphinscheduler-ui/src/locales/en_US/security.ts
@@ -77,6 +77,8 @@ export default {
update_time: 'Update Time',
operation: 'Operation',
edit: 'Edit',
+ delete: 'Delete',
+ delete_confirm: 'Delete?',
queue_name_tips: 'Please enter your queue name',
queue_value_tips: 'Please enter your queue value'
},
diff --git a/dolphinscheduler-ui/src/locales/zh_CN/security.ts b/dolphinscheduler-ui/src/locales/zh_CN/security.ts
index ffe4f7dff8..d015730d8c 100644
--- a/dolphinscheduler-ui/src/locales/zh_CN/security.ts
+++ b/dolphinscheduler-ui/src/locales/zh_CN/security.ts
@@ -77,6 +77,8 @@ export default {
update_time: '更新时间',
operation: '操作',
edit: '编辑',
+ delete: '删除',
+ delete_confirm: '确定删除吗?',
queue_name_tips: '请输入队列名',
queue_value_tips: '请输入队列值'
},
diff --git a/dolphinscheduler-ui/src/service/modules/queues/index.ts b/dolphinscheduler-ui/src/service/modules/queues/index.ts
index ef93de6151..be7a8a8a8c 100644
--- a/dolphinscheduler-ui/src/service/modules/queues/index.ts
+++ b/dolphinscheduler-ui/src/service/modules/queues/index.ts
@@ -56,3 +56,10 @@ export function updateQueue(data: QueueReq, idReq: IdReq): any {
data
})
}
+
+export function deleteQueueById(id: number): any {
+ return axios({
+ url: `/queues/${id}`,
+ method: 'delete'
+ })
+}
diff --git a/dolphinscheduler-ui/src/views/security/yarn-queue-manage/use-table.ts b/dolphinscheduler-ui/src/views/security/yarn-queue-manage/use-table.ts
index be5400020d..7008b8979d 100644
--- a/dolphinscheduler-ui/src/views/security/yarn-queue-manage/use-table.ts
+++ b/dolphinscheduler-ui/src/views/security/yarn-queue-manage/use-table.ts
@@ -17,10 +17,12 @@
import { useAsyncState } from '@vueuse/core'
import { reactive, h, ref } from 'vue'
-import { NButton, NIcon, NTooltip } from 'naive-ui'
+import {NButton, NIcon, NPopconfirm, NSpace, NTooltip} from 'naive-ui'
import { useI18n } from 'vue-i18n'
-import { queryQueueListPaging } from '@/service/modules/queues'
-import { EditOutlined } from '@vicons/antd'
+import { queryQueueListPaging,
+ deleteQueueById
+} from '@/service/modules/queues'
+import {DeleteOutlined, EditOutlined} from '@vicons/antd'
import type { QueueRes } from '@/service/modules/queues/types'
export function useTable() {
@@ -32,6 +34,19 @@ export function useTable() {
variables.row = row
}
+ const handleDelete = (row: any) => {
+ deleteQueueById(row.id).then(() => {
+ getTableData({
+ pageSize: variables.pageSize,
+ pageNo:
+ variables.tableData.length === 1 && variables.page > 1
+ ? variables.page - 1
+ : variables.page,
+ searchVal: variables.searchVal
+ })
+ })
+ }
+
const createColumns = (variables: any) => {
variables.columns = [
{
@@ -60,30 +75,69 @@ export function useTable() {
title: t('security.yarn_queue.operation'),
key: 'operation',
render(row: any) {
- return h(
- NTooltip,
- {},
- {
- trigger: () =>
+ return h(NSpace, null, {
+ default: () => [
h(
- NButton,
- {
- circle: true,
- type: 'info',
- size: 'small',
- class: 'edit',
- onClick: () => {
- handleEdit(row)
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'info',
+ size: 'small',
+ class: 'edit',
+ onClick: () => {
+ handleEdit(row)
+ }
+ },
+ {
+ icon: () =>
+ h(NIcon, null, { default: () => h(EditOutlined) })
+ }
+ ),
+ default: () => t('security.yarn_queue.edit')
}
- },
- {
- icon: () =>
- h(NIcon, null, { default: () => h(EditOutlined) })
- }
),
- default: () => t('security.yarn_queue.edit')
- }
- )
+ h(
+ NPopconfirm,
+ {
+ onPositiveClick: () => {
+ handleDelete(row)
+ }
+ },
+ {
+ trigger: () =>
+ h(
+ NTooltip,
+ {},
+ {
+ trigger: () =>
+ h(
+ NButton,
+ {
+ circle: true,
+ type: 'error',
+ size: 'small',
+ class: 'delete'
+ },
+ {
+ icon: () =>
+ h(NIcon, null, {
+ default: () => h(DeleteOutlined)
+ })
+ }
+ ),
+ default: () => t('security.yarn_queue.delete')
+ }
+ ),
+ default: () => t('security.yarn_queue.delete_confirm')
+ }
+ )
+ ]
+ })
}
}
]