Commit 13f273d5 by huangfusuper

Merge branches 'developer' and 'test' of https://git.byitgroup.com/liyuan/byit-myth-job into test

 Conflicts:
	byit-mybatis-plugin/pom.xml
	byit-myth-core/myth-executor-core/pom.xml
	byit-myth-executor/myth-executor-plugin/pom.xml
	byit-plugin-core/byit-plugin-rpc-common/pom.xml
	byit-plugin-core/byit-plugin-rpc-common/src/main/java/com/byit/task/annotations/TaskClient.java
	byit-plugin-core/myth-plugin-rpc-client/pom.xml
	byit-plugin-core/plugin-spring-boot-starter/pom.xml
	byit-plugin-core/pom.xml
parents 4d0deef8 e5a4154f
......@@ -124,11 +124,6 @@
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.byit</groupId>
<artifactId>byit-mybatis-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<configuration>
<configurationFile>${basedir}/src/main/resources/Generator-config.xml</configurationFile>
......
......@@ -2,7 +2,9 @@ package com.byit.api;
import com.byit.dto.executor.KillDto;
import com.byit.dto.plugin.CollectData;
import com.byit.dto.plugin.RunInfo;
import com.byit.dto.plugin.StopFlowParam;
import com.byit.dto.recording.LoadScheduleCondition;
import com.byit.dto.specials.RepairFlow;
import com.byit.dto.web.ResponseResult;
import com.byit.model.RunRecording;
......@@ -114,37 +116,32 @@ public class ApiFlowController {
@PostMapping("reRunJob")
@ApiOperation("重跑节点")
public ResponseResult reRunJob(String param) {
public ResponseResult reRunJob(@RequestBody RunInfo param) {
apiFlowService.reRunJob(param);
return ResponseResult.ok("SUCCESS");
}
@PostMapping("reRunFlow")
@ApiOperation("重跑工作流")
public ResponseResult reRunFlow(String param) {
public void reRunFlow(@RequestBody RunInfo param) {
apiFlowService.reRunFlow(param);
return ResponseResult.ok("SUCCESS");
}
@PostMapping("madeSuccess")
@ApiOperation("手动置为成功")
public ResponseResult madeSuccess(String param) {
public ResponseResult madeSuccess(@RequestBody RunInfo param) {
apiFlowService.madeSuccess(param);
return ResponseResult.ok("SUCCESS");
}
/**
* @param param startTime
* endTime
* flowName
* workspaceName
* @return
* @param loadScheduleCondition 查询条件
* @return 对应的任务实例
*/
@PostMapping("loadScheduleResult")
@ApiOperation("加载运行记录")
public ResponseResult loadScheduleResult(String param) {
List<RunRecording> result = apiFlowService.loadScheduleResult(param);
return ResponseResult.ok(result);
public List<RunRecording> loadScheduleResult(@RequestBody LoadScheduleCondition loadScheduleCondition) {
return apiFlowService.loadScheduleResult(loadScheduleCondition);
}
/**
......
package com.byit.controller;
import com.byit.call.TaskServer;
import com.byit.conf.MythJobAutoConfigure;
import com.byit.dto.executor.DispatchResponseDto;
import com.byit.dto.executor.JobRunResultDto;
import com.byit.dto.executor.PluginBeanJobInfo;
import com.byit.enums.CallMethodEnum;
import com.byit.model.JobTask;
import com.byit.packet.request.PluginRpcRequestPacket;
import com.byit.packet.response.PluginRpcResponsePacket;
import com.byit.service.JobTaskService;
import com.byit.service.RunScriptService;
import com.byit.task.annotations.TaskClient;
import com.byit.thread.LogCallbackThread;
import com.byit.util.SourceObj2TargetObjUtil;
import com.byit.utils.ValidationUtil;
......@@ -35,6 +40,9 @@ public class JobController {
this.jobTaskService = jobTaskService;
}
@TaskClient(timeout = 30000, callMethodEnum = CallMethodEnum.SYNCHRONIZE)
private TaskServer taskServer;
@PostMapping(value = "addJob")
public String addJob(@RequestBody PluginBeanJobInfo pluginBeanJobInfo){
......@@ -55,10 +63,11 @@ public class JobController {
}
@GetMapping("test")
public DispatchResponseDto test(){
DispatchResponseDto dispatchResponseDto = runScriptService.runScript(null);
System.out.println("---------------------");
return dispatchResponseDto;
public PluginRpcResponsePacket test(){
PluginRpcRequestPacket rpcRequestPacket = new PluginRpcRequestPacket();
rpcRequestPacket.setJobName("qualityBeforeTaskJob");
rpcRequestPacket.setCallMethodEnum(CallMethodEnum.SYNCHRONIZE);
PluginRpcResponsePacket call = taskServer.call(rpcRequestPacket);
return call;
}
}
......@@ -2,7 +2,9 @@ package com.byit.service;
import com.byit.dto.plugin.CollectData;
import com.byit.dto.plugin.PluginFlow;
import com.byit.dto.plugin.RunInfo;
import com.byit.dto.plugin.StopFlowParam;
import com.byit.dto.recording.LoadScheduleCondition;
import com.byit.dto.specials.RepairFlow;
import com.byit.model.RunRecording;
import com.byit.model.vo.RunRecordingVo;
......@@ -47,26 +49,26 @@ public interface ApiFlowService {
* 重跑任务
* @param param
*/
void reRunJob(String param);
void reRunJob(RunInfo param);
/**
* 手动置为成功
* @param param
* @param runInfo
*/
void madeSuccess(String param);
void madeSuccess(RunInfo runInfo);
/**
* 重跑工作流
* @param param
*/
void reRunFlow(String param);
void reRunFlow(RunInfo param);
/**
* 加载运行记录
* @param param
* @param loadScheduleCondition
* @return
*/
List<RunRecording> loadScheduleResult(String param);
List<RunRecording> loadScheduleResult(LoadScheduleCondition loadScheduleCondition);
/**
* 补批
......
......@@ -4,15 +4,15 @@ import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.byit.dto.NodeRelyDto;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.dto.specials.MakeUpReturn;
import com.byit.dto.specials.RepairFlow;
import com.byit.dto.specials.RepairTimeParam;
import com.byit.dto.specials.SpecialJobParam;
import com.byit.enums.NodeTypeEnum;
import com.byit.enums.PlaceholderEnum;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.job.utils.CurrentUserUtils;
import com.byit.job.utils.DateUtil;
import com.byit.job.utils.PlaceholderUtils;
import com.byit.mapper.RunRecordingMapper;
......@@ -27,6 +27,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -54,22 +55,23 @@ public class ApiFlowOperatingServiceImpl implements ApiFlowOperatingService {
private final WorkspaceService workspaceService;
private final NodeService nodeService;
private final NodeDependencyService nodeDependencyService;
private final CurrentUserUtils currentUserUtils;
private final WaitingRecordMapper waitingRecordMapper;
private final RunRecordingMapper runRecordingMapper;
private final WaitingTaskMapper waitingTaskMapper;
private final StringRedisTemplate stringRedisTemplate;
public ApiFlowOperatingServiceImpl(FlowService flowService, WorkspaceService workspaceService, NodeService nodeService,
NodeDependencyService nodeDependencyService, CurrentUserUtils currentUserUtils,
WaitingRecordMapper waitingRecordMapper, RunRecordingMapper runRecordingMapper, WaitingTaskMapper waitingTaskMapper) {
NodeDependencyService nodeDependencyService, WaitingRecordMapper waitingRecordMapper,
RunRecordingMapper runRecordingMapper, WaitingTaskMapper waitingTaskMapper,
StringRedisTemplate stringRedisTemplate) {
this.flowService = flowService;
this.workspaceService = workspaceService;
this.nodeService = nodeService;
this.nodeDependencyService = nodeDependencyService;
this.currentUserUtils = currentUserUtils;
this.waitingRecordMapper = waitingRecordMapper;
this.runRecordingMapper = runRecordingMapper;
this.waitingTaskMapper = waitingTaskMapper;
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
......@@ -116,100 +118,23 @@ public class ApiFlowOperatingServiceImpl implements ApiFlowOperatingService {
List<NodeDependencyKey> allNodeDependencyKey = nodeDependencyService.findAllNodeDependencyKey(integerList);
//解析对应的版本依赖
Set<NodeRelyDto> nodeRelyDtoSet = FlowNodeRelyParseUtil.parseThisVersionNodeRely(nodeByFlowIdAndVersionName, startNodeTaskName, allNodeDependencyKey, "1".equals(supplementStatus));
if (CollectionUtil.isNotEmpty(nodeRelyDtoSet)) {
//循环所有的结果集
nodeRelyDtoSet.forEach(nodeWrapped -> {
Node node = nodeWrapped.getNode();
String runCommand = node.getRunCommand();
//将公共参数放到替换参数里面
if(CollectionUtil.isNotEmpty(publicParam) && StringUtils.isNoneBlank(runCommand) && !runCommand.startsWith("java")){
//获取运行参数
String runParam = node.getRunParam();
//创建包装参数
RunParamWrapped runParamWrapped = new RunParamWrapped();
//如果运行参数不为空
if(StringUtils.isNoneBlank(runParam)){
//json化运行参数
runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
//获取私有参数
String privateParam = runParamWrapped.getPrivateParam();
//如果私有参数不为空
if(StringUtils.isNoneBlank(privateParam)) {
//转换成参数对象
ScriptParamAndPlaceholderDto paramAndPlaceholderDto = JSON.parseObject(runParamWrapped.getPrivateParam(), ScriptParamAndPlaceholderDto.class);
//获取替换参数
Map<String, String> placeholder = paramAndPlaceholderDto.getPlaceholder();
if(placeholder == null){
placeholder = new HashMap<>(8);
}
//将公共参数放到替换参数
for (Map.Entry<String, String> stringStringEntry : publicParam.entrySet()) {
placeholder.put(stringStringEntry.getKey(),stringStringEntry.getValue());
}
paramAndPlaceholderDto.setPlaceholder(placeholder);
//重新设置包装对象
runParamWrapped.setPrivateParam(JSON.toJSONString(paramAndPlaceholderDto));
//如果运行参数为空
}else{
//创建一个参数对象
ScriptParamAndPlaceholderDto paramAndPlaceholderDto = new ScriptParamAndPlaceholderDto();
//设置替换参数
paramAndPlaceholderDto.setPlaceholder(publicParam);
//设置参数包装对象的私有参数
runParamWrapped.setPrivateParam(JSON.toJSONString(paramAndPlaceholderDto));
}
//运行参数为空
}else {
//重复上述步骤
ScriptParamAndPlaceholderDto paramAndPlaceholderDto = new ScriptParamAndPlaceholderDto();
paramAndPlaceholderDto.setPlaceholder(publicParam);
runParamWrapped.setPrivateParam(JSON.toJSONString(paramAndPlaceholderDto));
}
node.setRunParam(JSON.toJSONString(runParamWrapped));
}
//TODO 原来的参数替换位置
String nodeName = node.getNodeName();
//基于节点名称替换参数
String param = parseParam(paramCarrier,nodeName);
String param = parseParam(paramCarrier, nodeName);
if (StringUtils.isNoneBlank(param)) {
//获取包装逻辑
RunParamWrapped runParamWrapped = new RunParamWrapped();
runParamWrapped.setPrivateParam(param);
runParamWrapped.setPublicParamMap(publicParam);
//构建参数
node.setRunParam(JSON.toJSONString(runParamWrapped));
}else{
String runParam = node.getRunParam();
RunParamWrapped runParamWrapped = new RunParamWrapped();
if(StringUtils.isNoneBlank(runParam)) {
runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
}
runParamWrapped.setPublicParamMap(publicParam);
//构建参数
node.setRunParam(JSON.toJSONString(runParamWrapped));
}
if(StringUtils.isNoneBlank(runCommand)){
if(runCommand.startsWith(JAVA_TYPE) && CollectionUtil.isNotEmpty(publicParam)){
for (Map.Entry<String, String> stringStringEntry : publicParam.entrySet()) {
if(!"auditTime".equals(stringStringEntry.getKey())){
String keyName = String.format("${%s}",stringStringEntry.getKey());
runCommand = runCommand.replace(keyName,stringStringEntry.getValue());
}
}
node.setRunCommand(runCommand);
}
node.setRunParam(param);
}
});
}
if (CollectionUtil.isNotEmpty(nodeRelyDtoSet)) {
//构建等待队列
List<WaitingRecord> waitingRecords = buildWaitingRecordList(flowByName, nodeRelyDtoSet.size(), operator, repairTimeList);
List<WaitingRecord> waitingRecords = buildWaitingRecordList(flowByName, nodeRelyDtoSet.size(), operator, repairTimeList, JSON.toJSONString(publicParam));
waitingRecords.forEach(waitingRecordMapper::insertSelective);
List<RunRecording> runRecordings = buildRunRecordingList(waitingRecords);
List<WaitingTask> waitingTaskList = buildWaitingTaskResult(waitingRecords, nodeRelyDtoSet, specialJobParam.getPublicParam(), timeFormatName, nowTimeFormatName);
......@@ -230,12 +155,13 @@ public class ApiFlowOperatingServiceImpl implements ApiFlowOperatingService {
/**
* 解析参数
*
* @param paramCarrier 参数信息
* @param nodeName 节点名称
* @param nodeName 节点名称
* @return
*/
public String parseParam(Map<String, String> paramCarrier, String nodeName){
if(CollectionUtil.isNotEmpty(paramCarrier)){
public String parseParam(Map<String, String> paramCarrier, String nodeName) {
if (CollectionUtil.isNotEmpty(paramCarrier)) {
return paramCarrier.get(nodeName);
}
return null;
......@@ -263,7 +189,7 @@ public class ApiFlowOperatingServiceImpl implements ApiFlowOperatingService {
* @param nodeRelyDtoSet 节点对象
* @return 返回一个等待队的全部节点
*/
private List<WaitingTask> buildWaitingTask(WaitingRecord waitingRecord, Set<NodeRelyDto> nodeRelyDtoSet, Map<String, String> publicParam, String timeFormat, String nowDateFormat) {
protected List<WaitingTask> buildWaitingTask(WaitingRecord waitingRecord, Set<NodeRelyDto> nodeRelyDtoSet, Map<String, String> publicParam, String timeFormat, String nowDateFormat) {
return nodeRelyDtoSet.stream().map(nodeRelyDto -> {
Node node = nodeRelyDto.getNode();
String relyId = nodeRelyDto.getRelyId();
......@@ -280,33 +206,33 @@ public class ApiFlowOperatingServiceImpl implements ApiFlowOperatingService {
waitingTask.setScheduleType(ScheduleTypeEnum.REPAIR.getCode());
waitingTask.setWaitId(waitingRecord.getWaitId());
RunParamWrapped runParamWrapped = JSON.parseObject(waitingTask.getRunParam(), RunParamWrapped.class);
if(runParamWrapped == null) {
runParamWrapped = new RunParamWrapped();
}
runParamWrapped.setPublicParamMap(publicParam);
try {
SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
Date repairDate = sdf.parse(repeatTime);
ValidationUtil.isTrueValidation(!repairDate.before(new Date()), "只能补过去时间的批次!");
} catch (ParseException e) {
log.error("补批日期不符合规范,例:{}", timeFormat);
ValidationUtil.isTrueValidation(true, "补批日期不符合规范,例:" + timeFormat);
}
//补批只替换不是java的节点
if (!NodeTypeEnum.JAVA.getCode().equals(waitingTask.getJobType())) {
if (StringUtils.isNotEmpty(waitingTask.getRunParam())) {
String param = PlaceholderUtils.formatBizDateParam(runParamWrapped.getPrivateParam(), PlaceholderEnum.DATE_PLACEHOLDER.getName(), repeatTime, 0);
String dateFormat = DateUtil.dateFormat(new Date(), nowDateFormat);
param = PlaceholderUtils.formatBizDateParam(param, PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), dateFormat, 0);
//设置替换完成后的参数
runParamWrapped.setPrivateParam(param);
}
}
waitingTask.setRunParam(JSON.toJSONString(runParamWrapped));
// RunParamWrapped runParamWrapped = JSON.parseObject(waitingTask.getRunParam(), RunParamWrapped.class);
// if (runParamWrapped == null) {
// runParamWrapped = new RunParamWrapped();
// }
// runParamWrapped.setPublicParamMap(publicParam);
//
// try {
// SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
// Date repairDate = sdf.parse(repeatTime);
// ValidationUtil.isTrueValidation(!repairDate.before(new Date()), "只能补过去时间的批次!");
// } catch (ParseException e) {
// log.error("补批日期不符合规范,例:{}", timeFormat);
// ValidationUtil.isTrueValidation(true, "补批日期不符合规范,例:" + timeFormat);
// }
//
// //补批只替换不是java的节点
// if (!NodeTypeEnum.JAVA.getCode().equals(waitingTask.getJobType())) {
// if (StringUtils.isNotEmpty(waitingTask.getRunParam())) {
//
// String param = PlaceholderUtils.formatBizDateParam(runParamWrapped.getPrivateParam(), PlaceholderEnum.DATE_PLACEHOLDER.getName(), repeatTime, 0);
// String dateFormat = DateUtil.dateFormat(new Date(), nowDateFormat);
// param = PlaceholderUtils.formatBizDateParam(param, PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), dateFormat, 0);
// //设置替换完成后的参数
// runParamWrapped.setPrivateParam(param);
// }
// }
// waitingTask.setRunParam(JSON.toJSONString(runParamWrapped));
return waitingTask;
}).collect(Collectors.toList());
}
......@@ -354,31 +280,52 @@ public class ApiFlowOperatingServiceImpl implements ApiFlowOperatingService {
* @param repairTimeList 补时间
* @return 等待队列集合
*/
private List<WaitingRecord> buildWaitingRecordList(Flow flow, Integer nodeCount, String operator, List<RepairTimeParam> repairTimeList) {
private List<WaitingRecord> buildWaitingRecordList(Flow flow, Integer nodeCount, String operator, List<RepairTimeParam> repairTimeList, String publicParam) {
//查看当前排队的工作流最大排队序号
Integer order = waitingRecordMapper.findOrderByFlowId(flow.getFlowId());
if (order == null) {
order = 0;
}
//传递过来的公共参数格式化
Map<String,String> publicMap = JSON.parseObject(publicParam, Map.class);
if(CollectionUtil.isEmpty(publicMap)){
publicMap = new HashMap<>(8);
}
List<WaitingRecord> waitingRecords = new ArrayList<>(2);
for (RepairTimeParam repairTimeParam : repairTimeList) {
publicMap.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(),repairTimeParam.getRepairTime());
publicMap.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(),repairTimeParam.getRepairTime());
String repeatTime = repairTimeParam.getRepairTime();
String timeTypeName = repairTimeParam.getTimeTypeName();
WaitingRecord waitingRecord = new WaitingRecord();
BeanUtils.copyProperties(flow, waitingRecord);
//设置排期
BeanUtils.copyProperties(flow, waitingRecord);
String extendedConfiguration = flow.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
if (flowExtendedConfiguration != null) {
String flowPublicParam = flowExtendedConfiguration.getPublicParam();
Map<String,String> flowPublicParamMap = JSON.parseObject(flowPublicParam, Map.class);
if(flowPublicParamMap == null){
flowPublicParamMap = new HashMap<>();
}
flowPublicParamMap.putAll(publicMap);
flowExtendedConfiguration.setPublicParam(JSON.toJSONString(flowPublicParamMap));
} else {
flowExtendedConfiguration = new FlowExtendedConfiguration();
flowExtendedConfiguration.setPublicParam(JSON.toJSONString(publicMap));
}
waitingRecord.setExtendedConfiguration(JSON.toJSONString(flowExtendedConfiguration));
waitingRecord.setFlowVersionName(flow.getVersionName());
waitingRecord.setRunId(IDGenerationStrategy.runIdGenerationStrategy(serverPort));
String runId = IDGenerationStrategy.runIdGenerationStrategy(serverPort);
waitingRecord.setRunId(runId);
waitingRecord.setFlowNodeCount(nodeCount);
waitingRecord.setOperator(operator);
waitingRecord.setScheduleType(ScheduleTypeEnum.REPAIR.getCode());
waitingRecord.setRepeatTime(repeatTime);
waitingRecord.setWaitOrder(++order);
//需要按着时间先后来设置时间
long time = DateUtil.strFormatDate(repeatTime, timeTypeName).getTime();
waitingRecord.setTriggerTime(time);
waitingRecord.setTriggerTime(System.currentTimeMillis());
waitingRecords.add(waitingRecord);
}
......
package com.byit.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
......@@ -7,15 +8,15 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.byit.dto.StatisticsConditionDto;
import com.byit.dto.api.DeleteDto;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.dto.plugin.*;
import com.byit.dto.recording.LoadScheduleCondition;
import com.byit.dto.specials.RepairFlow;
import com.byit.dto.specials.RepairTimeParam;
import com.byit.enums.*;
import com.byit.enums.plugin.PluginNodeTypeEnum;
import com.byit.job.utils.CronExpression;
import com.byit.job.utils.CurrentUserUtils;
import com.byit.job.utils.PlaceholderUtils;
import com.byit.mapper.*;
import com.byit.model.JobTaskRunLog;
import com.byit.model.RunRecording;
......@@ -40,6 +41,7 @@ import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
......@@ -129,7 +131,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
Workspace workspace = validate(pluginPackage);
//保存工作流
log.debug("保存工作流和节点信息");
Flow flow = saveFlow(pluginPackage.getFlow(), workspace.getWorkspaceId(), false);
Flow flow = saveFlow(pluginPackage.getFlow(), workspace.getWorkspaceId(), false, "");
//生成工作流版本
log.debug("生成版本");
FlowVersion flowVersion = saveFlowVersion(flow);
......@@ -146,9 +148,17 @@ public class ApiFlowServiceImpl implements ApiFlowService {
* @param isInnner
* @param workspaceId
*/
private Flow saveFlow(PluginFlow pluginFlow, Integer workspaceId, boolean isInnner) throws Exception {
private Flow saveFlow(PluginFlow pluginFlow, Integer workspaceId, boolean isInnner, String upFlowName) throws Exception {
//拼装工作流名称
upFlowName = String.format("%s:%s", upFlowName, pluginFlow.getName());
Flow flow = new Flow();
FlowExtendedConfiguration extendedConfiguration = pluginFlow.getConfig().getExtendedConfiguration();
if (extendedConfiguration == null) {
extendedConfiguration = new FlowExtendedConfiguration();
}
extendedConfiguration.setFlowEmbedLogo(upFlowName);
flow.setExtendedConfiguration(JSON.toJSONString(extendedConfiguration));
flow.setFlowName(pluginFlow.getName());
flow.setIsInner(isInnner ? "0" : "1");
flow.setFlowNodeCount(pluginFlow.getNodeList().size());
......@@ -163,8 +173,6 @@ public class ApiFlowServiceImpl implements ApiFlowService {
flow.setAlarmlAction(pluginFlow.getConfig().getAlarmlAction());
flow.setAlarmEmail(pluginFlow.getConfig().getAlarmEmail());
flow.setScanMark("1");
Map<String, String> publicParamMap = pluginFlow.getConfig().getPublicParam();
flow.setFlowDesc(JSON.toJSONString(publicParamMap));
//设置可执行次数
//若没设置或者设置为-1,则响应设置剩余的执行次数
if (null != pluginFlow.getConfig().getRepeatCount() && !"-1".equals(pluginFlow.getConfig().getRepeatCount())) {
......@@ -176,8 +184,8 @@ public class ApiFlowServiceImpl implements ApiFlowService {
flow.setScheduleFollow(StringUtils.isEmpty(pluginFlow.getConfig().getScheduleFollow()) ? "1" : pluginFlow.getConfig().getScheduleFollow());
flow.setFlowCron(pluginFlow.getConfig().getFlowCron());
flow.setTriggerNextTime(StringUtils.isEmpty(pluginFlow.getConfig().getFlowCron()) ? null : new CronExpression(pluginFlow.getConfig().getFlowCron()).getNextValidTimeAfter(new Date()).getTime());
//设置超时时间,未设置默认30分钟
flow.setFlowTimeout(null == pluginFlow.getConfig().getFlowTimeout() ? 1000 * 60 * 120 : pluginFlow.getConfig().getFlowTimeout());
//设置超时时间,未设置默认5天
flow.setFlowTimeout(null == pluginFlow.getConfig().getFlowTimeout() ? TimeUnit.DAYS.toMillis(5) : pluginFlow.getConfig().getFlowTimeout());
Flow oldFlow = flowMapper.getByWorkSpaceAndName(workspaceId, pluginFlow.getName());
//判断是否是重发
if ((pluginFlow.isRePublish() && !isInnner) || (isInnner && null != oldFlow)) {
......@@ -193,7 +201,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
flow.setVersionName(versionName);
}
flowMapper.updateByIdSelective(flow);
updateNodeByFlow(pluginFlow.getNodeList(), flow, publicParamMap);
updateNodeByFlow(pluginFlow.getNodeList(), flow, upFlowName);
} else {
String versionName = pluginFlow.getVersionName();
......@@ -204,9 +212,8 @@ public class ApiFlowServiceImpl implements ApiFlowService {
}
Integer flowId = flowMapper.insertSelective(flow);
saveNode(pluginFlow.getNodeList(), flow, publicParamMap);
saveNode(pluginFlow.getNodeList(), flow, upFlowName);
}
return flow;
}
......@@ -216,7 +223,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
* @param pluginNodeList
* @param flow
*/
private void updateNodeByFlow(List<PluginBaseNode> pluginNodeList, Flow flow, Map<String, String> publicParamMap) throws Exception {
private void updateNodeByFlow(List<PluginBaseNode> pluginNodeList, Flow flow, String upFlowName) throws Exception {
//将工作流下的所有节点设为不在工作流调度上
log.debug("将工作流【{}】所有的节点移下调度,并删除相关的依赖关系", flow.getFlowName());
......@@ -246,7 +253,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
//保存节点信息
for (PluginBaseNode pluginNode : pluginNodeList) {
Node node = new Node();
buildNode(pluginNode, flow, node, publicParamMap);
buildNode(pluginNode, flow, node, upFlowName);
Integer nodeId = nodeMapper.insertSelective(node);
nameIdRel.put(node.getNodeName(), node.getNodeId());
......@@ -261,12 +268,12 @@ public class ApiFlowServiceImpl implements ApiFlowService {
* @param nodeList
* @param flow
*/
private void saveNode(List<PluginBaseNode> nodeList, Flow flow, Map<String, String> publicParamMap) throws Exception {
private void saveNode(List<PluginBaseNode> nodeList, Flow flow, String upFlowName) throws Exception {
HashMap<String, Integer> nameIdRel = new HashMap<>();
//保存节点信息
for (PluginBaseNode pluginNode : nodeList) {
Node node = new Node();
buildNode(pluginNode, flow, node, publicParamMap);
buildNode(pluginNode, flow, node, upFlowName);
node.setNodeId(null);
Integer nodeId = nodeMapper.insertSelective(node);
nameIdRel.put(node.getNodeName(), node.getNodeId());
......@@ -282,7 +289,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
* @param node
* @throws Exception
*/
private void buildNode(PluginBaseNode pluginNode, Flow flow, Node node, Map<String, String> publicParamMap) throws Exception {
private void buildNode(PluginBaseNode pluginNode, Flow flow, Node node, String upFlowName) throws Exception {
node.setVersionName(flow.getVersionName());
node.setFlowId(flow.getFlowId());
......@@ -295,7 +302,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
PluginFlow pluginFlow = (PluginFlow) pluginNode;
pluginFlow.getConfig().setFlowCron(flow.getFlowCron());
//如果是内嵌工作流先保存工作流信息
Flow innerFlow = saveFlow(pluginFlow, flow.getWorkspaceId(), true);
Flow innerFlow = saveFlow(pluginFlow, flow.getWorkspaceId(), true, upFlowName);
node.setIsVirtual(NodePropertyEnum.IS_VIRTUAL.getCode());
node.setMapFlowId(innerFlow.getFlowId());
node.setVersionName(pluginFlow.getVersionName());
......@@ -338,11 +345,6 @@ public class ApiFlowServiceImpl implements ApiFlowService {
node.setSuperSuccessRun("0");
}
node.setIsVirtual(NodePropertyEnum.ISNOT_VIRTUAL.getCode());
RunParamWrapped runParamWrapped = new RunParamWrapped();
runParamWrapped.setPrivateParam(node.getRunParam());
runParamWrapped.setPublicParamMap(publicParamMap);
node.setRunParam(JSON.toJSONString(runParamWrapped));
}
}
......@@ -489,12 +491,11 @@ public class ApiFlowServiceImpl implements ApiFlowService {
/**
* 重跑任务
*
* @param param
* @param runInfo
*/
@Override
public void reRunJob(String param) {
ValidationUtil.dataNotBank(param, "请求参数不允许为空!");
RunInfo runInfo = JSON.parseObject(param, RunInfo.class);
public void reRunJob(RunInfo runInfo) {
ValidationUtil.dataNotNull(runInfo, "请求参数不允许为空!");
//获取工作空间名称
ValidationUtil.dataNotBank(runInfo.getWorkspaceName(), "工作空间名称不允许为空!");
//获取工作流名称
......@@ -524,8 +525,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
JobTaskRunLog jobTaskRunLog = jobTaskRunLogMapper.findByRunIdAndFlowIdAndNodeName(runInfo.getRunId(), flow.getFlowId(), runInfo.getNodeName());
ValidationUtil.dataNotNull(jobTaskRunLog, "查无此运行记录");
String userName = currentUserUtils.account();
String userName = runInfo.getOperator();
//校验上级是否成功
if (StringUtils.isNotEmpty(jobTaskRunLog.getNodeDepend())) {
List<String> dependNodeList = Arrays.asList(jobTaskRunLog.getNodeDepend().split(","));
......@@ -637,9 +637,9 @@ public class ApiFlowServiceImpl implements ApiFlowService {
@Override
public void reRunFlow(String param) {
ValidationUtil.dataNotBank(param, "请求参数不允许为空!");
RunInfo runInfo = JSON.parseObject(param, RunInfo.class);
public void reRunFlow(RunInfo runInfo) {
ValidationUtil.dataNotNull(runInfo, "请求参数不允许为空!");
//获取工作空间名称
ValidationUtil.dataNotBank(runInfo.getWorkspaceName(), "工作空间名称不允许为空!");
//获取工作流名称
......@@ -660,7 +660,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
Node node = nodeMapper.getByMapFlowId(flow.getFlowId());
RunInfo nodeRun = RunInfo.builder().workspaceName(runInfo.getWorkspaceName()).flowName(runInfo.getFlowName())
.nodeName(node.getNodeName()).runId(runInfo.getRunId()).runState("1").build();
reRunJob(JSON.toJSONString(nodeRun, WriteClassName));
reRunJob(nodeRun);
} else {
//不是内嵌工作流
Long triggerTime = System.currentTimeMillis();
......@@ -673,6 +673,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
WaitingRecord waitingRecord = new WaitingRecord();
//生成新的实例
RunRecording newRunRecording = buildRunRecording(runRecording, triggerTime, reRunId, jobTaskRunLogList.size(), userName);
newRunRecording.setOperator(runInfo.getOperator());
BeanUtils.copyProperties(newRunRecording, waitingRecord);
Integer order = waitingRecordMapper.findOrderByFlowId(flow.getFlowId());
if (order == null) {
......@@ -742,12 +743,11 @@ public class ApiFlowServiceImpl implements ApiFlowService {
/**
* 重跑任务
*
* @param param
* @param runInfo
*/
@Override
public void madeSuccess(String param) {
ValidationUtil.dataNotBank(param, "请求参数不允许为空!");
RunInfo runInfo = JSON.parseObject(param, RunInfo.class);
public void madeSuccess(RunInfo runInfo) {
ValidationUtil.dataNotNull(runInfo, "请求参数不允许为空!");
ValidationUtil.dataNotBank(runInfo.getWorkspaceName(), "工作空间名称不允许为空!");
ValidationUtil.dataNotBank(runInfo.getFlowName(), "工作流名称不允许为空!");
......@@ -758,9 +758,16 @@ public class ApiFlowServiceImpl implements ApiFlowService {
//开始校验
Workspace workspace = workspaceMapper.getByName(runInfo.getWorkspaceName());
ValidationUtil.dataNotNull(workspace, runInfo.getWorkspaceName() + "工作空间不存在");
Flow flow = flowMapper.getByWorkSpaceAndName(workspace.getWorkspaceId(), runInfo.getFlowName());
ValidationUtil.dataNotNull(flow, runInfo.getFlowName() + "工作流不存在");
Node node = nodeMapper.getByNameAndFlow(runInfo.getNodeName(), flow.getFlowId());
String versionName = runInfo.getVersionName();
FlowVersion byWorkSpaceAndName = flowVersionMapper.getByWorkSpaceAndName(workspace.getWorkspaceId(), runInfo.getFlowName(), versionName);
//Flow flow = flowMapper.getByWorkSpaceAndName(workspace.getWorkspaceId(), runInfo.getFlowName());
ValidationUtil.dataNotNull(byWorkSpaceAndName, runInfo.getFlowName() + "工作流不存在");
NodeVersion node = nodeVersionMapper.getByNameAndFlow(runInfo.getNodeName(), byWorkSpaceAndName.getFlowVersionId());
ValidationUtil.dataNotNull(node, runInfo.getNodeName() + "节点不存在");
//获取运行日志实例
JobTaskRunLog jobTaskRunLog = jobTaskRunLogMapper.findByRunIdAndNodeId(runInfo.getRunId(), node.getNodeId());
......@@ -771,13 +778,12 @@ public class ApiFlowServiceImpl implements ApiFlowService {
}
@Override
public List<RunRecording> loadScheduleResult(String param) {
ValidationUtil.dataNotBank(param, "请求参数不允许为空!");
JSONObject jsonObject = JSON.parseObject(param);
Long startTime = jsonObject.getLong("startTime");
public List<RunRecording> loadScheduleResult(LoadScheduleCondition loadScheduleCondition) {
ValidationUtil.dataNotNull(loadScheduleCondition, "请求参数不允许为空!");
Long startTime = loadScheduleCondition.getStartTime();
ValidationUtil.dataNotNull(startTime, "开始时间不允许为空!");
Long endTime = jsonObject.getLong("endTime");
Long endTime = loadScheduleCondition.getEndTime();
ValidationUtil.dataNotNull(endTime, "结束时间不允许为空!");
ValidationUtil.isTrueValidation(String.valueOf(startTime).length() < 13 || String.valueOf(endTime).length() < 13, "时间格式必须是毫秒");
......@@ -788,8 +794,8 @@ public class ApiFlowServiceImpl implements ApiFlowService {
ValidationUtil.isTrueValidation(between > 60, "查询时间最长为60天!");
//获取工作空间名称
String workspaceName = jsonObject.getString("workspaceName");
String flowName = jsonObject.getString("flowName");
String workspaceName = loadScheduleCondition.getWorkspaceName();
String flowName = loadScheduleCondition.getFlowName();
List<Integer> flowIds = new ArrayList<>();
if (StringUtils.isNotBlank(workspaceName)) {
Workspace workspace = workspaceMapper.getByName(workspaceName);
......@@ -806,19 +812,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
}
}
String scheduleStatus = jsonObject.getString("scheduleStatus");
List<String> scheduleStatusList = null;
if (StringUtils.isNotEmpty(scheduleStatus)) {
scheduleStatusList = Arrays.asList(scheduleStatus.split(","));
}
String executeStatus = jsonObject.getString("executeStatus");
List<String> executeStatusList = null;
if (StringUtils.isNotEmpty(executeStatus)) {
executeStatusList = Arrays.asList(executeStatus.split(","));
}
List<RunRecording> runRecordList = runRecordingMapper.findByStartAndEndTime(startTime, endTime, flowIds, scheduleStatusList, executeStatusList);
return runRecordList;
return runRecordingMapper.findByStartAndEndTime(loadScheduleCondition, flowIds);
}
......@@ -1341,6 +1335,18 @@ public class ApiFlowServiceImpl implements ApiFlowService {
waitingRecord.setScheduleType(ScheduleTypeEnum.REPAIR.getCode());
waitingRecord.setRepeatTime(repairTime);
waitingRecord.setWaitOrder(++order);
String extendedConfiguration = flow.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
Map<String, String> publicParamMap = JSON.parseObject(flowExtendedConfiguration.getPublicParam(), Map.class);
if (CollectionUtil.isEmpty(publicParamMap)) {
publicParamMap = new HashMap<>(8);
}
publicParamMap.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), repairTime);
publicParamMap.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
flowExtendedConfiguration.setPublicParam(JSON.toJSONString(publicParamMap));
waitingRecord.setExtendedConfiguration(JSON.toJSONString(flowExtendedConfiguration));
//需要按着时间先后来设置时间
waitingRecord.setTriggerTime(System.currentTimeMillis());
//设置实例
......@@ -1407,23 +1413,13 @@ public class ApiFlowServiceImpl implements ApiFlowService {
}
waitingTaskList.forEach(waitingTask -> {
//补批只替换不是java的节点
if (!NodeTypeEnum.JAVA.getCode().equals(waitingTask.getJobType())) {
if (StringUtils.isNotEmpty(waitingTask.getRunParam())) {
String runParamSource = waitingTask.getRunParam();
RunParamWrapped runParamWrapped = JSON.parseObject(runParamSource, RunParamWrapped.class);
//替换私有参数
String param = PlaceholderUtils.formatBizDateParam(runParamWrapped.getPrivateParam(), PlaceholderEnum.DATE_PLACEHOLDER.getName(), repairTime, 0);
String dateFormat = com.byit.job.utils.DateUtil.dateFormat(new Date(), nowDateTimeFormatName);
param = PlaceholderUtils.formatBizDateParam(param, PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), dateFormat, 0);
runParamWrapped.setPrivateParam(param);
param = JSON.toJSONString(runParamWrapped);
waitingTask.setRunParam(param);
waitingTask.setScheduleType(ScheduleTypeEnum.REPAIR.getCode());
}
}
waitingTaskDateList.add(waitingTask);
String runParam = waitingTask.getRunParam();
WaitingTask waitingTaskCopy = new WaitingTask();
BeanUtil.copyProperties(waitingTask, waitingTaskCopy);
waitingTaskCopy.setRunParam(runParam);
waitingTaskDateList.add(waitingTaskCopy);
});
result.put(repairTime, waitingTaskDateList);
}
......@@ -1457,6 +1453,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
//设置为是当前版本的工作流
flowVersion.setVersionMark(FlowPropertyEnum.IS_CURRENTVERSION.getCode());
flowVersion.setAddTime(currentDate);
flowVersion.setExtendedConfiguration(flow.getExtendedConfiguration());
flowVersionMapper.insertSelective(flowVersion);
//查询在调度上的节点
......@@ -1676,6 +1673,9 @@ public class ApiFlowServiceImpl implements ApiFlowService {
StringBuffer runids = new StringBuffer();
//暂停工作流调度
recordingList.forEach(runRecording -> {
if (RunRecordingEnum.FAIL_FAST_YES.getCode().equals(runRecording.getFailFast())) {
throw new RuntimeException(String.format("实例%s是快速失败状态", runRecording.getFlowName()));
}
//runRecordingMapper.stopByRunIdAndFlowId(runRecording.getRunId(), runRecording.getFlowId());
runRecordingMapper.stopByRunIdAndFlowId(runRecording.getRunId(), runRecording.getFlowId());
jobTaskMapper.stopByRunIdAndFlowId(runRecording.getRunId(), runRecording.getFlowId());
......@@ -1698,7 +1698,7 @@ public class ApiFlowServiceImpl implements ApiFlowService {
List<RunRecording> runRecordList = runRecordingMapper.findStopRunCordByRunId(runId);
//ValidationUtil.isTrueValidation(CollectionUtil.isEmpty(runRecordList), "该工作流不是暂停状态!");
if(CollectionUtil.isEmpty(runRecordList)){
if (CollectionUtil.isEmpty(runRecordList)) {
log.warn("---------运行记录{},不存在暂停记录中!---", runId);
return;
}
......
......@@ -82,17 +82,16 @@ public class ApiNodeServiceImpl implements ApiNodeService {
JobTaskSchedule schedule = new JobTaskSchedule();
//获取运行参数
String runParam = runNode.getRunParam();
RunParamWrapped runParamWrapped = new RunParamWrapped();
//包装公共参数和私有参数
runParamWrapped.setPrivateParam(runParam);
runParamWrapped.setPublicParamMap(runNode.getPublicParam());
// RunParamWrapped runParamWrapped = new RunParamWrapped();
// //包装公共参数和私有参数
// runParamWrapped.setPrivateParam(runParam);
// runParamWrapped.setPublicParamMap(runNode.getPublicParam());
//开始构建 schedule
schedule.setRunParam(JSON.toJSONString(runParamWrapped));
schedule.setRunParam(runParam);
schedule.setNodeId(Integer.valueOf(runNode.getNodeId()));
schedule.setRunId(runId);
schedule.setNodeName(runNode.getNodeName());
schedule.setIsVirtual(NodePropertyEnum.ISNOT_VIRTUAL.getCode());
schedule.setRunParam(JSON.toJSONString(runParamWrapped));
schedule.setRunCommand(runNode.getRunCmd());
schedule.setNodeDesc(runNode.getHasAddLogToFlow());
schedule.setRunSource(runNode.getRunSource());
......@@ -126,7 +125,6 @@ public class ApiNodeServiceImpl implements ApiNodeService {
if (NodeTypeEnum.JAVA.getCode().equals(runNode.getJobType())) {
timerTask = new JavaNodeExecutorTask(schedule);
}else{
schedule.setRunParam(JSON.toJSONString(runParamWrapped));
timerTask = new ScriptExecutorJobTask(schedule);
}
//添加到调度轮
......
package com.byit.annotations;
import java.lang.annotation.*;
/**
* 自定义类排序
*
* @author huangfu
* @date 2020年12月14日15:10:15
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MythRankOrder {
/**
* 级别
* @return 该类的级别
*/
int value() default -1;
}
package com.byit.conf;
import com.byit.util.ThreadPoolUtil;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @author Administrator
*/
public class RunRecordingThreadPool {
/**
* 实例执行生命周期后置回调的线程
*/
public static ThreadPoolExecutor RUN_RECORDING_THREAD_POOL = ThreadPoolUtil.createCutomizeThreadPoolExecutor("RunRecordingThreadPool",Runtime.getRuntime().availableProcessors()*2,100,60, TimeUnit.SECONDS,1024);
}
package com.byit.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 策略包包裹
*
* @author huangfu
* @date 2020年12月14日15:14:56
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BeanStrategyPackage<T> {
private String beanName;
private T bean;
}
package com.byit.dto;
import com.byit.model.JobTask;
import com.byit.model.RunRecording;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 实例包装
*
* @author huangfu
* @date 2020年11月25日18:31:07
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RunRecordingWrapped implements Serializable {
private static final long serialVersionUID = 6309696511670011734L;
private List<JobTask> nodeList;
private RunRecording runRecording;
}
......@@ -29,7 +29,7 @@ public enum NodeTypeEnum {
return this.code;
}
public NodeTypeEnum getTypeByCode(String code){
public static NodeTypeEnum getTypeByCode(String code){
for (NodeTypeEnum typeEnum : NodeTypeEnum.values()) {
if (typeEnum.getCode().equals(code)){
return typeEnum;
......
package com.byit.enums;
/**
* @author huangfu
*/
public enum RedisKeyNameEnum {
/**
* 调度中心公共参数
*/
REDIS_PUBLIC_PARAM_KEY("myth:param:public:%s%s"),
REDIS_FLOW_ERROR_MSG_KEY("myth:error:msg:%s:%s:"),
;
private final String keyName;
RedisKeyNameEnum(String keyName) {
this.keyName = keyName;
}
public String getKeyName() {
return keyName;
}
}
package com.byit.event;
import com.byit.model.RunRecording;
import org.springframework.context.ApplicationEvent;
/**
......@@ -9,20 +10,20 @@ import org.springframework.context.ApplicationEvent;
public class EndFlowEvent extends ApplicationEvent {
private static final long serialVersionUID = 2874836396737756384L;
private Integer flowId;
private final RunRecording runRecording;
/**
* 创建工作流完结的事件
*
* @param source the object on which the event initially occurred (never {@code null})
* @param flowId 工作流id
* @param runRecording 工作流实例
*/
public EndFlowEvent(Object source,Integer flowId) {
public EndFlowEvent(Object source,RunRecording runRecording) {
super(source);
this.flowId = flowId;
this.runRecording = runRecording;
}
public Integer getFlowId() {
return flowId;
public RunRecording getRunRecording() {
return runRecording;
}
}
package com.byit.event;
import com.byit.model.RunRecording;
import org.springframework.context.ApplicationEvent;
/**
......@@ -9,20 +10,21 @@ import org.springframework.context.ApplicationEvent;
*/
public class FlowScanEndEvent extends ApplicationEvent {
private Integer flowId;
private static final long serialVersionUID = -6549668138353259198L;
private final RunRecording runRecording;
/**
* 创建工作流添加进实例表完毕后的事件
*
* @param source the object on which the event initially occurred (never {@code null})
* @param flowId 工作流id
* @param runRecording 工作流
*/
public FlowScanEndEvent(Object source,Integer flowId) {
public FlowScanEndEvent(Object source,RunRecording runRecording) {
super(source);
this.flowId = flowId;
this.runRecording = runRecording;
}
public Integer getFlowId() {
return flowId;
public RunRecording getRunRecording() {
return runRecording;
}
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ public class FlowEventListener {
public void flowScanEndEventListener(FlowScanEndEvent flowScanEndEvent){
log.info("-----------监听到事件{},工作流添加进实例完成事件-------",flowScanEndEvent);
Flow flow = Flow.builder()
.flowId(flowScanEndEvent.getFlowId())
.flowId(flowScanEndEvent.getRunRecording().getFlowId())
.scanMark(FlowPropertyEnum.NOT_SCAN.getCode())
.build();
flowService.updateByIdSelective(flow);
......@@ -46,9 +46,11 @@ public class FlowEventListener {
public void flowEndEventListener(EndFlowEvent endFlowEvent){
log.info("-----------监听到事件{},工作流实例完成事件-------",endFlowEvent);
Flow flow = Flow.builder()
.flowId(endFlowEvent.getFlowId())
.flowId(endFlowEvent.getRunRecording().getFlowId())
.scanMark(FlowPropertyEnum.SCAN.getCode())
.build();
flowService.updateByIdSelective(flow);
}
}
package com.byit.mapper;
import com.byit.dto.FlowConditionDto;
import com.byit.model.Flow;
import com.byit.model.FlowVersion;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
......@@ -25,6 +27,14 @@ public interface FlowVersionMapper {
int updateByIdSelective(FlowVersion record);
/**
* 根据工作空间和工作流名称查找是否存在工作流
* @param workspaceId
* @param flowName
* @return
*/
FlowVersion getByWorkSpaceAndName(@Param("workspaceId") Integer workspaceId, @Param("flowName") String flowName, @Param("versionName")String versionName);
/**
* 根据当前工作流id查找当前应用的版本
* @param flowId
* @return
......
package com.byit.mapper;
import com.byit.model.Node;
import com.byit.model.NodeVersion;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
......@@ -28,6 +29,8 @@ public interface NodeVersionMapper {
NodeVersion getById(Integer nodeVersionId);
NodeVersion getByNameAndFlow(@Param("nodeName") String nodeName, @Param("flowVersionId") Integer flowVersionId);
int updateByIdSelective(NodeVersion record);
/**
......
......@@ -5,6 +5,7 @@ import com.byit.dto.FlowStatusCoreDto;
import com.byit.dto.StatisticsConditionDto;
import com.byit.dto.plugin.JobStatusDto;
import com.byit.dto.plugin.StatisticData;
import com.byit.dto.recording.LoadScheduleCondition;
import com.byit.model.RunRecording;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
......@@ -78,7 +79,7 @@ public interface RunRecordingMapper {
* @param runId
* @return
*/
RunRecording findAllByRunID(String runId);
RunRecording findAllByRunIDAndFlowName(@Param("runId") String runId, @Param("flowName") String flowName);
/**
*根据运行标识查询对应的运行实例
......@@ -221,11 +222,7 @@ public interface RunRecordingMapper {
*/
List<RunRecording> findUnFinishByRunId(@Param("runId")String runId, @Param("flowIdList")List<Integer> flowIdList);
List<RunRecording> findByStartAndEndTime(@Param("startDate")long startDate,
@Param("endDate")long endDate,
@Param("flowIds")List<Integer> flowIds,
@Param("scheduleStatusList")List<String> scheduleStatusList,
@Param("executeStatusList")List<String> executeStatusList);
List<RunRecording> findByStartAndEndTime(@Param("loadScheduleCondition")LoadScheduleCondition loadScheduleCondition, @Param("flowIds")List<Integer> flowIds);
/**
......
......@@ -157,6 +157,12 @@ public class Flow implements Serializable {
private String scanMark;
/**
* 扩展配置
*/
@ApiModelProperty("扩展配置")
private String extendedConfiguration;
/**
*/
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
......@@ -134,6 +134,12 @@ public class FlowVersion implements Serializable {
private String isInner;
/**
* 扩展配置
*/
@ApiModelProperty("扩展配置")
private String extendedConfiguration;
/**
*/
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
......@@ -36,7 +36,7 @@ public class NodeVersion implements Serializable {
* 插件端网关令牌
*/
@ApiModelProperty("插件端网关令牌")
private String puginToken;
private String pluginToken;
/**
* 当前节点的失败重试次数
......
......@@ -88,7 +88,7 @@ public class RunRecording implements Serializable {
/**
* 本次任务的执行时间
*/
@ApiModelProperty("本次任务的执行时间")
@ApiModelProperty("计划本次任务开始的时间")
private Long triggerTime;
/**
......@@ -106,13 +106,13 @@ public class RunRecording implements Serializable {
/**
* 开始时间
*/
@ApiModelProperty("开始时间")
@ApiModelProperty("实际开始时间")
private Date startTime;
/**
* 结束时间
*/
@ApiModelProperty("结束时间")
@ApiModelProperty("实际结束时间")
private Date endTime;
/**
......@@ -172,6 +172,12 @@ public class RunRecording implements Serializable {
private Integer stopCount;
/**
* 扩展配置
*/
@ApiModelProperty("扩展配置")
private String extendedConfiguration;
/**
*/
private static final long serialVersionUID = 1L;
}
\ No newline at end of file
......@@ -120,6 +120,12 @@ public class WaitingRecord implements Serializable {
@ApiModelProperty("工作空间id")
private Integer workspaceId;
/**
* 扩展配置
*/
@ApiModelProperty("扩展配置")
private String extendedConfiguration;
/**
*/
private static final long serialVersionUID = 1L;
......
......@@ -75,7 +75,7 @@ public interface RunRecordingService {
* @param runId
* @return
*/
RunRecording findAllByRunID(String runId);
RunRecording findAllByRunIDAndFlowName(String runId,String flowName);
/**
* 根据工作流ID查询 是否有正在运行中的实例
......
package com.byit.service.impl;
import com.byit.enums.EmailEnum;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.enums.RunRecordingEnum;
import com.byit.enums.task.RunResultEnum;
import com.byit.enums.task.RunTypeEnum;
......@@ -8,8 +9,9 @@ import com.byit.model.JobTaskRunLogWithBLOBs;
import com.byit.model.JobTaskSchedule;
import com.byit.service.FastRunLogService;
import com.byit.service.JobTaskRunLogService;
import com.byit.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Date;
......@@ -22,9 +24,11 @@ import java.util.Date;
public class FastRunLogServiceImpl implements FastRunLogService {
private final JobTaskRunLogService jobTaskRunLogService;
public static final String LINE = "\n";
private final StringRedisTemplate stringRedisTemplate;
public FastRunLogServiceImpl(JobTaskRunLogService jobTaskRunLogService) {
public FastRunLogServiceImpl(JobTaskRunLogService jobTaskRunLogService, StringRedisTemplate stringRedisTemplate) {
this.jobTaskRunLogService = jobTaskRunLogService;
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
......@@ -77,6 +81,12 @@ public class FastRunLogServiceImpl implements FastRunLogService {
}else{
jobTaskRunLog.setRunMsg(msg+ LINE);
}
String format = String.format(RedisKeyNameEnum.REDIS_FLOW_ERROR_MSG_KEY.getKeyName(), mythJobTaskSchedule.getRunId(), mythJobTaskSchedule.getFlowName());
String errorMsg = stringRedisTemplate.opsForValue().get(format);
if(StringUtils.isNoneBlank(errorMsg)) {
jobTaskRunLog.setRunMsg(errorMsg+ LINE);
stringRedisTemplate.delete(format);
}
jobTaskRunLog.setRunCount(jobTaskRunLogById.getRunCount()+1);
jobTaskRunLogService.updateJobTaskRunLogWithBLOBs(jobTaskRunLog);
log.info("-----------saveErrorLog--保存KILL脚本调度日志结束------------");
......
......@@ -517,13 +517,20 @@ public class FlowServiceImpl implements FlowService {
String killUrl = "http://" + exectUrl + "/myth-executor-server/processManager/killJob";
Map<String, Object> requestMap = new HashMap<>(2);
requestMap.put("logId", logId);
String killResult = HttpUtil.post(killUrl, requestMap);
log.info("请求结果{}", killResult);
ResponseResult responseResult = JSON.parseObject(killResult, ResponseResult.class);
if (!"SUCCESS".equals(responseResult.getResult())) {
errorMsg.append("【").append(nodeName).append("】杀死失败,错误信息为:").append(responseResult.getMsg());
try{
String killResult = HttpUtil.post(killUrl, requestMap);
log.info("请求结果{}", killResult);
ResponseResult responseResult = JSON.parseObject(killResult, ResponseResult.class);
if (!"SUCCESS".equals(responseResult.getResult())) {
errorMsg.append("【").append(nodeName).append("】杀死失败,错误信息为:").append(responseResult.getMsg());
return false;
}
}catch (Exception e) {
errorMsg.append("【").append(nodeName).append("】杀死失败,错误信息为:").append(e.getMessage());
return false;
}
return true;
}
......
......@@ -26,9 +26,12 @@ public class FlowStatusServiceImpl implements FlowStatusService {
if (RunRecordingEnum.RUN_FLOW_KILL.getCode().equals(runRecordingByFlowIdAndRunId.getFlowRunResult())) {
return RunRecordingEnum.RUN_FLOW_KILL.getCode();
}
if (RunRecordingEnum.FAIL_FAST_YES.getCode().equals(runRecordingByFlowIdAndRunId.getFailFast())) {
return RunRecordingEnum.FAIL_FAST_YES.getCode();
}
}
return null;
}
......
package com.byit.service.impl;
import com.byit.dto.BeanStrategyPackage;
import com.byit.enums.NodeNameEnum;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.enums.RunRecordingEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.enums.task.RunResultEnum;
import com.byit.event.FlowScanEndEvent;
import com.byit.job.utils.CronExpression;
import com.byit.job.utils.MythLogUtils;
import com.byit.model.Flow;
import com.byit.model.JobTask;
import com.byit.model.Node;
import com.byit.model.RunRecording;
import com.byit.service.*;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import com.byit.util.ClassSortUtil;
import com.byit.util.IDGenerationStrategy;
import com.byit.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.*;
/**
* @author huangfu
*/
@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
@Slf4j
public class RunNodeServiceImpl implements RunNodeServer, ApplicationEventPublisherAware {
private static final String TRIGGER_NAME = "系统调度";
private final RunRecordingService runRecordingService;
private final JobTaskService jobTaskService;
private final FlowService flowService;
private ApplicationEventPublisher applicationEventPublisher;
private final StringRedisTemplate stringRedisTemplate;
@Value("${server.port}")
private Integer serverPort;
/**
......@@ -45,43 +54,45 @@ public class RunNodeServiceImpl implements RunNodeServer, ApplicationEventPublis
private final NodeDependencyService nodeDependencyService;
public RunNodeServiceImpl(RunRecordingService runRecordingService, JobTaskService jobTaskService,
FlowService flowService, NodeDependencyService nodeDependencyService) {
FlowService flowService, StringRedisTemplate stringRedisTemplate, NodeDependencyService nodeDependencyService) {
this.runRecordingService = runRecordingService;
this.jobTaskService = jobTaskService;
this.flowService = flowService;
this.stringRedisTemplate = stringRedisTemplate;
this.nodeDependencyService = nodeDependencyService;
}
/**
* 保存到运行记录一份 将节点保存到job_task表
* @param flow 工作流
*
* @param flow 工作流
* @param nodes 节点
*/
@Override
public void saveRunRec(Flow flow, List<Node> nodes) {
log.info("---------saveRunRecAndTask start------【保存工作流:{}和节点:{}】-----------------------",flow,nodes);
log.info("---------saveRunRecAndTask start------【保存工作流:{}和节点:{}】-----------------------", flow, nodes);
String runId = IDGenerationStrategy.runIdGenerationStrategy(serverPort);
log.info("-------------【开始保存运行记录runId为:{}】------------------",runId);
log.info("-------------【开始保存运行记录runId为:{}】------------------", runId);
RunRecording build = new RunRecording();
BeanUtils.copyProperties(flow,build);
BeanUtils.copyProperties(flow, build);
build.setRunId(runId);
//TODO 这个不解释 不知道干嘛的 后续需要修改
build.setDispatchIp("0.0.0.0");
build.setFlowVersionName(flow.getVersionName());
build.setTriggerTime(flow.getTriggerNextTime());
runRecordingService.saveRunRecording(build);
build.setOperator(TRIGGER_NAME);
boolean isScheduleFollow = "1".equals(flow.getScheduleFollow());
log.info("-------------【开始保存节点信息,任务是否为跟随工作流,{}】---------------",isScheduleFollow);
log.info("-------------【开始保存节点信息,任务是否为跟随工作流,{}】---------------", isScheduleFollow);
List<JobTask> jobTasks = new ArrayList<>(32);
nodes.forEach(node -> {
for (Node node : nodes) {
JobTask jobTask = new JobTask();
jobTask.setScheduleType(1);
jobTask.setTriggerStatus("1");
BeanUtils.copyProperties(node,jobTask);
if(isScheduleFollow){
BeanUtils.copyProperties(node, jobTask);
if (isScheduleFollow) {
jobTask.setTriggerTime(flow.getTriggerNextTime());
}else {
} else {
jobTask.setTriggerTime(node.getTriggerNextTime());
try {
node.setTriggerNextTime(new CronExpression(node.getNodeCron()).getNextValidTimeAfter(new Date(node.getTriggerNextTime())).getTime());
......@@ -94,15 +105,42 @@ public class RunNodeServiceImpl implements RunNodeServer, ApplicationEventPublis
jobTask.setFlowName(flow.getFlowName());
jobTask.setScheduleType(ScheduleTypeEnum.NORMAL.getCode());
//如果不是开始节点
if(!NodeNameEnum.START_NODE.getNodeName().equals(jobTask.getNodeName())){
if (!NodeNameEnum.START_NODE.getNodeName().equals(jobTask.getNodeName())) {
List<Integer> dependIdByNodeId = nodeDependencyService.findDependIdByNodeId(jobTask.getNodeId());
String parentIds = StringUtils.join(dependIdByNodeId, ",");
jobTask.setNodeDepend(parentIds);
}
jobTasks.add(jobTask);
});
}
Map<String, InstanceRunTheLifeCycleCallback> beansOfType = SpringUtil.getBeansOfType(InstanceRunTheLifeCycleCallback.class);
//回调生命周期
try {
//数据排序
List<BeanStrategyPackage<InstanceRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(beansOfType);
for (BeanStrategyPackage<InstanceRunTheLifeCycleCallback> beanStrategyPackage : beanStrategyPackages) {
log.info("-------------【开始回调周期{}前置】---------------", beanStrategyPackage.getBeanName());
RunRecording runRecording = beanStrategyPackage.getBean().postProcessAfterInitialization(build);
if (runRecording != null) {
build = runRecording;
}
}
} catch (Exception e) {
String format = String.format(RedisKeyNameEnum.REDIS_FLOW_ERROR_MSG_KEY.getKeyName(), build.getRunId(), build.getFlowName());
stringRedisTemplate.opsForValue().set(format, MythLogUtils.getMessage(e));
// build.setFlowStatus(RunRecordingEnum.FLOW_STATUS_IS_END.getCode());
// build.setFlowRunResult(RunResultEnum.RUN_ERROR.getCode());
build.setFailFast(RunRecordingEnum.FAIL_FAST_YES.getCode());
build.setStartTime(new Date());
build.setEndTime(new Date());
}
//开始正式保存
runRecordingService.saveRunRecording(build);
jobTaskService.saveJobTasks(jobTasks);
log.info("-------------【开始修改工作流{}的下次运行时间,以及各种状态】---------------",flow);
log.info("-------------【开始修改工作流{}的下次运行时间,以及各种状态】---------------", flow);
try {
Long triggerNextTime = flow.getTriggerNextTime();
flow.setTriggerNextTime(new CronExpression(flow.getFlowCron()).getNextValidTimeAfter(new Date(triggerNextTime)).getTime());
......@@ -112,26 +150,27 @@ public class RunNodeServiceImpl implements RunNodeServer, ApplicationEventPublis
e.printStackTrace();
}
updateFlow(flow);
applicationEventPublisher.publishEvent(new FlowScanEndEvent(this,flow.getFlowId()));
applicationEventPublisher.publishEvent(new FlowScanEndEvent(this, build));
log.info("-------saveRunRecAndTaskAndUpdate end-----------【运行结束】-----------------");
}
/**
* 修改工作流的信息
*
* @param flow 工作流
*/
private void updateFlow(Flow flow){
if (flow.getRemainingCount()>0) {
flow.setRemainingCount(flow.getRemainingCount()-1);
private void updateFlow(Flow flow) {
if (flow.getRemainingCount() > 0) {
flow.setRemainingCount(flow.getRemainingCount() - 1);
}
flowService.updateByIdSelective(flow);
}
/**
* 设置时间发布器
*
* @param applicationEventPublisher
*/
@Override
......
......@@ -124,8 +124,8 @@ public class RunRecordingServiceImpl implements RunRecordingService {
}
@Override
public RunRecording findAllByRunID(String runId) {
return runRecordingMapper.findAllByRunID(runId);
public RunRecording findAllByRunIDAndFlowName(String runId,String flowName) {
return runRecordingMapper.findAllByRunIDAndFlowName(runId,flowName);
}
/**
......
......@@ -12,7 +12,7 @@ import org.springframework.stereotype.Service;
*/
@Service
public class RunScriptServiceImpl implements RunScriptService {
@RpcReference(timeout = 30000)
@RpcReference(timeout = -1)
private ScriptExecutorService scriptExecutorService;
@Override
public DispatchResponseDto runScript(ScriptDto scriptDto) {
......
package com.byit.service.mapservice.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.byit.dto.BeanStrategyPackage;
import com.byit.enums.*;
import com.byit.enums.task.RunResultEnum;
import com.byit.job.utils.CronExpression;
import com.byit.job.utils.DateUtil;
import com.byit.job.utils.MythLogUtils;
import com.byit.model.*;
import com.byit.service.*;
import com.byit.service.mapservice.RunRecordingAndJobTaskService;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import com.byit.util.ClassSortUtil;
import com.byit.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
......@@ -17,9 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -37,6 +41,7 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
private final JobTaskService jobTaskService;
private final WaitingRecordService waitingRecordService;
private final WaitingTaskService taskService;
private final StringRedisTemplate stringRedisTemplate;
/**
* 节点依赖查询操作
*/
......@@ -44,7 +49,7 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
public RunRecordingAndJobTaskServiceImpl(JobTaskRunLogService jobTaskRunLogService, NodeService nodeService,
FlowService flowService, RunRecordingService runRecordingService,
JobTaskService jobTaskService, WaitingRecordService waitingRecordService, WaitingTaskService taskService, NodeDependencyService nodeDependencyService) {
JobTaskService jobTaskService, WaitingRecordService waitingRecordService, WaitingTaskService taskService, StringRedisTemplate stringRedisTemplate, NodeDependencyService nodeDependencyService) {
this.jobTaskRunLogService = jobTaskRunLogService;
this.nodeService = nodeService;
this.flowService = flowService;
......@@ -52,6 +57,7 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
this.jobTaskService = jobTaskService;
this.waitingRecordService = waitingRecordService;
this.taskService = taskService;
this.stringRedisTemplate = stringRedisTemplate;
this.nodeDependencyService = nodeDependencyService;
}
/**
......@@ -121,6 +127,7 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
.failFast(RunRecordingEnum.FAIL_FAST_NO.getCode())
.workspaceId(virFlow.getWorkspaceId())
.repeatTime(mainRecording.getRepeatTime())
.extendedConfiguration(virFlow.getExtendedConfiguration())
.build();
if(repair) {
runRecording.setTriggerTime(mainRecording.getTriggerTime());
......@@ -128,6 +135,24 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
runRecording.setOperator(jobTask.getOperator());
runRecording.setScheduleType(jobTask.getScheduleType());
}
//开始执行生命周期 开始的
Map<String, InstanceRunTheLifeCycleCallback> beansOfType = SpringUtil.getBeansOfType(InstanceRunTheLifeCycleCallback.class);
try {
List<BeanStrategyPackage<InstanceRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(beansOfType);
//回调生命周期
for (BeanStrategyPackage<InstanceRunTheLifeCycleCallback> beanStrategyPackage : beanStrategyPackages) {
log.info("-------------【开始回调周期{}前置】---------------",beanStrategyPackage.getBeanName());
beanStrategyPackage.getBean().postProcessAfterInitialization(runRecording);
}
}catch (Exception e) {
String format = String.format(RedisKeyNameEnum.REDIS_FLOW_ERROR_MSG_KEY.getKeyName(), runRecording.getRunId(), runRecording.getFlowName());
stringRedisTemplate.opsForValue().set(format, MythLogUtils.getMessage(e));
runRecording.setFailFast(RunRecordingEnum.FAIL_FAST_YES.getCode());
runRecording.setStartTime(new Date());
runRecording.setEndTime(new Date());
}
runRecordingService.saveRunRecording(runRecording);
log.info("-----------【虚节点对应节点保存到任务表】--------------");
//获取所有的节点,开始将所有节点保存到任务表
......@@ -160,8 +185,9 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
task.setFlowName(runRecording.getFlowName());
if(repair) {
task.setOperator(jobTask.getOperator());
task.setScheduleType(jobTask.getScheduleType());
}
task.setScheduleType(jobTask.getScheduleType());
return task;
}).collect(Collectors.toList());
jobTaskService.saveJobTasks(jobTasks);
......@@ -234,7 +260,7 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
public void updateRunRecordingAndTask(WaitingRecord waitingRecord) {
log.debug("---------开始查询等待工作流{}对应的数据-------------",waitingRecord);
RunRecording runRecording = runRecordingService.findAllByRunID(waitingRecord.getRunId());
RunRecording runRecording = runRecordingService.findAllByRunIDAndFlowName(waitingRecord.getRunId(),waitingRecord.getFlowName());
log.info("-------修改运行实例表成功,查询对应等待实例{},的等待节点-------",waitingRecord);
List<WaitingTask> allByWaitId = taskService.findAllByWaitId(waitingRecord.getWaitId());
if(waitingRecord.getFlowNodeCount() != allByWaitId.size()){
......@@ -245,7 +271,7 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
runRecording.setStartTime(new Date());
//将运行实例改为以执行
runRecording.setFlowStatus(RunRecordingEnum.FLOW_STATUS_RUN_ING.getCode());
runRecordingService.updateRunRecordingById(runRecording);
log.info("-------查询等待节点成功,查询对应的等待节点成功,开始保存对应的等待节点{}-------",allByWaitId);
List<Integer> ids = new ArrayList<>(2);
......@@ -263,11 +289,35 @@ public class RunRecordingAndJobTaskServiceImpl implements RunRecordingAndJobTask
target.setTriggerTime(0L);
return target;
}).collect(Collectors.toList());
//开始执行生命周期 开始的
Map<String, InstanceRunTheLifeCycleCallback> beansOfType = SpringUtil.getBeansOfType(InstanceRunTheLifeCycleCallback.class);
try {
List<BeanStrategyPackage<InstanceRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(beansOfType);
//回调生命周期
for (BeanStrategyPackage<InstanceRunTheLifeCycleCallback> beanStrategyPackage : beanStrategyPackages) {
log.info("-------------【开始回调周期{}前置】---------------",beanStrategyPackage.getBeanName());
RunRecording runRecordingLi = beanStrategyPackage.getBean().postProcessAfterInitialization(runRecording);
if(runRecordingLi != null) {
runRecording = runRecordingLi;
}
}
}catch (Exception e) {
String format = String.format(RedisKeyNameEnum.REDIS_FLOW_ERROR_MSG_KEY.getKeyName(), runRecording.getRunId(), runRecording.getFlowName());
stringRedisTemplate.opsForValue().set(format, MythLogUtils.getMessage(e));
// runRecording.setFlowStatus(RunRecordingEnum.FLOW_STATUS_IS_END.getCode());
// runRecording.setFlowRunResult(RunResultEnum.RUN_ERROR.getCode());
runRecording.setFailFast(RunRecordingEnum.FAIL_FAST_YES.getCode());
runRecording.setStartTime(new Date());
runRecording.setEndTime(new Date());
}
runRecordingService.updateRunRecordingById(runRecording);
jobTaskService.saveJobTasks(jobTasks);
//保存等待实例
waitingRecord.setWaitOrder(-1);
log.info("-------保存jobTask成功,开始修改等待实例{}-----------------",waitingRecord);
//waitingRecordService.updateById(waitingRecord);
if (CollectionUtil.isNotEmpty(ids)) {
taskService.deleteAllByIds(ids);
}
......
package com.byit.service.mapservice.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.byit.conf.RunRecordingThreadPool;
import com.byit.dto.BeanStrategyPackage;
import com.byit.dto.RunRecordingWrapped;
import com.byit.enums.EmailEnum;
import com.byit.enums.FlowPropertyEnum;
import com.byit.enums.RunRecordingEnum;
......@@ -9,6 +12,9 @@ import com.byit.event.EndFlowEvent;
import com.byit.model.*;
import com.byit.service.*;
import com.byit.service.mapservice.RunRecordingAndLogService;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import com.byit.util.ClassSortUtil;
import com.byit.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
......@@ -17,9 +23,7 @@ import org.springframework.stereotype.Service;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -88,7 +92,7 @@ public class RunRecordingAndLogServiceImpl implements RunRecordingAndLogService,
runRecording.setIsAlarm(EmailEnum.IS_ALARM_NO.getCode());
runRecordingService.updateRunRecordingById(runRecording);
//执行工作流的完成事件
applicationEventPublisher.publishEvent(new EndFlowEvent(this,runRecording.getFlowId()));
applicationEventPublisher.publishEvent(new EndFlowEvent(this,runRecording));
virtualTasks.forEach(virtualTask -> {
Integer mapFlowId = virtualTask.getMapFlowId();
......@@ -150,6 +154,19 @@ public class RunRecordingAndLogServiceImpl implements RunRecordingAndLogService,
runRecordingService.updateRunRecordingById(virtualRunRecording);
}
RunRecordingThreadPool.RUN_RECORDING_THREAD_POOL.submit(() ->{
Map<String, InstanceRunTheLifeCycleCallback> beansOfType = SpringUtil.getBeansOfType(InstanceRunTheLifeCycleCallback.class);
List<BeanStrategyPackage<InstanceRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(beansOfType);
//回调生命周期
for (BeanStrategyPackage<InstanceRunTheLifeCycleCallback> beanStrategyPackage : beanStrategyPackages) {
log.info("-------------【开始回调周期{}后置】---------------",beanStrategyPackage.getBeanName());
beanStrategyPackage.getBean().postProcessBeforeInitialization(runRecording);
}
});
});
//删除task里面的数据
......
package com.byit.strategy;
import com.byit.dto.RunRecordingWrapped;
import com.byit.model.JobTask;
import com.byit.model.RunRecording;
import java.util.List;
/**
* 实例声明周期
*
* @author huangfu
* @date 2020年11月25日15:20:59
*/
public interface InstanceRunTheLifeCycleCallback {
/**
* 实例执行前
* @param runRecording 运行实例
* @return 两者的包装对象
*/
default RunRecording postProcessAfterInitialization(RunRecording runRecording){
return runRecording;
}
/**
* 后置处理器
* @param runRecording 实例
*/
default void postProcessBeforeInitialization(RunRecording runRecording){}
}
package com.byit.strategy;
import com.byit.model.JobTaskSchedule;
/**
* 任务执行生命周期
*
* @author huangfu
* @date 2020年12月14日18:24:11
*/
public interface TaskRunTheLifeCycleCallback {
/**
* 实例执行前
*
* @param jobTaskSchedule 任务对象
*/
default void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
}
/**
* 后置处理器 postProcessBeforeInitialization
*
* @param jobTaskSchedule 任务对象
*/
default void postProcessBeforeInitialization(JobTaskSchedule jobTaskSchedule) {
}
/**
* 判断是否匹配类型
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配本次的执行对象
*/
boolean matchType(JobTaskSchedule jobTaskSchedule);
}
package com.byit.strategy.instances;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.call.TaskServer;
import com.byit.dto.common.CallbackDto;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.dto.web.ReturnResult;
import com.byit.enums.CallMethodEnum;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.enums.RunRecordingEnum;
import com.byit.model.RunRecording;
import com.byit.model.Workspace;
import com.byit.packet.request.PluginRpcRequestPacket;
import com.byit.packet.response.PluginRpcResponsePacket;
import com.byit.param.CommunicationParam;
import com.byit.service.WorkspaceService;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import com.byit.task.annotations.TaskClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* rpc回调平台服务
*
* @author huangfu
*/
@Component
@Slf4j
@MythRankOrder(2)
public class RpcCallbackInstanceRunTheLifeCycleCallback implements InstanceRunTheLifeCycleCallback {
@TaskClient(timeout = 60000, callMethodEnum = CallMethodEnum.SYNCHRONIZE)
private TaskServer taskServer;
private final WorkspaceService workspaceService;
private final StringRedisTemplate stringRedisTemplate;
public RpcCallbackInstanceRunTheLifeCycleCallback(WorkspaceService workspaceService, StringRedisTemplate stringRedisTemplate) {
this.workspaceService = workspaceService;
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* 实例执行前
*
* @param runRecording 运行实例
* @return 两者的包装对象
*/
@Override
public RunRecording postProcessAfterInitialization(RunRecording runRecording) {
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
if (flowExtendedConfiguration == null) {
return runRecording;
}
String rpcServerKey = flowExtendedConfiguration.getRpcStartServerKey();
if (StringUtils.isBlank(rpcServerKey)) {
return runRecording;
}
CallbackDto callbackDto = new CallbackDto();
callbackDto.setData(flowExtendedConfiguration.getPublicParam());
PluginRpcRequestPacket param = buildPluginRpcRequestPacket(runRecording, callbackDto, rpcServerKey);
//给用户全部的公共参数
PluginRpcResponsePacket call = taskServer.call(param);
if (!call.isStatus()) {
throw new RuntimeException(call.getMsg());
}
Object result = call.getResult();
//获取客户方返回修改后的公共参数
ReturnResult<String> returnResult = (ReturnResult<String>) result;
//将对应的参数转换为公共参数 修改后的公共参数
Map<String, String> lifeCyclePublicParam = JSON.parseObject(returnResult.getContent(), Map.class);
//修改后的公共参数重新保存到实例里面以及redis里面
flowExtendedConfiguration.setPublicParam(JSON.toJSONString(lifeCyclePublicParam));
//保存到redis
String toJSONString = JSON.toJSONString(flowExtendedConfiguration);
stringRedisTemplate.opsForValue().set(String.format(RedisKeyNameEnum.REDIS_PUBLIC_PARAM_KEY.getKeyName(), runRecording.getRunId(), flowExtendedConfiguration.getFlowEmbedLogo()), toJSONString);
runRecording.setExtendedConfiguration(toJSONString);
return runRecording;
}
/**
* 后置处理器
*
* @param runRecording 实例
*/
@Override
public void postProcessBeforeInitialization(RunRecording runRecording) {
//获取执行扩展参数
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
if (flowExtendedConfiguration == null) {
return;
}
String rpcEndServerKey = flowExtendedConfiguration.getRpcEndServerKey();
if (StringUtils.isBlank(rpcEndServerKey)) {
return;
}
//获取本实例的公共参数
String publicParam = flowExtendedConfiguration.getPublicParam();
CallbackDto callbackDto = new CallbackDto();
if (RunRecordingEnum.RUN_FLOW_SUCCESS.getCode().equals(runRecording.getFlowRunResult()) || RunRecordingEnum.RUN_FLOW_RE_SUCCESS.getCode().equals(runRecording.getFlowRunResult())) {
callbackDto.setRunRecordingStatus(true);
}
callbackDto.setData(publicParam);
PluginRpcRequestPacket rpcRequestPacket = buildPluginRpcRequestPacket(runRecording, callbackDto, rpcEndServerKey);
try {
PluginRpcResponsePacket call = taskServer.call(rpcRequestPacket);
log.info("回调{}通讯成功!", call);
} catch (Exception e) {
log.info("回调通讯失败!");
}
}
/**
* 构建 PluginRpcRequestPacket
*
* @param runRecording 执行实例
* @return {@link PluginRpcRequestPacket}
*/
private PluginRpcRequestPacket buildPluginRpcRequestPacket(RunRecording runRecording, CallbackDto callbackDto, String serverKey) {
PluginRpcRequestPacket rpcRequestPacket = new PluginRpcRequestPacket();
rpcRequestPacket.setCallMethodEnum(CallMethodEnum.SYNCHRONIZE);
rpcRequestPacket.setJobName(serverKey);
CommunicationParam param = new CommunicationParam();
param.setRunId(runRecording.getRunId());
param.setHasMakeUp(String.valueOf(runRecording.getScheduleType()));
callbackDto.setFlowName(runRecording.getFlowName());
callbackDto.setVersionName(runRecording.getFlowVersionName());
Workspace workspaceServiceOneById = workspaceService.findOneById(runRecording.getWorkspaceId());
callbackDto.setWorkspaceName(workspaceServiceOneById.getWorkspaceName());
callbackDto.setRunId(runRecording.getRunId());
param.setBody(JSON.toJSONString(callbackDto));
rpcRequestPacket.setParam(param);
return rpcRequestPacket;
}
public static void main(String[] args) {
Map<String,String> publicParam = new HashMap<>(8);
publicParam.put("name","张三");
publicParam.put("age","12");
publicParam.put("sex","男");
publicParam.put("class","计算及网路");
FlowExtendedConfiguration flowExtendedConfiguration = new FlowExtendedConfiguration();
flowExtendedConfiguration.setPublicParam(JSON.toJSONString(publicParam));
flowExtendedConfiguration.setFlowEmbedLogo(":main_flow");
flowExtendedConfiguration.setRpcEndServerKey("qualityAfterTaskJob");
flowExtendedConfiguration.setRpcStartServerKey("qualityBeforeTaskJob");
System.out.println(JSON.toJSONString(flowExtendedConfiguration));
//{"flowEmbedLogo":":main_flow","rpcEndServerKey":"qualityAfterTaskJob","rpcStartServerKey":"qualityBeforeTaskJob"}
//{"privateParam":"{\"param\":{},\"placeholder\":{\"biz_date\":\"2020-11-17 09:02:38\",\"jobId\":\"899\",\"now_date\":\"2020-11-17 09:02:38\",\"env\":\"pro\",\"flowId\":\"764\",\"projectId\":\"14\",\"qualityParam\":\"[{\\\"column\\\":\\\"ddmp_data_time\\\",\\\"data\\\":\\\"2020-11-17 09:02:38\\\",\\\"type\\\":\\\"2\\\"}]\",\"status\":\"1\"}}","publicParamMap":{"@type":"java.util.LinkedHashMap","qualityParam":"[{\"column\":\"ddmp_data_time\",\"data\":\"2020-11-17 09:02:38\",\"type\":\"2\"}]"}}
}
}
package com.byit.strategy.instances;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.model.RunRecording;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
/**
* @author huangfu
* @date 2020年12月15日17:37:02
*/
@Component
@Slf4j
@MythRankOrder(1)
public class RunRecodingExtendedCinfigBroadcast implements InstanceRunTheLifeCycleCallback {
private final StringRedisTemplate stringRedisTemplate;
public RunRecodingExtendedCinfigBroadcast(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* 实例执行前
*
* @param runRecording 运行实例
* @return 两者的包装对象
*/
@Override
public RunRecording postProcessAfterInitialization(RunRecording runRecording) {
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
String flowEmbedLogo = flowExtendedConfiguration.getFlowEmbedLogo();
String redisKey = String.format(RedisKeyNameEnum.REDIS_PUBLIC_PARAM_KEY.getKeyName(), runRecording.getRunId(), flowEmbedLogo);
stringRedisTemplate.opsForValue().set(redisKey, JSON.toJSONString(flowExtendedConfiguration));
return runRecording;
}
}
package com.byit.strategy.instances;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.model.RunRecording;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
/**
* 关于公共参数的redis数据删除
*
* @author huangfu
* @date 2020年12月14日11:55:37
*/
@Component
@Slf4j
@MythRankOrder(1000)
public class RunRecordingRunRedisRemoveTheLifeCycleCallback implements InstanceRunTheLifeCycleCallback {
private final StringRedisTemplate stringRedisTemplate;
public RunRecordingRunRedisRemoveTheLifeCycleCallback(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* 后置处理器 清除实例执行中产生的各种redis信息
*
* @param runRecording 实例
*/
@Override
public void postProcessBeforeInitialization(RunRecording runRecording) {
String runId = runRecording.getRunId();
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
//删除本次实例的公共参数
String publicRedisName = String.format(RedisKeyNameEnum.REDIS_PUBLIC_PARAM_KEY.getKeyName(), runId,flowExtendedConfiguration.getFlowEmbedLogo());
stringRedisTemplate.delete(publicRedisName);
}
}
package com.byit.strategy.instances;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.enums.RedisKeyNameEnum;
import com.byit.model.RunRecording;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 工作流参数汇总
* key的生成策略为: myth:param:public:runId:mark
*
* @author huangfu
* @date 2020年12月14日16:28:35
*/
@Component
@Slf4j
@MythRankOrder(5)
public class WorkflowCommonParameterAggregation implements InstanceRunTheLifeCycleCallback {
private final StringRedisTemplate stringRedisTemplate;
public WorkflowCommonParameterAggregation(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
@Override
public RunRecording postProcessAfterInitialization(RunRecording runRecording) {
log.info("-------{}实例参数聚合-------", runRecording);
String extendedConfiguration = runRecording.getExtendedConfiguration();
//获取扩展配置
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
//获取工作流层级
String flowEmbedLogo = flowExtendedConfiguration.getFlowEmbedLogo();
String publicRedisKey = String.format(RedisKeyNameEnum.REDIS_PUBLIC_PARAM_KEY.getKeyName(), runRecording.getRunId(), flowEmbedLogo);
String redisKeyPrefix = String.format("myth:param:public:%s", runRecording.getRunId());
String publicParamStr = flowExtendedConfiguration.getPublicParam();
Map<String, String> publicMap = JSON.parseObject(publicParamStr, Map.class);
if(CollectionUtil.isEmpty(publicMap)) {
publicMap = new HashMap<>();
}
//获取工作流的层级关系
String leven = publicRedisKey.replace(redisKeyPrefix, "");
while (StringUtils.isNoneBlank(leven)) {
polymerizationPublicParam(publicMap, leven, runRecording.getRunId());
leven = leven.substring(0, leven.lastIndexOf(":"));
}
//转换聚合后的公共参数
String publicParam = JSON.toJSONString(publicMap);
//将聚合后的参数放置到扩展配置
flowExtendedConfiguration.setPublicParam(publicParam);
String jsonString = JSON.toJSONString(flowExtendedConfiguration);
//将扩展配置更新进redis
stringRedisTemplate.opsForValue().set(publicRedisKey, jsonString);
//更新该实例的扩展配置
runRecording.setExtendedConfiguration(jsonString);
return runRecording;
}
/**
* 聚合参数
*
* @param publicParam 公共参数
*/
private void polymerizationPublicParam(Map<String, String> publicParam, String leven, String runId) {
String redisKey = String.format(RedisKeyNameEnum.REDIS_PUBLIC_PARAM_KEY.getKeyName(), runId, leven);
String thisRedisKeyData = stringRedisTemplate.opsForValue().get(redisKey);
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(thisRedisKeyData, FlowExtendedConfiguration.class);
if(flowExtendedConfiguration != null) {
Map<String, String> thisRedisKeyMap = JSON.parseObject(flowExtendedConfiguration.getPublicParam(), Map.class);
if (CollectionUtil.isNotEmpty(thisRedisKeyMap)) {
thisRedisKeyMap.forEach((key, value) -> {
if (!publicParam.containsKey(key)) {
publicParam.put(key, value);
}
});
}
}
}
}
package com.byit.strategy.task.java;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.enums.NodeTypeEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.model.JobTaskSchedule;
import com.byit.model.RunRecording;
import com.byit.service.RunRecordingService;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
@MythRankOrder(1)
public class JavaParamWrappedCallback implements TaskRunTheLifeCycleCallback {
private final RunRecordingService runRecordingService;
public JavaParamWrappedCallback(RunRecordingService runRecordingService) {
this.runRecordingService = runRecordingService;
}
/**
* 判断是否匹配类型
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配本次的执行对象
*/
@Override
public boolean matchType(JobTaskSchedule jobTaskSchedule) {
return NodeTypeEnum.JAVA.getType().equals(jobTaskSchedule.getJobType()) && !ScheduleTypeEnum.REPEAT.getCode().equals(jobTaskSchedule.getScheduleType());
}
/**
* 实例执行前
*
* @param jobTaskSchedule 任务对象
*/
@Override
public void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
RunParamWrapped runParamWrapped = new RunParamWrapped();
String runId = jobTaskSchedule.getRunId();
String flowName = jobTaskSchedule.getFlowName();
RunRecording runRecording = runRecordingService.findAllByRunIDAndFlowName(runId, flowName);
if(runRecording != null) {
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
String publicParam = flowExtendedConfiguration.getPublicParam();
Map<String,String> publicMap = JSON.parseObject(publicParam, Map.class);
if(publicMap == null) {
publicMap = new HashMap<>(8);
}
runParamWrapped.setPublicParamMap(publicMap);
}
String runParam = jobTaskSchedule.getRunParam();
runParamWrapped.setPrivateParam(runParam);
jobTaskSchedule.setRunParam(JSON.toJSONString(runParamWrapped));
}
}
package com.byit.strategy.task.script;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.enums.NodeTypeEnum;
import com.byit.enums.PlaceholderEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.job.utils.PlaceholderUtils;
import com.byit.model.JobTaskSchedule;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 脚本命令参数替换
*
* @author huangfu
* @date 2020年12月14日20:39:53
*/
@Component
@Slf4j
@MythRankOrder(10)
public class ScriptCommandTaskRunTheLifeCycleCallback implements TaskRunTheLifeCycleCallback {
public static final String JAVA_TYPE = "java";
/**
* 脚本类型的数据
*/
public static final String SCRIPT = "SCRIPT";
/**
* 任务执行前
*
* @param jobTaskSchedule 任务对象
*/
@Override
public void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
String runParam = jobTaskSchedule.getRunParam();
RunParamWrapped runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
String privateParam = runParamWrapped.getPrivateParam();
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = JSON.parseObject(privateParam, ScriptParamAndPlaceholderDto.class);
String command = jobTaskSchedule.getRunCommand();
command = command.replaceAll(" ","&&");
//脚本参数不为空的时候
if (scriptParamAndPlaceholderDto != null) {
Map<String, String> param = scriptParamAndPlaceholderDto.getParam();
if (CollectionUtil.isNotEmpty(param)) {
//将参数追加到命令上
command = PlaceholderUtils.commandReplace(command, param);
}
//补批的
if (ScheduleTypeEnum.REPAIR.getCode().equals(jobTaskSchedule.getScheduleType())) {
if (command.startsWith(JAVA_TYPE)) {
//去替换时间
command = PlaceholderUtils.commandDateReplace(param, command, param.get(PlaceholderEnum.DATE_PLACEHOLDER.getName()),
param.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName()));
}
}
jobTaskSchedule.setRunCommand(command);
}
}
/**
* 判断是否匹配类型
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配本次的执行对象
*/
@Override
public boolean matchType(JobTaskSchedule jobTaskSchedule) {
String jobType = jobTaskSchedule.getJobType();
NodeTypeEnum typeByCode = NodeTypeEnum.getTypeByCode(jobType);
if (typeByCode == null) {
throw new RuntimeException(String.format("调度暂不支持此种类型的任务:%s", jobType));
}
return typeByCode.getType().equals(SCRIPT);
}
}
package com.byit.strategy.task.script;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.enums.NodeTypeEnum;
import com.byit.model.JobTaskSchedule;
import com.byit.model.RunRecording;
import com.byit.service.RunRecordingService;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 脚本参数合并 工作流执行节点下 私有参数与共有参数合并
*
* @author huangfu
* @date 2020年12月14日19:43:30
*/
@Component
@Slf4j
@MythRankOrder(5)
public class ScriptFlowParamMergeTaskRunTheLifeCycleCallback implements TaskRunTheLifeCycleCallback {
private final StringRedisTemplate stringRedisTemplate;
private final RunRecordingService runRecordingService;
/**
* 脚本类型的数据
*/
public static final String SCRIPT = "SCRIPT";
public ScriptFlowParamMergeTaskRunTheLifeCycleCallback(StringRedisTemplate stringRedisTemplate, RunRecordingService runRecordingService) {
this.stringRedisTemplate = stringRedisTemplate;
this.runRecordingService = runRecordingService;
}
/**
* 实例执行前
*
* @param jobTaskSchedule 任务对象
*/
@Override
public void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
String runId = jobTaskSchedule.getRunId();
String flowName = jobTaskSchedule.getFlowName();
RunRecording runRecording = runRecordingService.findAllByRunIDAndFlowName(runId, flowName);
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
String publicParam = flowExtendedConfiguration.getPublicParam();
Map<String,String> publicMap = JSON.parseObject(publicParam, Map.class);
if(publicMap == null) {
publicMap = new HashMap<>(8);
}
String runParam = jobTaskSchedule.getRunParam();
RunParamWrapped runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
if(runParamWrapped == null) {
runParamWrapped = new RunParamWrapped();
}
String privateParam = runParamWrapped.getPrivateParam();
Map<String, String> publicParamMap = runParamWrapped.getPublicParamMap();
if(publicParamMap == null){
publicParamMap = new HashMap<>(2);
}
publicParamMap.putAll(publicMap);
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = JSON.parseObject(privateParam, ScriptParamAndPlaceholderDto.class);
if(scriptParamAndPlaceholderDto == null) {
scriptParamAndPlaceholderDto = new ScriptParamAndPlaceholderDto();
}
//处理命令参数
Map<String, String> commandParam = scriptParamAndPlaceholderDto.getParam();
Map<String, String> placeholder = scriptParamAndPlaceholderDto.getPlaceholder();
if(CollectionUtil.isEmpty(commandParam)){
commandParam.putAll(publicMap);
}else{
publicMap.forEach((key,value) ->{
if (!commandParam.containsKey(key)) {
commandParam.put(key,value);
}
});
}
//处理替换参数
if(CollectionUtil.isEmpty(placeholder)){
placeholder.putAll(publicMap);
}else{
publicMap.forEach((key,value) ->{
if (!placeholder.containsKey(key)) {
placeholder.put(key,value);
}
});
}
//重新设置值
String privateParamNew = JSON.toJSONString(scriptParamAndPlaceholderDto);
runParamWrapped.setPrivateParam(privateParamNew);
runParamWrapped.setPublicParamMap(publicParamMap);
//设置运行参数
jobTaskSchedule.setRunParam(JSON.toJSONString(runParamWrapped));
}
/**
* 判断是否匹配类型 正常调度的时候
*
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配本次的执行对象
*/
@Override
public boolean matchType(JobTaskSchedule jobTaskSchedule) {
String jobType = jobTaskSchedule.getJobType();
NodeTypeEnum typeByCode = NodeTypeEnum.getTypeByCode(jobType);
if (typeByCode == null) {
throw new RuntimeException(String.format("调度暂不支持此种类型的任务:%s", jobType));
}
boolean equals = typeByCode.getType().equals(SCRIPT);
boolean isPlugin = 4 != jobTaskSchedule.getScheduleType();
return equals && isPlugin;
}
}
package com.byit.strategy.task.script;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.enums.NodeTypeEnum;
import com.byit.enums.PlaceholderEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.mapper.RunRecordingMapper;
import com.byit.model.JobTaskSchedule;
import com.byit.model.RunRecording;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Map;
/**
* @author huangfu
*/
@Component
@Slf4j
@MythRankOrder(2)
public class ScriptMakeUpScriptTaskCallbackRunTheLifeCycleCallback implements TaskRunTheLifeCycleCallback {
public static final String SCRIPT = "SCRIPT";
private final RunRecordingMapper runRecordingService;
public ScriptMakeUpScriptTaskCallbackRunTheLifeCycleCallback(RunRecordingMapper runRecordingService) {
this.runRecordingService = runRecordingService;
}
/**
* 判断是否匹配类型
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配本次的执行对象
*/
@Override
public boolean matchType(JobTaskSchedule jobTaskSchedule) {
String jobType = jobTaskSchedule.getJobType();
NodeTypeEnum typeByCode = NodeTypeEnum.getTypeByCode(jobType);
if (typeByCode == null) {
throw new RuntimeException(String.format("调度暂不支持此种类型的任务:%s", jobType));
}
//是否是脚本类型的
boolean isScript = typeByCode.getType().equals(SCRIPT);
//是否是重跑或者补批
boolean isNormal = ScheduleTypeEnum.REPEAT.getCode().equals(jobTaskSchedule.getScheduleType()) || ScheduleTypeEnum.REPAIR.getCode().equals(jobTaskSchedule.getScheduleType());
return isScript && isNormal;
}
/**
* 实例执行前
*
* @param jobTaskSchedule 任务对象
*/
@Override
public void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
String runId = jobTaskSchedule.getRunId();
String flowName = jobTaskSchedule.getFlowName();
RunRecording runRecording = runRecordingService.findAllByRunIDAndFlowName(runId, flowName);
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
String publicParam = flowExtendedConfiguration.getPublicParam();
Map<String,String> publicParamMap = JSON.parseObject(publicParam, Map.class);
String runParam = jobTaskSchedule.getRunParam();
RunParamWrapped runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
String privateParam = runParamWrapped.getPrivateParam();
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = JSON.parseObject(privateParam, ScriptParamAndPlaceholderDto.class);
if(scriptParamAndPlaceholderDto == null) {
scriptParamAndPlaceholderDto = new ScriptParamAndPlaceholderDto();
}
Map<String, String> param = scriptParamAndPlaceholderDto.getParam();
Map<String, String> placeholder = scriptParamAndPlaceholderDto.getPlaceholder();
String nowDateFormatPh = "yyyyMMdd";
String nowDateFormatPr = "yyyyMMdd";
if (param.containsKey(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName())) {
nowDateFormatPr = param.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
param.remove(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
}
if (placeholder.containsKey(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName())) {
nowDateFormatPh = param.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
placeholder.remove(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
}
//获取公共参数里面的biz_date
String bizDateStr = publicParamMap.get(PlaceholderEnum.DATE_PLACEHOLDER.getName());
param.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), bizDateStr);
placeholder.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), bizDateStr);
//生成 now_date
param.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), nowDateFormatPr));
placeholder.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), nowDateFormatPh));
//设置参数
scriptParamAndPlaceholderDto.setParam(param);
scriptParamAndPlaceholderDto.setPlaceholder(placeholder);
runParamWrapped.setPrivateParam(JSON.toJSONString(scriptParamAndPlaceholderDto));
jobTaskSchedule.setRunParam(JSON.toJSONString(runParamWrapped));
}
}
package com.byit.strategy.task.script;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.enums.NodeTypeEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.model.JobTaskSchedule;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 参数对象包装
*
* @author huangfu
* @date 2020年12月15日15:15:29
*/
@Component
@Slf4j
@MythRankOrder(1)
public class ScriptParamWrappedCallback implements TaskRunTheLifeCycleCallback {
public static final String SCRIPT = "SCRIPT";
/**
* 实例执行前
*
* @param jobTaskSchedule 任务对象
*/
@Override
public void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
String runParam = jobTaskSchedule.getRunParam();
RunParamWrapped runParamWrapped = new RunParamWrapped();
runParamWrapped.setPublicParamMap(new HashMap<>(8));
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = JSON.parseObject(runParam, ScriptParamAndPlaceholderDto.class);
if(scriptParamAndPlaceholderDto == null) {
scriptParamAndPlaceholderDto = new ScriptParamAndPlaceholderDto();
}
Map<String, String> placeholder = scriptParamAndPlaceholderDto.getPlaceholder();
Map<String, String> param = scriptParamAndPlaceholderDto.getParam();
if(CollectionUtil.isEmpty(placeholder)){
placeholder = new HashMap<>(8);
}
if(CollectionUtil.isEmpty(param)){
param = new HashMap<>(8);
}
scriptParamAndPlaceholderDto.setPlaceholder(placeholder);
scriptParamAndPlaceholderDto.setParam(param);
runParamWrapped.setPrivateParam(JSON.toJSONString(scriptParamAndPlaceholderDto));
jobTaskSchedule.setRunParam(JSON.toJSONString(runParamWrapped));
}
/**
* 判断是否匹配类型
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配本次的执行对象
*/
@Override
public boolean matchType(JobTaskSchedule jobTaskSchedule) {
String jobType = jobTaskSchedule.getJobType();
NodeTypeEnum typeByCode = NodeTypeEnum.getTypeByCode(jobType);
if (typeByCode == null) {
throw new RuntimeException(String.format("调度暂不支持此种类型的任务:%s", jobType));
}
//是否是脚本类型的 不能是重跑的 重跑的节点是封装后的
return typeByCode.getType().equals(SCRIPT) && !ScheduleTypeEnum.REPEAT.getCode().equals(jobTaskSchedule.getScheduleType());
}
}
package com.byit.strategy.task.script;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.enums.NodeTypeEnum;
import com.byit.enums.PlaceholderEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.model.JobTaskSchedule;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 脚本执行的生命周期
* 脚本类型的任务特殊参数的替换
*
* @author huangfu
* @date 2020年12月14日18:28:08
*/
@Component
@Slf4j
@MythRankOrder(3)
public class ScriptSpecialParametersTaskRunTheLifeCycleCallback implements TaskRunTheLifeCycleCallback {
/**
* 脚本类型的数据
*/
public static final String SCRIPT = "SCRIPT";
public static final String DEFAULT_DATE_FORMAT = "yyyyMMdd";
/**
* 正常流程的情况下 进行特殊参数的替换
* 只有在正常调度的时候才会存在 bizdate等特殊的参数 补批重跑的情况下 会预先将数据放置到公共参数里面
*
* @param jobTaskSchedule 任务对象
* @return 是否匹配
*/
@Override
public boolean matchType(JobTaskSchedule jobTaskSchedule) {
String jobType = jobTaskSchedule.getJobType();
NodeTypeEnum typeByCode = NodeTypeEnum.getTypeByCode(jobType);
if (typeByCode == null) {
throw new RuntimeException(String.format("调度暂不支持此种类型的任务:%s", jobType));
}
//是否是脚本类型的
boolean isScript = typeByCode.getType().equals(SCRIPT);
//是否是正常
boolean isNormal = ScheduleTypeEnum.NORMAL.getCode().equals(jobTaskSchedule.getScheduleType()) || ScheduleTypeEnum.REAL.getCode().equals(jobTaskSchedule.getScheduleType());
return isScript && isNormal;
}
/**
* 实例执行前 特殊参数的替换
*
* @param jobTaskSchedule 任务对象
* @return 两者的包装对象
*/
@Override
public void postProcessAfterInitialization(JobTaskSchedule jobTaskSchedule) {
String runParam = jobTaskSchedule.getRunParam();
//转换参数对象为参数包装体
RunParamWrapped runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
String privateParam = runParamWrapped.getPrivateParam();
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = JSON.parseObject(privateParam, ScriptParamAndPlaceholderDto.class);
//处理私有参数
if (scriptParamAndPlaceholderDto == null) {
scriptParamAndPlaceholderDto = new ScriptParamAndPlaceholderDto();
}
//获取替换参数
Map<String, String> placeholder = scriptParamAndPlaceholderDto.getPlaceholder();
//获取命令参数
Map<String, String> commandParam = scriptParamAndPlaceholderDto.getParam();
//向前偏移一天
DateTime dateTime = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, -1);
//替换参数
if (CollectionUtil.isEmpty(placeholder)) {
placeholder = new HashMap<>(2);
//替换 biz_date
placeholder.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), DateUtil.format(dateTime, DEFAULT_DATE_FORMAT));
//替换 now_date
placeholder.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), DEFAULT_DATE_FORMAT));
} else {
//替换 biz_date
String bizDateFormat = placeholder.get(PlaceholderEnum.DATE_PLACEHOLDER.getName());
if (StringUtils.isBlank(bizDateFormat)) {
bizDateFormat = DEFAULT_DATE_FORMAT;
}
placeholder.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), DateUtil.format(dateTime, bizDateFormat));
//替换 now_date
String nowDateFormat = placeholder.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
if (StringUtils.isBlank(nowDateFormat)) {
nowDateFormat = DEFAULT_DATE_FORMAT;
}
placeholder.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), nowDateFormat));
}
//命令参数
if (CollectionUtil.isEmpty(commandParam)) {
commandParam = new HashMap<>(4);
//替换 biz_date
commandParam.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), DateUtil.format(dateTime, DEFAULT_DATE_FORMAT));
//替换 now_date
commandParam.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), DEFAULT_DATE_FORMAT));
} else {
//替换 biz_date
String bizDateFormat = placeholder.get(PlaceholderEnum.DATE_PLACEHOLDER.getName());
if (StringUtils.isBlank(bizDateFormat)) {
bizDateFormat = DEFAULT_DATE_FORMAT;
}
commandParam.put(PlaceholderEnum.DATE_PLACEHOLDER.getName(), DateUtil.format(dateTime, bizDateFormat));
//替换 now_date
String nowDateFormat = placeholder.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
if (StringUtils.isBlank(nowDateFormat)) {
nowDateFormat = DEFAULT_DATE_FORMAT;
}
commandParam.put(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), DateUtil.format(new Date(), nowDateFormat));
}
scriptParamAndPlaceholderDto.setPlaceholder(placeholder);
scriptParamAndPlaceholderDto.setParam(commandParam);
//重新设置参数
runParamWrapped.setPrivateParam(JSON.toJSONString(scriptParamAndPlaceholderDto));
//这一步将参数对象转换为包装对象
jobTaskSchedule.setRunParam(JSON.toJSONString(runParamWrapped));
}
}
......@@ -2,7 +2,9 @@ package com.byit.task;
import com.alibaba.fastjson.JSON;
import com.byit.conf.MythJobAutoConfigure;
import com.byit.dto.BeanStrategyPackage;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.plugin.FlowExtendedConfiguration;
import com.byit.dto.plugin.RunLog;
import com.byit.enums.NodePropertyEnum;
import com.byit.enums.task.RunResultEnum;
......@@ -11,13 +13,17 @@ import com.byit.filesystem.FileSystem;
import com.byit.job.utils.MythLogUtils;
import com.byit.model.JobTaskRunLogWithBLOBs;
import com.byit.model.JobTaskSchedule;
import com.byit.model.RunRecording;
import com.byit.packet.request.PluginRpcRequestPacket;
import com.byit.packet.response.PluginRpcResponsePacket;
import com.byit.param.CommunicationParam;
import com.byit.service.FastRunLogService;
import com.byit.service.FlowStatusService;
import com.byit.service.RunRecordingService;
import com.byit.service.impl.JobTaskRunLogServiceImpl;
import com.byit.service.impl.RunJavaServiceImpl;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import com.byit.util.ClassSortUtil;
import com.byit.util.GetRegConfig;
import com.byit.util.SpringUtil;
import io.netty.util.Timeout;
......@@ -26,10 +32,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.TreeSet;
import java.util.*;
import java.util.stream.Collectors;
import static com.alibaba.fastjson.serializer.SerializerFeature.WriteClassName;
......@@ -80,6 +83,17 @@ public class JavaNodeExecutorTask implements TimerTask {
JobTaskRunLogServiceImpl jobTaskRunLogService = SpringUtil.getBean(JobTaskRunLogServiceImpl.class);
JobTaskRunLogWithBLOBs jobTaskRunLogById = null;
try {
//获取该节点的全部声明周期函数
Map<String, TaskRunTheLifeCycleCallback> stringTaskRunTheLifeCycleCallbackMap = SpringUtil.getBeansOfType(TaskRunTheLifeCycleCallback.class);
//数据排序
List<BeanStrategyPackage<TaskRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(stringTaskRunTheLifeCycleCallbackMap);
beanStrategyPackages.forEach(beanStrategyPackage -> {
log.info("--------------脚本节点生命周期开始回调{}--------------", beanStrategyPackage.getBeanName());
TaskRunTheLifeCycleCallback beanStrategyPackageBean = beanStrategyPackage.getBean();
if (beanStrategyPackageBean.matchType(mythJobTaskSchedule)) {
beanStrategyPackageBean.postProcessAfterInitialization(mythJobTaskSchedule);
}
});
String runParam = mythJobTaskSchedule.getRunParam();
RunParamWrapped runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
if (runParamWrapped == null) {
......@@ -105,13 +119,27 @@ public class JavaNodeExecutorTask implements TimerTask {
communicationParam.setFlowId(mythJobTaskSchedule.getFlowId());
communicationParam.setHasMakeUp(mythJobTaskSchedule.getScheduleType() + "");
communicationParam.setRunId(mythJobTaskSchedule.getRunId());
String runId = mythJobTaskSchedule.getRunId();
communicationParam.setRunId(runId);
communicationParam.setExpand1("REAL:EXEC:" + jobTaskRunLogById.getLogId());
communicationParam.setLogId(jobTaskRunLogById.getLogId() + "");
communicationParam.setCallbackUrl(JSON.toJSONString(callUrlList));
communicationParam.setBody(runParamWrapped.getPrivateParam());
communicationParam.setPublicParam(runParamWrapped.getPublicParamMap());
//查询对应的实例 获取实例的全局参数
String flowName = mythJobTaskSchedule.getFlowName();
RunRecordingService bean = SpringUtil.getBean(RunRecordingService.class);
RunRecording runRecording = bean.findAllByRunIDAndFlowName(runId, flowName);
if(runRecording != null) {
String extendedConfiguration = runRecording.getExtendedConfiguration();
FlowExtendedConfiguration flowExtendedConfiguration = JSON.parseObject(extendedConfiguration, FlowExtendedConfiguration.class);
if(flowExtendedConfiguration != null) {
communicationParam.setPublicParam(JSON.parseObject(flowExtendedConfiguration.getPublicParam(), Map.class));
}
}
request.setParam(communicationParam);
request.setJobName(mythJobTaskSchedule.getHandlerName());
......
......@@ -3,25 +3,26 @@ package com.byit.task;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.byit.conf.MythJobAutoConfigure;
import com.byit.dto.BeanStrategyPackage;
import com.byit.dto.executor.DispatchResponseDto;
import com.byit.dto.executor.RunParamWrapped;
import com.byit.dto.executor.ScriptDto;
import com.byit.dto.executor.ScriptParamAndPlaceholderDto;
import com.byit.dto.plugin.RunLog;
import com.byit.enums.*;
import com.byit.enums.EmailEnum;
import com.byit.enums.JobResultEnum;
import com.byit.enums.NodePropertyEnum;
import com.byit.enums.task.RunResultEnum;
import com.byit.enums.task.RunTypeEnum;
import com.byit.filesystem.FastDfsFileSystem;
import com.byit.filesystem.FileSystem;
import com.byit.job.utils.DateUtil;
import com.byit.job.utils.MythLogUtils;
import com.byit.job.utils.PlaceholderUtils;
import com.byit.model.JobTaskRunLogWithBLOBs;
import com.byit.model.JobTaskSchedule;
import com.byit.service.FastRunLogService;
import com.byit.service.FlowStatusService;
import com.byit.service.RunScriptService;
import com.byit.service.impl.JobTaskRunLogServiceImpl;
import com.byit.strategy.TaskRunTheLifeCycleCallback;
import com.byit.util.ClassSortUtil;
import com.byit.util.GetRegConfig;
import com.byit.util.SpringUtil;
import io.netty.util.Timeout;
......@@ -50,7 +51,7 @@ public class ScriptExecutorJobTask implements TimerTask {
private static final Integer INIT_SLEEP_TIME = 100;
public static final String JAVA_TYPE = "java";
private JobTaskSchedule mythJobTaskSchedule;
private final JobTaskSchedule mythJobTaskSchedule;
public ScriptExecutorJobTask(JobTaskSchedule mythJobTaskSchedule) {
this.mythJobTaskSchedule = mythJobTaskSchedule;
......@@ -72,9 +73,9 @@ public class ScriptExecutorJobTask implements TimerTask {
String priority = mythJobTaskSchedule.getPriority();
if (NodePropertyEnum.ADVANCED_NODE.getCode().equals(priority)) {
MythJobAutoConfigure.ADVANCED_JOB_THREAD_POOL.execute(() -> runJob(mythJobTaskSchedule));
MythJobAutoConfigure.ADVANCED_JOB_THREAD_POOL.execute(() -> runJob());
} else {
MythJobAutoConfigure.LOW_LEVEL_JOB_THREAD_POOL.execute(() -> runJob(mythJobTaskSchedule));
MythJobAutoConfigure.LOW_LEVEL_JOB_THREAD_POOL.execute(() -> runJob());
}
}
......@@ -91,85 +92,25 @@ public class ScriptExecutorJobTask implements TimerTask {
return bean.checkFlowStatusIsKill(flowId, runId);
}
private void paramBuild(JobTaskSchedule mythJobTaskSchedule) {
//获取参数
String runParam = mythJobTaskSchedule.getRunParam();
//获取命令
String command = mythJobTaskSchedule.getRunCommand();
command = PlaceholderUtils.formatJavaJarCommand(command);
if (!command.startsWith(JAVA_TYPE)) {
command = command.replaceAll(" ","&&");
}
//转换参数对象为参数包装体
RunParamWrapped runParamWrapped = JSON.parseObject(runParam, RunParamWrapped.class);
//当参数包装体不为空时 证明存在参数 或私有或公有
if (runParamWrapped != null) {
//获取到私有参数
String privateParam = runParamWrapped.getPrivateParam();
//替换运行参数中的时间参数 当为正常运行或者立即执行的时候
if (ScheduleTypeEnum.NORMAL.getCode().equals(mythJobTaskSchedule.getScheduleType())
|| ScheduleTypeEnum.REAL.getCode().equals(mythJobTaskSchedule.getScheduleType())) {
privateParam = PlaceholderUtils.formatBizDateParam(privateParam, PlaceholderEnum.DATE_PLACEHOLDER.getName(), 1);
if (StringUtils.isNoneBlank(privateParam)) {
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = JSON.parseObject(privateParam, ScriptParamAndPlaceholderDto.class);
Map<String, String> placeholder = scriptParamAndPlaceholderDto.getPlaceholder();
if (CollectionUtil.isNotEmpty(placeholder)) {
if (placeholder.containsKey(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName())) {
String nowDateFormatName = placeholder.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName());
String dateFormat = DateUtil.dateFormat(new Date(), nowDateFormatName);
privateParam = PlaceholderUtils.formatBizDateParam(privateParam, PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName(), dateFormat, 0);
}
}
runParamWrapped.setPrivateParam(privateParam);
mythJobTaskSchedule.setRunParam(JSON.toJSONString(runParamWrapped));
}
}
//获取到公有参数
Map<String, String> publicParam = runParamWrapped.getPublicParamMap();
//将私有参数转换为对应的参数DTO
ScriptParamAndPlaceholderDto scriptParamAndPlaceholderDto = null;
if (StringUtils.isNoneBlank(privateParam)) {
scriptParamAndPlaceholderDto = JSON.parseObject(privateParam, ScriptParamAndPlaceholderDto.class);
}
//脚本参数不为空的时候
if (scriptParamAndPlaceholderDto != null) {
Map<String, String> param = scriptParamAndPlaceholderDto.getParam();
if (CollectionUtil.isNotEmpty(param)) {
command = PlaceholderUtils.commandReplace(command, param);
}
if (ScheduleTypeEnum.REPAIR.getCode().equals(mythJobTaskSchedule.getScheduleType())) {
if (command.startsWith(JAVA_TYPE)) {
if (ScheduleTypeEnum.REPAIR.getCode().equals(mythJobTaskSchedule.getScheduleType())) {
command = PlaceholderUtils.commandDateReplace(param, command, param.get(PlaceholderEnum.DATE_PLACEHOLDER.getName()),
param.get(PlaceholderEnum.NOW_DATE_PLACEHOLDER.getName()));
} else {
command = PlaceholderUtils.commandDateReplace(param, command);
}
}
}
}
//公共参数不为空的时候
if (CollectionUtil.isNotEmpty(publicParam)) {
command = PlaceholderUtils.commandReplace(command, publicParam);
}
mythJobTaskSchedule.setRunCommand(command);
}
}
/**
* 运行任务
*
* @param mythJobTaskSchedule 运行的排期表
*/
private void runJob(JobTaskSchedule mythJobTaskSchedule) {
private void runJob() {
DispatchResponseDto dispatchResponseDto = new DispatchResponseDto();
String uploadFilePath = null;
try {
paramBuild(mythJobTaskSchedule);
//获取该节点的全部声明周期函数
Map<String, TaskRunTheLifeCycleCallback> stringTaskRunTheLifeCycleCallbackMap = SpringUtil.getBeansOfType(TaskRunTheLifeCycleCallback.class);
//数据排序
List<BeanStrategyPackage<TaskRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(stringTaskRunTheLifeCycleCallbackMap);
beanStrategyPackages.forEach(beanStrategyPackage -> {
log.info("--------------脚本节点生命周期开始回调{}--------------", beanStrategyPackage.getBeanName());
TaskRunTheLifeCycleCallback beanStrategyPackageBean = beanStrategyPackage.getBean();
if (beanStrategyPackageBean.matchType(this.mythJobTaskSchedule)) {
beanStrategyPackageBean.postProcessAfterInitialization(this.mythJobTaskSchedule);
}
});
mythJobTaskSchedule.setRunCommand(mythJobTaskSchedule.getRunCommand());
RunScriptService runScriptService = SpringUtil.getBean(RunScriptService.class);
JobTaskRunLogServiceImpl jobTaskRunLogService = SpringUtil.getBean(JobTaskRunLogServiceImpl.class);
......@@ -195,7 +136,7 @@ public class ScriptExecutorJobTask implements TimerTask {
} catch (Exception e) {
//错误信息
String errorMessage = MythLogUtils.getMessage(e);
if (mythJobTaskSchedule.getScheduleType().equals(4)) {
if (mythJobTaskSchedule.getScheduleType() != null && mythJobTaskSchedule.getScheduleType() == 4) {
StringRedisTemplate stringRedisTemplate = (StringRedisTemplate) SpringUtil.getBean("stringRedisTemplate");
RunLog runLog = RunLog.builder().isEnd(true).isSuccess(false).runLog("执行资源异常" + errorMessage).build();
stringRedisTemplate.opsForList().rightPush("REAL:EXEC:" + mythJobTaskSchedule.getLogId(), JSON.toJSONString(runLog, WriteClassName));
......
package com.byit.thread.helper;
import com.byit.conf.RunRecordingThreadPool;
import com.byit.dto.BeanStrategyPackage;
import com.byit.enums.EmailEnum;
import com.byit.enums.NodeRunStatusPropertyEnum;
import com.byit.enums.RunRecordingEnum;
......@@ -10,7 +12,10 @@ import com.byit.model.JobTaskRunLogWithBLOBs;
import com.byit.model.RunRecording;
import com.byit.service.JobTaskRunLogService;
import com.byit.service.RunRecordingService;
import com.byit.strategy.InstanceRunTheLifeCycleCallback;
import com.byit.thread.BaseThreadRunHelper;
import com.byit.util.ClassSortUtil;
import com.byit.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
......@@ -20,6 +25,8 @@ import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 完结实例的线程
......@@ -72,17 +79,19 @@ public class ClosingExampleThreadRunHelper extends BaseThreadRunHelper implement
runRecording.setIsAlarm(EmailEnum.IS_ALARM_NO.getCode());
runRecording.setEndTime(new Date());
runRecordingService.updateRunRecordingById(runRecording);
applicationEventPublisher.publishEvent(new EndFlowEvent(this,flowId));
/*if (StringUtils.isNotBlank(runRecording.getReRunId())) {
String reRunId = runRecording.getReRunId();
Integer flowId1 = runRecording.getFlowId();
RunRecording runRecordingByFlowIdAndRunId = runRecordingService.findRunRecordingByFlowIdAndRunId(flowId1, reRunId);
runRecordingByFlowIdAndRunId.setIsAlarm(EmailEnum.IS_ALARM_NO.getCode());
runRecordingByFlowIdAndRunId.setEndTime(new Date());
runRecordingByFlowIdAndRunId.setFlowStatus(RunRecordingEnum.FLOW_STATUS_IS_END.getCode());
runRecordingService.updateRunRecordingById(runRecordingByFlowIdAndRunId);
}*/
applicationEventPublisher.publishEvent(new EndFlowEvent(this,runRecording));
RunRecordingThreadPool.RUN_RECORDING_THREAD_POOL.submit(() ->{
Map<String, InstanceRunTheLifeCycleCallback> beansOfType = SpringUtil.getBeansOfType(InstanceRunTheLifeCycleCallback.class);
List<BeanStrategyPackage<InstanceRunTheLifeCycleCallback>> beanStrategyPackages = ClassSortUtil.objectSort(beansOfType);
//回调生命周期
for (BeanStrategyPackage<InstanceRunTheLifeCycleCallback> beanStrategyPackage : beanStrategyPackages) {
log.info("-------------【开始回调周期{}后置】---------------",beanStrategyPackage.getBeanName());
beanStrategyPackage.getBean().postProcessBeforeInitialization(runRecording);
}
});
}
});
return UNIVERSAL_WAIT_TIME;
......
......@@ -25,6 +25,8 @@ public class FlowThreadRunHelper extends BaseThreadRunHelper {
private static final String LOCK_NAME = "flow_lock";
private final DataSource dataSource;
private final FlowService flowService;
private final NodeService nodeService;
private final RunNodeServer runNodeServer;
......
......@@ -3,6 +3,7 @@ package com.byit.thread.helper;
import cn.hutool.core.collection.CollectionUtil;
import com.byit.enums.FlowPropertyEnum;
import com.byit.enums.NodeNameEnum;
import com.byit.enums.RunRecordingEnum;
import com.byit.enums.ScheduleTypeEnum;
import com.byit.exceptions.SuperiorNodeRunException;
import com.byit.flowservice.NodeVerification;
......@@ -179,9 +180,12 @@ public class JobTaskThreadRunHelper extends BaseThreadRunHelper {
*/
private void updateRunRecording (Integer flowId, String runId) {
RunRecording runRecordingByFlowIdAndRunId = runRecordingService.findRunRecordingByFlowIdAndRunId(flowId, runId);
runRecordingByFlowIdAndRunId.setFlowStatus(FlowPropertyEnum.FLOW_RUN_ING.getCode());
runRecordingByFlowIdAndRunId.setStartTime(new Date());
runRecordingService.updateRunRecordingById(runRecordingByFlowIdAndRunId);
if (!RunRecordingEnum.FAIL_FAST_YES.getCode().equals(runRecordingByFlowIdAndRunId.getFailFast())) {
runRecordingByFlowIdAndRunId.setFlowStatus(FlowPropertyEnum.FLOW_RUN_ING.getCode());
runRecordingByFlowIdAndRunId.setStartTime(new Date());
runRecordingService.updateRunRecordingById(runRecordingByFlowIdAndRunId);
}
}
@Override
......
package com.byit.util;
import com.byit.annotations.MythRankOrder;
import com.byit.dto.BeanStrategyPackage;
import lombok.Data;
import java.util.*;
/**
* 类排序
*
* @author huangfu
* @date 2020年12月14日15:11:55
*/
public class ClassSortUtil {
/**
* 对Spring返回的bean进行数据排序
* @param beanMap beanMap
* @param <T> 泛型
* @return 排序后的集合
*/
public static <T> List<BeanStrategyPackage<T>> objectSort(Map<String,T> beanMap){
List<BeanStrategyPackage<T>> beanStrategyPackages = new ArrayList<>(8);
beanMap.forEach((beanName,bean) ->{
if(!bean.getClass().isAnnotationPresent(MythRankOrder.class)){
throw new RuntimeException(String.format("%s,不存在排序注解,请联系调度官方团队!",beanName));
}
beanStrategyPackages.add(new BeanStrategyPackage<>(beanName,bean));
});
beanStrategyPackages.sort((o1, o2) -> {
Object bean1 = o1.getBean();
Object bean2 = o2.getBean();
MythRankOrder mythRankOrder1 = bean1.getClass().getAnnotation(MythRankOrder.class);
MythRankOrder mythRankOrder2 = bean2.getClass().getAnnotation(MythRankOrder.class);
int value1 = mythRankOrder1.value();
int value2 = mythRankOrder2.value();
return Integer.compare(value1, value2);
});
return beanStrategyPackages;
}
}
......@@ -70,6 +70,6 @@ public class ThreadPoolUtil {
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("[byit-myth-job]-"+threadName+"-Thread-%d").build();
return new ThreadPoolExecutor(coreCount, maxCount,
keepAliveTime, timeUnit,
new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
new LinkedBlockingQueue<Runnable>(queueLength), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
}
}
......@@ -26,12 +26,13 @@
<result column="schedule_follow" jdbcType="CHAR" property="scheduleFollow" />
<result column="is_update" jdbcType="CHAR" property="isUpdate" />
<result column="scan_mark" jdbcType="CHAR" property="scanMark" />
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration" />
</resultMap>
<sql id="Base_Column_List">
flow_id, alarm_email, exec_type, flow_cron, flow_desc, flow_name, flow_node_count,
flow_timeout, is_inner, alarml_action, priority, trigger_next_time, workspace_id,
author, add_time, start_up, principal, version_name, repeat_count, remaining_count,
schedule_follow, is_update, scan_mark
schedule_follow, is_update, scan_mark, extended_configuration
</sql>
<select id="findAllByThisDayFlow" resultMap="BaseResultMap" parameterType="com.byit.dto.StatisticsConditionDto">
......@@ -205,6 +206,9 @@
<if test="scanMark != null">
scan_mark,
</if>
<if test="extendedConfiguration != null">
extended_configuration,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
......@@ -277,6 +281,9 @@
<if test="scanMark != null">
#{scanMark,jdbcType=CHAR},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration},
</if>
</trim>
</insert>
<update id="updateByIdSelective" parameterType="com.byit.model.Flow">
......@@ -349,6 +356,10 @@
<if test="scanMark != null">
scan_mark = #{scanMark,jdbcType=CHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration},
</if>
</set>
where flow_id = #{flowId,jdbcType=INTEGER}
</update>
......
......@@ -23,12 +23,13 @@
<result column="principal" jdbcType="VARCHAR" property="principal" />
<result column="version_name" jdbcType="VARCHAR" property="versionName" />
<result column="is_inner" jdbcType="CHAR" property="isInner" />
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration" />
</resultMap>
<sql id="Base_Column_List">
<!-- generated @mbg.generated date: 2019-12-31 -->
flow_version_id, add_time, alarm_email, exec_type, flow_cron, flow_desc, flow_id,
flow_name, flow_node_count, alarml_action, schedule_follow, priority, remove_mark,
repeat_count, version_mark, workspace_id, author, principal, version_name, is_inner
repeat_count, version_mark, workspace_id, author, principal, version_name, is_inner,extended_configuration
</sql>
<select id="findAllByFlowId" resultMap="BaseResultMap">
......@@ -69,7 +70,17 @@
and version_mark = '0'
</select>
<delete id="deleteById" parameterType="java.lang.Integer">
<select id="getByWorkSpaceAndName" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from flow_version
where workspace_id = #{workspaceId}
and flow_name = #{flowName}
and version_name = #{versionName}
</select>
<delete id="deleteById" parameterType="java.lang.Integer">
<!-- generated @mbg.generated date: 2019-12-31 -->
delete from flow_version
where flow_version_id = #{flowVersionId,jdbcType=INTEGER}
......@@ -139,6 +150,9 @@
<if test="isInner != null">
is_inner,
</if>
<if test="extendedConfiguration != null">
extended_configuration,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="flowVersionId != null">
......@@ -201,6 +215,9 @@
<if test="isInner != null">
#{isInner,jdbcType=CHAR},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration},
</if>
</trim>
</insert>
<update id="updateByIdSelective" parameterType="com.byit.model.FlowVersion">
......@@ -264,6 +281,9 @@
<if test="isInner != null">
is_inner = #{isInner,jdbcType=CHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration},
</if>
</set>
where flow_version_id = #{flowVersionId,jdbcType=INTEGER}
</update>
......
......@@ -37,7 +37,7 @@
<result column="node_depend" jdbcType="VARCHAR" property="nodeDepend"/>
<result column="operator" jdbcType="VARCHAR" property="operator"/>
<result column="schedule_type" jdbcType="INTEGER" property="scheduleType"/>
<result column="extended_configuration" jdbcType="VARCHAR" property="extendedConfiguration"/>
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.byit.model.JobTask">
<!-- generated @mbg.generated date: 2019-12-25 -->
......@@ -315,7 +315,7 @@
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration,jdbcType=VARCHAR},
#{extendedConfiguration},
</if>
</trim>
</insert>
......@@ -340,7 +340,7 @@
#{jobTask.versionName,jdbcType=VARCHAR},#{jobTask.runCommand,jdbcType=VARCHAR},#{jobTask.runSource,jdbcType=LONGVARCHAR},
#{jobTask.flowName,jdbcType=VARCHAR},#{jobTask.superSuccessRun,jdbcType=CHAR},#{jobTask.reRunId,jdbcType=VARCHAR},
#{jobTask.logId,jdbcType=INTEGER},#{jobTask.nodeDepend,jdbcType=VARCHAR},#{jobTask.operator,jdbcType=VARCHAR},
#{jobTask.scheduleType,jdbcType=INTEGER}, #{jobTask.extendedConfiguration,jdbcType=VARCHAR}
#{jobTask.scheduleType,jdbcType=INTEGER}, #{jobTask.extendedConfiguration}
)
</foreach>
</insert>
......@@ -452,7 +452,7 @@
schedule_type = #{scheduleType,jdbcType=INTEGER},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
......
......@@ -34,7 +34,7 @@
<result column="operator" jdbcType="VARCHAR" property="operator"/>
<result column="schedule_type" jdbcType="INTEGER" property="scheduleType"/>
<result column="script_urls" jdbcType="VARCHAR" property="scriptUrls"/>
<result column="extended_configuration" jdbcType="VARCHAR" property="extendedConfiguration"/>
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.byit.model.JobTaskRunLogWithBLOBs">
<result column="run_msg" jdbcType="LONGVARCHAR" property="runMsg" />
......@@ -470,7 +470,7 @@
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration,jdbcType=VARCHAR},
#{extendedConfiguration},
</if>
</trim>
</insert>
......@@ -577,7 +577,7 @@
script_urls = #{scriptUrls,jdbcType=VARCHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where log_id = #{logId,jdbcType=INTEGER}
......@@ -679,7 +679,7 @@
script_urls = #{scriptUrls,jdbcType=VARCHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where log_id = #{logId,jdbcType=INTEGER}
......
......@@ -37,7 +37,7 @@
<result column="node_depend" jdbcType="VARCHAR" property="nodeDepend"/>
<result column="operator" jdbcType="VARCHAR" property="operator"/>
<result column="schedule_type" jdbcType="INTEGER" property="scheduleType"/>
<result column="extended_configuration" jdbcType="VARCHAR" property="extendedConfiguration"/>
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.byit.model.JobTaskSchedule">
......@@ -301,7 +301,7 @@
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration,jdbcType=VARCHAR},
#{extendedConfiguration},
</if>
</trim>
</insert>
......@@ -344,7 +344,7 @@
#{jobTaskSchedule.flowName,jdbcType=VARCHAR}, #{jobTaskSchedule.superSuccessRun,jdbcType=CHAR},
#{jobTaskSchedule.reRunId,jdbcType=VARCHAR}, #{jobTaskSchedule.nodeDepend,jdbcType=VARCHAR},
#{jobTaskSchedule.operator,jdbcType=VARCHAR}, #{jobTaskSchedule.scheduleType,jdbcType=INTEGER},
#{jobTaskSchedule.extendedConfiguration,jdbcType=VARCHAR}
#{jobTaskSchedule.extendedConfiguration}
)
</foreach>
</insert>
......@@ -456,7 +456,7 @@
schedule_type = #{scheduleType,jdbcType=INTEGER},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
......
......@@ -35,7 +35,7 @@
<result column="on_fork" jdbcType="CHAR" property="onFork" />
<result column="run_command" jdbcType="VARCHAR" property="runCommand" />
<result column="super_success_run" jdbcType="CHAR" property="superSuccessRun"/>
<result column="extended_configuration" jdbcType="VARCHAR" property="extendedConfiguration"/>
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.byit.model.Node">
<!-- generated @mbg.generated date: 2019-12-31 -->
......@@ -386,7 +386,7 @@
#{superSuccessRun,jdbcType=CHAR},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration,jdbcType=VARCHAR},
#{extendedConfiguration},
</if>
</trim>
</insert>
......@@ -502,7 +502,7 @@
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where node_id = #{nodeId,jdbcType=INTEGER}
......
......@@ -6,7 +6,7 @@
<id column="node_version_id" jdbcType="INTEGER" property="nodeVersionId" />
<result column="node_id" jdbcType="INTEGER" property="nodeId" />
<result column="block_strategy" jdbcType="VARCHAR" property="blockStrategy" />
<result column="pugin_token" jdbcType="VARCHAR" property="puginToken" />
<result column="plugin_token" jdbcType="VARCHAR" property="pluginToken" />
<result column="failed_retry_count" jdbcType="INTEGER" property="failedRetryCount" />
<result column="flow_id" jdbcType="INTEGER" property="flowId" />
<result column="flow_version_id" jdbcType="INTEGER" property="flowVersionId" />
......@@ -37,7 +37,7 @@
<result column="on_fork" jdbcType="CHAR" property="onFork" />
<result column="run_command" jdbcType="VARCHAR" property="runCommand" />
<result column="super_success_run" jdbcType="CHAR" property="superSuccessRun"/>
<result column="extended_configuration" jdbcType="VARCHAR" property="extendedConfiguration"/>
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.byit.model.NodeVersion">
<!-- generated @mbg.generated date: 2019-12-31 -->
......@@ -45,7 +45,7 @@
</resultMap>
<sql id="Base_Column_List">
<!-- generated @mbg.generated date: 2019-12-31 -->
node_version_id, node_id, block_strategy, pugin_token, failed_retry_count, flow_id,
node_version_id, node_id, block_strategy, plugin_token, failed_retry_count, flow_id,
flow_version_id, gateway_token, job_type, handler_name, node_cron, node_desc, node_name,
map_flow_id, node_timeout, is_virtual, plugin_urls, priority, remove_mark, repeat_count,
failed_retry_interval, routing_strategy, run_param, run_source_desc, script_urls,
......@@ -97,6 +97,16 @@
</select>
<select id="getByNameAndFlow" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from node_version
where node_name = #{nodeName} and flow_version_id = #{flowVersionId}
</select>
<delete id="deleteById" parameterType="java.lang.Integer">
<!-- generated @mbg.generated date: 2019-12-31 -->
delete from node_version
......@@ -116,8 +126,8 @@
<if test="blockStrategy != null">
block_strategy,
</if>
<if test="puginToken != null">
pugin_token,
<if test="pluginToken != null">
plugin_token,
</if>
<if test="failedRetryCount != null">
failed_retry_count,
......@@ -226,8 +236,8 @@
<if test="blockStrategy != null">
#{blockStrategy,jdbcType=VARCHAR},
</if>
<if test="puginToken != null">
#{puginToken,jdbcType=VARCHAR},
<if test="pluginToken != null">
#{pluginToken,jdbcType=VARCHAR},
</if>
<if test="failedRetryCount != null">
#{failedRetryCount,jdbcType=INTEGER},
......@@ -323,7 +333,7 @@
#{superSuccessRun,jdbcType=CHAR},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration,jdbcType=VARCHAR},
#{extendedConfiguration},
</if>
</trim>
</insert>
......@@ -344,8 +354,8 @@
<if test="blockStrategy != null">
block_strategy = #{blockStrategy,jdbcType=VARCHAR},
</if>
<if test="puginToken != null">
pugin_token = #{puginToken,jdbcType=VARCHAR},
<if test="pluginToken != null">
plugin_token = #{pluginToken,jdbcType=VARCHAR},
</if>
<if test="failedRetryCount != null">
failed_retry_count = #{failedRetryCount,jdbcType=INTEGER},
......@@ -442,7 +452,7 @@
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where node_version_id = #{nodeVersionId,jdbcType=INTEGER}
......
......@@ -28,12 +28,13 @@
<result column="workspace_id" jdbcType="INTEGER" property="workspaceId" />
<result column="repeat_time" jdbcType="VARCHAR" property="repeatTime" />
<result column="stop_count" jdbcType="INTEGER" property="stopCount" />
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration" />
</resultMap>
<sql id="Base_Column_List">
recording_id, run_id, alarm_email, dispatch_ip, flow_name, flow_run_result, flow_status,
flow_timeout, flow_version_name, alarml_action, priority, trigger_time, principal,
flow_id, start_time, end_time, is_alarm,is_inner,fail_fast, flow_node_count, schedule_type, operator, re_run_id
,workspace_id, repeat_time, stop_count
,workspace_id, repeat_time, stop_count,extended_configuration
</sql>
<select id="findThisDayRunRecording" resultMap="BaseResultMap" parameterType="com.byit.dto.StatisticsConditionDto">
......@@ -130,11 +131,11 @@
where flow_status ='4' and is_alarm = '1' and schedule_type != 4
</select>
<!--and is_inner = '1'-->
<select id="findAllByRunID" resultMap="BaseResultMap">
<select id="findAllByRunIDAndFlowName" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from run_recording
where run_id=#{runId,jdbcType=VARCHAR} and schedule_type != 4
where run_id=#{runId,jdbcType=VARCHAR} and schedule_type != 4 and flow_name=#{flowName}
</select>
<select id="findByRunID" resultMap="BaseResultMap">
......@@ -228,8 +229,8 @@
select
<include refid="Base_Column_List" />
from run_recording
where trigger_time &gt;= #{startDate}
and trigger_time &lt;= #{endDate}
where trigger_time &gt;= #{loadScheduleCondition.startTime}
and trigger_time &lt;= #{loadScheduleCondition.endTime}
and schedule_type != 4
<if test="flowIds != null">
and flow_id in (
......@@ -238,20 +239,24 @@
</foreach>
)
</if>
<if test="scheduleStatusList != null">
<if test="loadScheduleCondition.scheduleStatusList != null and loadScheduleCondition.scheduleStatusList.size()>0">
and flow_status in (
<foreach collection="scheduleStatusList" item="scheduleStatus" separator=",">
<foreach collection="loadScheduleCondition.scheduleStatusList" item="scheduleStatus" separator=",">
#{scheduleStatus}
</foreach>
)
</if>
<if test="executeStatusList != null">
<if test="loadScheduleCondition.executeStatusList != null and loadScheduleCondition.executeStatusList.size()>0">
and flow_run_result in (
<foreach collection="executeStatusList" item="executeStatus" separator=",">
<foreach collection="loadScheduleCondition.executeStatusList" item="executeStatus" separator=",">
#{executeStatus}
</foreach>
)
</if>
<if test="loadScheduleCondition.operator != null and loadScheduleCondition.operator != ''">
and operator = #{loadScheduleCondition.operator}
</if>
order by start_time desc
</select>
......@@ -284,7 +289,7 @@
<include refid="Base_Column_List" />
from run_recording
where flow_id = #{flowId}
and (flow_status != '4' or flow_status != '1') and schedule_type != 4
and (flow_status != '4' and flow_status != '1') and schedule_type != 4
</select>
<select id="findStatusByStartAndEndTime" resultType="com.byit.dto.plugin.StatisticData" useCache="false" flushCache="true">
......@@ -461,6 +466,9 @@
<if test="stopCount != null">
stop_count,
</if>
<if test="extendedConfiguration != null">
extended_configuration,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="recordingId != null">
......@@ -541,6 +549,9 @@
<if test="stopCount != null">
#{stopCount,jdbcType=VARCHAR},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration},
</if>
</trim>
</insert>
<update id="updateRunRecordingById" parameterType="com.byit.model.RunRecording">
......@@ -621,6 +632,9 @@
<if test="stopCount != null">
stop_count = #{stopCount,jdbcType=VARCHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration},
</if>
</set>
where recording_id = #{recordingId,jdbcType=INTEGER}
</update>
......@@ -703,6 +717,9 @@
<if test="stopCount != null">
stop_count = #{stopCount,jdbcType=VARCHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration},
</if>
</set>
where flow_id = #{flowId,jdbcType=INTEGER} and run_id = #{runId,jdbcType=VARCHAR}
</update>
......
......@@ -21,12 +21,13 @@
<result column="run_id" jdbcType="VARCHAR" property="runId" />
<result column="repeat_time" jdbcType="VARCHAR" property="repeatTime" />
<result column="workspace_id" jdbcType="INTEGER" property="workspaceId" />
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration" />
</resultMap>
<sql id="Base_Column_List">
<!-- generated @mbg.generated date: 2020-03-12 -->
wait_id, flow_id, flow_name, flow_version_name, flow_timeout, alarm_email, alarml_action,
priority, trigger_time, principal, is_inner, flow_node_count, schedule_type, `operator`,
wait_order, run_id, repeat_time, workspace_id
wait_order, run_id, repeat_time, workspace_id, extended_configuration
</sql>
<select id="findAllByCondition" resultMap="BaseResultMap" parameterType="com.byit.dto.StatisticsConditionDto">
......@@ -149,6 +150,9 @@
<if test="workspaceId != null">
workspace_id,
</if>
<if test="extendedConfiguration != null">
extended_configuration,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="waitId != null">
......@@ -205,6 +209,9 @@
<if test="workspaceId != null">
#{workspaceId,jdbcType=INTEGER},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration},
</if>
</trim>
</insert>
<update id="updateByIdSelective" parameterType="com.byit.model.WaitingRecord">
......@@ -262,6 +269,10 @@
<if test="workspaceId != null">
workspace_id = #{workspaceId,jdbcType=INTEGER},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration},
</if>
</set>
where wait_id = #{waitId,jdbcType=INTEGER}
</update>
......
......@@ -35,7 +35,7 @@
<result column="node_depend" jdbcType="VARCHAR" property="nodeDepend" />
<result column="operator" jdbcType="VARCHAR" property="operator" />
<result column="schedule_type" jdbcType="INTEGER" property="scheduleType" />
<result column="extended_configuration" jdbcType="VARCHAR" property="extendedConfiguration"/>
<result column="extended_configuration" jdbcType="LONGVARCHAR" property="extendedConfiguration"/>
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.byit.model.WaitingTask">
......@@ -309,7 +309,7 @@
#{runSource,jdbcType=LONGVARCHAR},
</if>
<if test="extendedConfiguration != null">
#{extendedConfiguration,jdbcType=VARCHAR},
#{extendedConfiguration},
</if>
</trim>
</insert>
......@@ -414,7 +414,7 @@
run_source = #{runSource,jdbcType=LONGVARCHAR},
</if>
<if test="extendedConfiguration != null">
extended_configuration = #{extendedConfiguration,jdbcType=VARCHAR},
extended_configuration = #{extendedConfiguration},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
......
package com.byit.dto.common;
import lombok.Data;
import java.io.Serializable;
/**
* 回调dto
*
* @author huangfu
* @date 2020年11月26日17:53:00
*/
@Data
public class CallbackDto implements Serializable {
private static final long serialVersionUID = 3452189099483453750L;
private String flowName;
private String workspaceName;
private String versionName;
private String runId;
private String data;
private Boolean runRecordingStatus = false;
}
......@@ -20,11 +20,11 @@ public class ScriptParamAndPlaceholderDto implements Serializable {
/**
* 参数的处理 命令参数
*/
private Map<String,String> param;
private Map<String,String> param = new HashMap<>(8);
/**
* 占位符的处理
*/
private Map<String,String> Placeholder;
private Map<String,String> Placeholder = new HashMap<>(8);
}
\ No newline at end of file
package com.byit.dto.plugin;
import lombok.Data;
/**
* 扩展配置
*
* @author huangfu
* @date 2020年11月25日18:18:30
*/
@Data
public class FlowExtendedConfiguration {
/**
* rpc开始节点的回调
*/
private String rpcStartServerKey;
/**
* rpc结束节点的回调
*/
private String rpcEndServerKey;
/**
* 公共参数
*/
public String publicParam;
/**
* 节点嵌入标记 a:b:c
*/
private String flowEmbedLogo;
}
package com.byit.dto.plugin;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
......@@ -19,11 +20,6 @@ import java.util.Map;
public class PluginFlowConfig {
/**
* 公共参数
*/
private Map<String,String> publicParam;
/**
* 当前工作流版本的告警的时机(0 不告警, 1 完成时告警, 2 失败时告警, 3 成功时告警)
*/
private String alarmlAction;
......@@ -63,4 +59,9 @@ public class PluginFlowConfig {
*/
private Long flowTimeout;
/**
* 扩展配置
*/
private FlowExtendedConfiguration extendedConfiguration;
}
......@@ -35,4 +35,13 @@ public class RunInfo {
* 节点名称 重跑节点和手动置为成功时需要
*/
private String nodeName;
/**
* 操作人
*/
private String operator;
/**
* 版本号
*/
private String versionName;
}
......@@ -164,6 +164,12 @@ public class RunRecording implements Serializable {
private String repeatTime;
/**
* 扩展配置
*/
@ApiModelProperty("扩展配置")
private String extendedConfiguration;
/**
*/
private static final long serialVersionUID = 2L;
}
\ No newline at end of file
package com.byit.dto.recording;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 加载运行实例条件
*
* @author huangfu
* @date 2020年12月3日10:29:03
*/
@Data
public class LoadScheduleCondition implements Serializable {
private static final long serialVersionUID = -3011707470248774142L;
private String workspaceName;
private String flowName;
private Long startTime;
private Long endTime;
/**
* 责任人
*/
private String operator;
/**
* 工作流的状态
*/
private List<String> scheduleStatusList;
/**
* 执行结果状态
*/
private List<String> executeStatusList;
}
......@@ -40,7 +40,7 @@ public class SpecialJobParam implements Serializable {
private String startNodeTaskName;
/**
* 任务名称 -> 任务参数载体
* 任务名称 -> 任务参数载体 value对应 ScriptParamAndPlaceholderDto
*/
private Map<String,String> paramCarrier;
......@@ -54,7 +54,7 @@ public class SpecialJobParam implements Serializable {
*/
private List<RepairTimeParam> repairTimeList;
/**
* 时间类型格式
* 时间类型格式 与 RepairTimeParam 里面的时间格式一致
*/
private String timeFormatName;
......
......@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSON;
import com.byit.dto.api.JavaCallbackLogDto;
import com.byit.dto.executor.PluginBeanJobInfo;
import com.byit.dto.plugin.*;
import com.byit.dto.recording.LoadScheduleCondition;
import com.byit.dto.recording.SelectRecordingStatusCondition;
import com.byit.dto.specials.RepairFlow;
import com.byit.dto.specials.SpecialJobParam;
......@@ -536,7 +537,7 @@ public class JobUtils {
*/
public static ResponseResult reRunJob(RunInfo runInfo) {
//发送请求 添加任务
String response = createHttpRequest(REQUEST_FLOW_RERUNJOB, "param=" + JSON.toJSONString(runInfo, WriteClassName));
String response = createHttpRequest(REQUEST_FLOW_RERUNJOB, JSON.toJSONString(runInfo, WriteClassName));
log.debug("--------------------重跑节点接口调用成功,结果为:{}------------------------", response);
return JSON.parseObject(response, ResponseResult.class);
}
......@@ -549,7 +550,7 @@ public class JobUtils {
*/
public static ResponseResult reRunFlow(RunInfo runInfo) {
//发送请求 添加任务
String response = createHttpRequest(REQUEST_FLOW_RERUNFLOW, "param=" + JSON.toJSONString(runInfo, WriteClassName));
String response = createHttpRequest(REQUEST_FLOW_RERUNFLOW, JSON.toJSONString(runInfo, WriteClassName));
log.debug("--------------------重跑节点接口调用成功,结果为:{}------------------------", response);
return JSON.parseObject(response, ResponseResult.class);
}
......@@ -561,7 +562,7 @@ public class JobUtils {
*/
public static ResponseResult makeSuccess(RunInfo runInfo) {
//发送请求 添加任务
String response = createHttpRequest(REQUEST_FLOW_MAKESUCCESS, "param=" + JSON.toJSONString(runInfo, WriteClassName));
String response = createHttpRequest(REQUEST_FLOW_MAKESUCCESS, JSON.toJSONString(runInfo, WriteClassName));
log.debug("--------------------手动置为成功接口调用成功,结果为:{}------------------------", response);
return JSON.parseObject(response, ResponseResult.class);
}
......@@ -569,23 +570,11 @@ public class JobUtils {
/**
* 获取运行实例接口
*
* @param startTime 开始时间 毫秒级别时间
* @param endTime 结束时间 毫秒级别时间
* @param workspaceName 工作空间名称
* @param flowName 工作流名称
* @param scheduleStatus 调度状态 1 未开始 2运行中 3暂停 4完成 多个以“,”隔开
* @param executeStatus 执行结果 1 成功 2 失败 3 补批成功 4 补批失败 5.kill 多个以“,”隔开
* @return
* @param loadScheduleCondition 查询条件
* @return 对应的数据
*/
public static ResponseResult loadScheduleResult(Long startTime, Long endTime, String workspaceName, String flowName, String scheduleStatus, String executeStatus) {
Map<String, Object> param = new HashMap<>();
param.put("startTime", startTime);
param.put("endTime", endTime);
param.put("workspaceName", workspaceName);
param.put("flowName", flowName);
param.put("scheduleStatus", scheduleStatus);
param.put("executeStatus", executeStatus);
String response = createHttpRequest(REQUEST_LOADSCHEDULE, "param=" + JSON.toJSONString(param));
public static ResponseResult loadScheduleResult(LoadScheduleCondition loadScheduleCondition) {
String response = createHttpRequest(REQUEST_LOADSCHEDULE, JSON.toJSONString(loadScheduleCondition, WriteClassName));
log.debug("--------------------获取运行实例接口调用成功,结果为:{}------------------------", response);
return JSON.parseObject(response, ResponseResult.class);
}
......
......@@ -121,11 +121,6 @@
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.byit</groupId>
<artifactId>byit-mybatis-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
<configuration>
<configurationFile>${basedir}/src/main/resources/Generator-config.xml</configurationFile>
......
......@@ -60,7 +60,7 @@ public class CommandAndScriptProcessingMachine implements ProcessingMachine {
}
//判断是否需要拉取文件服务器的文件,包含biz_file的条件下会对这个字段进行替换
if (StringUtils.isNoneBlank(scriptDto.getRemotePath())) {
//这里需要解压压缩包 然后将
//这里需要解压压缩包 然后将压缩包删除
String scriptDirPath = byteArrayToSource(scriptDto.getRemotePath());
log.debug("-----远程地址的文件被拉取到:[{}]------------", scriptDirPath);
log.debug("-----执行命令初始化完成,命令为:[{}]------------", command);
......@@ -73,7 +73,7 @@ public class CommandAndScriptProcessingMachine implements ProcessingMachine {
processingNodeChain.doProcessing(scriptDto, processingNodeChain);
} catch (Exception e) {
log.error("{}", ExecutorLogUtil.getMessage(e));
throw new ExecutorException(e);
throw new ExecutorException(ExecutorLogUtil.getMessage(e));
}
}
......
package com.byit.enums;
/**
* 调用的方式 异步 同步
*
* @author huangfu
* @date 2020年11月26日11:12:26
*/
public enum CallMethodEnum {
/**
* 同步
*/
SYNCHRONIZE,
/**
* 异步
*/
ASYNCHRONOUS
}
package com.byit.packet.request;
import com.byit.enums.CallMethodEnum;
import com.byit.enums.Command;
import com.byit.enums.SerializerAlgorithm;
import com.byit.packet.BasePacketModel;
......@@ -32,6 +33,8 @@ public class PluginRpcRequestPacket extends BasePacketModel {
private String callbackUrl;
private CallMethodEnum callMethodEnum = CallMethodEnum.ASYNCHRONOUS;
@Override
public Command getCommand() {
return Command.RUN_REMOTELY_JOB_NODE_REQUEST;
......
......@@ -2,7 +2,7 @@ package com.byit.factory;
import com.byit.client.NettyPluginClient;
import com.byit.client.PluginClient;
import com.byit.executor.handler.interfaces.IJobHandler;
import com.byit.enums.CallMethodEnum;
import com.byit.init.PluginClientInitialization;
import com.byit.registry.DataSourceServiceRegistry;
import com.byit.registry.PluginServiceRegistry;
......@@ -13,12 +13,12 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.util.ReflectionUtils;
/**
* spring 方式实现的插件端 客户端 实现工厂
*
* @author huangfu
*/
public class PluginSpringClientFactory extends InstantiationAwareBeanPostProcessorAdapter implements InitializingBean, DisposableBean, BeanFactoryAware {
......@@ -32,14 +32,13 @@ public class PluginSpringClientFactory extends InstantiationAwareBeanPostProcess
private String biz;
public PluginSpringClientFactory(String registryUrl, String env, String biz) {
this(null,null);
this(null, null);
this.registryUrl = registryUrl;
this.env = env;
this.biz = biz;
}
public PluginSpringClientFactory(Class<? extends PluginServiceRegistry> pluginServiceRegistryClass,
Class<? extends PluginClient> pluginClientClass) {
this.pluginServiceRegistryClass = pluginServiceRegistryClass;
......@@ -56,16 +55,18 @@ public class PluginSpringClientFactory extends InstantiationAwareBeanPostProcess
/**
* 属性设置之后调用
*
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
pluginClientFactory = new PluginClientFactory(pluginServiceRegistryClass,registryUrl,biz,env);
pluginClientFactory = new PluginClientFactory(pluginServiceRegistryClass, registryUrl, biz, env);
pluginClientFactory.start();
}
/**
* bean进行实例化后的后期处理 能够拿到每一个bean的实例 插手bean的实例化后的属性注入
*
* @param bean
* @param beanName
* @return
......@@ -75,7 +76,7 @@ public class PluginSpringClientFactory extends InstantiationAwareBeanPostProcess
public boolean postProcessAfterInstantiation(final Object bean, final String beanName) throws BeansException {
Class<?> beanClass = bean.getClass();
//寻找bean中每一个带有注解的操作 对其进行代理
ReflectionUtils.doWithFields(beanClass,field -> {
ReflectionUtils.doWithFields(beanClass, field -> {
if (field.isAnnotationPresent(TaskClient.class)) {
//获取改属性的接口
Class<?> iFace = field.getType();
......@@ -87,19 +88,21 @@ public class PluginSpringClientFactory extends InstantiationAwareBeanPostProcess
String callbackUrl = taskClientAnn.callbackUrl();
LoadBalance loadBalance = taskClientAnn.loadBalance();
long timeout = taskClientAnn.timeout();
CallMethodEnum callMethodEnum = taskClientAnn.callMethodEnum();
PluginClientInitialization pluginClientInitialization = new PluginClientInitialization(callbackUrl, timeout, loadBalance,
pluginClientFactory, iFace,pluginClientClass);
pluginClientFactory, iFace, pluginClientClass, callMethodEnum);
Object proxyObject = pluginClientInitialization.getObject();
field.setAccessible(true);
field.set(bean,proxyObject);
field.set(bean, proxyObject);
}
});
return super.postProcessAfterInstantiation(bean,beanName);
return super.postProcessAfterInstantiation(bean, beanName);
}
/**
* 能够获取bean工厂
*
* @param beanFactory
* @throws BeansException
*/
......@@ -110,6 +113,7 @@ public class PluginSpringClientFactory extends InstantiationAwareBeanPostProcess
/**
* bean被销毁时 自动调用
*
* @throws Exception
*/
@Override
......
......@@ -2,6 +2,7 @@ package com.byit.init;
import cn.hutool.core.collection.CollectionUtil;
import com.byit.client.PluginClient;
import com.byit.enums.CallMethodEnum;
import com.byit.factory.PluginClientFactory;
import com.byit.future.PluginFutureResponse;
import com.byit.packet.request.PluginRpcRequestPacket;
......@@ -18,6 +19,7 @@ import java.util.concurrent.TimeUnit;
/**
* 插件端 客户端的数据初始化
*
* @author huangfu
*/
public class PluginClientInitialization {
......@@ -30,20 +32,24 @@ public class PluginClientInitialization {
private PluginClient pluginClient;
private CallMethodEnum callMethodEnum;
public PluginClientInitialization(String callbackUrl, long timeout, LoadBalance loadBalance, PluginClientFactory pluginClientFactory, Class<?> iFace,Class<? extends PluginClient> pluginClientClass) {
public PluginClientInitialization(String callbackUrl, long timeout, LoadBalance loadBalance,
PluginClientFactory pluginClientFactory, Class<?> iFace, Class<? extends PluginClient> pluginClientClass,
CallMethodEnum callMethodEnum) {
this.callbackUrl = callbackUrl;
this.timeout = timeout;
this.loadBalance = loadBalance;
this.pluginClientFactory = pluginClientFactory;
this.iFace = iFace;
this.pluginClientClass = pluginClientClass;
this.callMethodEnum = callMethodEnum;
initClient();
}
private void initClient(){
private void initClient() {
try {
pluginClient = this.pluginClientClass.newInstance();
pluginClient.init(this);
......@@ -55,47 +61,44 @@ public class PluginClientInitialization {
/**
* 动态代理 生成动态代理的方法实现 ,并将动态代理生成的实现返还回调用方!
*
* @return 动态代理生成的实现类
*/
public Object getObject(){
public Object getObject() {
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{this.iFace},
(proxy, method, args) ->{
(proxy, method, args) -> {
PluginRpcRequestPacket pluginRpcRequestPacket = (PluginRpcRequestPacket)args[0];
if(pluginRpcRequestPacket == null){
PluginRpcRequestPacket pluginRpcRequestPacket = (PluginRpcRequestPacket) args[0];
if (pluginRpcRequestPacket == null) {
throw new RuntimeException("服务参数为null:【com.byit.packet.request.PluginRpcRequestPacket】!");
}
PluginServiceRegistry pluginServiceRegistry = pluginClientFactory.getPluginServiceRegistry();
//服务器的注册ip:port
String address = null;
TreeSet<String> discovery = pluginServiceRegistry.discovery(pluginRpcRequestPacket.getJobName());
if(CollectionUtil.isNotEmpty(discovery)){
address = ClientRpcUtil.selectRPCServer(pluginClient,loadBalance,discovery,pluginRpcRequestPacket);
// if(discovery.size() ==1){
// address = discovery.first();
// }else{
// address = loadBalance.rpcInvokerRouter.route(pluginRpcRequestPacket.getJobName(), discovery);
// }
if (CollectionUtil.isNotEmpty(discovery)) {
address = ClientRpcUtil.selectRPCServer(pluginClient, loadBalance, discovery, pluginRpcRequestPacket);
}
if(StringUtils.isBlank(address)){
if (StringUtils.isBlank(address)) {
throw new RuntimeException("该服务在注册表中不存在!");
}
pluginRpcRequestPacket.setRequestId(UUID.randomUUID().toString());
pluginRpcRequestPacket.setCallMethodEnum(callMethodEnum);
PluginFutureResponse pluginFutureResponse = new PluginFutureResponse(pluginClientFactory,pluginRpcRequestPacket,null);
PluginFutureResponse pluginFutureResponse = new PluginFutureResponse(pluginClientFactory, pluginRpcRequestPacket, null);
try {
//发送请求
pluginClient.send(address,pluginRpcRequestPacket);
pluginClient.send(address, pluginRpcRequestPacket);
//获取结果
PluginRpcResponsePacket pluginRpcResponsePacket = pluginFutureResponse.get(timeout, TimeUnit.MILLISECONDS);
pluginRpcResponsePacket.setRunIp(address);
return pluginRpcResponsePacket;
}catch (Exception e){
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
} finally {
pluginFutureResponse.remove(pluginRpcRequestPacket.getRequestId());
}
......
......@@ -9,6 +9,7 @@ import com.byit.rpc.remoting.invoker.route.LoadBalance;
import com.byit.rpc.util.RPCLogUtil;
import com.byit.rpc.util.RpcException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.TreeSet;
......@@ -31,7 +32,11 @@ public class ClientRpcUtil {
for (String ignored : address) {
String routeHost = loadBalance.rpcInvokerRouter.route(pluginRpcRequestPacket.getJobName(), address);
String extension = pluginRpcRequestPacket.getExtension();
String runKey = KeyUtil.generateRunKey(Integer.parseInt(extension));
String runKey = null;
if(StringUtils.isNoneBlank(extension)){
runKey = KeyUtil.generateRunKey(Integer.parseInt(extension));
}
boolean retryRpcHost = retryRpcHost(client, routeHost, runKey, 3, 1);
if (retryRpcHost) {
return routeHost;
......@@ -57,7 +62,9 @@ public class ClientRpcUtil {
client.send(host, PluginBeat.PLUGIN_RPC_REQUEST_PACKET);
String redisFormat = String.format("与执行服务器[%s]建立成功,总共重试%s次!", host, thisRetryCount - 1);
RunLog runLog = RunLog.builder().runLog(redisFormat).isEnd(false).build();
stringRedisTemplate.opsForList().rightPush(runKey, JSON.toJSONString(runLog, WriteClassName));
if (StringUtils.isNoneBlank(runKey)) {
stringRedisTemplate.opsForList().rightPush(runKey, JSON.toJSONString(runLog, WriteClassName));
}
log.info("------{}plugin-rpc通道建立成功,重试了{}次------", host, thisRetryCount - 1);
return true;
} catch (Exception e) {
......@@ -68,7 +75,10 @@ public class ClientRpcUtil {
log.error(format);
//redis模板
RunLog runLog = RunLog.builder().runLog(redisFormat).isEnd(false).build();
stringRedisTemplate.opsForList().rightPush(runKey, JSON.toJSONString(runLog, WriteClassName));
if (StringUtils.isNoneBlank(runKey)) {
stringRedisTemplate.opsForList().rightPush(runKey, JSON.toJSONString(runLog, WriteClassName));
}
Thread.sleep(1000 * thisRetryCount);
retryRpcHost(client, host,runKey, retryTotalCount, ++thisRetryCount);
}
......@@ -78,8 +88,9 @@ public class ClientRpcUtil {
String format = String.format("与主机【%s】建立通道,总共【%s】次,全部失败,开始挑选下一个负载均衡方案重试,请稍后", host, retryTotalCount);
RunLog runLog = RunLog.builder().runLog(format).isEnd(false).build();
stringRedisTemplate.opsForList().rightPush(runKey, JSON.toJSONString(runLog, WriteClassName));
if (StringUtils.isNoneBlank(runKey)) {
stringRedisTemplate.opsForList().rightPush(runKey, JSON.toJSONString(runLog, WriteClassName));
}
log.error(format);
}
return false;
......
......@@ -3,6 +3,7 @@ package com.byit.server.netty.handler;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.byit.dto.web.ReturnResult;
import com.byit.enums.CallMethodEnum;
import com.byit.enums.JobResultEnum;
import com.byit.enums.ResponseTyEnum;
import com.byit.factory.PluginServerFactory;
......@@ -45,9 +46,35 @@ public class NettyPluginServerHandler extends SimpleChannelInboundHandler<Plugin
if(PluginBeat.BEAT_ID.equals(msg.getRequestId())){
return;
}
PluginRpcResponsePacket transferPluginRpcResponse = new PluginRpcResponsePacket();
threadPoolExecutor.execute(()->{
CallMethodEnum callMethodEnum = msg.getCallMethodEnum();
CallMethod callMethod = null;
//同步调用
if(CallMethodEnum.SYNCHRONIZE.equals(callMethodEnum)){
callMethod = new Synchronize();
callMethod.run(msg,ctx);
}
//异步调用
if(CallMethodEnum.ASYNCHRONOUS.equals(callMethodEnum)){
callMethod = new Asynchronous();
callMethod.run(msg,ctx);
}
}
/**
* 同步调用
* @author huangfu
* @date 2020年11月26日11:22:11
*/
private class Synchronize implements CallMethod{
/**
* 开始执行
*/
@Override
public void run(PluginRpcRequestPacket msg,ChannelHandlerContext ctx) {
PluginRpcResponsePacket rpcResponsePacket = new PluginRpcResponsePacket();
rpcResponsePacket.setRequestId(msg.getRequestId());
try {
Map<String, Object> serverPoll = pluginServerFactory.getServerPoll();
String jobName = msg.getJobName();
......@@ -62,7 +89,7 @@ public class NettyPluginServerHandler extends SimpleChannelInboundHandler<Plugin
rpcResponsePacket.setStatus(true);
rpcResponsePacket.setRunTime(endTime-startTime);
rpcResponsePacket.setExtension(msg.getExtension());
sendMsg(rpcResponsePacket,msg);
rpcResponsePacket.setType(ResponseTyEnum.RESPONSE.getType());
}catch (Throwable e){
rpcResponsePacket.setCode(JobResultEnum.FAIL.getCode());
rpcResponsePacket.setMsg(PluginLogUtils.getMessage(e));
......@@ -72,19 +99,75 @@ public class NettyPluginServerHandler extends SimpleChannelInboundHandler<Plugin
execute.setMsg(PluginLogUtils.getMessage(e));
execute.setCode(JobResultEnum.FAIL.getCode());
rpcResponsePacket.setResult(execute);
sendMsg(rpcResponsePacket,msg);
rpcResponsePacket.setType(ResponseTyEnum.RESPONSE.getType());
throw new RuntimeException(e);
}finally {
ctx.channel().writeAndFlush(rpcResponsePacket);
}
}
}
/**
* 异步调用
* @author huangfu
* @date 2020年11月26日11:22:11
*/
private class Asynchronous implements CallMethod{
/**
* 开始执行
*/
@Override
public void run(PluginRpcRequestPacket msg, ChannelHandlerContext ctx) {
PluginRpcResponsePacket transferPluginRpcResponse = new PluginRpcResponsePacket();
threadPoolExecutor.execute(()->{
PluginRpcResponsePacket rpcResponsePacket = new PluginRpcResponsePacket();
try {
Map<String, Object> serverPoll = pluginServerFactory.getServerPoll();
String jobName = msg.getJobName();
Object bean = serverPoll.get(jobName);
IJobHandler iJobHandler = (IJobHandler)bean;
long startTime = System.currentTimeMillis();
ReturnResult<String> execute = iJobHandler.execute(msg.getParam());
long endTime = System.currentTimeMillis();
rpcResponsePacket.setResult(execute);
rpcResponsePacket.setCode(JobResultEnum.SUCCESS.getCode());
rpcResponsePacket.setMsg(JobResultEnum.SUCCESS.getMsg());
rpcResponsePacket.setStatus(true);
rpcResponsePacket.setRunTime(endTime-startTime);
rpcResponsePacket.setExtension(msg.getExtension());
sendMsg(rpcResponsePacket,msg);
}catch (Throwable e){
rpcResponsePacket.setCode(JobResultEnum.FAIL.getCode());
rpcResponsePacket.setMsg(PluginLogUtils.getMessage(e));
rpcResponsePacket.setStatus(false);
rpcResponsePacket.setExtension(msg.getExtension());
ReturnResult<String> execute = new ReturnResult<>();
execute.setMsg(PluginLogUtils.getMessage(e));
execute.setCode(JobResultEnum.FAIL.getCode());
rpcResponsePacket.setResult(execute);
sendMsg(rpcResponsePacket,msg);
throw new RuntimeException(e);
}
});
transferPluginRpcResponse.setRequestId(msg.getRequestId());
transferPluginRpcResponse.setStatus(true);
transferPluginRpcResponse.setCode("00000000");
transferPluginRpcResponse.setMsg("调用成功");
transferPluginRpcResponse.setType(ResponseTyEnum.TRANSFER.getType());
ctx.channel().writeAndFlush(transferPluginRpcResponse);
}
}
});
transferPluginRpcResponse.setRequestId(msg.getRequestId());
transferPluginRpcResponse.setStatus(true);
transferPluginRpcResponse.setCode("00000000");
transferPluginRpcResponse.setMsg("调用成功");
transferPluginRpcResponse.setExtension(msg.getExtension());
transferPluginRpcResponse.setType(ResponseTyEnum.TRANSFER.getType());
ctx.channel().writeAndFlush(transferPluginRpcResponse);
private interface CallMethod{
/**
* 开始执行
*/
void run(PluginRpcRequestPacket pluginRpcRequestPacket,ChannelHandlerContext ctx);
}
/**
......
......@@ -223,6 +223,7 @@
</snapshotRepository>
</distributionManagement>
<build>
<plugins>
<plugin>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment