Browse Source

[Cherry-pick-2.0.3] 20220107 (#7871)

* cherry-pick

* fix bug_7629 (#7630)

* fix bug_7564 (#7625)

* fix bug_7512 (#7716)

* [Fix-7459][Sqoop] running error in parallel (#7752)

* fix bug_7459

* fix bug_7459

* fix bug_7459

* fix bug_7459

* fix bug_7459

Co-authored-by: SbloodyS <sbloodys@qq.com>

* [Feature-7576][Master] Optimize complement task's date (#7585)

* feature_7576

* feature_7576

* feature 7576

* feature 7576

* [Fix-7767]Task instance is not deleted while deleting the process instance (#7768)

* fix bug_7767

* fix bug_7767

* fix bug_7767

* fix bug_7767

* fix bug_7767

* [Feature-5951][Improvement][UI] When creating an alarm instance, the alarm instance name input box prompts optimization (#7770)

* cherry-pick

* [Fix-7773][Api] malform batchDeleteProcessInstanceByIds log output (#7774)

* bug_7773

* bug_7773

* bug_7773

* bug_7773

* bug_7773

* [Feature-7777][UI] process definition page add create username (#7778)

* feature_7777

* fix bug_7499 (#7739)

Co-authored-by: SbloodyS <sbloodys@qq.com>

* fix conflict

* fix conflict

* fix mapState never used error

* fix bug_7789 (#7790)

Co-authored-by: SbloodyS <sbloodys@qq.com>

Co-authored-by: SbloodyS <sbloodys@qq.com>
Co-authored-by: wangyizhi <wangyizhi1_yewu@cmss.chinamobile.com>
2.0.3-release
xiangzihao 2 years ago committed by GitHub
parent
commit
be86eaf357
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 104
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ExecutorController.java
  2. 3
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  3. 43
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ExecutorServiceImpl.java
  4. 2
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessDefinitionServiceImpl.java
  5. 5
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
  6. 5
      dolphinscheduler-api/src/main/resources/i18n/messages.properties
  7. 4
      dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties
  8. 1
      dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties
  9. 37
      dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorServiceTest.java
  10. 3
      dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/upgrade/ResourceDao.java
  11. 19
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/process/ProcessService.java
  12. 4
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/quartz/cron/CronUtils.java
  13. 6
      dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/targets/HiveTargetGenerator.java
  14. 12
      dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/targets/TargetHiveParameter.java
  15. 2
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue
  16. 83
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/dependentTimeout.vue
  17. 4
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/selectInput.vue
  18. 36
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/_source/dependItemList.vue
  19. 41
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/dependent.vue
  20. 13
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue
  21. 2
      dolphinscheduler-ui/src/js/conf/home/pages/datasource/pages/list/_source/createDataSource.vue
  22. 1
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  23. 4
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue
  24. 2
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  25. 2
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
  26. 2
      script/dolphinscheduler-daemon.sh

104
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ExecutorController.java

@ -23,6 +23,7 @@ import static org.apache.dolphinscheduler.api.enums.Status.START_PROCESS_INSTANC
import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
import org.apache.dolphinscheduler.api.enums.ExecuteType;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ApiException;
import org.apache.dolphinscheduler.api.service.ExecutorService;
import org.apache.dolphinscheduler.api.utils.Result;
@ -36,8 +37,6 @@ import org.apache.dolphinscheduler.common.enums.WarningType;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.entity.User;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
@ -55,6 +54,13 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import springfox.documentation.annotations.ApiIgnore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* executor controller
*/
@ -138,6 +144,100 @@ public class ExecutorController extends BaseController {
return returnDataList(result);
}
/**
* batch execute process instance
* If any processDefinitionCode cannot be found, the failure information is returned and the status is set to
* failed. The successful task will run normally and will not stop
*
* @param loginUser login user
* @param projectCode project code
* @param processDefinitionCodes process definition codes
* @param scheduleTime schedule time
* @param failureStrategy failure strategy
* @param startNodeList start nodes list
* @param taskDependType task depend type
* @param execType execute type
* @param warningType warning type
* @param warningGroupId warning group id
* @param runMode run mode
* @param processInstancePriority process instance priority
* @param workerGroup worker group
* @param timeout timeout
* @param expectedParallelismNumber the expected parallelism number when execute complement in parallel mode
* @return start process result code
*/
@ApiOperation(value = "batchStartProcessInstance", notes = "BATCH_RUN_PROCESS_INSTANCE_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "processDefinitionCodes", value = "PROCESS_DEFINITION_CODES", required = true, dataType = "String", example = "1,2,3"),
@ApiImplicitParam(name = "scheduleTime", value = "SCHEDULE_TIME", required = true, dataType = "String"),
@ApiImplicitParam(name = "failureStrategy", value = "FAILURE_STRATEGY", required = true, dataType = "FailureStrategy"),
@ApiImplicitParam(name = "startNodeList", value = "START_NODE_LIST", dataType = "String"),
@ApiImplicitParam(name = "taskDependType", value = "TASK_DEPEND_TYPE", dataType = "TaskDependType"),
@ApiImplicitParam(name = "execType", value = "COMMAND_TYPE", dataType = "CommandType"),
@ApiImplicitParam(name = "warningType", value = "WARNING_TYPE", required = true, dataType = "WarningType"),
@ApiImplicitParam(name = "warningGroupId", value = "WARNING_GROUP_ID", required = true, dataType = "Int", example = "100"),
@ApiImplicitParam(name = "runMode", value = "RUN_MODE", dataType = "RunMode"),
@ApiImplicitParam(name = "processInstancePriority", value = "PROCESS_INSTANCE_PRIORITY", required = true, dataType = "Priority"),
@ApiImplicitParam(name = "workerGroup", value = "WORKER_GROUP", dataType = "String", example = "default"),
@ApiImplicitParam(name = "environmentCode", value = "ENVIRONMENT_CODE", dataType = "Long", example = "-1"),
@ApiImplicitParam(name = "timeout", value = "TIMEOUT", dataType = "Int", example = "100"),
@ApiImplicitParam(name = "expectedParallelismNumber", value = "EXPECTED_PARALLELISM_NUMBER", dataType = "Int", example = "8")
})
@PostMapping(value = "batch-start-process-instance")
@ResponseStatus(HttpStatus.OK)
@ApiException(START_PROCESS_INSTANCE_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result batchStartProcessInstance(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@ApiParam(name = "projectCode", value = "PROJECT_CODE", required = true) @PathVariable long projectCode,
@RequestParam(value = "processDefinitionCodes") String processDefinitionCodes,
@RequestParam(value = "scheduleTime", required = false) String scheduleTime,
@RequestParam(value = "failureStrategy", required = true) FailureStrategy failureStrategy,
@RequestParam(value = "startNodeList", required = false) String startNodeList,
@RequestParam(value = "taskDependType", required = false) TaskDependType taskDependType,
@RequestParam(value = "execType", required = false) CommandType execType,
@RequestParam(value = "warningType", required = true) WarningType warningType,
@RequestParam(value = "warningGroupId", required = false) int warningGroupId,
@RequestParam(value = "runMode", required = false) RunMode runMode,
@RequestParam(value = "processInstancePriority", required = false) Priority processInstancePriority,
@RequestParam(value = "workerGroup", required = false, defaultValue = "default") String workerGroup,
@RequestParam(value = "environmentCode", required = false, defaultValue = "-1") Long environmentCode,
@RequestParam(value = "timeout", required = false) Integer timeout,
@RequestParam(value = "startParams", required = false) String startParams,
@RequestParam(value = "expectedParallelismNumber", required = false) Integer expectedParallelismNumber,
@RequestParam(value = "dryRun", defaultValue = "0", required = false) int dryRun) {
if (timeout == null) {
timeout = Constants.MAX_TASK_TIMEOUT;
}
Map<String, String> startParamMap = null;
if (startParams != null) {
startParamMap = JSONUtils.toMap(startParams);
}
Map<String, Object> result = new HashMap<>();
List<String> processDefinitionCodeArray = Arrays.asList(processDefinitionCodes.split(Constants.COMMA));
List<String> startFailedProcessDefinitionCodeList = new ArrayList<>();
processDefinitionCodeArray = processDefinitionCodeArray.stream().distinct().collect(Collectors.toList());
for (String strProcessDefinitionCode : processDefinitionCodeArray) {
long processDefinitionCode = Long.parseLong(strProcessDefinitionCode);
result = execService.execProcessInstance(loginUser, projectCode, processDefinitionCode, scheduleTime, execType, failureStrategy,
startNodeList, taskDependType, warningType, warningGroupId, runMode, processInstancePriority, workerGroup, environmentCode, timeout, startParamMap, expectedParallelismNumber, dryRun);
if (!Status.SUCCESS.equals(result.get(Constants.STATUS))) {
startFailedProcessDefinitionCodeList.add(String.valueOf(processDefinitionCode));
}
}
if (!startFailedProcessDefinitionCodeList.isEmpty()) {
putMsg(result, Status.BATCH_START_PROCESS_INSTANCE_ERROR, String.join(Constants.COMMA, startFailedProcessDefinitionCodeList));
}
return returnDataList(result);
}
/**
* do action to process instancepause, stop, repeat, recover from pause, recover from stop
*

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

@ -166,7 +166,7 @@ public enum Status {
NAME_EXIST(10135, "name {0} already exists", "名称[{0}]已存在"),
SAVE_ERROR(10136, "save error", "保存错误"),
DELETE_PROJECT_ERROR_DEFINES_NOT_NULL(10137, "please delete the process definitions in project first!", "请先删除全部工作流定义"),
BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR(10117, "batch delete process instance by ids {0} error", "批量删除工作流实例错误"),
BATCH_DELETE_PROCESS_INSTANCE_BY_IDS_ERROR(10117, "batch delete process instance by ids {0} error", "批量删除工作流实例错误: {0}"),
PREVIEW_SCHEDULE_ERROR(10139, "preview schedule error", "预览调度配置错误"),
PARSE_TO_CRON_EXPRESSION_ERROR(10140, "parse cron to cron expression error", "解析调度表达式错误"),
SCHEDULE_START_TIME_END_TIME_SAME(10141, "The start time must not be the same as the end", "开始时间不能和结束时间一样"),
@ -250,6 +250,7 @@ public enum Status {
COUNT_PROCESS_INSTANCE_STATE_ERROR(50012, "count process instance state error", "查询各状态流程实例数错误"),
COUNT_PROCESS_DEFINITION_USER_ERROR(50013, "count process definition user error", "查询各用户流程定义数错误"),
START_PROCESS_INSTANCE_ERROR(50014, "start process instance error", "运行工作流实例错误"),
BATCH_START_PROCESS_INSTANCE_ERROR(50014, "batch start process instance error: {0}", "批量运行工作流实例错误: {0}"),
EXECUTE_PROCESS_INSTANCE_ERROR(50015, "execute process instance error", "操作工作流实例错误"),
CHECK_PROCESS_DEFINITION_ERROR(50016, "check process definition error", "工作流定义错误"),
QUERY_RECIPIENTS_AND_COPYERS_BY_PROCESS_DEFINITION_ERROR(50017, "query recipients and copyers by process definition error", "查询收件人和抄送人错误"),

43
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ExecutorServiceImpl.java

@ -571,6 +571,10 @@ public class ExecutorServiceImpl extends BaseServiceImpl implements ExecutorServ
Map<String, String> cmdParam = JSONUtils.toMap(command.getCommandParam());
switch (runMode) {
case RUN_MODE_SERIAL: {
if (start.after(end)) {
logger.warn("The startDate {} is later than the endDate {}", start, end);
break;
}
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_START_DATE, DateUtils.dateToString(start));
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_END_DATE, DateUtils.dateToString(end));
command.setCommandParam(JSONUtils.toJsonString(cmdParam));
@ -578,26 +582,45 @@ public class ExecutorServiceImpl extends BaseServiceImpl implements ExecutorServ
break;
}
case RUN_MODE_PARALLEL: {
if (start.after(end)) {
logger.warn("The startDate {} is later than the endDate {}", start, end);
break;
}
LinkedList<Date> listDate = new LinkedList<>();
List<Schedule> schedules = processService.queryReleaseSchedulerListByProcessDefinitionCode(command.getProcessDefinitionCode());
listDate.addAll(CronUtils.getSelfFireDateList(start, end, schedules));
int listDateSize = listDate.size();
createCount = listDate.size();
if (!CollectionUtils.isEmpty(listDate)) {
if (expectedParallelismNumber != null && expectedParallelismNumber != 0) {
createCount = Math.min(listDate.size(), expectedParallelismNumber);
if (listDateSize < createCount) {
createCount = listDateSize;
}
}
logger.info("In parallel mode, current expectedParallelismNumber:{}", createCount);
listDate.addLast(end);
int chunkSize = listDate.size() / createCount;
for (int i = 0; i < createCount; i++) {
int rangeStart = i == 0 ? i : (i * chunkSize);
int rangeEnd = i == createCount - 1 ? listDate.size() - 1
: rangeStart + chunkSize;
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_START_DATE, DateUtils.dateToString(listDate.get(rangeStart)));
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_END_DATE, DateUtils.dateToString(listDate.get(rangeEnd)));
// Distribute the number of tasks equally to each command.
// The last command with insufficient quantity will be assigned to the remaining tasks.
int itemsPerCommand = (listDateSize / createCount);
int remainingItems = (listDateSize % createCount);
int startDateIndex = 0;
int endDateIndex = 0;
for (int i = 1; i <= createCount; i++) {
int extra = (i <= remainingItems) ? 1 : 0;
int singleCommandItems = (itemsPerCommand + extra);
if (i == 1) {
endDateIndex += singleCommandItems - 1;
} else {
startDateIndex = endDateIndex + 1;
endDateIndex += singleCommandItems;
}
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_START_DATE, DateUtils.dateToString(listDate.get(startDateIndex)));
cmdParam.put(CMDPARAM_COMPLEMENT_DATA_END_DATE, DateUtils.dateToString(listDate.get(endDateIndex)));
command.setCommandParam(JSONUtils.toJsonString(cmdParam));
processService.createCommand(command);
}

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

@ -377,7 +377,7 @@ public class ProcessDefinitionServiceImpl extends BaseServiceImpl implements Pro
processDefinitionNode.put("id", processDefinition.getId());
processDefinitionNode.put("code", processDefinition.getCode());
processDefinitionNode.put("name", processDefinition.getName());
processDefinitionNode.put("projectCode", processDefinition.getCode());
processDefinitionNode.put("projectCode", processDefinition.getProjectCode());
arrayNode.add(processDefinitionNode);
}
result.put(Constants.DATA_LIST, arrayNode);

5
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java

@ -629,13 +629,13 @@ public class ProcessInstanceServiceImpl extends BaseServiceImpl implements Proce
}
ProcessInstance processInstance = processService.findProcessInstanceDetailById(processInstanceId);
if (null == processInstance) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, processInstanceId);
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, String.valueOf(processInstanceId));
return result;
}
ProcessDefinition processDefinition = processDefineMapper.queryByCode(processInstance.getProcessDefinitionCode());
if (processDefinition != null && projectCode != processDefinition.getProjectCode()) {
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, processInstanceId);
putMsg(result, Status.PROCESS_INSTANCE_NOT_EXIST, String.valueOf(processInstanceId));
return result;
}
@ -649,6 +649,7 @@ public class ProcessInstanceServiceImpl extends BaseServiceImpl implements Proce
processService.deleteAllSubWorkProcessByParentId(processInstanceId);
processService.deleteWorkProcessMapByParentId(processInstanceId);
processService.deleteWorkTaskInstanceByProcessInstanceId(processInstanceId);
if (delete > 0) {
putMsg(result, Status.SUCCESS);

5
dolphinscheduler-api/src/main/resources/i18n/messages.properties

@ -18,13 +18,14 @@
QUERY_SCHEDULE_LIST_NOTES=query schedule list
EXECUTE_PROCESS_TAG=execute process related operation
PROCESS_INSTANCE_EXECUTOR_TAG=process instance executor related operation
RUN_PROCESS_INSTANCE_NOTES=run process instance
RUN_PROCESS_INSTANCE_NOTES=run process instance
BATCH_RUN_PROCESS_INSTANCE_NOTES=batch run process instance
START_NODE_LIST=start node list(node name)
TASK_DEPEND_TYPE=task depend type
COMMAND_TYPE=command type
RUN_MODE=run mode
TIMEOUT=timeout
EXECUTE_ACTION_TO_PROCESS_INSTANCE_NOTES=execute action to process instance
EXECUTE_ACTION_TO_PROCESS_INSTANCE_NOTES=execute action to process instance
EXECUTE_TYPE=execute type
START_CHECK_PROCESS_DEFINITION_NOTES=start check process definition
GET_RECEIVER_CC_NOTES=query receiver cc

4
dolphinscheduler-api/src/main/resources/i18n/messages_en_US.properties

@ -17,7 +17,9 @@
QUERY_SCHEDULE_LIST_NOTES=query schedule list
EXECUTE_PROCESS_TAG=execute process related operation
PROCESS_INSTANCE_EXECUTOR_TAG=process instance executor related operation
RUN_PROCESS_INSTANCE_NOTES=run process instance
RUN_PROCESS_INSTANCE_NOTES=run process instance
BATCH_RUN_PROCESS_INSTANCE_NOTES=batch run process instance(If any processDefinitionCode cannot be found, the failure\
\ information is returned and the status is set to failed. The successful task will run normally and will not stop)
START_NODE_LIST=start node list(node name)
TASK_DEPEND_TYPE=task depend type
COMMAND_TYPE=command type

1
dolphinscheduler-api/src/main/resources/i18n/messages_zh_CN.properties

@ -19,6 +19,7 @@ PROCESS_INSTANCE_EXECUTOR_TAG=流程实例执行相关操作
UI_PLUGINS_TAG=UI插件相关操作
WORK_FLOW_LINEAGE_TAG=工作流血缘相关操作
RUN_PROCESS_INSTANCE_NOTES=运行流程实例
BATCH_RUN_PROCESS_INSTANCE_NOTES=批量运行流程实例(其中有任意一个processDefinitionCode找不到,则返回失败信息并且状态置为失败,成功的任务会正常运行,不会停止)
START_NODE_LIST=开始节点列表(节点name)
TASK_DEPEND_TYPE=任务依赖类型
COMMAND_TYPE=指令类型

37
dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/ExecutorServiceTest.java

@ -17,6 +17,8 @@
package org.apache.dolphinscheduler.api.service;
import static org.apache.dolphinscheduler.common.Constants.CMDPARAM_COMPLEMENT_DATA_END_DATE;
import static org.apache.dolphinscheduler.common.Constants.CMDPARAM_COMPLEMENT_DATA_START_DATE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ -32,6 +34,8 @@ import org.apache.dolphinscheduler.common.enums.Priority;
import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.common.enums.RunMode;
import org.apache.dolphinscheduler.common.model.Server;
import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.entity.Command;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
@ -340,22 +344,35 @@ public class ExecutorServiceTest {
listDate.add(1);
listDate.add(2);
listDate.add(3);
listDate.add(4);
int listDateSize = listDate.size();
int createCount = Math.min(listDate.size(), expectedParallelismNumber);
logger.info("In parallel mode, current expectedParallelismNumber:{}", createCount);
listDate.addLast(4);
int chunkSize = listDate.size() / createCount;
for (int i = 0; i < createCount; i++) {
int rangeStart = i == 0 ? i : (i * chunkSize);
int rangeEnd = i == createCount - 1 ? listDate.size() - 1 : rangeStart + chunkSize;
logger.info("rangeStart:{}, rangeEnd:{}",rangeStart, rangeEnd);
result.add(listDate.get(rangeStart) + "," + listDate.get(rangeEnd));
int itemsPerCommand = (listDateSize / createCount);
int remainingItems = (listDateSize % createCount);
int startDateIndex = 0;
int endDateIndex = 0;
for (int i = 1; i <= createCount; i++) {
int extra = (i <= remainingItems) ? 1 : 0;
int singleCommandItems = (itemsPerCommand + extra);
if (i == 1) {
endDateIndex += singleCommandItems - 1;
} else {
startDateIndex = endDateIndex + 1;
endDateIndex += singleCommandItems;
}
logger.info("startDate:{}, endDate:{}", listDate.get(startDateIndex), listDate.get(endDateIndex));
result.add(listDate.get(startDateIndex) + "," + listDate.get(endDateIndex));
}
Assert.assertEquals("0,1", result.get(0));
Assert.assertEquals("1,2", result.get(1));
Assert.assertEquals("2,4", result.get(2));
Assert.assertEquals("2,3", result.get(1));
Assert.assertEquals("4,4", result.get(2));
}
}

3
dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/upgrade/ResourceDao.java

@ -18,7 +18,6 @@
package org.apache.dolphinscheduler.dao.upgrade;
import org.apache.dolphinscheduler.common.utils.ConnectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,7 +31,7 @@ import java.util.Map;
* resource dao
*/
public class ResourceDao {
public static final Logger logger = LoggerFactory.getLogger(ProcessDefinitionDao.class);
public static final Logger logger = LoggerFactory.getLogger(ResourceDao.class);
/**
* list all resources

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

@ -451,6 +451,25 @@ public class ProcessService {
}
}
/**
* recursive delete all task instance by process instance id
* @param processInstanceId
*/
public void deleteWorkTaskInstanceByProcessInstanceId(int processInstanceId) {
List<TaskInstance> taskInstanceList = findValidTaskListByProcessId(processInstanceId);
if (CollectionUtils.isEmpty(taskInstanceList)) {
return;
}
List<Integer> taskInstanceIdList = new ArrayList<>();
for (TaskInstance taskInstance : taskInstanceList) {
taskInstanceIdList.add(taskInstance.getId());
}
taskInstanceMapper.deleteBatchIds(taskInstanceIdList);
}
/**
* recursive query sub process definition id by parent id.
*

4
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/quartz/cron/CronUtils.java

@ -191,9 +191,9 @@ public class CronUtils {
return result;
}
// support left closed and right open time interval (startDate <= N < endDate)
// support left closed and right closed time interval (startDate <= N <= endDate)
Date from = new Date(startTime.getTime() - Constants.SECOND_TIME_MILLIS);
Date to = new Date(endTime.getTime() - Constants.SECOND_TIME_MILLIS);
Date to = new Date(endTime.getTime() + Constants.SECOND_TIME_MILLIS);
List<Schedule> listSchedule = new ArrayList<>();
listSchedule.addAll(schedules);

6
dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/generator/targets/HiveTargetGenerator.java

@ -27,6 +27,7 @@ import static org.apache.dolphinscheduler.plugin.task.sqoop.SqoopConstants.HIVE_
import static org.apache.dolphinscheduler.plugin.task.sqoop.SqoopConstants.HIVE_PARTITION_KEY;
import static org.apache.dolphinscheduler.plugin.task.sqoop.SqoopConstants.HIVE_PARTITION_VALUE;
import static org.apache.dolphinscheduler.plugin.task.sqoop.SqoopConstants.HIVE_TABLE;
import static org.apache.dolphinscheduler.plugin.task.sqoop.SqoopConstants.TARGET_DIR;
import static org.apache.dolphinscheduler.spi.task.TaskConstants.SPACE;
import org.apache.dolphinscheduler.plugin.task.sqoop.generator.ITargetGenerator;
@ -91,6 +92,11 @@ public class HiveTargetGenerator implements ITargetGenerator {
.append(SPACE).append(targetHiveParameter.getHivePartitionValue());
}
if (StringUtils.isNotEmpty(targetHiveParameter.getHiveTargetDir())) {
hiveTargetSb.append(SPACE).append(TARGET_DIR)
.append(SPACE).append(targetHiveParameter.getHiveTargetDir());
}
}
} catch (Exception e) {
logger.error(String.format("Sqoop hive target params build failed: [%s]", e.getMessage()));

12
dolphinscheduler-task-plugin/dolphinscheduler-task-sqoop/src/main/java/org/apache/dolphinscheduler/plugin/task/sqoop/parameter/targets/TargetHiveParameter.java

@ -54,6 +54,10 @@ public class TargetHiveParameter {
* hive partition value
*/
private String hivePartitionValue;
/**
* hive target dir
*/
private String hiveTargetDir;
public String getHiveDatabase() {
return hiveDatabase;
@ -118,4 +122,12 @@ public class TargetHiveParameter {
public void setHivePartitionValue(String hivePartitionValue) {
this.hivePartitionValue = hivePartitionValue;
}
public String getHiveTargetDir() {
return hiveTargetDir;
}
public void setHiveTargetDir(String hiveTargetDir) {
this.hiveTargetDir = hiveTargetDir;
}
}

2
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue

@ -529,7 +529,7 @@
this.$router.push({
name: 'task-instance',
query: {
processInstanceId: this.$route.params.code,
processInstanceId: this.instanceId,
taskName: taskName
}
})

83
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/dependentTimeout.vue

@ -28,6 +28,7 @@
</label>
</div>
</div>
<div class="clearfix list" v-if="enable">
<div class="text-box">
<span>{{$t('Waiting Dependent start')}}</span>
@ -40,25 +41,44 @@
</label>
</div>
</div>
<div class="clearfix list" v-if="enable && waitStartTimeout.enable">
<div class="text-box">
<span>{{$t('Timeout period')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<div style="padding-top: 2px;">
<el-input v-model="waitStartTimeout.interval" size="small" style="width: 100px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</el-input>
</div>
</label>
</div>
</div>
<div class="clearfix list" v-if="enable && waitStartTimeout.enable">
<div class="text-box">
<span>{{$t('Check interval')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<div style="padding-top: 2px;">
<el-input v-model="waitStartTimeout.checkInterval" size="small" style="width: 100px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</el-input>
</div>
</label>
</div>
</div>
<div class="clearfix list" v-if="enable && waitStartTimeout.enable">
<div class="text-box">
<span>{{$t('Timeout strategy')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<span class="text-box">
<span>{{$t('Timeout period')}}</span>
</span>
<el-input v-model="waitStartTimeout.interval" size="small" style="width: 100px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</el-input>
<span class="text-box">
<span>{{$t('Check interval')}}</span>
</span>
<el-input v-model="waitStartTimeout.checkInterval" size="small" style="width: 100px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</el-input>
<span class="text-box">
<span>{{$t('Timeout strategy')}}</span>
</span>
<div style="padding-top: 6px;">
<div style="padding-top: 5px;">
<el-checkbox-group size="small" v-model="waitStartTimeout.strategy">
<el-checkbox label="FAILED" :disabled="true">{{$t('Timeout failure')}}</el-checkbox>
</el-checkbox-group>
@ -66,6 +86,7 @@
</label>
</div>
</div>
<div class="clearfix list" v-if="enable">
<div class="text-box">
<span>{{$t('Waiting Dependent complete')}}</span>
@ -78,19 +99,29 @@
</label>
</div>
</div>
<div class="clearfix list" v-if="enable && waitCompleteTimeout.enable">
<div class="text-box">
<span>{{$t('Timeout period')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<div style="padding-top: 2px;">
<el-input v-model="waitCompleteTimeout.interval" size="small" style="width: 100px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</el-input>
</div>
</label>
</div>
</div>
<div class="clearfix list" v-if="enable && waitCompleteTimeout.enable">
<div class="text-box">
<span>{{$t('Timeout strategy')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<span class="text-box">
<span>{{$t('Timeout period')}}</span>
</span>
<el-input v-model="waitCompleteTimeout.interval" size="small" style="width: 100px;" :disabled="isDetails" maxlength="9">
<span slot="append">{{$t('Minute')}}</span>
</el-input>
<span class="text-box">
<span>{{$t('Timeout strategy')}}</span>
</span>
<div style="padding-top: 6px;">
<div style="padding-top: 5px;">
<el-checkbox-group size="small" v-model="waitCompleteTimeout.strategy">
<el-checkbox label="WARN" :disabled="isDetails">{{$t('Timeout alarm')}}</el-checkbox>
<el-checkbox label="FAILED" :disabled="isDetails">{{$t('Timeout failure')}}</el-checkbox>

4
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/selectInput.vue

@ -20,7 +20,9 @@
:disabled="isDetails"
size="small"
@change="_onChange"
v-model="selectedValue">
v-model="selectedValue"
filterable
allow-create>
<el-input
ref="input"
slot="trigger"

36
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/_source/dependItemList.vue

@ -76,7 +76,8 @@
props: {
dependItemList: Array,
index: Number,
dependTaskList: Array
dependTaskList: Array,
projectDefinitionsCache: Object
},
model: {
prop: 'dependItemList',
@ -136,6 +137,9 @@
})
},
_getProcessByProjectCode (code) {
if (this.projectDefinitionsCache[code]) {
return Promise.resolve(this.projectDefinitionsCache[code])
}
return new Promise((resolve, reject) => {
this.store.dispatch('dag/getProcessByProjectCode', code).then(res => {
let definitionList = _.map(_.cloneDeep(res), v => {
@ -144,6 +148,10 @@
label: v.processDefinition.name
}
})
this.$emit('addProjectDefinitionsCache', {
projectCode: code,
definitionList
})
resolve(definitionList)
})
})
@ -281,16 +289,26 @@
}
})
} else {
// get definitionCode codes
let codes = _.map(this.dependItemList, v => v.definitionCode).join(',')
// get item list
this._getDependItemList(codes, false).then(res => {
_.map(this.dependItemList, (v, i) => {
this._getProcessByProjectCode(v.projectCode).then(definitionList => {
this.$set(this.dependItemList, i, this._rtOldParams(v.definitionCode, definitionList, [_.cloneDeep(DEP_ALL_TASK)].concat(_.map(res[v.definitionCode] || [], v => ({ code: v.code, name: v.name }))), v))
// Get uniq definitionCodes and projectCodes
const definitionCodes = _.uniq(this.dependItemList.map(dep => dep.definitionCode)).join(',')
// Query all tasks by definitionCodes, definitionCodes can cross projects
this._getDependItemList(definitionCodes, false)
.then(definitionTasks => {
_.map(this.dependItemList, (dep, i) => {
const definitionList = this.projectDefinitionsCache[dep.projectCode]
const depTasksList = (definitionTasks[dep.definitionCode] || [])
.map(task => ({ code: task.code, name: task.name }))
.concat(_.cloneDeep(DEP_ALL_TASK))
this.$set(this.dependItemList, i, this._rtOldParams(
dep.definitionCode,
definitionList,
depTasksList,
dep
))
})
})
})
}
})
},

41
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/dependent.vue

@ -27,7 +27,7 @@
<em v-if="isLoading" class="el-icon-loading as as-spin" data-toggle="tooltip" :title="$t('Add')"></em>
</a>
</div>
<div class="dep-box">
<div class="dep-box" v-if="cacheReady">
<span
class="dep-relation"
@click="!isDetails && _setGlobalRelation()"
@ -49,9 +49,11 @@
</em>
<m-depend-item-list
:dependTaskList='dependTaskList'
:projectDefinitionsCache='projectDefinitionsCache'
v-model="el.dependItemList"
@on-delete-all="_onDeleteAll"
@getDependTaskList="getDependTaskList"
@addProjectDefinitionsCache="addProjectDefinitionsCache"
:index="$index">
</m-depend-item-list>
</div>
@ -65,6 +67,7 @@
import mListBox from './_source/listBox'
import mDependItemList from './_source/dependItemList'
import disabledState from '@/module/mixin/disabledState'
import { mapActions } from 'vuex'
export default {
name: 'dependent',
@ -72,7 +75,10 @@
return {
relation: 'AND',
dependTaskList: [],
isLoading: false
isLoading: false,
// Reduce repeated requests
projectDefinitionsCache: {},
cacheReady: false
}
},
mixins: [disabledState],
@ -80,6 +86,7 @@
backfillItem: Object
},
methods: {
...mapActions('dag', ['getProcessByProjectCode']),
_addDep () {
if (!this.isLoading) {
this.isLoading = true
@ -124,6 +131,25 @@
})
})
return true
},
_getProcessByProjectCode (code) {
return new Promise((resolve, reject) => {
this.getProcessByProjectCode(code).then(res => {
let definitionList = _.map(_.cloneDeep(res), v => {
return {
value: v.processDefinition.code,
label: v.processDefinition.name
}
})
resolve({
definitionList,
projectCode: code
})
})
})
},
addProjectDefinitionsCache ({ projectCode, definitionList }) {
this.projectDefinitionsCache[projectCode] = definitionList
}
},
watch: {
@ -150,6 +176,17 @@
_.map(this.dependTaskList, v => _.map(v.dependItemList, v1 => {
v1.state = dependentResult[`${v1.definitionId}-${v1.depTaskCode}-${v1.cycle}-${v1.dateValue}`] || defaultState
}))
// cache project definitions
const projectCodes = _.uniq(_.flatten(this.dependTaskList.map(dep => dep.dependItemList.map(item => item.projectCode))))
Promise.all(projectCodes.map(projectCode => this._getProcessByProjectCode(projectCode))).then((arr) => {
arr.forEach((item) => {
const { projectCode, definitionList } = item
this.projectDefinitionsCache[projectCode] = definitionList
})
this.cacheReady = true
})
} else {
this.cacheReady = true
}
},
mounted () {

13
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue

@ -325,6 +325,18 @@
<el-switch v-model="targetHiveParams.hiveOverWrite" size="small"></el-switch>
</div>
</m-list-box>
<m-list-box>
<div slot="text">{{$t('Hive Target Dir')}}</div>
<div slot="content">
<el-input
:disabled="isDetails"
type="text"
size="small"
v-model="targetHiveParams.hiveTargetDir"
:placeholder="$t('Please enter hive target dir')">
</el-input>
</div>
</m-list-box>
<m-list-box>
<div slot="text">{{$t('ReplaceDelimiter')}}</div>
<div slot="content">
@ -691,6 +703,7 @@
dropDelimiter: false,
hiveOverWrite: true,
replaceDelimiter: '',
hiveTargetDir: '',
hivePartitionKey: '',
hivePartitionValue: ''
},

2
dolphinscheduler-ui/src/js/conf/home/pages/datasource/pages/list/_source/createDataSource.vue

@ -56,7 +56,7 @@
<el-input
type="input"
v-model="host"
maxlength="60"
maxlength="255"
size="small"
:placeholder="$t('Please enter IP')">
</el-input>

1
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue

@ -52,6 +52,7 @@
<span>{{scope.row.description | filterNull}}</span>
</template>
</el-table-column>
<el-table-column prop="userName" :label="$t('Create User')"></el-table-column>
<el-table-column prop="modifyBy" :label="$t('Modify User')"></el-table-column>
<el-table-column :label="$t('Timing state')">
<template slot-scope="scope">

4
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue

@ -30,7 +30,7 @@
v-model="instanceName"
maxlength="60"
size="small"
:placeholder="$t('Please enter group name')">
:placeholder="$t('Please enter alarm plugin instance name')">
</el-input>
</template>
</m-list-box-f>
@ -108,7 +108,7 @@
_verification () {
// group name
if (!this.instanceName.replace(/\s*/g, '')) {
this.$message.warning(`${i18n.$t('Please enter group name')}`)
this.$message.warning(`${i18n.$t('Please enter alarm plugin instance name')}`)
return false
}
if (!this.pluginDefineId) {

2
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -238,6 +238,7 @@ export default {
'Instance parameter exception': 'Instance parameter exception',
'Group Type': 'Group Type',
'Alarm plugin instance': 'Alarm plugin instance',
'Please enter alarm plugin instance name': 'Please enter alarm plugin instance name',
'Select Alarm plugin instance': 'Please select an Alarm plugin instance',
Remarks: 'Remarks',
SMS: 'SMS',
@ -606,6 +607,7 @@ export default {
'Please enter Export Dir(required)': 'Please enter Export Dir(required)',
'Please enter Hive Database(required)': 'Please enter Hive Databasec(required)',
'Please enter Hive Table(required)': 'Please enter Hive Table(required)',
'Please enter hive target dir': 'Please enter hive target dir',
'Please enter Hive Partition Keys': 'Please enter Hive Partition Key',
'Please enter Hive Partition Values': 'Please enter Partition Value',
'Please enter Replace Delimiter': 'Please enter Replace Delimiter',

2
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -237,6 +237,7 @@ export default {
'Instance parameter exception': '实例参数异常',
'Group Type': '组类型',
'Alarm plugin instance': '告警插件实例',
'Please enter alarm plugin instance name': '请输入告警实例名称',
'Select Alarm plugin instance': '请选择告警插件实例',
Remarks: '备注',
SMS: '短信',
@ -605,6 +606,7 @@ export default {
'Please enter Export Dir(required)': '请输入数据源路径(必填)',
'Please enter Hive Database(required)': '请输入Hive数据库(必填)',
'Please enter Hive Table(required)': '请输入Hive表名(必填)',
'Please enter hive target dir': '请输入Hive临时目录',
'Please enter Hive Partition Keys': '请输入分区键',
'Please enter Hive Partition Values': '请输入分区值',
'Please enter Replace Delimiter': '请输入替换分隔符',

2
script/dolphinscheduler-daemon.sh

@ -152,7 +152,7 @@ case $startStop in
(status)
# more details about the status can be added later
serverCount=`ps -ef |grep "$CLASS" |grep -v "grep" |wc -l`
serverCount=`ps -ef | grep "$DOLPHINSCHEDULER_HOME" | grep "$CLASS" | grep -v "grep" | wc -l`
state="STOP"
# font color - red
state="[ \033[1;31m $state \033[0m ]"

Loading…
Cancel
Save