[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>
This commit is contained in:
parent
512f4c7021
commit
5ccc4cc889
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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", "更新项目偏好设置错误"),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
},
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ export default {
|
|||
update_time: '更新时间',
|
||||
operation: '操作',
|
||||
edit: '编辑',
|
||||
delete: '删除',
|
||||
delete_confirm: '确定删除吗?',
|
||||
queue_name_tips: '请输入队列名',
|
||||
queue_value_tips: '请输入队列值'
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
}
|
||||
)
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in New Issue