Browse Source

[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 <Guoqing.Mao@Yumchina.com>
Co-authored-by: xiangzihao <460888207@qq.com>
3.2.1-prepare
amao 1 year ago committed by GitHub
parent
commit
5ccc4cc889
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java
  2. 7
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  3. 12
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/QueueService.java
  4. 56
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java
  5. 18
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java
  6. 7
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/TenantMapper.java
  7. 7
      dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TenantMapper.xml
  8. 2
      dolphinscheduler-ui/src/locales/en_US/security.ts
  9. 2
      dolphinscheduler-ui/src/locales/zh_CN/security.ts
  10. 7
      dolphinscheduler-ui/src/service/modules/queues/index.ts
  11. 102
      dolphinscheduler-ui/src/views/security/yarn-queue-manage/use-table.ts

25
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/QueueController.java

@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.api.controller; 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.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.QUERY_QUEUE_LIST_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_QUEUE_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_QUEUE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.VERIFY_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.dao.entity.User;
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils; import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; 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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -156,6 +160,27 @@ public class QueueController extends BaseController {
return queueService.updateQueue(loginUser, id, queue, queueName); 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 * verify queue and queue name
* *

7
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", "查询任务实例错误"), QUERY_TASK_INSTANCE_ERROR(10205, "query task instance error", "查询任务实例错误"),
EXECUTE_NOT_DEFINE_TASK(10206, "please save and try again", 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", START_NODE_NOT_EXIST_IN_LAST_PROCESS(10207, "this node {0} does not exist in the latest process definition",
"该节点 {0} 不存在于最新的流程定义中"), "该节点 {0} 不存在于最新的流程定义中"),
LIST_AZURE_DATA_FACTORY_ERROR(10208, "list azure data factory error", "查询AZURE数据工厂列表错误"), 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_NOT_EXISTS(10219, "project parameter {0} not exists", "项目参数[{0}]不存在"),
PROJECT_PARAMETER_CODE_EMPTY(10220, "project parameter code empty", "项目参数code为空"), PROJECT_PARAMETER_CODE_EMPTY(10220, "project parameter code empty", "项目参数code为空"),
CREATE_PROJECT_PREFERENCE_ERROR(10300, "create project preference error", "创建项目偏好设置错误"), CREATE_PROJECT_PREFERENCE_ERROR(10300, "create project preference error", "创建项目偏好设置错误"),
UPDATE_PROJECT_PREFERENCE_ERROR(10301, "update project preference error", "更新项目偏好设置错误"), UPDATE_PROJECT_PREFERENCE_ERROR(10301, "update project preference error", "更新项目偏好设置错误"),

12
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.Queue;
import org.apache.dolphinscheduler.dao.entity.User; import org.apache.dolphinscheduler.dao.entity.User;
import java.util.Map;
/** /**
* queue service * queue service
*/ */
@ -66,6 +68,16 @@ public interface QueueService {
*/ */
Result updateQueue(User loginUser, int id, String queue, String queueName); 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 * verify queue and queueName
* *

56
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/QueueServiceImpl.java

@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.service.impl; 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_CREATE;
import static org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.YARN_QUEUE_UPDATE; 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.AuthorizationType;
import org.apache.dolphinscheduler.common.enums.UserType; import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.Queue; 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.entity.User;
import org.apache.dolphinscheduler.dao.mapper.QueueMapper; import org.apache.dolphinscheduler.dao.mapper.QueueMapper;
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
import org.apache.dolphinscheduler.dao.mapper.UserMapper; import org.apache.dolphinscheduler.dao.mapper.UserMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
@ -64,6 +70,9 @@ public class QueueServiceImpl extends BaseServiceImpl implements QueueService {
@Autowired @Autowired
private UserMapper userMapper; private UserMapper userMapper;
@Autowired
private TenantMapper tenantMapper;
/** /**
* Check the queue new object valid or not * Check the queue new object valid or not
* *
@ -223,6 +232,53 @@ public class QueueServiceImpl extends BaseServiceImpl implements QueueService {
return result; 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 * verify queue and queueName
* *

18
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/QueueControllerTest.java

@ -17,6 +17,7 @@
package org.apache.dolphinscheduler.api.controller; 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.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; 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(mvcResult.getResponse().getContentAsString());
logger.info("verify queue return result:{}", 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());
}
} }

7
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); 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 * tenant page
* *

7
dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/TenantMapper.xml

@ -42,6 +42,13 @@
where tenant_code = #{tenantCode} where tenant_code = #{tenantCode}
</select> </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 id="queryAll" resultType="org.apache.dolphinscheduler.dao.entity.Tenant">
select select
<include refid="baseSql"/> <include refid="baseSql"/>

2
dolphinscheduler-ui/src/locales/en_US/security.ts

@ -77,6 +77,8 @@ export default {
update_time: 'Update Time', update_time: 'Update Time',
operation: 'Operation', operation: 'Operation',
edit: 'Edit', edit: 'Edit',
delete: 'Delete',
delete_confirm: 'Delete?',
queue_name_tips: 'Please enter your queue name', queue_name_tips: 'Please enter your queue name',
queue_value_tips: 'Please enter your queue value' queue_value_tips: 'Please enter your queue value'
}, },

2
dolphinscheduler-ui/src/locales/zh_CN/security.ts

@ -77,6 +77,8 @@ export default {
update_time: '更新时间', update_time: '更新时间',
operation: '操作', operation: '操作',
edit: '编辑', edit: '编辑',
delete: '删除',
delete_confirm: '确定删除吗?',
queue_name_tips: '请输入队列名', queue_name_tips: '请输入队列名',
queue_value_tips: '请输入队列值' queue_value_tips: '请输入队列值'
}, },

7
dolphinscheduler-ui/src/service/modules/queues/index.ts

@ -56,3 +56,10 @@ export function updateQueue(data: QueueReq, idReq: IdReq): any {
data data
}) })
} }
export function deleteQueueById(id: number): any {
return axios({
url: `/queues/${id}`,
method: 'delete'
})
}

102
dolphinscheduler-ui/src/views/security/yarn-queue-manage/use-table.ts

@ -17,10 +17,12 @@
import { useAsyncState } from '@vueuse/core' import { useAsyncState } from '@vueuse/core'
import { reactive, h, ref } from 'vue' 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 { useI18n } from 'vue-i18n'
import { queryQueueListPaging } from '@/service/modules/queues' import { queryQueueListPaging,
import { EditOutlined } from '@vicons/antd' deleteQueueById
} from '@/service/modules/queues'
import {DeleteOutlined, EditOutlined} from '@vicons/antd'
import type { QueueRes } from '@/service/modules/queues/types' import type { QueueRes } from '@/service/modules/queues/types'
export function useTable() { export function useTable() {
@ -32,6 +34,19 @@ export function useTable() {
variables.row = row 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) => { const createColumns = (variables: any) => {
variables.columns = [ variables.columns = [
{ {
@ -60,30 +75,69 @@ export function useTable() {
title: t('security.yarn_queue.operation'), title: t('security.yarn_queue.operation'),
key: 'operation', key: 'operation',
render(row: any) { render(row: any) {
return h( return h(NSpace, null, {
NTooltip, default: () => [
{},
{
trigger: () =>
h( h(
NButton, NTooltip,
{ {},
circle: true, {
type: 'info', trigger: () =>
size: 'small', h(
class: 'edit', NButton,
onClick: () => { {
handleEdit(row) 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')
}
)
]
})
} }
} }
] ]

Loading…
Cancel
Save