|
|
@@ -1,8 +1,10 @@ |
|
|
|
package com.ruoyi.business.service.impl; |
|
|
|
|
|
|
|
import java.text.ParseException; |
|
|
|
import java.time.ZoneId; |
|
|
|
import java.time.ZonedDateTime; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.concurrent.atomic.AtomicBoolean; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
@@ -23,14 +25,19 @@ import com.ruoyi.business.service.IResourceLibraryService; |
|
|
|
import com.ruoyi.business.util.YinDaoHttpUtils; |
|
|
|
import com.ruoyi.business.yddoman.BaseDTO; |
|
|
|
import com.ruoyi.common.annotation.DataScope; |
|
|
|
import com.ruoyi.common.core.redis.RedisCache; |
|
|
|
import com.ruoyi.common.enums.ExcTypeStatus; |
|
|
|
import com.ruoyi.common.enums.PlanRunStatus; |
|
|
|
import com.ruoyi.common.enums.RebotStatus; |
|
|
|
import com.ruoyi.common.exception.ServiceException; |
|
|
|
import com.ruoyi.common.utils.SecurityUtils; |
|
|
|
import com.ruoyi.common.utils.StringUtils; |
|
|
|
import com.ruoyi.common.utils.bean.BeanUtils; |
|
|
|
import org.quartz.*; |
|
|
|
import org.redisson.api.RLock; |
|
|
|
import org.redisson.api.RedissonClient; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.data.redis.core.RedisTemplate; |
|
|
|
import org.springframework.scheduling.support.CronSequenceGenerator; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import com.ruoyi.business.mapper.ApplyPlanMapper; |
|
|
@@ -56,6 +63,10 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
@Autowired |
|
|
|
private IResourceLibraryService resourceLibraryService; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private RedissonClient redissonClient; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 重新运行 |
|
|
|
* |
|
|
@@ -92,40 +103,168 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
public boolean runAppBySetTime() throws IllegalAccessException { |
|
|
|
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TWO.getKey()).isNull(ApplyPlan::getTaskUuid).orderByAsc(ApplyPlan::getExcTime).list(); |
|
|
|
if (applyPlanList.isEmpty()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
RLock lock = redissonClient.getLock("runAppBySetTime"); |
|
|
|
try { |
|
|
|
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒 |
|
|
|
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS); |
|
|
|
if (isLocked) { |
|
|
|
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TWO.getKey()).isNull(ApplyPlan::getTaskUuid).orderByAsc(ApplyPlan::getExcTime).list(); |
|
|
|
if (applyPlanList.isEmpty()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
ListRebotBO listRebotBO = new ListRebotBO(); |
|
|
|
listRebotBO.setStatus(RebotStatus.IDLE.getKey()); |
|
|
|
listRebotBO.setPage(1); |
|
|
|
listRebotBO.setSize(100); |
|
|
|
// 只获取空闲的机器人 |
|
|
|
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
log.debug("暂无空闲机器人"); |
|
|
|
// 刷新机器人数据 |
|
|
|
ListRebotBO listRebotBO = new ListRebotBO(); |
|
|
|
listRebotBO.setStatus(RebotStatus.IDLE.getKey()); |
|
|
|
listRebotBO.setPage(1); |
|
|
|
listRebotBO.setSize(100); |
|
|
|
// 只获取空闲的机器人 |
|
|
|
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
log.debug("暂无空闲机器人"); |
|
|
|
// 刷新机器人数据 |
|
|
|
// rebotService.syn(new Rebot()); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
List<String> ids = new ArrayList<>(); |
|
|
|
listRebotVos.forEach(rebot -> { |
|
|
|
applyPlanList.forEach(e -> { |
|
|
|
log.debug("指定时间执行 执行时间:" + e.getExcTime()); |
|
|
|
if (ids.contains(e.getId())) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (e.getExcTime().getTime() <= System.currentTimeMillis() && PlanRunStatus.AWAIT_CREATE.getKey().equals(e.getTaskStatus())) { |
|
|
|
ApplyStartBO applyStartBO = new ApplyStartBO(); |
|
|
|
applyStartBO.setRobotUuid(e.getAppId()); |
|
|
|
applyStartBO.setAccountName(rebot.getRobotClientName()); |
|
|
|
applyStartBO.setManualTime(e.getManualTime()); |
|
|
|
//high 高 middle 中 low 低 |
|
|
|
applyStartBO.setPriority("high"); |
|
|
|
// 如果应用支持参数 |
|
|
|
if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) { |
|
|
|
if (StringUtils.isNotEmpty(e.getPlanParams())) { |
|
|
|
applyStartBO.setPlanParams(e.getPlanParams()); |
|
|
|
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class); |
|
|
|
applyStartBO.setPlanParamsList(paramList); |
|
|
|
} |
|
|
|
} |
|
|
|
try { |
|
|
|
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO); |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
|
applyPlan.setId(e.getId()); |
|
|
|
applyPlan.setUpdateBy("系统修改"); |
|
|
|
applyPlan.setUpdateTime(new Date()); |
|
|
|
applyPlan.setTaskUuid(jobStartVO.getJobUuid()); |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey()); |
|
|
|
this.updateById(applyPlan); |
|
|
|
Rebot updateRebot = new Rebot(); |
|
|
|
updateRebot.setUpdateBy("系统修改"); |
|
|
|
updateRebot.setUpdateTime(new Date()); |
|
|
|
updateRebot.setStatus(RebotStatus.RUNNING.getKey()); |
|
|
|
if (rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot)) { |
|
|
|
log.debug("applyPlanList:" + applyPlanList.size()); |
|
|
|
ids.add(e.getId()); |
|
|
|
} |
|
|
|
} catch (IllegalAccessException ex) { |
|
|
|
throw new RuntimeException(ex); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} catch (InterruptedException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} finally { |
|
|
|
if (lock.isHeldByCurrentThread()) { |
|
|
|
// 释放锁 |
|
|
|
lock.unlock(); |
|
|
|
} |
|
|
|
} |
|
|
|
listRebotVos.forEach(rebot -> { |
|
|
|
applyPlanList.forEach(e -> { |
|
|
|
if (e.getExcTime().getTime() <= System.currentTimeMillis() && PlanRunStatus.AWAIT_CREATE.getKey().equals(e.getTaskStatus())) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 表达式执行 |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public boolean runAppByCron() throws IllegalAccessException { |
|
|
|
RLock lock = redissonClient.getLock("runAppByCron"); |
|
|
|
try { |
|
|
|
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒 |
|
|
|
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS); |
|
|
|
if (isLocked) { |
|
|
|
// 先查计划,避免每次命中第三方接口 |
|
|
|
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TREE.getKey()).ne(ApplyPlan::getTaskStatus, PlanRunStatus.RUNNING.getKey()).ne(ApplyPlan::getTaskStatus, PlanRunStatus.CREATED.getKey()).list(); |
|
|
|
if (applyPlanList.isEmpty()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
// 需要执行的计划 |
|
|
|
List<ApplyPlan> execApplyPlan = new ArrayList<>(); |
|
|
|
applyPlanList.forEach(e -> { |
|
|
|
try { |
|
|
|
CronExpression cron = new CronExpression(e.getCronExpression()); |
|
|
|
// 如果该计划没有执行过 |
|
|
|
if (Objects.isNull(e.getLastExecTime())) { |
|
|
|
// 执行一次 |
|
|
|
execApplyPlan.add(e); |
|
|
|
} else { |
|
|
|
// 根据表达式返回下一个执行时间 |
|
|
|
if (new Date().compareTo(e.getNextExecTime()) > -1) { |
|
|
|
execApplyPlan.add(e); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (ParseException ex) { |
|
|
|
log.error(e.getPlanName() + "的时间表达式错误!"); |
|
|
|
throw new RuntimeException(ex); |
|
|
|
} |
|
|
|
}); |
|
|
|
if (execApplyPlan.isEmpty()) { |
|
|
|
log.debug("没有待执行的计划"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
ListRebotBO listRebotBO = new ListRebotBO(); |
|
|
|
listRebotBO.setStatus(RebotStatus.IDLE.getKey()); |
|
|
|
listRebotBO.setPage(1); |
|
|
|
listRebotBO.setSize(100); |
|
|
|
// 只获取空闲的机器人 |
|
|
|
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
log.debug("暂无空闲机器人"); |
|
|
|
// 刷新机器人数据 |
|
|
|
// rebotService.syn(new Rebot()); |
|
|
|
return false; |
|
|
|
} |
|
|
|
List<String> ids = new ArrayList<>(); |
|
|
|
execApplyPlan.forEach(e -> { |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
// 刷新机器人数据 |
|
|
|
// rebotService.syn(new Rebot()); |
|
|
|
return; |
|
|
|
} |
|
|
|
ListRebotVO rebot = listRebotVos.get(0); |
|
|
|
log.debug("机器人表达式执行调度日志" + rebot.getRobotClientName() + "调度" + e.getAppName() + "应用,排除的应用id为" + ids.toString()); |
|
|
|
if (ids.contains(e.getId())) { |
|
|
|
return; |
|
|
|
} |
|
|
|
log.debug("机器人表达式成功调度日志" + rebot.getRobotClientName() + "调度" + e.getAppName() + "应用,排除的应用id为" + ids.toString()); |
|
|
|
// 该计划满足执行条件 |
|
|
|
ApplyStartBO applyStartBO = new ApplyStartBO(); |
|
|
|
applyStartBO.setRobotUuid(e.getAppId()); |
|
|
|
applyStartBO.setAccountName(rebot.getRobotClientName()); |
|
|
|
applyStartBO.setManualTime(e.getManualTime()); |
|
|
|
//high 高 middle 中 low 低 |
|
|
|
applyStartBO.setPriority("high"); |
|
|
|
|
|
|
|
// 如果应用支持参数 |
|
|
|
if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) { |
|
|
|
// 获取参数 |
|
|
|
if (StringUtils.isNotEmpty(e.getPlanParams())) { |
|
|
|
applyStartBO.setPlanParams(e.getPlanParams()); |
|
|
|
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class); |
|
|
|
applyStartBO.setPlanParamsList(paramList); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
try { |
|
|
|
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO); |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
@@ -133,136 +272,69 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
applyPlan.setUpdateBy("系统修改"); |
|
|
|
applyPlan.setUpdateTime(new Date()); |
|
|
|
applyPlan.setTaskUuid(jobStartVO.getJobUuid()); |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey()); |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.RUNNING.getKey()); |
|
|
|
// 根据表达式返回下一个执行时间 |
|
|
|
log.debug("表达式:" + e.getCronExpression()); |
|
|
|
// 设置时区,例如设置为中国时区 |
|
|
|
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai").toString()); |
|
|
|
|
|
|
|
final CronExpression cron = new CronExpression(e.getCronExpression()); |
|
|
|
Date nextDate = null; |
|
|
|
if (Objects.isNull(e.getLastExecTime())) { |
|
|
|
Date date = new Date(); |
|
|
|
log.debug("当前时间:" + date); |
|
|
|
nextDate = cron.getNextValidTimeAfter(date);//下次执行时间 |
|
|
|
log.debug("下次时间:" + nextDate); |
|
|
|
applyPlan.setLastExecTime(date); |
|
|
|
applyPlan.setNextExecTime(nextDate); |
|
|
|
} else { |
|
|
|
applyPlan.setLastExecTime(e.getNextExecTime()); |
|
|
|
log.debug("当前时间:" + e.getNextExecTime()); |
|
|
|
nextDate = cron.getNextValidTimeAfter(e.getNextExecTime());//下次执行时间 |
|
|
|
log.debug("下次时间:" + nextDate); |
|
|
|
applyPlan.setNextExecTime(nextDate); |
|
|
|
} |
|
|
|
this.updateById(applyPlan); |
|
|
|
Rebot updateRebot = new Rebot(); |
|
|
|
updateRebot.setUpdateBy("系统修改"); |
|
|
|
updateRebot.setUpdateTime(new Date()); |
|
|
|
updateRebot.setStatus(RebotStatus.RUNNING.getKey()); |
|
|
|
if (rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot)) { |
|
|
|
applyPlanList.remove(e); |
|
|
|
ids.add(e.getId()); |
|
|
|
} |
|
|
|
} catch (IllegalAccessException ex) { |
|
|
|
throw new RuntimeException(ex); |
|
|
|
} catch (ParseException ex) { |
|
|
|
throw new RuntimeException(ex); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 表达式执行 |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public boolean runAppByCron() throws IllegalAccessException { |
|
|
|
// 先查计划,避免每次命中第三方接口 |
|
|
|
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TREE.getKey()).list(); |
|
|
|
if (applyPlanList.isEmpty()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
// 需要执行的计划 |
|
|
|
List<ApplyPlan> execApplyPlan = new ArrayList<>(); |
|
|
|
applyPlanList.forEach(e -> { |
|
|
|
try { |
|
|
|
CronExpression cron = new CronExpression(e.getCronExpression()); |
|
|
|
// 如果该计划没有执行过 |
|
|
|
if (Objects.isNull(e.getLastExecTime())) { |
|
|
|
// 判断当前时间是否满足表达式 |
|
|
|
Date nextDate = cron.getNextValidTimeAfter(new Date()); |
|
|
|
if (new Date().compareTo(nextDate) > -1) { |
|
|
|
execApplyPlan.add(e); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 根据表达式返回下一个执行时间 |
|
|
|
Date nextDate = cron.getNextValidTimeAfter(e.getNextExecTime()); |
|
|
|
if (new Date().compareTo(nextDate) > -1) { |
|
|
|
execApplyPlan.add(e); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (ParseException ex) { |
|
|
|
log.error(e.getPlanName() + "的时间表达式错误!"); |
|
|
|
throw new RuntimeException(ex); |
|
|
|
listRebotVos.remove(0); |
|
|
|
}); |
|
|
|
} |
|
|
|
} catch (InterruptedException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} finally { |
|
|
|
if (lock.isHeldByCurrentThread()) { |
|
|
|
// 释放锁 |
|
|
|
lock.unlock(); |
|
|
|
} |
|
|
|
}); |
|
|
|
if (execApplyPlan.isEmpty()) { |
|
|
|
log.debug("没有待执行的计划"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
ListRebotBO listRebotBO = new ListRebotBO(); |
|
|
|
listRebotBO.setStatus(RebotStatus.IDLE.getKey()); |
|
|
|
listRebotBO.setPage(1); |
|
|
|
listRebotBO.setSize(100); |
|
|
|
// 只获取空闲的机器人 |
|
|
|
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
log.debug("暂无空闲机器人"); |
|
|
|
// 刷新机器人数据 |
|
|
|
// rebotService.syn(new Rebot()); |
|
|
|
return false; |
|
|
|
} |
|
|
|
listRebotVos.forEach(rebot -> { |
|
|
|
execApplyPlan.forEach(e -> { |
|
|
|
// 该计划满足执行条件 |
|
|
|
ApplyStartBO applyStartBO = new ApplyStartBO(); |
|
|
|
applyStartBO.setRobotUuid(e.getAppId()); |
|
|
|
applyStartBO.setAccountName(rebot.getRobotClientName()); |
|
|
|
applyStartBO.setManualTime(e.getManualTime()); |
|
|
|
//high 高 middle 中 low 低 |
|
|
|
applyStartBO.setPriority("high"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// 如果应用支持参数 |
|
|
|
if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) { |
|
|
|
// 获取参数 |
|
|
|
if (StringUtils.isNotEmpty(e.getPlanParams())) { |
|
|
|
applyStartBO.setPlanParams(e.getPlanParams()); |
|
|
|
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class); |
|
|
|
applyStartBO.setPlanParamsList(paramList); |
|
|
|
} |
|
|
|
} |
|
|
|
String planParams = e.getPlanParams(); |
|
|
|
if (StringUtils.isNotEmpty(planParams)) { |
|
|
|
JSONArray jsonArray = JSON.parseArray(planParams); |
|
|
|
// 直接转换成List |
|
|
|
List<ApplyStartBO.RobotParam> list = jsonArray.toJavaList(ApplyStartBO.RobotParam.class); |
|
|
|
applyStartBO.setPlanParamsList(list); |
|
|
|
} |
|
|
|
try { |
|
|
|
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO); |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
|
applyPlan.setId(e.getId()); |
|
|
|
applyPlan.setUpdateBy("系统修改"); |
|
|
|
applyPlan.setUpdateTime(new Date()); |
|
|
|
applyPlan.setTaskUuid(jobStartVO.getJobUuid()); |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey()); |
|
|
|
// 根据表达式返回下一个执行时间 |
|
|
|
CronExpression cron = new CronExpression(e.getCronExpression()); |
|
|
|
Date nextDate = null; |
|
|
|
if (Objects.isNull(e.getLastExecTime())) { |
|
|
|
nextDate = cron.getNextValidTimeAfter(new Date()); |
|
|
|
} else { |
|
|
|
nextDate = cron.getNextValidTimeAfter(e.getLastExecTime()); |
|
|
|
} |
|
|
|
Date date = new Date(); |
|
|
|
applyPlan.setLastExecTime(date); |
|
|
|
applyPlan.setNextExecTime(nextDate); |
|
|
|
this.updateById(applyPlan); |
|
|
|
Rebot updateRebot = new Rebot(); |
|
|
|
updateRebot.setUpdateBy("系统修改"); |
|
|
|
updateRebot.setUpdateTime(new Date()); |
|
|
|
updateRebot.setStatus(RebotStatus.RUNNING.getKey()); |
|
|
|
if (rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot)) { |
|
|
|
applyPlanList.remove(e); |
|
|
|
} |
|
|
|
} catch (IllegalAccessException | ParseException ex) { |
|
|
|
throw new RuntimeException(ex); |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
public static void main(String[] args) { |
|
|
|
String cronExp="0 0/2 * * * ? "; |
|
|
|
// 解析cron表达式 |
|
|
|
final CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cronExp); |
|
|
|
Date now = new Date(); |
|
|
|
// 任务下次执行时间 |
|
|
|
Date nextTime = cronSequenceGenerator.next(now); |
|
|
|
// 任务下下次执行时间 |
|
|
|
Date nextNextTime = cronSequenceGenerator.next(nextTime); |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
private static Date matchDate(Date date, String cron) throws ParseException { |
|
|
|
CronExpression cronExpression = new CronExpression(cron); |
|
|
|
return cronExpression.getNextValidTimeAfter(date); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@@ -283,7 +355,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
noStatus.add(PlanRunStatus.SKIPPED.getKey()); |
|
|
|
noStatus.add(PlanRunStatus.CANCEL.getKey()); |
|
|
|
// 查询任务运行状态非空非终态并且已经创建的任务 |
|
|
|
List<ApplyPlan> list = this.lambdaQuery().notIn(ApplyPlan::getTaskStatus, noStatus).isNotNull(ApplyPlan::getTaskStatus).orderByAsc(ApplyPlan::getPriority).list(); |
|
|
|
List<ApplyPlan> list = this.lambdaQuery().notIn(ApplyPlan::getTaskStatus, noStatus).isNotNull(ApplyPlan::getTaskUuid).isNotNull(ApplyPlan::getTaskStatus).orderByAsc(ApplyPlan::getPriority).list(); |
|
|
|
if (list.isEmpty()) { |
|
|
|
log.debug("没有需要更新状态的计划任务"); |
|
|
|
return; |
|
|
@@ -300,12 +372,13 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
if (null != jobQueryVO.getEndTime()) { |
|
|
|
updateApplyPlan.setEndTime(jobQueryVO.getEndTime()); |
|
|
|
updateApplyPlan.setStartTime(jobQueryVO.getStartTime()); |
|
|
|
updateApplyPlan.setEndTime(jobQueryVO.getEndTime()); |
|
|
|
long diff = updateApplyPlan.getEndTime().getTime() - updateApplyPlan.getStartTime().getTime(); |
|
|
|
long planTime = diff / (60 * 1000); |
|
|
|
updateApplyPlan.setPlanTime(planTime + ""); |
|
|
|
if (!Objects.isNull(applyPlan.getManualTime())) { |
|
|
|
updateApplyPlan.setTimeSaving((Long.parseLong(applyPlan.getManualTime()) - planTime) + ""); |
|
|
|
if (!Objects.isNull(updateApplyPlan.getEndTime()) && !Objects.isNull(updateApplyPlan.getStartTime())) { |
|
|
|
long diff = updateApplyPlan.getEndTime().getTime() - updateApplyPlan.getStartTime().getTime(); |
|
|
|
long planTime = diff / (60 * 1000); |
|
|
|
updateApplyPlan.setPlanTime(planTime + ""); |
|
|
|
if (!Objects.isNull(applyPlan.getManualTime())) { |
|
|
|
updateApplyPlan.setTimeSaving((Long.parseLong(applyPlan.getManualTime()) - planTime) + ""); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
updateApplyPlan.setId(applyPlan.getId()); |
|
|
@@ -351,86 +424,102 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
public boolean execPlan(ApplyStartBO applyStartBO) throws IllegalAccessException { |
|
|
|
// 先查计划 避免每次直接命中第三方接口 |
|
|
|
Map<Long, List<ApplyPlan>> applyPlanMap = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.ONE.getKey()).isNull(ApplyPlan::getTaskUuid) |
|
|
|
.orderByAsc(ApplyPlan::getPriority).list().stream().collect(Collectors.groupingBy(ApplyPlan::getDeptId)); |
|
|
|
|
|
|
|
// 查询所有待执行的任务 |
|
|
|
if (null == applyStartBO && applyPlanMap.isEmpty()) { |
|
|
|
log.debug("没有等待执行的计划"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
public boolean execPlan(ApplyStartBO applyStartBO, ApplyPlan applyPlan) throws IllegalAccessException { |
|
|
|
RLock lock = redissonClient.getLock("execPlan"); |
|
|
|
int i = 0; |
|
|
|
try { |
|
|
|
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒 |
|
|
|
boolean isLocked = lock.tryLock(2, 20, TimeUnit.SECONDS); |
|
|
|
if (isLocked) { |
|
|
|
// 先查计划 避免每次直接命中第三方接口 |
|
|
|
Map<Long, List<ApplyPlan>> applyPlanMap = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.ONE.getKey()).isNull(ApplyPlan::getTaskUuid) |
|
|
|
.orderByAsc(ApplyPlan::getPriority).list().stream().collect(Collectors.groupingBy(ApplyPlan::getDeptId)); |
|
|
|
|
|
|
|
// 查询所有待执行的任务 |
|
|
|
if (null == applyStartBO && applyPlanMap.isEmpty()) { |
|
|
|
log.debug("没有等待执行的计划"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
ListRebotBO listRebotBO = new ListRebotBO(); |
|
|
|
listRebotBO.setStatus(RebotStatus.IDLE.getKey()); |
|
|
|
listRebotBO.setPage(1); |
|
|
|
listRebotBO.setSize(100); |
|
|
|
// 只获取空闲的机器人 |
|
|
|
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
log.debug("暂无空闲机器人"); |
|
|
|
// 刷新机器人数据 |
|
|
|
ListRebotBO listRebotBO = new ListRebotBO(); |
|
|
|
listRebotBO.setStatus(RebotStatus.IDLE.getKey()); |
|
|
|
listRebotBO.setPage(1); |
|
|
|
listRebotBO.setSize(100); |
|
|
|
// 只获取空闲的机器人 |
|
|
|
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); |
|
|
|
if (listRebotVos.isEmpty()) { |
|
|
|
log.debug("暂无空闲机器人"); |
|
|
|
// 刷新机器人数据 |
|
|
|
// rebotService.syn(new Rebot()); |
|
|
|
return false; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
// 获取每个部门优先级最高的计划 |
|
|
|
List<ApplyPlan> applyPlans = new ArrayList<>(); |
|
|
|
applyPlanMap.forEach((k, v) -> { |
|
|
|
v.sort((Comparator.comparingInt(ApplyPlan::getPriority))); |
|
|
|
applyPlans.add(v.get(0)); |
|
|
|
}); |
|
|
|
if (null == applyStartBO && applyPlans.isEmpty()) { |
|
|
|
log.debug("没有等待执行的计划"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
applyPlans.sort((Comparator.comparingInt(ApplyPlan::getPriority))); |
|
|
|
// 获取每个部门优先级最高的计划 |
|
|
|
List<ApplyPlan> applyPlans = new ArrayList<>(); |
|
|
|
applyPlanMap.forEach((k, v) -> { |
|
|
|
v.sort((Comparator.comparingInt(ApplyPlan::getPriority))); |
|
|
|
applyPlans.add(v.get(0)); |
|
|
|
}); |
|
|
|
if (null == applyStartBO && applyPlans.isEmpty()) { |
|
|
|
log.debug("没有等待执行的计划"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
applyPlans.sort((Comparator.comparingInt(ApplyPlan::getPriority))); |
|
|
|
|
|
|
|
int i = 0; |
|
|
|
for (ListRebotVO listRebotVO : listRebotVos) { |
|
|
|
ApplyPlan applyPlan = null; |
|
|
|
if (applyPlans.isEmpty()) { |
|
|
|
log.debug("没有等待执行的计划!"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (null == applyStartBO) { |
|
|
|
applyPlan = applyPlans.get(0); |
|
|
|
applyStartBO = new ApplyStartBO(); |
|
|
|
applyStartBO.setRobotUuid(applyPlan.getAppId()); |
|
|
|
//high 高 middle 中 low 低 |
|
|
|
applyStartBO.setPriority("high"); |
|
|
|
} else { |
|
|
|
applyPlan = new ApplyPlan(); |
|
|
|
BeanUtils.copyBeanProp(applyPlan, applyStartBO); |
|
|
|
// 运行的应用上一步已给值,此处无需再给 |
|
|
|
} |
|
|
|
applyStartBO.setAccountName(listRebotVO.getRobotClientName()); |
|
|
|
// 如果应用支持参数 |
|
|
|
if (!Objects.isNull(applyPlan.getSupportParam()) && applyPlan.getSupportParam() == 1) { |
|
|
|
if (StringUtils.isNotEmpty(applyPlan.getPlanParams())) { |
|
|
|
applyStartBO.setPlanParams(applyPlan.getPlanParams()); |
|
|
|
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(applyPlan.getPlanParams(), ApplyStartBO.RobotParam.class); |
|
|
|
applyStartBO.setPlanParamsList(paramList); |
|
|
|
for (ListRebotVO listRebotVO : listRebotVos) { |
|
|
|
if (applyPlans.isEmpty() && null == applyStartBO) { |
|
|
|
log.debug("没有等待执行的计划!"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (null == applyStartBO) { |
|
|
|
applyPlan = applyPlans.get(0); |
|
|
|
applyStartBO = new ApplyStartBO(); |
|
|
|
applyStartBO.setRobotUuid(applyPlan.getAppId()); |
|
|
|
//high 高 middle 中 low 低 |
|
|
|
applyStartBO.setPriority("high"); |
|
|
|
} else { |
|
|
|
applyPlan = new ApplyPlan(); |
|
|
|
BeanUtils.copyBeanProp(applyPlan, applyStartBO); |
|
|
|
// 运行的应用上一步已给值,此处无需再给 |
|
|
|
} |
|
|
|
applyStartBO.setAccountName(listRebotVO.getRobotClientName()); |
|
|
|
// 如果应用支持参数 |
|
|
|
if (!Objects.isNull(applyPlan.getSupportParam()) && applyPlan.getSupportParam() == 1) { |
|
|
|
if (StringUtils.isNotEmpty(applyPlan.getPlanParams())) { |
|
|
|
applyStartBO.setPlanParams(applyPlan.getPlanParams()); |
|
|
|
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(applyPlan.getPlanParams(), ApplyStartBO.RobotParam.class); |
|
|
|
applyStartBO.setPlanParamsList(paramList); |
|
|
|
} |
|
|
|
} |
|
|
|
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO); |
|
|
|
ApplyPlan updateApplyPlan = new ApplyPlan(); |
|
|
|
updateApplyPlan.setId(applyPlan.getId()); |
|
|
|
updateApplyPlan.setCreateBy("系统创建"); |
|
|
|
updateApplyPlan.setCreateTime(new Date()); |
|
|
|
updateApplyPlan.setUpdateBy("系统修改"); |
|
|
|
updateApplyPlan.setUpdateTime(new Date()); |
|
|
|
updateApplyPlan.setStartTime(new Date()); |
|
|
|
updateApplyPlan.setTaskUuid(jobStartVO.getJobUuid()); |
|
|
|
updateApplyPlan.setPlanName(applyPlan.getPlanName()); |
|
|
|
updateApplyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey()); |
|
|
|
updateApplyPlan.setRobotName(listRebotVO.getRobotClientName()); |
|
|
|
updateApplyPlan.setManualTime(applyPlan.getManualTime()); |
|
|
|
updateApplyPlan.setDeptId(applyStartBO.getDeptId()); |
|
|
|
applyPlan.setTaskUuid(jobStartVO.getJobUuid()); |
|
|
|
if (this.saveOrUpdate(updateApplyPlan)) { |
|
|
|
if (!applyPlans.isEmpty()) { |
|
|
|
applyPlans.remove(0); |
|
|
|
} |
|
|
|
i++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO); |
|
|
|
ApplyPlan updateApplyPlan = new ApplyPlan(); |
|
|
|
updateApplyPlan.setId(applyPlan.getId()); |
|
|
|
updateApplyPlan.setCreateBy("系统创建"); |
|
|
|
updateApplyPlan.setCreateTime(new Date()); |
|
|
|
updateApplyPlan.setUpdateBy("系统修改"); |
|
|
|
updateApplyPlan.setUpdateTime(new Date()); |
|
|
|
updateApplyPlan.setStartTime(new Date()); |
|
|
|
updateApplyPlan.setTaskUuid(jobStartVO.getJobUuid()); |
|
|
|
updateApplyPlan.setPlanName(applyPlan.getPlanName()); |
|
|
|
updateApplyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey()); |
|
|
|
updateApplyPlan.setRobotName(listRebotVO.getRobotClientName()); |
|
|
|
updateApplyPlan.setManualTime(applyPlan.getManualTime()); |
|
|
|
updateApplyPlan.setDeptId(applyStartBO.getDeptId()); |
|
|
|
if (this.saveOrUpdate(updateApplyPlan)) { |
|
|
|
applyPlans.remove(0); |
|
|
|
i++; |
|
|
|
} catch (InterruptedException e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} finally { |
|
|
|
if (lock.isHeldByCurrentThread()) { |
|
|
|
// 释放锁 |
|
|
|
lock.unlock(); |
|
|
|
} |
|
|
|
} |
|
|
|
return i > 0; |
|
|
@@ -440,71 +529,96 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan |
|
|
|
@Override |
|
|
|
@Transactional |
|
|
|
public boolean save(AddApplyPlanBO addApplyPlanBO) { |
|
|
|
// 指定时间执行 |
|
|
|
if (addApplyPlanBO.getExcType().equals("1") && null == addApplyPlanBO.getExcTime()) { |
|
|
|
throw new ServiceException("指定时间执行时间不能为空"); |
|
|
|
} |
|
|
|
// 表达式执行 |
|
|
|
if (addApplyPlanBO.getExcType().equals("2")) { |
|
|
|
if (null == addApplyPlanBO.getCronExpression()) { |
|
|
|
throw new ServiceException("周期执行表达式不能为空"); |
|
|
|
} |
|
|
|
try { |
|
|
|
// cron 验证表达式是否正确 |
|
|
|
CronExpression.validateExpression(addApplyPlanBO.getCronExpression()); |
|
|
|
} catch (Exception ex) { |
|
|
|
throw new ServiceException("时间表达式错误"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
List<ApplyPlan> applyPlanList = new ArrayList<>(); |
|
|
|
Map<String, List<Apply>> appMap = applyService.lambdaQuery().in(Apply::getAppId, addApplyPlanBO.getAppId()).list().stream().collect(Collectors.groupingBy(Apply::getAppId)); |
|
|
|
// 是否有空闲机器人并且创建计划成功 |
|
|
|
boolean isExec = false; |
|
|
|
AtomicBoolean insert = new AtomicBoolean(false); |
|
|
|
|
|
|
|
addApplyPlanBO.getAppId().forEach(e -> { |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
|
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO); |
|
|
|
Apply apply = appMap.get(e).get(0); |
|
|
|
applyPlan.setAppName(apply.getAppName()); |
|
|
|
applyPlan.setAppId(apply.getAppId()); |
|
|
|
applyPlan.setAppType(apply.getAppType()); |
|
|
|
applyPlan.setAppTypeName(apply.getAppTypeName()); |
|
|
|
applyPlan.setManualTime(apply.getManualTime()); |
|
|
|
if (null != apply.getSupportParam() && apply.getSupportParam() == 1) { |
|
|
|
// 获取参数 每一次执行计划的参数都是独立的 |
|
|
|
List<ApplyStartBO.RobotParam> paramList = resourceLibraryService.lambdaQuery().eq(ResourceLibrary::getAppId, apply.getAppId()).list().stream() |
|
|
|
.map(item -> { |
|
|
|
ApplyStartBO.RobotParam robotParam = new ApplyStartBO.RobotParam(); |
|
|
|
robotParam.setName(item.getResourceName()); |
|
|
|
robotParam.setValue(item.getResourceValue()); |
|
|
|
robotParam.setType(item.getResourceType()); |
|
|
|
return robotParam; |
|
|
|
}).collect(Collectors.toList()); |
|
|
|
if (!paramList.isEmpty()) { |
|
|
|
// json集合转字符串 |
|
|
|
applyPlan.setPlanParams(JSONArray.toJSONString(paramList)); |
|
|
|
} |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
|
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO); |
|
|
|
Apply apply = appMap.get(addApplyPlanBO.getAppId()).get(0); |
|
|
|
applyPlan.setAppName(apply.getAppName()); |
|
|
|
applyPlan.setAppId(apply.getAppId()); |
|
|
|
applyPlan.setAppType(apply.getAppType()); |
|
|
|
applyPlan.setAppTypeName(apply.getAppTypeName()); |
|
|
|
applyPlan.setManualTime(apply.getManualTime()); |
|
|
|
if (null != apply.getSupportParam() && apply.getSupportParam() == 1) { |
|
|
|
// 获取参数 每一次执行计划的参数都是独立的 |
|
|
|
List<ApplyStartBO.RobotParam> paramList = addApplyPlanBO.getResourceLibrarieList().stream() |
|
|
|
.map(item -> { |
|
|
|
ApplyStartBO.RobotParam robotParam = new ApplyStartBO.RobotParam(); |
|
|
|
robotParam.setName(item.getResourceName()); |
|
|
|
robotParam.setValue(item.getResourceValue()); |
|
|
|
robotParam.setType(item.getResourceType()); |
|
|
|
return robotParam; |
|
|
|
}).collect(Collectors.toList()); |
|
|
|
resourceLibraryService.saveOrUpdateBatch(addApplyPlanBO.getResourceLibrarieList()); |
|
|
|
if (paramList.isEmpty()) { |
|
|
|
throw new ServiceException("该应用需要参数,没有检测到参数!"); |
|
|
|
} else { |
|
|
|
// json集合转字符串 |
|
|
|
applyPlan.setPlanParams(JSONArray.toJSONString(paramList)); |
|
|
|
} |
|
|
|
applyPlan.setDeptId(SecurityUtils.getDeptId()); |
|
|
|
|
|
|
|
} |
|
|
|
applyPlan.setDeptId(SecurityUtils.getDeptId()); |
|
|
|
// 立即执行才执行 |
|
|
|
if (addApplyPlanBO.getExcType().equals("0")) { |
|
|
|
// 只指定优先级和应用和人工用时 机器人等下一个阶段判读是否有空闲 |
|
|
|
ApplyStartBO applyStartBO = new ApplyStartBO(); |
|
|
|
try { |
|
|
|
// 只指定优先级和应用和人工用时 机器人等下一个阶段判读是否有空闲 |
|
|
|
ApplyStartBO applyStartBO = new ApplyStartBO(); |
|
|
|
applyStartBO.setRobotUuid(applyPlan.getAppId()); |
|
|
|
//high 高 middle 中 low 低 |
|
|
|
applyStartBO.setPriority("high"); |
|
|
|
applyStartBO.setPlanParams(applyPlan.getPlanParams()); |
|
|
|
applyStartBO.setManualTime(applyPlan.getManualTime()); |
|
|
|
applyStartBO.setPlanName(addApplyPlanBO.getPlanName()); |
|
|
|
insert.set(execPlan(applyStartBO)); |
|
|
|
ApplyPlan retApplyPlan = new ApplyPlan(); |
|
|
|
isExec = execPlan(applyStartBO, retApplyPlan); |
|
|
|
applyPlan.setTaskUuid(retApplyPlan.getTaskUuid()); |
|
|
|
} catch (Exception ex) { |
|
|
|
log.error("分配机器人异常:" + ex.getMessage()); |
|
|
|
} |
|
|
|
if (!insert.get()) { |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.AWAIT_CREATE.getKey()); |
|
|
|
applyPlanList.add(applyPlan); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
if (isExec) { |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey()); |
|
|
|
} else { |
|
|
|
applyPlan.setTaskStatus(PlanRunStatus.AWAIT_CREATE.getKey()); |
|
|
|
} |
|
|
|
applyPlanList.add(applyPlan); |
|
|
|
return this.saveBatch(applyPlanList) || insert.get(); |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public boolean update(AddApplyPlanBO addApplyPlanBO) { |
|
|
|
List<ApplyPlan> applyPlanList = new ArrayList<>(); |
|
|
|
Map<String, List<Apply>> appMap = applyService.lambdaQuery().in(Apply::getAppId, addApplyPlanBO.getAppId()).eq(Apply::getDeptId, SecurityUtils.getDeptId()).list().stream().collect(Collectors.groupingBy(Apply::getAppId)); |
|
|
|
addApplyPlanBO.getAppId().forEach(e -> { |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
|
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO); |
|
|
|
Apply apply = appMap.get(e).get(0); |
|
|
|
applyPlan.setAppName(apply.getAppName()); |
|
|
|
applyPlan.setAppId(apply.getAppId()); |
|
|
|
applyPlan.setAppType(apply.getAppType()); |
|
|
|
applyPlan.setAppTypeName(apply.getAppTypeName()); |
|
|
|
applyPlanList.add(applyPlan); |
|
|
|
}); |
|
|
|
Map<String, List<Apply>> appMap = applyService.lambdaQuery().in(Apply::getAppId, addApplyPlanBO.getAppId()).list().stream().collect(Collectors.groupingBy(Apply::getAppId)); |
|
|
|
ApplyPlan applyPlan = new ApplyPlan(); |
|
|
|
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO); |
|
|
|
Apply apply = appMap.get(addApplyPlanBO.getAppId()).get(0); |
|
|
|
applyPlan.setAppName(apply.getAppName()); |
|
|
|
applyPlan.setAppId(apply.getAppId()); |
|
|
|
applyPlan.setAppType(apply.getAppType()); |
|
|
|
applyPlan.setAppTypeName(apply.getAppTypeName()); |
|
|
|
applyPlanList.add(applyPlan); |
|
|
|
|
|
|
|
return super.updateBatchById(applyPlanList); |
|
|
|
} |
|
|
|