鞍钢多次重试网络异常请求超时的,自动驳回审批,做好异常捕获日志

This commit is contained in:
guoshengxiong 2024-08-30 15:48:48 +08:00
parent 3ce4ef018e
commit e17c8172a4
4 changed files with 116 additions and 85 deletions

View File

@ -1,17 +1,23 @@
package com.wflow.exception; package com.wflow.exception;
import lombok.Getter; import lombok.Data;
/** /**
* @author : willian fu * @author : willian fu
* @date : 2022/6/27 * @date : 2022/6/27
*/ */
@Getter @Data
public class BusinessException extends RuntimeException { public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(String message) { public BusinessException(String message) {
super(message); super(message);
} }
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
} }

View File

@ -1,7 +1,6 @@
package com.wflow.workflow.config.listener; package com.wflow.workflow.config.listener;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.wflow.exception.BusinessException; import com.wflow.exception.BusinessException;
import com.wflow.workflow.bean.dto.NotifyDto; import com.wflow.workflow.bean.dto.NotifyDto;
@ -10,7 +9,6 @@ import com.wflow.workflow.service.NotifyService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.EndEvent; import org.flowable.bpmn.model.EndEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService; import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.event.*; import org.flowable.engine.delegate.event.*;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
@ -88,7 +86,7 @@ public class GlobalTaskListener extends AbstractFlowableEngineEventListener {
if (pass != null) { if (pass != null) {
JSONObject obj = JSONObject.parseObject(pass.toString()); JSONObject obj = JSONObject.parseObject(pass.toString());
if (obj.getJSONObject("data").getInteger("code") != 200) { if (obj.getJSONObject("data").getInteger("code") != 200) {
throw new BusinessException(obj.getJSONObject("data").getString("message")); throw new BusinessException(obj.getJSONObject("data").getInteger("code"), obj.getJSONObject("data").getString("message"));
} }
} }
ProcessInstance instance = runtimeService.createProcessInstanceQuery() ProcessInstance instance = runtimeService.createProcessInstanceQuery()

View File

@ -2,28 +2,24 @@ package com.wflow.workflow.execute;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpException;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wflow.bean.entity.WflowModelHistorys; import com.wflow.bean.entity.WflowModelHistorys;
import com.wflow.mapper.WflowModelHistorysMapper; import com.wflow.mapper.WflowModelHistorysMapper;
import com.wflow.workflow.UELTools; import com.wflow.workflow.UELTools;
import com.wflow.workflow.bean.dto.ProcessInstanceOwnerDto;
import com.wflow.workflow.bean.process.HttpDefinition; import com.wflow.workflow.bean.process.HttpDefinition;
import com.wflow.workflow.bean.process.props.ApprovalProps; import com.wflow.workflow.bean.process.props.ApprovalProps;
import com.wflow.workflow.bean.process.props.RootProps; import com.wflow.workflow.bean.process.props.RootProps;
import com.wflow.workflow.config.WflowGlobalVarDef; import com.wflow.workflow.config.WflowGlobalVarDef;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
/** /**
@ -65,18 +61,35 @@ public class ListenerExecutor {
new ElExecute().execute(object.getString("java"), contextVar, Object.class); new ElExecute().execute(object.getString("java"), contextVar, Object.class);
break; break;
case "HTTP": case "HTTP":
for (int i = 0; i < 3; i++) {
try {
result[0] = new HttpExecute().execute(object.getObject("http", HttpDefinition.class), executorService, Object.class, contextVar); result[0] = new HttpExecute().execute(object.getObject("http", HttpDefinition.class), executorService, Object.class, contextVar);
break; break;
} catch (HttpException e) {
if (i == 2) {
throw e;
}
}
}
break;
} }
}); });
} }
} }
return result[0]; return result[0];
} catch (HttpException e) {
log.warn("流程实例[{}]的[{}]事件触发失败:{}", instanceId, event, e.getMessage());
JSONObject jo = new JSONObject();
JSONObject jo1 = new JSONObject();
jo1.put("code", 5001);
jo1.put("message", "网络超时");
jo.put("data", jo1);
return jo;
} catch (Exception e) { } catch (Exception e) {
log.warn("流程实例[{}]的[{}]事件触发失败:{}", instanceId, event, e.getMessage()); log.warn("流程实例[{}]的[{}]事件触发失败:{}", instanceId, event, e.getMessage());
}
return null; return null;
} }
}
public void doProcessNodeChangeHandler(String event, String instanceId, String defId, String nodeId, String actType) { public void doProcessNodeChangeHandler(String event, String instanceId, String defId, String nodeId, String actType) {
if (!"userTask".equals(actType)) { if (!"userTask".equals(actType)) {

View File

@ -1,4 +1,5 @@
package com.wflow.workflow.service.impl; package com.wflow.workflow.service.impl;
import java.util.Date;
import cn.hutool.cache.CacheUtil; import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache; import cn.hutool.cache.impl.TimedCache;
@ -7,6 +8,8 @@ import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -26,8 +29,10 @@ import com.wflow.workflow.bean.process.props.CcProps;
import com.wflow.workflow.bean.vo.*; import com.wflow.workflow.bean.vo.*;
import com.wflow.workflow.config.WflowGlobalVarDef; import com.wflow.workflow.config.WflowGlobalVarDef;
import com.wflow.workflow.extension.cmd.RecallToHisApprovalNodeCmd; import com.wflow.workflow.extension.cmd.RecallToHisApprovalNodeCmd;
import com.wflow.workflow.service.*; import com.wflow.workflow.service.BusinessDataStorageService;
import com.wflow.workflow.service.FormService; import com.wflow.workflow.service.NotifyService;
import com.wflow.workflow.service.ProcessTaskService;
import com.wflow.workflow.service.UserDeptOrLeaderService;
import com.wflow.workflow.utils.FlowableUtils; import com.wflow.workflow.utils.FlowableUtils;
import com.zhgd.xmgl.tenant.TenantContextHolder; import com.zhgd.xmgl.tenant.TenantContextHolder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -38,24 +43,21 @@ import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.*; import org.flowable.engine.*;
import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity; import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.util.ExecutionGraphUtil; import org.flowable.engine.impl.util.ExecutionGraphUtil;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance; import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance; import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery; import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.task.api.Task; import org.flowable.task.api.Task;
import org.flowable.task.api.TaskInfo;
import org.flowable.task.api.TaskQuery; import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery; import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery;
import org.flowable.variable.api.history.HistoricVariableInstance; import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -67,43 +69,8 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@Service("processTaskService") @Service("processTaskService")
public class ProcessTaskServiceImpl implements ProcessTaskService { public class ProcessTaskServiceImpl implements ProcessTaskService {
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private NotifyService notifyService;
@Autowired
private BusinessDataStorageService businessDataService;
@Autowired
private UserDeptOrLeaderService userDeptOrLeaderService;
@Autowired
private OrgRepositoryService orgRepositoryService;
@Autowired
private HistoryService historyService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ManagementService managementService;
@Autowired
private WflowModelHistorysMapper historysMapper;
@Autowired
private WflowModelsMapper wflowModelsMapper;
//超时缓存数据缓存20秒用来存储审批人防止flowable高频调用 //超时缓存数据缓存20秒用来存储审批人防止flowable高频调用
private static final TimedCache<String, List<String>> taskCache = CacheUtil.newTimedCache(20000); private static final TimedCache<String, List<String>> taskCache = CacheUtil.newTimedCache(20000);
//用来存储正在处理的节点防止并发处理 //用来存储正在处理的节点防止并发处理
private static final Set<String> HANDLER_NODE_LOCK = new ConcurrentHashSet<>(); private static final Set<String> HANDLER_NODE_LOCK = new ConcurrentHashSet<>();
@ -111,6 +78,31 @@ public class ProcessTaskServiceImpl implements ProcessTaskService {
taskCache.schedulePrune(10000); taskCache.schedulePrune(10000);
} }
@Value("${server.port:}")
private String serverPort;
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private NotifyService notifyService;
@Autowired
private BusinessDataStorageService businessDataService;
@Autowired
private UserDeptOrLeaderService userDeptOrLeaderService;
@Autowired
private OrgRepositoryService orgRepositoryService;
@Autowired
private HistoryService historyService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ManagementService managementService;
@Autowired
private WflowModelHistorysMapper historysMapper;
@Autowired
private WflowModelsMapper wflowModelsMapper;
@Override @Override
public Page<ProcessTaskVo> getUserTodoList(Integer pageSize, Integer pageNo, String code, String[] startTimes, String startUser, String key) { public Page<ProcessTaskVo> getUserTodoList(Integer pageSize, Integer pageNo, String code, String[] startTimes, String startUser, String key) {
String userId = UserUtil.getLoginUserId(); String userId = UserUtil.getLoginUserId();
@ -650,7 +642,29 @@ public class ProcessTaskServiceImpl implements ProcessTaskService {
if (StrUtil.isNotBlank(params.getSignature())) { if (StrUtil.isNotBlank(params.getSignature())) {
var.put("sign_" + task.getId(), params.getSignature()); var.put("sign_" + task.getId(), params.getSignature());
} }
try {
taskService.complete(params.getTaskId(), var); taskService.complete(params.getTaskId(), var);
} catch (BusinessException e) {
if (Objects.equals(e.getCode(), 5001)) {
log.error("", e);
String url = "http://127.0.0.1:" + serverPort + "/xmgl/flowExceptionLog/flow/add";
JSONObject jo = new JSONObject();
jo.put("instanceId", task.getProcessInstanceId());
String body = jo.toJSONString();
log.info("工作流提交网络超时插入日志的url{}body{}",url,body);
String result2 = HttpRequest.post(url)
.body(body)//表单内容
.timeout(20000)//超时毫秒
.execute().body();
log.info("工作流提交网络超时插入日志的返回结果:{}", result2);
//网络超时自动驳回
params.setAction(ProcessHandlerParamsVo.Action.refuse);
var.put("approve_" + task.getId(), params.getAction());
taskService.complete(params.getTaskId(), var);
} else {
throw e;
}
}
} }
private void doRecallTask(Task task, String userId, ProcessHandlerParamsVo params) { private void doRecallTask(Task task, String userId, ProcessHandlerParamsVo params) {