反序列化问题。
This commit is contained in:
parent
a3ea410f5b
commit
dd07b181ce
@ -1,12 +1,11 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.config;
|
package com.qqchen.deploy.backend.workflow.config;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.workflow.listener.FlowableEventDispatcher;
|
import com.qqchen.deploy.backend.workflow.listener.event.FlowableEventDispatcher;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.flowable.spring.SpringProcessEngineConfiguration;
|
import org.flowable.spring.SpringProcessEngineConfiguration;
|
||||||
import org.flowable.spring.boot.EngineConfigurationConfigurer;
|
import org.flowable.spring.boot.EngineConfigurationConfigurer;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -32,7 +32,7 @@ public class WorkflowNodeDefinitionDTO extends BaseDTO {
|
|||||||
|
|
||||||
@Schema(description = "X6图形配置JSON")
|
@Schema(description = "X6图形配置JSON")
|
||||||
private JsonNode graphConfig;
|
private JsonNode graphConfig;
|
||||||
|
|
||||||
@Schema(description = "排序号")
|
@Schema(description = "排序号")
|
||||||
private Integer orderNum;
|
private Integer orderNum;
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.listener;
|
package com.qqchen.deploy.backend.workflow.listener.event;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.workflow.listener.handler.IFlowableEventHandler;
|
import com.qqchen.deploy.backend.workflow.listener.event.handler.IFlowableEventHandler;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
|
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
|
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
|
||||||
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.RuntimeService;
|
||||||
import org.flowable.job.service.impl.persistence.entity.JobEntityImpl;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -14,8 +12,6 @@ import jakarta.annotation.Resource;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.ASYNC_CONTINUATION;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class FlowableEventDispatcher implements FlowableEventListener {
|
public class FlowableEventDispatcher implements FlowableEventListener {
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.listener.handler;
|
package com.qqchen.deploy.backend.workflow.listener.event.handler;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
|
||||||
import com.qqchen.deploy.backend.workflow.event.WorkflowNodeInstanceStatusChangeEvent;
|
import com.qqchen.deploy.backend.workflow.event.WorkflowNodeInstanceStatusChangeEvent;
|
||||||
@ -13,7 +13,6 @@ import jakarta.annotation.Resource;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX;
|
import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX;
|
||||||
@ -38,8 +37,6 @@ public class ActivityEventHandler implements IFlowableEventHandler {
|
|||||||
if (!(event instanceof FlowableActivityEvent activityEvent)) {
|
if (!(event instanceof FlowableActivityEvent activityEvent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// log.info("Processing Flowable event: {}, id: {}, name:{}", eventType, activityEvent.getActivityId(), activityEvent.getActivityName());
|
|
||||||
|
|
||||||
List<String> ignoredList = Arrays.asList(BOUNDARY_EVENT_ERROR_PREFIX, END_EVENT_ERROR_PREFIX);
|
List<String> ignoredList = Arrays.asList(BOUNDARY_EVENT_ERROR_PREFIX, END_EVENT_ERROR_PREFIX);
|
||||||
|
|
||||||
boolean ignored = ignoredList.stream().anyMatch(v -> activityEvent.getActivityId().contains(v));
|
boolean ignored = ignoredList.stream().anyMatch(v -> activityEvent.getActivityId().contains(v));
|
||||||
@ -56,8 +53,7 @@ public class ActivityEventHandler implements IFlowableEventHandler {
|
|||||||
.nodeName(StringUtils.isEmpty(activityEvent.getActivityName()) ? activityEvent.getActivityId() : activityEvent.getActivityName())
|
.nodeName(StringUtils.isEmpty(activityEvent.getActivityName()) ? activityEvent.getActivityId() : activityEvent.getActivityName())
|
||||||
.nodeType(activityEvent.getActivityType())
|
.nodeType(activityEvent.getActivityType())
|
||||||
.status(status)
|
.status(status)
|
||||||
.startTime(status == WorkflowNodeInstanceStatusEnums.RUNNING ? LocalDateTime.now() : null)
|
.endTime(LocalDateTime.now())
|
||||||
.endTime(status.isFinalState() ? LocalDateTime.now() : null)
|
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -65,8 +61,6 @@ public class ActivityEventHandler implements IFlowableEventHandler {
|
|||||||
|
|
||||||
private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) {
|
private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) {
|
||||||
return switch (eventType) {
|
return switch (eventType) {
|
||||||
case "ACTIVITY_STARTED" -> WorkflowNodeInstanceStatusEnums.RUNNING;
|
|
||||||
case "ACTIVITY_COMPLETED" -> WorkflowNodeInstanceStatusEnums.COMPLETED;
|
|
||||||
case "ACTIVITY_CANCELLED" -> WorkflowNodeInstanceStatusEnums.TERMINATED;
|
case "ACTIVITY_CANCELLED" -> WorkflowNodeInstanceStatusEnums.TERMINATED;
|
||||||
case "ACTIVITY_ERROR_RECEIVED" -> WorkflowNodeInstanceStatusEnums.FAILED;
|
case "ACTIVITY_ERROR_RECEIVED" -> WorkflowNodeInstanceStatusEnums.FAILED;
|
||||||
default -> null;
|
default -> null;
|
||||||
@ -1,9 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.listener.handler;
|
package com.qqchen.deploy.backend.workflow.listener.event.handler;
|
||||||
|
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flowable事件处理器接口
|
* Flowable事件处理器接口
|
||||||
*/
|
*/
|
||||||
@ -1,10 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.listener.handler;
|
package com.qqchen.deploy.backend.workflow.listener.event.handler;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.json.JSON;
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
|
||||||
import com.qqchen.deploy.backend.workflow.event.WorkflowNodeInstanceStatusChangeEvent;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
|
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
|
||||||
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
||||||
@ -14,10 +11,6 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class JobEventHandler implements IFlowableEventHandler {
|
public class JobEventHandler implements IFlowableEventHandler {
|
||||||
@ -36,9 +29,9 @@ public class JobEventHandler implements IFlowableEventHandler {
|
|||||||
if (!(event instanceof FlowableEngineEntityEvent entityEvent)) {
|
if (!(event instanceof FlowableEngineEntityEvent entityEvent)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log.info("Processing job event: {}, jobType: {}", eventType, entityEvent.getType());
|
//log.info("Processing job event: {}, jobType: {}", eventType, entityEvent.getType());
|
||||||
JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity();
|
JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity();
|
||||||
log.info("Processing job event: {}", JSONUtil.toJsonStr(job));
|
//log.info("Processing job event: {}", JSONUtil.toJsonStr(job));
|
||||||
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
|
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
// publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
// publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.listener.handler;
|
package com.qqchen.deploy.backend.workflow.listener.event.handler;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
|
||||||
@ -14,9 +14,6 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
public class ProcessEventHandler implements IFlowableEventHandler {
|
public class ProcessEventHandler implements IFlowableEventHandler {
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.listener.execution;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
|
||||||
|
import com.qqchen.deploy.backend.workflow.event.WorkflowNodeInstanceStatusChangeEvent;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.delegate.ExecutionListener;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component("globalNodeExecutionListener")
|
||||||
|
public class GlobalExecutionListener implements ExecutionListener {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notify(DelegateExecution execution) {
|
||||||
|
// 获取当前节点信息
|
||||||
|
FlowElement flowElement = execution.getCurrentFlowElement();
|
||||||
|
String eventName = execution.getEventName();
|
||||||
|
String processInstanceId = execution.getProcessInstanceId();
|
||||||
|
String executionId = execution.getId();
|
||||||
|
String nodeId = execution.getCurrentActivityId();
|
||||||
|
String nodeName = flowElement.getName();
|
||||||
|
String nodeType = flowElement.getClass().getSimpleName();
|
||||||
|
log.debug("Node execution event: {}, processInstanceId: {}, nodeId: {}, nodeType: {}, nodeName:{}", eventName, processInstanceId, nodeId, nodeType, nodeName);
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
WorkflowNodeInstanceStatusEnums status = null;
|
||||||
|
LocalDateTime startTime = null;
|
||||||
|
LocalDateTime endTime = null;
|
||||||
|
switch (eventName) {
|
||||||
|
case ExecutionListener.EVENTNAME_START:
|
||||||
|
status = WorkflowNodeInstanceStatusEnums.RUNNING;
|
||||||
|
startTime = now;
|
||||||
|
break;
|
||||||
|
case ExecutionListener.EVENTNAME_END:
|
||||||
|
status = WorkflowNodeInstanceStatusEnums.COMPLETED;
|
||||||
|
endTime = now;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("Unexpected event type: {}", eventName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eventPublisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
||||||
|
.processInstanceId(processInstanceId)
|
||||||
|
.executionId(executionId)
|
||||||
|
.nodeId(nodeId)
|
||||||
|
.nodeName(nodeName)
|
||||||
|
.nodeType(nodeType)
|
||||||
|
.status(status)
|
||||||
|
.startTime(startTime)
|
||||||
|
.endTime(endTime)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -118,26 +119,37 @@ public class BpmnConverter {
|
|||||||
* @param process 当前流程
|
* @param process 当前流程
|
||||||
*/
|
*/
|
||||||
private void configureFlowElement(FlowElement element, WorkflowDefinitionNode node, Process process) {
|
private void configureFlowElement(FlowElement element, WorkflowDefinitionNode node, Process process) {
|
||||||
|
// 为所有节点添加执行监听器
|
||||||
|
Map<String, List<ExtensionElement>> extensionElements = new HashMap<>();
|
||||||
|
List<ExtensionElement> executionListeners = new ArrayList<>();
|
||||||
|
|
||||||
|
// 开始事件监听器
|
||||||
|
ExtensionElement startListener = createExecutionListener("start", "${globalNodeExecutionListener}");
|
||||||
|
executionListeners.add(startListener);
|
||||||
|
|
||||||
|
// 结束事件监听器
|
||||||
|
ExtensionElement endListener = createExecutionListener("end", "${globalNodeExecutionListener}");
|
||||||
|
executionListeners.add(endListener);
|
||||||
|
|
||||||
|
extensionElements.put("executionListener", executionListeners);
|
||||||
|
|
||||||
|
// 根据节点类型进行特定配置
|
||||||
if (element instanceof ServiceTask) {
|
if (element instanceof ServiceTask) {
|
||||||
ServiceTask serviceTask = (ServiceTask) element;
|
ServiceTask serviceTask = (ServiceTask) element;
|
||||||
// 设置委托表达式
|
// 设置委托表达式
|
||||||
String delegate = (String) node.getConfig().get("delegate");
|
String delegate = (String) node.getConfig().get("delegate");
|
||||||
// serviceTask.setImplementationType("class");
|
|
||||||
// serviceTask.setImplementation("com.qqchen.deploy.backend.workflow.delegate.ShellTaskDelegate");
|
|
||||||
serviceTask.setImplementationType("delegateExpression");
|
serviceTask.setImplementationType("delegateExpression");
|
||||||
serviceTask.setImplementation(delegate);
|
serviceTask.setImplementation(delegate);
|
||||||
// serviceTask.setAsynchronous(false); // 设置为异步执行
|
|
||||||
|
|
||||||
// 设置失败时不重试
|
// 配置重试策略
|
||||||
ExtensionElement failedJobRetryTimeCycle = new ExtensionElement();
|
ExtensionElement retryConfig = new ExtensionElement();
|
||||||
failedJobRetryTimeCycle.setName("failedJobRetryTimeCycle");
|
retryConfig.setName("failedJobRetryTimeCycle");
|
||||||
failedJobRetryTimeCycle.setNamespace("http://flowable.org/bpmn");
|
retryConfig.setNamespace("http://flowable.org/bpmn");
|
||||||
failedJobRetryTimeCycle.setNamespacePrefix("flowable");
|
retryConfig.setNamespacePrefix("flowable");
|
||||||
failedJobRetryTimeCycle.setElementText("R0/PT1H"); // 设置为0次重试
|
retryConfig.setElementText("R0/PT1H"); // 设置为0次重试
|
||||||
|
|
||||||
Map<String, List<ExtensionElement>> extensionElements = new HashMap<>();
|
|
||||||
List<ExtensionElement> retryElements = new ArrayList<>();
|
List<ExtensionElement> retryElements = new ArrayList<>();
|
||||||
retryElements.add(failedJobRetryTimeCycle);
|
retryElements.add(retryConfig);
|
||||||
extensionElements.put("failedJobRetryTimeCycle", retryElements);
|
extensionElements.put("failedJobRetryTimeCycle", retryElements);
|
||||||
|
|
||||||
// 添加字段注入
|
// 添加字段注入
|
||||||
@ -150,16 +162,53 @@ public class BpmnConverter {
|
|||||||
fieldExtensions.add(fieldExtension);
|
fieldExtensions.add(fieldExtension);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 设置到服务任务
|
||||||
serviceTask.setFieldExtensions(fieldExtensions);
|
serviceTask.setFieldExtensions(fieldExtensions);
|
||||||
serviceTask.setExtensionElements(extensionElements);
|
serviceTask.setExtensionElements(extensionElements);
|
||||||
|
|
||||||
// 添加错误边界事件
|
// 添加错误边界事件
|
||||||
addErrorBoundaryEventHandler(process, serviceTask);
|
addErrorBoundaryEventHandler(process, serviceTask);
|
||||||
|
} else if (element instanceof StartEvent || element instanceof EndEvent) {
|
||||||
|
// 为开始节点和结束节点设置监听器
|
||||||
|
element.setExtensionElements(extensionElements);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为服务任务添加错误边界事件和错误结束事件
|
* 创建执行监听器扩展元素
|
||||||
|
*
|
||||||
|
* @param event 事件类型(start/end)
|
||||||
|
* @param delegateExpression 委托表达式
|
||||||
|
* @return 配置好的监听器扩展元素
|
||||||
|
*/
|
||||||
|
private ExtensionElement createExecutionListener(String event, String delegateExpression) {
|
||||||
|
ExtensionElement listener = new ExtensionElement();
|
||||||
|
listener.setName("executionListener");
|
||||||
|
listener.setNamespace("http://flowable.org/bpmn");
|
||||||
|
listener.setNamespacePrefix("flowable");
|
||||||
|
|
||||||
|
// 设置事件属性
|
||||||
|
ExtensionAttribute eventAttr = new ExtensionAttribute();
|
||||||
|
eventAttr.setName("event");
|
||||||
|
eventAttr.setValue(event);
|
||||||
|
|
||||||
|
// 设置委托表达式属性
|
||||||
|
ExtensionAttribute delegateAttr = new ExtensionAttribute();
|
||||||
|
delegateAttr.setName("delegateExpression");
|
||||||
|
delegateAttr.setValue(delegateExpression);
|
||||||
|
|
||||||
|
// 添加属性到监听器
|
||||||
|
Map<String, List<ExtensionAttribute>> attributes = new HashMap<>();
|
||||||
|
attributes.put("event", Collections.singletonList(eventAttr));
|
||||||
|
attributes.put("delegateExpression", Collections.singletonList(delegateAttr));
|
||||||
|
listener.setAttributes(attributes);
|
||||||
|
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为服务任务添加错误边界事件和错误结<EFBFBD><EFBFBD><EFBFBD>事件
|
||||||
* 当服务任务执行失败时,会触发错误边界事件,并流转到错误结束事件
|
* 当服务任务执行失败时,会触发错误边界事件,并流转到错误结束事件
|
||||||
*
|
*
|
||||||
* @param process BPMN流程定义
|
* @param process BPMN流程定义
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user