Merge branch 'feature/REQ-2090' into 1.3.1-SNAPSHOT

This commit is contained in:
wangli 2024-04-03 11:54:53 +08:00
commit 3b5425c3d1
12 changed files with 233 additions and 7 deletions

View File

@ -0,0 +1,48 @@
package cn.axzo.workflow.core.common.event;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
/**
* Api Log Event 事件对象
*
* @author wangli
* @since 2024/4/3 10:35
*/
@Slf4j
public class ApiLogEvent extends ApplicationEvent {
private String uniqueId;
private String apiUrl;
private Object requestBody;
private Object responseBody;
private Double takeTime;
public ApiLogEvent(String uniqueId, String apiUrl, Object requestBody, Object responseBody, Double takeTime) {
super(uniqueId);
this.apiUrl = apiUrl;
this.requestBody = requestBody;
this.responseBody = responseBody;
this.takeTime = takeTime;
}
public String getUniqueId() {
return uniqueId;
}
public String getApiUrl() {
return apiUrl;
}
public Object getRequestBody() {
return requestBody;
}
public Object getResponseBody() {
return responseBody;
}
public Double getTakeTime() {
return takeTime;
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.workflow.core.common.event;
import cn.axzo.workflow.core.repository.entity.ExtAxApiLog;
import cn.axzo.workflow.core.service.ExtAxApiLogService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* Api Log 记录表操作监听
*
* @author wangli
* @since 2024/4/3 10:37
*/
@Component
@Slf4j
public class ApiLogListener implements ApplicationListener<ApiLogEvent> {
@Resource
private ExtAxApiLogService apiLogService;
@Override
@Async
public void onApplicationEvent(ApiLogEvent event) {
ExtAxApiLog apiLog = new ExtAxApiLog();
apiLog.setUniqueId(event.getUniqueId());
apiLog.setApiUrl(event.getApiUrl());
apiLog.setRequestBody(JSON.toJSONString(event.getRequestBody()));
apiLog.setResponseBody(JSON.toJSONString(event.getResponseBody()));
apiLog.setTakeTime(event.getTakeTime());
apiLogService.insert(apiLog);
}
}

View File

@ -342,6 +342,7 @@ public class CustomTaskHelper {
}
return new ArrayList<>(delegateAssigners.stream()
.filter(i -> StringUtils.hasText(i.getPersonId()))
.filter(i -> !Objects.equals(i.getPersonId(), "null"))
.collect(Collectors.toMap(BpmnTaskDelegateAssigner::getPersonId, Function.identity(), (s, t) -> s))
.values());
}

View File

@ -0,0 +1,46 @@
package cn.axzo.workflow.core.repository.entity;
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* API 请求日志记录
*
* @author wangli
* @since 2024/4/3 10:16
*/
@EqualsAndHashCode(callSuper = true)
@TableName(value = "ext_ax_api_log", autoResultMap = true)
@Data
@ToString(callSuper = true)
public class ExtAxApiLog extends BaseEntity<ExtAxDict> {
/**
* 唯一标识
*/
private String uniqueId;
/**
* 请求 API
*/
private String apiUrl;
/**
* 请求参数
*/
private String requestBody;
/**
* 响应参数
*/
private String responseBody;
/**
* 执行耗时 (s)
*/
private Double takeTime;
}

View File

@ -0,0 +1,8 @@
package cn.axzo.workflow.core.repository.mapper;
import cn.axzo.workflow.core.repository.entity.ExtAxApiLog;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ExtAxApiLogMapper extends BaseMapperX<ExtAxApiLog> {
}

View File

@ -0,0 +1,13 @@
package cn.axzo.workflow.core.service;
import cn.axzo.workflow.core.repository.entity.ExtAxApiLog;
/**
* Api Log 表操作服务
*
* @author wangli
* @since 2024/4/3 10:40
*/
public interface ExtAxApiLogService {
Long insert(ExtAxApiLog apiLog);
}

View File

@ -0,0 +1,28 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.workflow.core.repository.entity.ExtAxApiLog;
import cn.axzo.workflow.core.repository.mapper.ExtAxApiLogMapper;
import cn.axzo.workflow.core.service.ExtAxApiLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* Api Log 表操服务实现
*
* @author wangli
* @since 2024/4/3 10:41
*/
@Service
@Slf4j
public class ExtAxApiLogServiceImpl implements ExtAxApiLogService {
@Resource
private ExtAxApiLogMapper apiLogMapper;
@Override
public Long insert(ExtAxApiLog apiLog) {
apiLogMapper.insert(apiLog);
return apiLog.getId();
}
}

View File

@ -0,0 +1,14 @@
DROP TABLE IF EXISTS `EXT_AX_API_LOG`;
CREATE TABLE IF NOT EXISTS EXT_AX_API_LOG
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`unique_id` varchar(100) NOT NULL DEFAULT '' COMMENT '唯一标识',
`api_url` varchar(2000) NOT NULL DEFAULT '' COMMENT '请求 API',
`request_body` text NOT NULL COMMENT '请求参数',
`response_body` text NOT NULL COMMENT '响应参数',
`take_time` varchar(100) NOT NULL DEFAULT '' COMMENT '执行耗时',
`create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_delete` bigint NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE = InnoDB COMMENT 'API 执行耗时记录表';

View File

@ -5,6 +5,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@ -12,6 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@ComponentScan({"cn.axzo.workflow", "cn.axzo.maokai"})
@SpringBootApplication(exclude = RabbitAutoConfiguration.class)
@EnableTransactionManagement
@EnableAsync
public class WorkflowEnginApplication {
public static void main(String[] args) {

View File

@ -1,7 +1,9 @@
package cn.axzo.workflow.server.common.aspectj;
import cn.axzo.workflow.core.common.event.ApiLogEvent;
import cn.axzo.workflow.server.common.annotation.EnvConfig;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.hutool.core.util.IdUtil;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
@ -11,9 +13,11 @@ import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import javax.annotation.Resource;
import java.util.Arrays;
/**
@ -30,6 +34,10 @@ public class ErrorReportAspect {
private String profile;
@Value("${workflow.sendDingTalk:true}")
private Boolean sendDingTalk;
@Value("${workflow.api.timeout:10}")
private Long apiTimeout;
@Resource
private ApplicationEventPublisher applicationEventPublisher;
/**
* 处理完请求后执行
@ -44,6 +52,9 @@ public class ErrorReportAspect {
Object result = joinPoint.proceed();
watch.stop();
log.info("StopWatch '" + watch.getLastTaskName() + "': running time = " + watch.getTotalTimeSeconds() + " s");
ApiLogEvent event = new ApiLogEvent(IdUtil.fastSimpleUUID(), signature.toShortString(), joinPoint.getArgs(), result, watch.getTotalTimeSeconds());
applicationEventPublisher.publishEvent(event);
return result;
}

View File

@ -22,9 +22,7 @@ public class DingTalkUtils {
@SneakyThrows
public static void sendDingTalk(String profile, String title, Object req, Throwable throwable) {
DingTalkClient client = new DefaultDingTalkClient(dingtalk_robot_webhook);
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle("Notice " + title + ", Env: " + profile);
@ -33,14 +31,12 @@ public class DingTalkUtils {
"> ###### 异常信息: " + JSON.toJSONString(Objects.isNull(throwable.getCause()) ? throwable.getMessage() :
throwable.getCause().getMessage()) + " \n");
request.setMarkdown(markdown);
OapiRobotSendResponse response = client.execute(request);
sendDingTalk(request);
}
@SneakyThrows
public static void sendDingTalkForSlowUrl(String profile, Double time, String apiUrl, Object requestParam, Object responseBody) {
DingTalkClient client = new DefaultDingTalkClient(dingtalk_robot_webhook);
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle("Notice 请求二方接口慢 URL, Env: " + profile);
@ -49,6 +45,25 @@ public class DingTalkUtils {
"> 请求参数: " + JSON.toJSONString(requestParam) + "\n\n" +
"> ###### 结果: " + JSON.toJSONString(responseBody) + " \n");
request.setMarkdown(markdown);
sendDingTalk(request);
}
@SneakyThrows
public static void sendDingTalkForSlowApi(String profile, Double time, String apiUrl, String uniqueId) {
OapiRobotSendRequest request = new OapiRobotSendRequest();
request.setMsgtype("markdown");
OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
markdown.setTitle("Notice API 处理耗时报告, Env: " + profile);
markdown.setText("#### [" + profile + "]API 处理耗时报告\n" +
"> 接口地址: " + apiUrl + ",经过了" + time + "\n\n" +
"> ###### 标识: " + uniqueId + " \n");
request.setMarkdown(markdown);
sendDingTalk(request);
}
@SneakyThrows
private static void sendDingTalk(OapiRobotSendRequest request) {
DingTalkClient client = new DefaultDingTalkClient(dingtalk_robot_webhook);
OapiRobotSendResponse response = client.execute(request);
}
}

View File

@ -87,8 +87,11 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
return invokeService(flowElement, execution, scopeDto);
} catch (Throwable t) {
if (throwException) {
throw new WorkflowEngineException(ENGINE_USER_TASK_CALC_ERROR, flowElement.getId(),
this.getType(), t.getMessage());
if (!(t instanceof WorkflowEngineException)) {
throw new WorkflowEngineException(ENGINE_USER_TASK_CALC_ERROR, flowElement.getId(),
this.getType(), t.getMessage());
}
throw t;
} else {
return Collections.emptyList();
}