Browse Source

[Feature][JsonSplit-api] copy of processDefinition (#5740)

* select-by-code of processDefinition

* fix ut

* prcessDefinition copy

Co-authored-by: JinyLeeChina <297062848@qq.com>
2.0.7-release
JinyLeeChina 4 years ago committed by GitHub
parent
commit
c386b64500
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java
  2. 6
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java
  3. 4
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  4. 8
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java
  5. 219
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java
  6. 9
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java
  7. 272
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java
  8. 32
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionServiceTest.java
  9. 4
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java
  10. 37
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ProcessDefinition.java
  11. 28
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java

16
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionController.java

@ -136,14 +136,14 @@ public class ProcessDefinitionController extends BaseController {
*
* @param loginUser login user
* @param projectName project name
* @param processDefinitionIds process definition ids
* @param targetProjectId target project id
* @param processDefinitionCodes process definition codes
* @param targetProjectName target project name
* @return copy result code
*/
@ApiOperation(value = "copyProcessDefinition", notes = "COPY_PROCESS_DEFINITION_NOTES")
@ApiOperation(value = "copy", notes = "COPY_PROCESS_DEFINITION_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "processDefinitionIds", value = "PROCESS_DEFINITION_IDS", required = true, dataType = "String", example = "3,4"),
@ApiImplicitParam(name = "targetProjectId", value = "TARGET_PROJECT_ID", required = true, dataType = "Int", example = "10")
@ApiImplicitParam(name = "processDefinitionCodes", value = "PROCESS_DEFINITION_CODES", required = true, dataType = "String", example = "3,4"),
@ApiImplicitParam(name = "targetProjectName", value = "TARGET_PROJECT_NAME", required = true, dataType = "String", example = "ddd")
})
@PostMapping(value = "/copy")
@ResponseStatus(HttpStatus.OK)
@ -151,10 +151,10 @@ public class ProcessDefinitionController extends BaseController {
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result copyProcessDefinition(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@ApiParam(name = "projectName", value = "PROJECT_NAME", required = true) @PathVariable String projectName,
@RequestParam(value = "processDefinitionIds", required = true) String processDefinitionIds,
@RequestParam(value = "targetProjectId", required = true) int targetProjectId) {
@RequestParam(value = "processDefinitionCodes", required = true) String processDefinitionCodes,
@RequestParam(value = "targetProjectName", required = true) String targetProjectName) {
return returnDataList(
processDefinitionService.batchCopyProcessDefinition(loginUser, projectName, processDefinitionIds, targetProjectId));
processDefinitionService.batchCopyProcessDefinition(loginUser, projectName, processDefinitionCodes, targetProjectName));
}
/**

6
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ProjectController.java

@ -23,7 +23,7 @@ import static org.apache.dolphinscheduler.api.enums.Status.IMPORT_PROCESS_DEFINE
import static org.apache.dolphinscheduler.api.enums.Status.LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_AUTHORIZED_AND_USER_CREATED_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_AUTHORIZED_PROJECT;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROJECT_DETAILS_BY_ID_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_PROJECT_DETAILS_BY_CODE_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_UNAUTHORIZED_PROJECT_ERROR;
import static org.apache.dolphinscheduler.api.enums.Status.UPDATE_PROJECT_ERROR;
@ -136,9 +136,9 @@ public class ProjectController extends BaseController {
})
@GetMapping(value = "/query-by-code")
@ResponseStatus(HttpStatus.OK)
@ApiException(QUERY_PROJECT_DETAILS_BY_ID_ERROR)
@ApiException(QUERY_PROJECT_DETAILS_BY_CODE_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result queryProjectById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
public Result queryProjectByCode(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam("projectCode") Long projectCode) {
Map<String, Object> result = projectService.queryByCode(loginUser, projectCode);
return returnDataList(result);

4
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -74,7 +74,7 @@ public enum Status {
LIST_WORKERS_ERROR(10044, "list workers error", "查询worker列表错误"),
LIST_MASTERS_ERROR(10045, "list masters error", "查询master列表错误"),
UPDATE_PROJECT_ERROR(10046, "update project error", "更新项目信息错误"),
QUERY_PROJECT_DETAILS_BY_ID_ERROR(10047, "query project details by id error", "查询项目详细信息错误"),
QUERY_PROJECT_DETAILS_BY_CODE_ERROR(10047, "query project details by code error", "查询项目详细信息错误"),
CREATE_PROJECT_ERROR(10048, "create project error", "创建项目错误"),
LOGIN_USER_QUERY_PROJECT_LIST_PAGING_ERROR(10049, "login user query project list paging error", "分页查询项目列表错误"),
DELETE_PROJECT_ERROR(10050, "delete project error", "删除项目错误"),
@ -189,7 +189,7 @@ public enum Status {
DELETE_PROCESS_DEFINITION_VERSION_ERROR(10156, "delete process definition version error", "删除工作流历史版本出错"),
QUERY_USER_CREATED_PROJECT_ERROR(10157, "query user created project error error", "查询用户创建的项目错误"),
PROCESS_DEFINITION_IDS_IS_EMPTY(10158, "process definition ids is empty", "工作流IDS不能为空"),
PROCESS_DEFINITION_CODES_IS_EMPTY(10158, "process definition codes is empty", "工作流CODES不能为空"),
BATCH_COPY_PROCESS_DEFINITION_ERROR(10159, "batch copy process definition error", "复制工作流错误"),
BATCH_MOVE_PROCESS_DEFINITION_ERROR(10160, "batch move process definition error", "移动工作流错误"),
QUERY_WORKFLOW_LINEAGE_ERROR(10161, "query workflow lineage error", "查询血缘失败"),

8
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionService.java

@ -120,13 +120,13 @@ public interface ProcessDefinitionService {
*
* @param loginUser loginUser
* @param projectName projectName
* @param processDefinitionIds processDefinitionIds
* @param targetProjectId targetProjectId
* @param processDefinitionCodes processDefinitionCodes
* @param targetProjectName targetProjectName
*/
Map<String, Object> batchCopyProcessDefinition(User loginUser,
String projectName,
String processDefinitionIds,
int targetProjectId);
String processDefinitionCodes,
String targetProjectName);
/**
* batch move process definition

219
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java

@ -67,6 +67,7 @@ import org.apache.dolphinscheduler.dao.entity.Tenant;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionLogMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessTaskRelationLogMapper;
import org.apache.dolphinscheduler.dao.mapper.ProcessTaskRelationMapper;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper;
@ -107,7 +108,6 @@ import org.springframework.web.multipart.MultipartFile;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@ -157,6 +157,9 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
@Autowired
private ProcessTaskRelationMapper processTaskRelationMapper;
@Autowired
private ProcessTaskRelationLogMapper processTaskRelationLogMapper;
@Autowired
TaskDefinitionLogMapper taskDefinitionLogMapper;
@ -194,14 +197,11 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
String tenantCode,
String taskRelationJson) {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
// check project auth
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
if (resultStatus != Status.SUCCESS) {
return checkResult;
Map<String, Object> result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
long projectCode = (long) result.get(Constants.PROJECT_CODE);
List<ProcessTaskRelationLog> taskRelationList = JSONUtils.toList(taskRelationJson, ProcessTaskRelationLog.class);
Map<String, Object> checkRelationJson = checkTaskRelationList(taskRelationList, taskRelationJson);
@ -222,16 +222,23 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
putMsg(result, Status.CREATE_PROCESS_DEFINITION);
return result;
}
ProcessDefinition processDefinition = new ProcessDefinition(projectCode, name, processDefinitionCode, description,
globalParams, locations, connects, timeout, loginUser.getId(), tenant.getId());
int insertVersion = processService.saveProcessDefine(loginUser, project, name, description, globalParams,
locations, connects, timeout, tenant.getId(), processDefinitionCode, 0, true);
return createProcessDefine(loginUser, result, taskRelationList, processDefinition);
}
private Map<String, Object> createProcessDefine(User loginUser,
Map<String, Object> result,
List<ProcessTaskRelationLog> taskRelationList,
ProcessDefinition processDefinition) {
int insertVersion = processService.saveProcessDefine(loginUser, processDefinition, true);
if (insertVersion > 0) {
int insertResult = processService.saveTaskRelation(loginUser, project.getCode(), processDefinitionCode, insertVersion, taskRelationList);
int insertResult = processService.saveTaskRelation(loginUser, processDefinition.getProjectCode(), processDefinition.getCode(), insertVersion, taskRelationList);
if (insertResult > 0) {
putMsg(result, Status.SUCCESS);
// return processDefinitionCode
result.put(Constants.DATA_LIST, processDefinitionCode);
result.put(Constants.DATA_LIST, processDefinition.getCode());
} else {
putMsg(result, Status.CREATE_PROCESS_DEFINITION);
}
@ -282,17 +289,11 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
*/
@Override
public Map<String, Object> queryProcessDefinitionList(User loginUser, String projectName) {
HashMap<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
if (resultStatus != Status.SUCCESS) {
return checkResult;
Map<String, Object> result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
List<ProcessDefinition> resourceList = processDefinitionMapper.queryAllDefinitionList(project.getCode());
List<ProcessDefinition> resourceList = processDefinitionMapper.queryAllDefinitionList((long) result.get(Constants.PROJECT_CODE));
resourceList.forEach(processDefinition -> {
ProcessData processData = processService.genProcessData(processDefinition);
@ -387,17 +388,12 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
@Override
public Map<String, Object> queryProcessDefinitionByName(User loginUser, String projectName, String processDefinitionName) {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
if (resultStatus != Status.SUCCESS) {
return checkResult;
Map<String, Object> result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
ProcessDefinition processDefinition = processDefinitionMapper.queryByDefineName(project.getCode(), processDefinitionName);
long projectCode = (long) result.get(Constants.PROJECT_CODE);
ProcessDefinition processDefinition = processDefinitionMapper.queryByDefineName(projectCode, processDefinitionName);
if (processDefinition == null) {
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, processDefinitionName);
@ -438,14 +434,11 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
int timeout,
String tenantCode,
String taskRelationJson) {
Map<String, Object> result = new HashMap<>();
Project project = projectMapper.queryByName(projectName);
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
if (resultStatus != Status.SUCCESS) {
return checkResult;
Map<String, Object> result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
long projectCode = (long) result.get(Constants.PROJECT_CODE);
List<ProcessTaskRelationLog> taskRelationList = JSONUtils.toList(taskRelationJson, ProcessTaskRelationLog.class);
Map<String, Object> checkRelationJson = checkTaskRelationList(taskRelationList, taskRelationJson);
@ -471,10 +464,11 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
return result;
}
int insertVersion = processService.saveProcessDefine(loginUser, project, name, description, globalParams,
locations, connects, timeout, tenant.getId(), code, processDefinition.getId(), true);
processDefinition.set(projectCode, name, description, globalParams, locations, connects, timeout, tenant.getId());
processDefinition.setUpdateTime(new Date());
int insertVersion = processService.saveProcessDefine(loginUser, processDefinition, true);
if (insertVersion > 0) {
int insertResult = processService.saveTaskRelation(loginUser, project.getCode(), code, insertVersion, taskRelationList);
int insertResult = processService.saveTaskRelation(loginUser, projectCode, code, insertVersion, taskRelationList);
if (insertResult > 0) {
putMsg(result, Status.SUCCESS);
result.put(Constants.DATA_LIST, processDefinition);
@ -1453,51 +1447,24 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
}
private Map<String, Object> copyProcessDefinition(User loginUser,
Integer processId,
Project targetProject) throws JsonProcessingException {
Long processCode,
long targetProjectCode) {
Map<String, Object> result = new HashMap<>();
String currentTimeStamp = DateUtils.getCurrentTimeStamp();
ProcessDefinition processDefinition = processDefinitionMapper.selectById(processId);
ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(processCode);
if (processDefinition == null) {
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, processId);
putMsg(result, Status.PROCESS_DEFINE_NOT_EXIST, processCode);
return result;
} else {
ProcessData processData = processService.genProcessData(processDefinition);
List<TaskNode> taskNodeList = processData.getTasks();
String locations = processDefinition.getLocations();
ObjectNode locationsJN = JSONUtils.parseObject(locations);
for (TaskNode taskNode : taskNodeList) {
String suffix = "_copy_" + currentTimeStamp;
String id = taskNode.getId();
String newName = locationsJN.path(id).path("name").asText() + suffix;
((ObjectNode) locationsJN.get(id)).put("name", newName);
List<String> depList = taskNode.getDepList();
List<String> newDepList = depList.stream()
.map(s -> s + suffix)
.collect(Collectors.toList());
taskNode.setDepList(newDepList);
taskNode.setName(taskNode.getName() + suffix);
taskNode.setCode(0L);
}
processData.setTasks(taskNodeList);
String processDefinitionJson = JSONUtils.toJsonString(processData);
// TODO copy process
// return createProcessDefinition(
// loginUser,
// targetProject.getName(),
// processDefinition.getName() + "_copy_" + currentTimeStamp,
// processDefinitionJson,
// processDefinition.getDescription(),
// locationsJN.toString(),
// processDefinition.getConnects());
// TODO remove
}
List<ProcessTaskRelationLog> taskRelationList =
processTaskRelationLogMapper.queryByProcessCodeAndVersion(processDefinition.getCode(), processDefinition.getVersion());
if (taskRelationList.isEmpty()) {
putMsg(result, Status.PROCESS_TASK_RELATION_NOT_EXIST, processCode);
return result;
}
processDefinition.setName(processDefinition.getName() + "_copy_" + DateUtils.getCurrentTimeStamp());
processDefinition.setProjectCode(targetProjectCode);
return createProcessDefine(loginUser, result, taskRelationList, processDefinition);
}
/**
@ -1505,45 +1472,37 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
*
* @param loginUser loginUser
* @param projectName projectName
* @param processDefinitionIds processDefinitionIds
* @param targetProjectId targetProjectId
* @param processDefinitionCodes processDefinitionCodes
* @param targetProjectName targetProjectName
*/
@Override
public Map<String, Object> batchCopyProcessDefinition(User loginUser,
String projectName,
String processDefinitionIds,
int targetProjectId) {
Map<String, Object> result = new HashMap<>();
String processDefinitionCodes,
String targetProjectName) {
List<String> failedProcessList = new ArrayList<>();
if (StringUtils.isEmpty(processDefinitionIds)) {
putMsg(result, Status.PROCESS_DEFINITION_IDS_IS_EMPTY, processDefinitionIds);
return result;
}
//check src project auth
Map<String, Object> checkResult = checkProjectAndAuth(loginUser, projectName);
if (checkResult != null) {
return checkResult;
Map<String, Object> result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
Project targetProject = projectMapper.queryDetailById(targetProjectId);
if (targetProject == null) {
putMsg(result, Status.PROJECT_NOT_FOUNT, targetProjectId);
if (StringUtils.isEmpty(processDefinitionCodes)) {
putMsg(result, Status.PROCESS_DEFINITION_CODES_IS_EMPTY, processDefinitionCodes);
return result;
}
if (!(targetProject.getName()).equals(projectName)) {
Map<String, Object> checkTargetProjectResult = checkProjectAndAuth(loginUser, targetProject.getName());
if (checkTargetProjectResult != null) {
long targetProjectCode = 0L;
if (!(targetProjectName).equals(projectName)) {
Map<String, Object> checkTargetProjectResult = checkProjectAndAuth(loginUser, targetProjectName);
if (checkTargetProjectResult.get(Constants.STATUS) != Status.SUCCESS) {
return checkTargetProjectResult;
} else {
targetProjectCode = (long) checkTargetProjectResult.get(Constants.PROJECT_CODE);
}
}
String[] processDefinitionIdList = processDefinitionIds.split(Constants.COMMA);
doBatchCopyProcessDefinition(loginUser, targetProject, failedProcessList, processDefinitionIdList);
checkBatchOperateResult(projectName, targetProject.getName(), result, failedProcessList, true);
String[] processDefinitionCodeList = processDefinitionCodes.split(Constants.COMMA);
doBatchCopyProcessDefinition(loginUser, targetProjectCode, failedProcessList, processDefinitionCodeList);
checkBatchOperateResult(projectName, targetProjectName, result, failedProcessList, true);
return result;
}
@ -1561,16 +1520,15 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
String projectName,
String processDefinitionIds,
int targetProjectId) {
Map<String, Object> result = new HashMap<>();
List<String> failedProcessList = new ArrayList<>();
//check src project auth
Map<String, Object> checkResult = checkProjectAndAuth(loginUser, projectName);
if (checkResult != null) {
return checkResult;
Map<String, Object> result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
if (StringUtils.isEmpty(processDefinitionIds)) {
putMsg(result, Status.PROCESS_DEFINITION_IDS_IS_EMPTY, processDefinitionIds);
putMsg(result, Status.PROCESS_DEFINITION_CODES_IS_EMPTY, processDefinitionIds);
return result;
}
@ -1697,23 +1655,21 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
* batch copy process definition
*
* @param loginUser loginUser
* @param targetProject targetProject
* @param targetProjectCode targetProjectCode
* @param failedProcessList failedProcessList
* @param processDefinitionIdList processDefinitionIdList
* @param processDefinitionCodeList processDefinitionCodeList
*/
private void doBatchCopyProcessDefinition(User loginUser, Project targetProject, List<String> failedProcessList, String[] processDefinitionIdList) {
for (String processDefinitionId : processDefinitionIdList) {
private void doBatchCopyProcessDefinition(User loginUser, long targetProjectCode, List<String> failedProcessList, String[] processDefinitionCodeList) {
for (String processDefinitionCode : processDefinitionCodeList) {
try {
Map<String, Object> copyProcessDefinitionResult =
copyProcessDefinition(loginUser, Integer.valueOf(processDefinitionId), targetProject);
Map<String, Object> copyProcessDefinitionResult = copyProcessDefinition(loginUser, Long.valueOf(processDefinitionCode), targetProjectCode);
if (!Status.SUCCESS.equals(copyProcessDefinitionResult.get(Constants.STATUS))) {
setFailedProcessList(failedProcessList, processDefinitionId);
setFailedProcessList(failedProcessList, processDefinitionCode);
logger.error((String) copyProcessDefinitionResult.get(Constants.MSG));
}
} catch (Exception e) {
setFailedProcessList(failedProcessList, processDefinitionId);
setFailedProcessList(failedProcessList, processDefinitionCode);
logger.error("copy processDefinition error: {}", e.getMessage(), e);
}
}
}
@ -1741,15 +1697,12 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
*/
private Map<String, Object> checkProjectAndAuth(User loginUser, String projectName) {
Project project = projectMapper.queryByName(projectName);
//check user access for project
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
if (resultStatus != Status.SUCCESS) {
return checkResult;
Map<String, Object> result = projectService.checkProjectAndAuth(loginUser, project, projectName);
if (result.get(Constants.STATUS) == Status.SUCCESS) {
result.put(Constants.PROJECT_CODE, project.getCode());
}
return null;
return result;
}
/**
@ -1811,13 +1764,9 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
return result;
}
Project project = projectMapper.queryByName(projectName);
// check project auth
Map<String, Object> checkResult = projectService.checkProjectAndAuth(loginUser, project, projectName);
Status resultStatus = (Status) checkResult.get(Constants.STATUS);
if (resultStatus != Status.SUCCESS) {
return checkResult;
result = checkProjectAndAuth(loginUser, projectName);
if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result;
}
ProcessDefinition processDefinition = processDefinitionMapper.queryByCode(processDefinitionCode);

9
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProcessDefinitionControllerTest.java

@ -67,7 +67,6 @@ public class ProcessDefinitionControllerTest {
loginUser.setId(1);
loginUser.setUserType(UserType.GENERAL_USER);
loginUser.setUserName("admin");
user = loginUser;
}
@ -190,14 +189,14 @@ public class ProcessDefinitionControllerTest {
public void testBatchCopyProcessDefinition() throws Exception {
String projectName = "test";
int targetProjectId = 2;
String id = "1";
String targetProjectName = "test1";
String code = "1";
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
Mockito.when(processDefinitionService.batchCopyProcessDefinition(user, projectName, id, targetProjectId)).thenReturn(result);
Result response = processDefinitionController.copyProcessDefinition(user, projectName, id, targetProjectId);
Mockito.when(processDefinitionService.batchCopyProcessDefinition(user, projectName, code, targetProjectName)).thenReturn(result);
Result response = processDefinitionController.copyProcessDefinition(user, projectName, code, targetProjectName);
Assert.assertTrue(response != null && response.isSuccess());
}

272
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/controller/ProjectControllerTest.java

@ -17,220 +17,140 @@
package org.apache.dolphinscheduler.api.controller;
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.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.service.impl.ProjectServiceImpl;
import org.apache.dolphinscheduler.api.utils.PageInfo;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.UserType;
import org.apache.dolphinscheduler.dao.entity.Project;
import org.apache.dolphinscheduler.dao.entity.Resource;
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
/**
* project controller test
*/
public class ProjectControllerTest extends AbstractControllerTest {
private static Logger logger = LoggerFactory.getLogger(ProjectControllerTest.class);
private String projectCode;
@Before
public void before() throws Exception {
projectCode = testCreateProject("project_test11", "the test project");
}
@After
public void after() throws Exception {
testDeleteProject(projectCode);
}
@RunWith(MockitoJUnitRunner.Silent.class)
public class ProjectControllerTest {
private String testCreateProject(String projectName, String description) throws Exception {
@InjectMocks
private ProjectController projectController;
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectName",projectName);
paramsMap.add("description",description);
@Mock
private ProjectServiceImpl projectService;
MvcResult mvcResult = mockMvc.perform(post("/projects/create")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
@Mock
private ProjectMapper projectMapper;
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), new TypeReference<Result<String>>() {});
Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
Assert.assertNotNull(result.getData());
logger.info("create project return result:{}", mvcResult.getResponse().getContentAsString());
return (String)result.getData();
}
@Test
public void testUpdateProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectCode", projectCode);
paramsMap.add("projectName","project_test_update");
paramsMap.add("desc","the test project update");
paramsMap.add("userName", "the project owner");
MvcResult mvcResult = mockMvc.perform(post("/projects/update")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.USER_NOT_EXIST.getCode(),result.getCode().intValue());
logger.info("update project return result:{}", mvcResult.getResponse().getContentAsString());
protected User user;
@Before
public void before() {
User loginUser = new User();
loginUser.setId(1);
loginUser.setUserType(UserType.GENERAL_USER);
loginUser.setUserName("admin");
user = loginUser;
}
@Test
public void testQueryProjectByCode() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectCode", projectCode);
MvcResult mvcResult = mockMvc.perform(get("/projects/query-by-code")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(), result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
logger.info("query project by code :{}, return result:{}", projectCode, mvcResult.getResponse().getContentAsString());
public void testUpdateProject() {
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
result.put("projectId", 1);
long projectCode = 1L;
String projectName = "test";
String desc = "";
String userName = "jack";
Mockito.when(projectService.update(user, projectCode, projectName, desc, userName)).thenReturn(result);
Result response = projectController.updateProject(user, projectCode, projectName, desc, userName);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
}
@Test
public void testQueryProjectListPaging() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("searchVal","test");
paramsMap.add("pageSize","2");
paramsMap.add("pageNo","2");
MvcResult mvcResult = mockMvc.perform(get("/projects/list-paging")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info("query list-paging project return result:{}", mvcResult.getResponse().getContentAsString());
public void testQueryProjectByCode() {
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
long projectCode = 1L;
Mockito.when(projectMapper.queryByCode(projectCode)).thenReturn(getProject());
Mockito.when(projectService.queryByCode(user, projectCode)).thenReturn(result);
Result response = projectController.queryProjectByCode(user, projectCode);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
}
@Test
public void testQueryUnauthorizedProject() throws Exception {
public void testQueryProjectListPaging() {
int pageNo = 1;
int pageSize = 10;
String searchVal = "";
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId","2");
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
result.put(Constants.DATA_LIST, new PageInfo<Resource>(1, 10));
MvcResult mvcResult = mockMvc.perform(get("/projects/unauth-project")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Mockito.when(projectService.queryProjectListPaging(user, pageSize, pageNo, searchVal)).thenReturn(result);
Result response = projectController.queryProjectListPaging(user, searchVal, pageSize, pageNo);
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info("query unauth project return result:{}", mvcResult.getResponse().getContentAsString());
Assert.assertTrue(response != null && response.isSuccess());
}
@Test
public void testQueryAuthorizedProject() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("userId",String.valueOf(user.getId()));
MvcResult mvcResult = mockMvc.perform(get("/projects/authed-project")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info("query authed project return result:{}", mvcResult.getResponse().getContentAsString());
public void testQueryUnauthorizedProject() {
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
Mockito.when(projectService.queryUnauthorizedProject(user, 2)).thenReturn(result);
Result response = projectController.queryUnauthorizedProject(user, 2);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
}
@Test
public void testQueryAllProjectList() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
MvcResult mvcResult = mockMvc.perform(get("/projects/query-project-list")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info("query all project return result:{}", mvcResult.getResponse().getContentAsString());
public void testQueryAuthorizedProject() {
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
Mockito.when(projectService.queryAuthorizedProject(user, 2)).thenReturn(result);
Result response = projectController.queryAuthorizedProject(user, 2);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
}
@Ignore
@Test
public void testImportProcessDefinition() throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("file","test");
MvcResult mvcResult = mockMvc.perform(post("/projects/import-definition")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.TEXT_PLAIN))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.IMPORT_PROCESS_DEFINE_ERROR.getCode(),result.getCode().intValue());
logger.info(mvcResult.getResponse().getContentAsString());
public void testQueryAllProjectList() {
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS);
Mockito.when(projectService.queryAllProjectList()).thenReturn(result);
Result response = projectController.queryAllProjectList(user);
Assert.assertEquals(Status.SUCCESS.getCode(), response.getCode().intValue());
}
private void testDeleteProject(String projectCode) throws Exception {
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("projectCode", projectCode);
MvcResult mvcResult = mockMvc.perform(get("/projects/delete")
.header(SESSION_ID, sessionId)
.params(paramsMap))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
logger.info("delete project return result:{}", mvcResult.getResponse().getContentAsString());
private Project getProject() {
Project project = new Project();
project.setCode(1L);
project.setId(1);
project.setName("test");
project.setUserId(1);
return project;
}
private void putMsg(Map<String, Object> result, Status status, Object... statusParams) {
result.put(Constants.STATUS, status);
if (statusParams != null && statusParams.length > 0) {
result.put(Constants.MSG, MessageFormat.format(status.getMsg(), statusParams));
} else {
result.put(Constants.MSG, status.getMsg());
}
}
}

32
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ProcessDefinitionServiceTest.java

@ -387,6 +387,8 @@ public class ProcessDefinitionServiceTest {
//instance exit
Mockito.when(processDefineMapper.queryByDefineName(project.getCode(), "test")).thenReturn(getProcessDefinition());
putMsg(result, Status.SUCCESS, projectName);
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
Map<String, Object> successRes = processDefinitionService.queryProcessDefinitionByName(loginUser,
"project_test1", "test");
Assert.assertEquals(Status.SUCCESS, successRes.get(Constants.STATUS));
@ -398,30 +400,32 @@ public class ProcessDefinitionServiceTest {
String projectName = "project_test1";
Project project = getProject(projectName);
User loginUser = new User();
loginUser.setId(-1);
loginUser.setId(1);
loginUser.setUserType(UserType.GENERAL_USER);
Mockito.when(projectMapper.queryByName(projectName)).thenReturn(getProject(projectName));
Map<String, Object> result = new HashMap<>();
putMsg(result, Status.SUCCESS, projectName);
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
// copy project definition ids empty test
Map<String, Object> map = processDefinitionService.batchCopyProcessDefinition(loginUser, projectName, StringUtils.EMPTY, 0);
Assert.assertEquals(Status.PROCESS_DEFINITION_IDS_IS_EMPTY, map.get(Constants.STATUS));
Map<String, Object> map = processDefinitionService.batchCopyProcessDefinition(loginUser, projectName, StringUtils.EMPTY, "project_test2");
Assert.assertEquals(Status.PROCESS_DEFINITION_CODES_IS_EMPTY, map.get(Constants.STATUS));
Map<String, Object> result = new HashMap<>();
// project check auth fail
putMsg(result, Status.PROJECT_NOT_FOUNT, projectName);
Mockito.when(projectMapper.queryByName(projectName)).thenReturn(getProject(projectName));
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
Map<String, Object> map1 = processDefinitionService.batchCopyProcessDefinition(
loginUser, projectName, String.valueOf(project.getId()), 0);
loginUser, projectName, String.valueOf(project.getId()), "project_test2");
Assert.assertEquals(Status.PROJECT_NOT_FOUNT, map1.get(Constants.STATUS));
// project check auth success, target project is null
putMsg(result, Status.SUCCESS, projectName);
Mockito.when(projectMapper.queryByName(projectName)).thenReturn(getProject(projectName));
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
Mockito.when(projectMapper.queryDetailById(0)).thenReturn(null);
putMsg(result, Status.PROJECT_NOT_FOUNT, "project_test2");
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
Map<String, Object> map2 = processDefinitionService.batchCopyProcessDefinition(
loginUser, projectName, String.valueOf(project.getId()), 0);
loginUser, projectName, String.valueOf(project.getId()), "project_test2");
Assert.assertEquals(Status.PROJECT_NOT_FOUNT, map2.get(Constants.STATUS));
// project check auth success, target project name not equal project name, check auth target project fail
@ -430,21 +434,13 @@ public class ProcessDefinitionServiceTest {
Mockito.when(projectService.checkProjectAndAuth(loginUser, project, projectName)).thenReturn(result);
putMsg(result, Status.SUCCESS, projectName);
String projectName2 = "project_test2";
Project project2 = getProject(projectName2);
Mockito.when(projectMapper.queryByName(projectName2)).thenReturn(project2);
Mockito.when(projectService.checkProjectAndAuth(loginUser, project2, projectName2)).thenReturn(result);
Mockito.when(projectMapper.queryDetailById(1)).thenReturn(project2);
// instance exit
ProcessDefinition definition = getProcessDefinition();
definition.setLocations("{\"tasks-36196\":{\"name\":\"ssh_test1\",\"targetarr\":\"\",\"x\":141,\"y\":70}}");
definition.setConnects("[]");
Mockito.when(processDefineMapper.selectById(46)).thenReturn(definition);
Mockito.when(processService.genProcessData(Mockito.any())).thenReturn(getProcessData());
Map<String, Object> map3 = processDefinitionService.batchCopyProcessDefinition(
loginUser, projectName, "46", 1);
loginUser, projectName, "46", projectName);
Assert.assertEquals(Status.COPY_PROCESS_DEFINITION_ERROR, map3.get(Constants.STATUS));
}

4
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/Constants.java

@ -709,6 +709,10 @@ public final class Constants {
* projectId
*/
public static final String PROJECT_ID = "projectId";
/**
* projectCode
*/
public static final String PROJECT_CODE = "projectCode";
/**
* processId
*/

37
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ProcessDefinition.java

@ -190,6 +190,43 @@ public class ProcessDefinition {
public ProcessDefinition(){}
public ProcessDefinition(Long projectCode,
String name,
Long code,
String description,
String globalParams,
String locations,
String connects,
int timeout,
int userId,
int tenantId) {
set(projectCode, name, description, globalParams, connects, locations, timeout, tenantId);
this.code = code;
this.userId = userId;
Date date = new Date();
this.createTime = date;
this.updateTime = date;
}
public void set(long projectCode,
String name,
String description,
String globalParams,
String connects,
String locations,
int timeout,
int tenantId) {
this.projectCode = projectCode;
this.name = name;
this.description = description;
this.globalParams = globalParams;
this.locations = locations;
this.connects = connects;
this.timeout = timeout;
this.tenantId = tenantId;
this.flag = Flag.YES;
}
public String getName() {
return name;
}

28
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java

@ -2205,36 +2205,20 @@ public class ProcessService {
/**
* save processDefinition (including create or update processDefinition)
*/
public int saveProcessDefine(User operator, Project project, String name, String description, String globalParams,
String locations, String connects, int timeout, int tenantId, long processDefinitionCode,
int processDefinitionId, Boolean isFromProcessDefine) {
ProcessDefinitionLog processDefinitionLog = new ProcessDefinitionLog();
Integer version = processDefineLogMapper.queryMaxVersionForDefinition(processDefinitionCode);
public int saveProcessDefine(User operator, ProcessDefinition processDefinition, Boolean isFromProcessDefine) {
ProcessDefinitionLog processDefinitionLog = new ProcessDefinitionLog(processDefinition);
Integer version = processDefineLogMapper.queryMaxVersionForDefinition(processDefinition.getCode());
int insertVersion = version == null || version == 0 ? 1 : version + 1;
processDefinitionLog.setUserId(operator.getId());
processDefinitionLog.setCode(processDefinitionCode);
processDefinitionLog.setVersion(insertVersion);
processDefinitionLog.setName(name);
processDefinitionLog.setFlag(Flag.YES);
processDefinitionLog.setReleaseState(isFromProcessDefine ? ReleaseState.OFFLINE : ReleaseState.ONLINE);
processDefinitionLog.setProjectCode(project.getCode());
processDefinitionLog.setDescription(description);
processDefinitionLog.setGlobalParams(globalParams);
processDefinitionLog.setLocations(locations);
processDefinitionLog.setConnects(connects);
processDefinitionLog.setTimeout(timeout);
processDefinitionLog.setTenantId(tenantId);
processDefinitionLog.setOperator(operator.getId());
Date now = new Date();
processDefinitionLog.setOperateTime(now);
processDefinitionLog.setUpdateTime(now);
processDefinitionLog.setCreateTime(now);
processDefinitionLog.setOperateTime(processDefinition.getUpdateTime());
int insertLog = processDefineLogMapper.insert(processDefinitionLog);
int result;
if (0 == processDefinitionId) {
if (0 == processDefinition.getId()) {
result = processDefineMapper.insert(processDefinitionLog);
} else {
processDefinitionLog.setId(processDefinitionId);
processDefinitionLog.setId(processDefinition.getId());
result = processDefineMapper.updateById(processDefinitionLog);
}
return (insertLog & result) > 0 ? insertVersion : 0;

Loading…
Cancel
Save