Browse Source

增加回调,完善代码

pull/5/head
lcr 3 months ago
parent
commit
df52ab6e7d
9 changed files with 203 additions and 62 deletions
  1. +1
    -1
      ruoyi-admin/src/main/resources/application-test.yml
  2. +28
    -8
      ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java
  3. +3
    -5
      ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/ApplyStartBO.java
  4. +69
    -0
      ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/YinDaoCallBackBO.java
  5. +9
    -0
      ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java
  6. +47
    -42
      ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java
  7. +23
    -2
      ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyServiceImpl.java
  8. +21
    -4
      ruoyi-business/src/main/java/com/ruoyi/business/util/YinDaoHttpUtils.java
  9. +2
    -0
      ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

+ 1
- 1
ruoyi-admin/src/main/resources/application-test.yml View File

@@ -1,7 +1,7 @@
# 项目相关配置
ruoyi:
# 文件路径 示例( Windows配置D:/poject,Linux配置 /home/poject)
profile: /home/pojectFile
profile: /home/pojectFile/
# Spring配置 数据源配置
spring:
# redis 配置


+ 28
- 8
ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java View File

@@ -4,23 +4,20 @@ import java.util.List;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.business.domain.bo.AddApplyPlanBO;
import com.ruoyi.business.domain.bo.JobQueryBO;
import com.ruoyi.business.domain.bo.YinDaoCallBackBO;
import com.ruoyi.common.utils.bean.BeanUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -39,10 +36,33 @@ import com.ruoyi.common.core.page.TableDataInfo;
@Api(tags = "应用执行计划管理接口")
@RestController
@RequestMapping("/business/ctApplyPlan")
@Slf4j
public class ApplyPlanController extends BaseController {
@Autowired
private IApplyPlanService applyPlanService;


@PostMapping("/callBack/updatePlanStatus")
public void updatePlanStatus(@RequestParam(required = false) String bodyMd5, @RequestParam(required = false) Long timestamp,
@RequestParam(required = false) String sign, @RequestBody String body) {
log.info("fake callback: bodyMd5:{}", bodyMd5);
log.info("fake callback: sign:{}", sign);
log.info("fake callback: timestamp:{}", timestamp);
log.info("fake callback: body:{}", body);

YinDaoCallBackBO yinDaoCallBackBO = JSONObject.parseObject(body, YinDaoCallBackBO.class);
// 获取应用名称 task_uuid
if (applyPlanService.ydCallBack(yinDaoCallBackBO)) {
log.debug("任务id:" + yinDaoCallBackBO.getJobUuid() + "回调成功,回调状态:" + yinDaoCallBackBO.getStatus());
}else{
log.debug("任务id:" + yinDaoCallBackBO.getJobUuid() + "回调失败,回调状态:" + yinDaoCallBackBO.getStatus());
}
//异步处理业务
// new Runable() -> {
// do things
// }
}

/**
* 重新运行
*/


+ 3
- 5
ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/ApplyStartBO.java View File

@@ -65,17 +65,17 @@ public class ApplyStartBO {
@Excel(name = "计划参数")
@ApiModelProperty(name="planParams",value = "计划参数")
private String planParams;

/**
* 应用运行参数
* <p>
*
* 非必填
*/
private List<RobotParam> planParamsList;
private List<RobotParam> params;

/**
* 等待超时时间
*
* @see com.xybot.api.sdk.enums.WaitTimeoutEnum
* <p>
* 非必填,不填,默认为10分钟
*/
@@ -83,8 +83,6 @@ public class ApplyStartBO {

/**
* 优先级
*
* @see com.xybot.api.sdk.enums.PriorityEnum
* 非必填,不填,默认为middle
*/
private String priority;


+ 69
- 0
ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/YinDaoCallBackBO.java View File

@@ -0,0 +1,69 @@
package com.ruoyi.business.domain.bo;

import lombok.Data;

import java.util.List;

/**
* 任务结果数据对象
*/
@Data
public class YinDaoCallBackBO {
/**
* 参考 DataTypeEnum
*/
private String dataType;

/**
* 应用运行uuid
*/
private String jobUuid;
/**
* @see YinDaoCallBackBO
*/
private String status;
/**
* 运行描述
*/
private String msg;
/**
* 应用运行参数
*/
private List<RobotParam> result;
/**
* 任务开始运行的时间
*/
private String startTime;

/**
* 任务结束运行的时间
*/
private String endTime;
/**
* 执行的机器人uuid
*/
private String robotClientUuid;

/**
* 机器人名称
*/
private String robotClientName;
/**
* 应用名
*/
private String robotName;

/**
* 应用运行参数
*/
@Data
public static class RobotParam {
// 参数名
private String name;
// 参数值
private String value;
// 参数类型
private String type;

}
}

+ 9
- 0
ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java View File

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.business.domain.bo.AddApplyPlanBO;
import com.ruoyi.business.domain.bo.ApplyStartBO;
import com.ruoyi.business.domain.bo.JobQueryBO;
import com.ruoyi.business.domain.bo.YinDaoCallBackBO;
import com.ruoyi.business.domain.vo.JobQueryVO;

/**
@@ -16,6 +17,14 @@ import com.ruoyi.business.domain.vo.JobQueryVO;
* @date 2024-06-14
*/
public interface IApplyPlanService extends IService<ApplyPlan> {
/**
* 影刀回调逻辑
*
* @param
* @return
*/
boolean ydCallBack(YinDaoCallBackBO yinDaoCallBackBO) ;


/**
* 重新运行


+ 47
- 42
ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java View File

@@ -30,6 +30,7 @@ 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.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
@@ -66,6 +67,36 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
@Autowired
private RedissonClient redissonClient;

/**
* 影刀回调
*
* @param yinDaoCallBackBO
* @return
*/
@Override
public boolean ydCallBack(YinDaoCallBackBO yinDaoCallBackBO) {
ApplyPlan applyPlan = this.lambdaQuery().eq(ApplyPlan::getTaskUuid, yinDaoCallBackBO.getJobUuid()).one();
applyPlan.setStartTime(DateUtils.parseDate(yinDaoCallBackBO.getStartTime()));
applyPlan.setEndTime(DateUtils.parseDate(yinDaoCallBackBO.getStartTime()));
applyPlan.setTaskStatus(yinDaoCallBackBO.getStatus());
boolean isUpdate = this.updateById(applyPlan);
// 终态
List<String> finalState = new ArrayList<>();
finalState.add(PlanRunStatus.FINISH.getKey());
finalState.add(PlanRunStatus.STOPPED.getKey());
finalState.add(PlanRunStatus.ERROR.getKey());
finalState.add(PlanRunStatus.SKIPPED.getKey());
finalState.add(PlanRunStatus.CANCEL.getKey());
// 如果是终态
if (StringUtils.isNotEmpty(yinDaoCallBackBO.getRobotClientName()) && finalState.contains(yinDaoCallBackBO.getStatus())) {
Rebot rebot = new Rebot();
rebot.setStatus(RebotStatus.IDLE.getKey());
return rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, yinDaoCallBackBO.getRobotClientName()).update(rebot);
} else {
return isUpdate;
}

}

/**
* 重新运行
@@ -106,7 +137,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
RLock lock = redissonClient.getLock("runAppBySetTime");
try {
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS);
boolean isLocked = lock.tryLock(2, 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()) {
@@ -144,7 +175,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
if (StringUtils.isNotEmpty(e.getPlanParams())) {
applyStartBO.setPlanParams(e.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
applyStartBO.setParams(paramList);
}
}
try {
@@ -190,7 +221,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
RLock lock = redissonClient.getLock("runAppByCron");
try {
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS);
boolean isLocked = lock.tryLock(2, 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();
@@ -261,7 +292,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
if (StringUtils.isNotEmpty(e.getPlanParams())) {
applyStartBO.setPlanParams(e.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
applyStartBO.setParams(paramList);
}
}

@@ -278,7 +309,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
// 设置时区,例如设置为中国时区
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai").toString());

final CronExpression cron = new CronExpression(e.getCronExpression());
final CronExpression cron = new CronExpression(e.getCronExpression());
Date nextDate = null;
if (Objects.isNull(e.getLastExecTime())) {
Date date = new Date();
@@ -321,23 +352,6 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
return false;
}

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);
}

private static Date matchDate(Date date, String cron) throws ParseException {
CronExpression cronExpression = new CronExpression(cron);
return cronExpression.getNextValidTimeAfter(date);
}


/**
* 获取应用执行结果
*
@@ -436,7 +450,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
.orderByAsc(ApplyPlan::getPriority).list().stream().collect(Collectors.groupingBy(ApplyPlan::getDeptId));

// 查询所有待执行的任务
if (null == applyStartBO && applyPlanMap.isEmpty()) {
if (applyPlanMap.isEmpty()) {
log.debug("没有等待执行的计划");
return false;
}
@@ -449,8 +463,6 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
// rebotService.syn(new Rebot());
return false;
}

@@ -460,35 +472,29 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
v.sort((Comparator.comparingInt(ApplyPlan::getPriority)));
applyPlans.add(v.get(0));
});
if (null == applyStartBO && applyPlans.isEmpty()) {
if (applyPlans.isEmpty()) {
log.debug("没有等待执行的计划");
return false;
}
applyPlans.sort((Comparator.comparingInt(ApplyPlan::getPriority)));

for (ListRebotVO listRebotVO : listRebotVos) {
if (applyPlans.isEmpty() && null == applyStartBO) {
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);
// 运行的应用上一步已给值,此处无需再给
}
applyPlan = applyPlans.get(0);
applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(applyPlan.getAppId());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");
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);
applyStartBO.setParams(paramList);
}
}
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO);
@@ -507,9 +513,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
updateApplyPlan.setDeptId(applyStartBO.getDeptId());
applyPlan.setTaskUuid(jobStartVO.getJobUuid());
if (this.saveOrUpdate(updateApplyPlan)) {
if (!applyPlans.isEmpty()) {
applyPlans.remove(0);
}
applyPlans.remove(0);
i++;
}
}
@@ -561,6 +565,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
applyPlan.setAppTypeName(apply.getAppTypeName());
applyPlan.setManualTime(apply.getManualTime());
if (null != apply.getSupportParam() && apply.getSupportParam() == 1) {
applyPlan.setSupportParam(apply.getSupportParam());
// 获取参数 每一次执行计划的参数都是独立的
List<ApplyStartBO.RobotParam> paramList = addApplyPlanBO.getResourceLibrarieList().stream()
.map(item -> {


+ 23
- 2
ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyServiceImpl.java View File

@@ -5,7 +5,9 @@ import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.business.domain.ApplyPlan;
import com.ruoyi.business.domain.Rebot;
import com.ruoyi.business.domain.ResourceLibrary;
import com.ruoyi.business.domain.bo.ApplyStartBO;
import com.ruoyi.business.domain.bo.JobQueryBO;
import com.ruoyi.business.domain.bo.ListApplyBO;
@@ -14,6 +16,8 @@ import com.ruoyi.business.domain.vo.JobQueryVO;
import com.ruoyi.business.domain.vo.JobStartVO;
import com.ruoyi.business.domain.vo.ListApplyVO;
import com.ruoyi.business.domain.vo.ListRebotVO;
import com.ruoyi.business.service.IApplyPlanService;
import com.ruoyi.business.service.IResourceLibraryService;
import com.ruoyi.business.util.YinDaoHttpUtils;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.entity.SysDept;
@@ -40,6 +44,13 @@ public class ApplyServiceImpl extends ServiceImpl<ApplyMapper, Apply> implements

@Autowired
private ISysDeptService sysDeptService;

@Autowired
private IResourceLibraryService resourceLibraryService;

@Autowired
private IApplyPlanService applyPlanService;

/**
* 启动应用
*
@@ -98,7 +109,7 @@ public class ApplyServiceImpl extends ServiceImpl<ApplyMapper, Apply> implements
BeanUtils.copyBeanProp(newApply, listRebotVO);
newApply.setAppCreateTime(listRebotVO.getCreateTime());
newApply.setAppUpdateTime(listRebotVO.getUpdateTime());
if(null != sysDepts){
if (null != sysDepts) {
newApply.setDeptId(sysDepts.get(0).getDeptId());
newApply.setDeptName(sysDepts.get(0).getDeptName());
}
@@ -110,11 +121,21 @@ public class ApplyServiceImpl extends ServiceImpl<ApplyMapper, Apply> implements
newApply.setAppCreateTime(listRebotVO.getCreateTime());
newApply.setAppUpdateTime(listRebotVO.getUpdateTime());
newApply.setId(apply.getId());
if(null != sysDepts){
newApply.setSupportParam(listRebotVO.getSupportParam());
if (null != sysDepts) {
newApply.setDeptId(sysDepts.get(0).getDeptId());
newApply.setDeptName(sysDepts.get(0).getDeptName());
}
// 修改应用名称
updateById(newApply);
// 修改参数里应用名称
ResourceLibrary resourceLibrary = new ResourceLibrary();
resourceLibrary.setAppName(listRebotVO.getAppName());
resourceLibraryService.lambdaUpdate().eq(ResourceLibrary::getAppId, apply.getId()).update(resourceLibrary);
// 修改已执行的计划应用名称
ApplyPlan applyPlan = new ApplyPlan();
applyPlan.setAppName(listRebotVO.getAppName());
applyPlanService.lambdaUpdate().eq(ApplyPlan::getAppId, apply.getId()).update(applyPlan);
}
});
}


+ 21
- 4
ruoyi-business/src/main/java/com/ruoyi/business/util/YinDaoHttpUtils.java View File

@@ -2,6 +2,7 @@ package com.ruoyi.business.util;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.ruoyi.business.domain.bo.*;
import com.ruoyi.business.domain.vo.*;
import com.ruoyi.business.yddoman.BaseDTO;
@@ -12,10 +13,8 @@ import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

/**
* 影刀请求工具类
@@ -44,14 +43,28 @@ public class YinDaoHttpUtils {
private static final String QUERY_APP_START_RESULT = REQUEST_PREFIX + "/dispatch/v2/job/query";
// 查询应用运行日志(异常时可以查询原因)
private static final String QUERY_APP_START_RESULT_LOG = REQUEST_PREFIX + "/dispatch/v2/job/list";
// 服务器ip
private static final String SERVER_URL = "http://192.168.10.214:9000";


/**
* 启动应用
*/
public static JobStartVO appStart(ApplyStartBO applyStartBO) throws IllegalAccessException {
if (!Objects.isNull(applyStartBO.getPlanParams())) {
List<ApplyStartBO.RobotParam> robotParams = JSON.parseArray(applyStartBO.getPlanParams(), ApplyStartBO.RobotParam.class);
List<ApplyStartBO.RobotParam> newParamList = robotParams.stream().peek(e -> {
if ("file".equals(e.getType())) {
e.setValue(SERVER_URL + e.getValue());
}
}).collect(Collectors.toList());
applyStartBO.setParams(newParamList);
log.debug("请求的参数:" + applyStartBO.getParams());
}

// 实体类转map
Map<String, Object> data = BeanToMapUtil.convertEntityToMap(applyStartBO);

BaseDTO baseDTO = sendPost(APP_START, data);
return JSON.parseObject(baseDTO.getData().toString(), JobStartVO.class);
}
@@ -185,7 +198,11 @@ public class YinDaoHttpUtils {
headMap.put("Content-Type", "application/json;charset=utf-8");
headMap.put("authorization", "Bearer " + getToken(tokenMap));

log.debug("请求的url:" + url);
log.debug("请求的参数:" + JSONUtil.toJsonStr(map));
log.debug("请求头:" + JSONUtil.toJsonStr(headMap));
String returnStr = HttpClientUtil.postJson(url, headMap, JSONUtil.toJsonStr(map), "utf-8");

if (StringUtils.isEmpty(returnStr)) {
throw new ServiceException("请求影刀接口失败");
}


+ 2
- 0
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java View File

@@ -117,6 +117,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 上传文件
.antMatchers("/common/upload","/dev-api/profile/upload/**").permitAll()
// 影刀回调
.antMatchers("/business/ctApplyPlan/callBack/updatePlanStatus").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and()


Loading…
Cancel
Save