反序列化问题。
This commit is contained in:
parent
88b5588531
commit
92471a8ce2
@ -0,0 +1,11 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.constants;
|
||||||
|
|
||||||
|
public interface WorkFlowConstants {
|
||||||
|
|
||||||
|
public static final String WORKFLOW_EXEC_ERROR = "WORKFLOW_EXEC_ERROR";
|
||||||
|
|
||||||
|
public static final String BOUNDARY_EVENT_ERROR_PREFIX = "BOUNDARY_EVENT_ERROR_";
|
||||||
|
public static final String END_EVENT_ERROR_PREFIX = "END_EVENT_ERROR_";
|
||||||
|
public static final String SEQUENCE_FLOW_ERROR_PREFIX = "SEQUENCE_FLOW_ERROR_";
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,11 +1,13 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.delegate;
|
package com.qqchen.deploy.backend.workflow.delegate;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants;
|
||||||
import com.qqchen.deploy.backend.workflow.event.ShellLogEvent;
|
import com.qqchen.deploy.backend.workflow.event.ShellLogEvent;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeLogTypeEnums;
|
import com.qqchen.deploy.backend.workflow.enums.NodeLogTypeEnums;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.common.engine.api.FlowableException;
|
import org.flowable.common.engine.api.FlowableException;
|
||||||
import org.flowable.engine.RuntimeService;
|
import org.flowable.engine.RuntimeService;
|
||||||
import org.flowable.engine.ManagementService;
|
import org.flowable.engine.ManagementService;
|
||||||
|
import org.flowable.engine.delegate.BpmnError;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.delegate.JavaDelegate;
|
import org.flowable.engine.delegate.JavaDelegate;
|
||||||
import org.flowable.common.engine.api.delegate.Expression;
|
import org.flowable.common.engine.api.delegate.Expression;
|
||||||
@ -78,8 +80,7 @@ public class ShellTaskDelegate implements JavaDelegate {
|
|||||||
|
|
||||||
if (scriptValue == null) {
|
if (scriptValue == null) {
|
||||||
log.error("脚本内容为空,执行失败");
|
log.error("脚本内容为空,执行失败");
|
||||||
handleFailure(execution, "Script is required but not provided");
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, "Script is required but not provided");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -169,8 +170,7 @@ public class ShellTaskDelegate implements JavaDelegate {
|
|||||||
if (exitCode != 0) {
|
if (exitCode != 0) {
|
||||||
log.error("Shell脚本执行失败,退出码: {}", exitCode);
|
log.error("Shell脚本执行失败,退出码: {}", exitCode);
|
||||||
log.error("错误输出: {}", finalError);
|
log.error("错误输出: {}", finalError);
|
||||||
handleFailure(execution, "Shell脚本执行失败,退出码: " + exitCode);
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, "Shell脚本执行失败,退出码: " + exitCode);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Shell脚本执行成功");
|
log.info("Shell脚本执行成功");
|
||||||
@ -178,14 +178,7 @@ public class ShellTaskDelegate implements JavaDelegate {
|
|||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Shell脚本执行失败", e);
|
log.error("Shell脚本执行失败", e);
|
||||||
// Job job = managementService.createJobQuery()
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, "Shell脚本执行失败");
|
||||||
// .processInstanceId(execution.getProcessInstanceId())
|
|
||||||
// .singleResult();
|
|
||||||
// if (job != null) {
|
|
||||||
// // 设置重试次数为 0,这样就不会进入死信队列
|
|
||||||
// managementService.setJobRetries(job.getId(), 0);
|
|
||||||
// }
|
|
||||||
throw new FlowableException("脚本执行失败。");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,25 +210,4 @@ public class ShellTaskDelegate implements JavaDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void handleFailure(DelegateExecution execution, String errorMessage) {
|
|
||||||
String processInstanceId = execution.getProcessInstanceId();
|
|
||||||
|
|
||||||
// 获取当前 Job
|
|
||||||
Job job = managementService.createJobQuery()
|
|
||||||
.processInstanceId(execution.getProcessInstanceId())
|
|
||||||
.singleResult();
|
|
||||||
if (job != null) {
|
|
||||||
// 设置重试次数为 0,这样就不会进入死信队列
|
|
||||||
managementService.setJobRetries(job.getId(), 0);
|
|
||||||
}
|
|
||||||
throw new FlowableException(errorMessage);
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// 直接终止流程实例
|
|
||||||
// runtimeService.deleteProcessInstance(processInstanceId, errorMessage);
|
|
||||||
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// log.error("处理Shell任务失败时出现错误,流程实例: {}", processInstanceId, e);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@ public class ActivityEventHandler implements IFlowableEventHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(FlowableEvent event) {
|
public void handle(FlowableEvent event) {
|
||||||
String eventType = event.getType().name();
|
String eventType = event.getType().name();
|
||||||
log.info("Processing activity event: {}", eventType);
|
// log.info("Processing activity event: {}", eventType);
|
||||||
|
|
||||||
if (!(event instanceof FlowableActivityEvent activityEvent)) {
|
if (!(event instanceof FlowableActivityEvent activityEvent)) {
|
||||||
return;
|
return;
|
||||||
@ -35,17 +35,17 @@ public class ActivityEventHandler implements IFlowableEventHandler {
|
|||||||
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
|
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
|
||||||
|
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
// publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
||||||
.processInstanceId(activityEvent.getProcessInstanceId())
|
// .processInstanceId(activityEvent.getProcessInstanceId())
|
||||||
.executionId(activityEvent.getExecutionId())
|
// .executionId(activityEvent.getExecutionId())
|
||||||
.nodeId(activityEvent.getActivityId())
|
// .nodeId(activityEvent.getActivityId())
|
||||||
.nodeName(activityEvent.getActivityName())
|
// .nodeName(activityEvent.getActivityName())
|
||||||
.nodeType(activityEvent.getActivityType())
|
// .nodeType(activityEvent.getActivityType())
|
||||||
.status(status)
|
// .status(status)
|
||||||
.startTime(status == WorkflowNodeInstanceStatusEnums.RUNNING ? LocalDateTime.now() : null)
|
// .startTime(status == WorkflowNodeInstanceStatusEnums.RUNNING ? LocalDateTime.now() : null)
|
||||||
.endTime(status.isFinalState() ? LocalDateTime.now() : null)
|
// .endTime(status.isFinalState() ? LocalDateTime.now() : null)
|
||||||
.build()
|
// .build()
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,29 +28,29 @@ public class JobEventHandler implements IFlowableEventHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(FlowableEvent event) {
|
public void handle(FlowableEvent event) {
|
||||||
String eventType = event.getType().name();
|
String eventType = event.getType().name();
|
||||||
log.info("Processing job event: {}", eventType);
|
// log.info("Processing job event: {}", eventType);
|
||||||
|
|
||||||
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();
|
||||||
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
|
WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType);
|
||||||
|
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
// publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder()
|
||||||
.processInstanceId(job.getProcessInstanceId())
|
// .processInstanceId(job.getProcessInstanceId())
|
||||||
.executionId(job.getExecutionId())
|
// .executionId(job.getExecutionId())
|
||||||
.nodeId(job.getElementId())
|
// .nodeId(job.getElementId())
|
||||||
.nodeName(job.getElementName())
|
// .nodeName(job.getElementName())
|
||||||
.nodeType(job.getJobHandlerType())
|
// .nodeType(job.getJobHandlerType())
|
||||||
.status(status)
|
// .status(status)
|
||||||
.startTime(job.getCreateTime() != null ? DateUtil.toLocalDateTime(job.getCreateTime()) : null)
|
// .startTime(job.getCreateTime() != null ? DateUtil.toLocalDateTime(job.getCreateTime()) : null)
|
||||||
.endTime(status.isFinalState() ? LocalDateTime.now() : null)
|
// .endTime(status.isFinalState() ? LocalDateTime.now() : null)
|
||||||
.build()
|
// .build()
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,24 +33,24 @@ public class ProcessEventHandler implements IFlowableEventHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(FlowableEvent event) {
|
public void handle(FlowableEvent event) {
|
||||||
String eventType = event.getType().name();
|
String eventType = event.getType().name();
|
||||||
log.info("Processing event: {}", eventType);
|
// log.info("Processing event: {}", eventType);
|
||||||
|
|
||||||
FlowableProcessEngineEvent processEvent = (FlowableProcessEngineEvent) event;
|
FlowableProcessEngineEvent processEvent = (FlowableProcessEngineEvent) event;
|
||||||
WorkflowInstanceStatusEnums status = convertToWorkflowStatus(eventType);
|
WorkflowInstanceStatusEnums status = convertToWorkflowStatus(eventType);
|
||||||
|
|
||||||
if (status != null) {
|
if (status != null) {
|
||||||
HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService()
|
// HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService()
|
||||||
.createHistoricProcessInstanceQuery()
|
// .createHistoricProcessInstanceQuery()
|
||||||
.processInstanceId(processEvent.getProcessInstanceId())
|
// .processInstanceId(processEvent.getProcessInstanceId())
|
||||||
.singleResult();
|
// .singleResult();
|
||||||
|
//
|
||||||
publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder()
|
// publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder()
|
||||||
.processInstanceId(processEvent.getProcessInstanceId())
|
// .processInstanceId(processEvent.getProcessInstanceId())
|
||||||
.status(status)
|
// .status(status)
|
||||||
.endTime(historicProcessInstance != null && historicProcessInstance.getEndTime() != null ?
|
// .endTime(historicProcessInstance != null && historicProcessInstance.getEndTime() != null ?
|
||||||
DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()) : null)
|
// DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()) : null)
|
||||||
.build()
|
// .build()
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.util;
|
package com.qqchen.deploy.backend.workflow.util;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants;
|
||||||
import com.qqchen.deploy.backend.workflow.dto.graph.*;
|
import com.qqchen.deploy.backend.workflow.dto.graph.*;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums;
|
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@ -38,6 +39,8 @@ public class BpmnConverter {
|
|||||||
|
|
||||||
// 创建BPMN模型
|
// 创建BPMN模型
|
||||||
BpmnModel bpmnModel = new BpmnModel();
|
BpmnModel bpmnModel = new BpmnModel();
|
||||||
|
bpmnModel.setTargetNamespace("http://www.flowable.org/test");
|
||||||
|
|
||||||
Process process = new Process();
|
Process process = new Process();
|
||||||
// 确保processKey符合NCName规则
|
// 确保processKey符合NCName规则
|
||||||
String validProcessKey = processKey.replaceAll("[^a-zA-Z0-9-_.]", "_");
|
String validProcessKey = processKey.replaceAll("[^a-zA-Z0-9-_.]", "_");
|
||||||
@ -67,7 +70,7 @@ public class BpmnConverter {
|
|||||||
element.setName(node.getName());
|
element.setName(node.getName());
|
||||||
|
|
||||||
// 设置节点特定属性
|
// 设置节点特定属性
|
||||||
configureFlowElement(element, node);
|
configureFlowElement(element, node, process);
|
||||||
|
|
||||||
process.addFlowElement(element);
|
process.addFlowElement(element);
|
||||||
}
|
}
|
||||||
@ -109,8 +112,9 @@ public class BpmnConverter {
|
|||||||
* 配置流程节点的特定属性
|
* 配置流程节点的特定属性
|
||||||
* @param element 流程节点元素
|
* @param element 流程节点元素
|
||||||
* @param node 工作流节点定义
|
* @param node 工作流节点定义
|
||||||
|
* @param process 当前流程
|
||||||
*/
|
*/
|
||||||
private void configureFlowElement(FlowElement element, WorkflowDefinitionNode node) {
|
private void configureFlowElement(FlowElement element, WorkflowDefinitionNode node, Process process) {
|
||||||
if (element instanceof ServiceTask) {
|
if (element instanceof ServiceTask) {
|
||||||
ServiceTask serviceTask = (ServiceTask) element;
|
ServiceTask serviceTask = (ServiceTask) element;
|
||||||
// 设置委托表达式
|
// 设置委托表达式
|
||||||
@ -126,42 +130,57 @@ public class BpmnConverter {
|
|||||||
failedJobRetryTimeCycle.setNamespacePrefix("flowable");
|
failedJobRetryTimeCycle.setNamespacePrefix("flowable");
|
||||||
failedJobRetryTimeCycle.setElementText("R0/PT1H"); // 设置为0次重试
|
failedJobRetryTimeCycle.setElementText("R0/PT1H"); // 设置为0次重试
|
||||||
|
|
||||||
// 添加错误处理配置
|
|
||||||
ExtensionElement errorHandling = new ExtensionElement();
|
|
||||||
errorHandling.setName("failOnError");
|
|
||||||
errorHandling.setNamespace("http://flowable.org/bpmn");
|
|
||||||
errorHandling.setNamespacePrefix("flowable");
|
|
||||||
errorHandling.setElementText("true");
|
|
||||||
|
|
||||||
Map<String, List<ExtensionElement>> extensionElements = new HashMap<>();
|
Map<String, List<ExtensionElement>> extensionElements = new HashMap<>();
|
||||||
List<ExtensionElement> retryElements = new ArrayList<>();
|
List<ExtensionElement> retryElements = new ArrayList<>();
|
||||||
retryElements.add(failedJobRetryTimeCycle);
|
retryElements.add(failedJobRetryTimeCycle);
|
||||||
extensionElements.put("failedJobRetryTimeCycle", retryElements);
|
extensionElements.put("failedJobRetryTimeCycle", retryElements);
|
||||||
|
|
||||||
List<ExtensionElement> errorElements = new ArrayList<>();
|
// 添加字段注入
|
||||||
errorElements.add(errorHandling);
|
List<FieldExtension> fieldExtensions = new ArrayList<>();
|
||||||
extensionElements.put("failOnError", errorElements);
|
node.getConfig().forEach((key, value) -> {
|
||||||
|
if (value != null && !"delegate".equals(key)) {
|
||||||
|
FieldExtension fieldExtension = new FieldExtension();
|
||||||
|
fieldExtension.setFieldName(key);
|
||||||
|
fieldExtension.setStringValue(String.valueOf(value));
|
||||||
|
fieldExtensions.add(fieldExtension);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
serviceTask.setFieldExtensions(fieldExtensions);
|
||||||
serviceTask.setExtensionElements(extensionElements);
|
serviceTask.setExtensionElements(extensionElements);
|
||||||
}
|
|
||||||
// 后续可以添加其他类型的节点配置
|
|
||||||
// else if (element instanceof UserTask) { ... }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// 添加错误边界事件
|
||||||
* 添加扩展属性
|
BoundaryEvent boundaryEvent = new BoundaryEvent();
|
||||||
*/
|
boundaryEvent.setId("error_boundary_" + serviceTask.getId());
|
||||||
private void addExtensionElement(Map<String, List<ExtensionElement>> extensionElements, String name, String value) {
|
boundaryEvent.setName("错误边界事件");
|
||||||
if (value != null && !value.trim().isEmpty()) {
|
boundaryEvent.setAttachedToRef(serviceTask);
|
||||||
ExtensionElement extensionElement = new ExtensionElement();
|
boundaryEvent.setAttachedToRefId(serviceTask.getId());
|
||||||
extensionElement.setName(name);
|
boundaryEvent.setCancelActivity(true); // 确保取消原有活动
|
||||||
extensionElement.setNamespace("http://flowable.org/bpmn");
|
|
||||||
extensionElement.setNamespacePrefix("flowable");
|
|
||||||
|
|
||||||
// 直接设置文本值,让Flowable自己处理XML转义
|
// 配置错误事件定义
|
||||||
extensionElement.setElementText(value);
|
ErrorEventDefinition errorEventDefinition = new ErrorEventDefinition();
|
||||||
|
errorEventDefinition.setErrorCode(WorkFlowConstants.WORKFLOW_EXEC_ERROR);
|
||||||
|
boundaryEvent.addEventDefinition(errorEventDefinition);
|
||||||
|
|
||||||
extensionElements.computeIfAbsent(name, k -> new ArrayList<>()).add(extensionElement);
|
// 添加错误结束事件
|
||||||
|
EndEvent errorEndEvent = new EndEvent();
|
||||||
|
errorEndEvent.setId("error_end_" + serviceTask.getId());
|
||||||
|
errorEndEvent.setName("错误结束事件");
|
||||||
|
|
||||||
|
// 添加终止定义
|
||||||
|
TerminateEventDefinition terminateEventDefinition = new TerminateEventDefinition();
|
||||||
|
errorEndEvent.addEventDefinition(terminateEventDefinition);
|
||||||
|
|
||||||
|
// 添加从边界事件到结束事件的连线
|
||||||
|
SequenceFlow errorFlow = new SequenceFlow();
|
||||||
|
errorFlow.setId("error_flow_" + serviceTask.getId());
|
||||||
|
errorFlow.setName("错误处理流程");
|
||||||
|
errorFlow.setSourceRef(boundaryEvent.getId());
|
||||||
|
errorFlow.setTargetRef(errorEndEvent.getId());
|
||||||
|
|
||||||
|
// 将错误处理相关的元素添加到流程中
|
||||||
|
process.addFlowElement(boundaryEvent);
|
||||||
|
process.addFlowElement(errorEndEvent);
|
||||||
|
process.addFlowElement(errorFlow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user