Merge branch 'feature/REQ-2616' into 'master'
Feature/req 2616 See merge request universal/infrastructure/backend/workflow-engine!8
This commit is contained in:
commit
db3f40e6f2
@ -2,7 +2,6 @@ package cn.axzo.workflow.client.config;
|
||||
|
||||
import feign.RequestInterceptor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
@ -43,7 +42,7 @@ public class WorkflowEngineClientAutoConfiguration {
|
||||
private static final Pattern POM_VERSION = Pattern.compile("<parent>.*<version>(\\S+)</version>.*</parent>",
|
||||
Pattern.DOTALL);
|
||||
|
||||
@Bean
|
||||
@Bean("serviceVersion")
|
||||
public String serviceVersion() {
|
||||
Map<String, String> env = System.getenv();
|
||||
if (env != null) {
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
package cn.axzo.workflow.client.feign.bpmn;
|
||||
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
import cn.axzo.workflow.common.annotation.Manageable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
@ -44,4 +45,24 @@ public interface ProcessActivityApi {
|
||||
@PostMapping("/api/process/activity/assignee/set")
|
||||
@Operation(summary = "业务节点设置审批人,不支持重复调用设置审批人,需一次性传入所有审批人")
|
||||
CommonResponse<Boolean> setAssignee(@Validated @RequestBody BpmnActivitySetAssigneeDTO dto);
|
||||
|
||||
/**
|
||||
* 该功能应该利用引擎的 TimerBoundaryEvent 来实现,但为了简便,先利用引擎的任务调度来实现
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/activity/timeout/trigger")
|
||||
@Manageable
|
||||
@Operation(summary = "设置指定业务节点定时继续往下执行")
|
||||
CommonResponse<Boolean> setTimeoutTrigger(@Validated @RequestBody BpmnActivityTimeoutTriggerDTO dto);
|
||||
|
||||
/**
|
||||
* 为指定业务节点设置定时回调
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Manageable
|
||||
@PostMapping("/api/process/activity/timeout/callback")
|
||||
@Operation(summary = "设置指定业务节点定时回调")
|
||||
CommonResponse<Boolean> setTimeoutCallback(@Validated @RequestBody BpmnActivityTimeoutCallbackDTO dto);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ public enum ProcessActivityEventEnum {
|
||||
PROCESS_ACTIVITY_START("process-activity", "process-activity-start", "流程活动节点已开始"),
|
||||
PROCESS_ACTIVITY_WAIT_ASSIGNEE("process-activity", "process-activity-wait-assignee", "流程活动节点等待指定审批人"),
|
||||
PROCESS_ACTIVITY_TAKE("process-activity", "process-activity-take", "该事件类型暂时不存在"),
|
||||
PROCESS_ACTIVITY_CALLBACK("process-activity", "process-activity-callback", "业务节点定时回调"),
|
||||
PROCESS_ACTIVITY_END("process-activity", "process-activity-end", "流程活动节点已取消"),
|
||||
;
|
||||
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.activity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 为指定业务节点设置倒计时回调
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-16 15:30
|
||||
*/
|
||||
@ApiModel("为指定业务节点设置倒计时回调")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BpmnActivityTimeoutCallbackDTO {
|
||||
|
||||
/**
|
||||
* 业务节点的触发 ID
|
||||
*/
|
||||
@NotBlank(message = "触发 ID 不能为空")
|
||||
private String triggerId;
|
||||
|
||||
/**
|
||||
* 触发往下流转的时间点, 格式:yyyy-MM-dd HH:mm:ss
|
||||
* <p>
|
||||
* 应该为 Date 类型,但为了确保特殊情况需要通过 pod 内直接触发
|
||||
*/
|
||||
@NotBlank(message = "触发时间不能为空,格式:yyyy-MM-dd HH:mm:ss")
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 用于追加或修改现有的变量值
|
||||
*/
|
||||
private Map<String, Object> variables;
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package cn.axzo.workflow.common.model.request.bpmn.activity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 为指定业务节点设置倒计时,在啥时候继续往下流转
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-16 15:30
|
||||
*/
|
||||
@ApiModel("为指定业务节点设置倒计时")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BpmnActivityTimeoutTriggerDTO {
|
||||
/**
|
||||
* 业务节点的触发 ID
|
||||
*/
|
||||
@NotBlank(message = "触发 ID 不能为空")
|
||||
private String triggerId;
|
||||
|
||||
/**
|
||||
* 触发往下流转的时间点, 格式:yyyy-MM-dd HH:mm:ss
|
||||
* <p>
|
||||
* 应该为 Date 类型,但为了确保特殊情况需要通过 pod 内直接触发
|
||||
*/
|
||||
@NotBlank(message = "触发时间不能为空,格式:yyyy-MM-dd HH:mm:ss")
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 用于追加或修改现有的变量值(暂不支持)
|
||||
*/
|
||||
@Deprecated
|
||||
private Map<String, Object> variables;
|
||||
}
|
||||
@ -11,6 +11,7 @@ import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.converter.json.AbstractBpmnJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.BoundaryEventJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.EndEventJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.ExclusiveGatewayJsonConverter;
|
||||
import cn.axzo.workflow.core.converter.json.NotSupportConverter;
|
||||
@ -27,6 +28,7 @@ import com.google.common.collect.Lists;
|
||||
import org.flowable.bpmn.BpmnAutoLayout;
|
||||
import org.flowable.bpmn.converter.BpmnXMLConverter;
|
||||
import org.flowable.bpmn.model.BaseElement;
|
||||
import org.flowable.bpmn.model.BoundaryEvent;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.EndEvent;
|
||||
import org.flowable.bpmn.model.ExclusiveGateway;
|
||||
@ -142,6 +144,7 @@ public final class BpmnJsonConverterUtil {
|
||||
CONVERTERS.put(UserTask.class, new UserTaskJsonConverter());
|
||||
CONVERTERS.put(ServiceTask.class, new ServiceTaskJsonConverter());
|
||||
CONVERTERS.put(ReceiveTask.class, new ReceiveTaskJsonConverter());
|
||||
CONVERTERS.put(BoundaryEvent.class, new BoundaryEventJsonConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -6,6 +6,8 @@ import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory;
|
||||
import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator;
|
||||
import cn.axzo.workflow.core.engine.interceptor.CustomRetryInterceptor;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncActivityCallbackJobHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncActivityLeaveJobHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncBpmnProcessActivityJobHandler;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncCancelProcessInstanceHandler;
|
||||
@ -89,6 +91,8 @@ public class FlowableConfiguration {
|
||||
configuration.addCustomJobHandler(new AsyncCancelProcessInstanceHandler(extAxHiTaskInstService));
|
||||
configuration.addCustomJobHandler(new AsyncAbortProcessInstanceHandler(extAxHiTaskInstService));
|
||||
configuration.addCustomJobHandler(new AsyncBpmnProcessActivityJobHandler(bpmnProcessActivityService));
|
||||
configuration.addCustomJobHandler(new AsyncActivityLeaveJobHandler(bpmnProcessActivityService));
|
||||
configuration.addCustomJobHandler(new AsyncActivityCallbackJobHandler());
|
||||
// 异步任务异常重试时间间隔
|
||||
configuration.setDefaultFailedJobWaitTime(30);
|
||||
configuration.setAsyncFailedJobWaitTime(30);
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
package cn.axzo.workflow.core.converter.json;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
|
||||
import org.flowable.bpmn.model.BoundaryEvent;
|
||||
import org.flowable.bpmn.model.EventDefinition;
|
||||
import org.flowable.bpmn.model.FlowableListener;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.TimerEventDefinition;
|
||||
import org.flowable.engine.delegate.BaseExecutionListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;
|
||||
|
||||
/**
|
||||
* 边界事件
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-16 11:47
|
||||
*/
|
||||
public class BoundaryEventJsonConverter extends AbstractBpmnJsonConverter<BoundaryEvent> {
|
||||
@Override
|
||||
public BoundaryEvent convertJsonToElement(BpmnJsonNode node, Process process) {
|
||||
BoundaryEvent boundaryEvent = new BoundaryEvent();
|
||||
boundaryEvent.setId(node.getId() + "_boundaryEvent");
|
||||
boundaryEvent.setCancelActivity(false);
|
||||
boundaryEvent.setAttachedToRefId(process.getId());
|
||||
|
||||
// 设置执行监听
|
||||
setExecutionListeners(boundaryEvent);
|
||||
|
||||
// 设置 TimerEventDefinition
|
||||
setTimerEventDefinition(boundaryEvent);
|
||||
return boundaryEvent;
|
||||
}
|
||||
|
||||
private void setTimerEventDefinition(BoundaryEvent boundaryEvent) {
|
||||
List<EventDefinition> eventDefinitions = new ArrayList<>();
|
||||
TimerEventDefinition timerEventDefinition = new TimerEventDefinition();
|
||||
timerEventDefinition.setEndDate("${timerEndDate}");
|
||||
eventDefinitions.add(timerEventDefinition);
|
||||
boundaryEvent.setEventDefinitions(eventDefinitions);
|
||||
}
|
||||
|
||||
private void setExecutionListeners(BoundaryEvent boundaryEvent) {
|
||||
List<FlowableListener> executionListeners = new ArrayList<>();
|
||||
// 设置执行监听
|
||||
FlowableListener executionListener = new FlowableListener();
|
||||
executionListener.setEvent(BaseExecutionListener.EVENTNAME_START);
|
||||
executionListener.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
|
||||
executionListener.setImplementation("${boundaryEventExecutionStartListener}");
|
||||
executionListeners.add(executionListener);
|
||||
|
||||
boundaryEvent.setExecutionListeners(executionListeners);
|
||||
}
|
||||
}
|
||||
@ -28,6 +28,12 @@ public abstract class AbstractCommand<T> implements Command<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现该方法,默认就捕获了 command 一些引擎内部异常
|
||||
*
|
||||
* @param commandContext
|
||||
* @return
|
||||
*/
|
||||
public T executeInternal(CommandContext commandContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncActivityCallbackJobHandler;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.bpmn.model.TimerEventDefinition;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.jobexecutor.TimerEventHandler;
|
||||
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.engine.impl.util.TimerUtil;
|
||||
import org.flowable.job.service.impl.persistence.entity.TimerJobEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 业务节点触发倒计时回调
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-20 16:59
|
||||
*/
|
||||
public class CustomBusinessNodeTimeoutCallbackCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String triggerId;
|
||||
private final String endTime;
|
||||
private final Map<String, Object> variables;
|
||||
|
||||
public CustomBusinessNodeTimeoutCallbackCmd(String triggerId, String endTime, Map<String, Object> variables) {
|
||||
this.triggerId = triggerId;
|
||||
this.endTime = endTime;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("triggerId", triggerId);
|
||||
params.put("endTime", endTime);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
ExecutionEntity executionEntity = (ExecutionEntity) processEngineConfiguration.getRuntimeService().createExecutionQuery().executionId(triggerId).singleResult();
|
||||
if (executionEntity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String newEndTime = parseDateTimeWithTimeZone();
|
||||
|
||||
TimerEventDefinition timerEventDefinition = new TimerEventDefinition();
|
||||
timerEventDefinition.setTimeDate(newEndTime);
|
||||
|
||||
TimerJobEntity timerJob = TimerUtil.createTimerEntityForTimerEventDefinition(timerEventDefinition, executionEntity.getCurrentFlowElement(),
|
||||
true, executionEntity, AsyncActivityCallbackJobHandler.TYPE, TimerEventHandler.createConfiguration(executionEntity.getCurrentActivityId(),
|
||||
timerEventDefinition.getEndDate(), timerEventDefinition.getCalendarName()));
|
||||
if (timerJob != null) {
|
||||
timerJob.setCustomValues(JSON.toJSONString(new BpmnActivityTimeoutCallbackDTO(triggerId, endTime, variables)));
|
||||
CommandContextUtil.getTimerJobService().scheduleTimerJob(timerJob);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String parseDateTimeWithTimeZone() {
|
||||
DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(endTime, inputFormat);
|
||||
|
||||
// 转换为东八区的ZonedDateTime
|
||||
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
|
||||
|
||||
// 格式化为包含时区偏移量的ISO 8601字符串
|
||||
DateTimeFormatter outputFormat = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
return zonedDateTime.format(outputFormat);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package cn.axzo.workflow.core.engine.cmd;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncActivityLeaveJobHandler;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import org.flowable.bpmn.model.TimerEventDefinition;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.jobexecutor.TimerEventHandler;
|
||||
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.engine.impl.util.TimerUtil;
|
||||
import org.flowable.job.service.impl.persistence.entity.TimerJobEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 业务节点触发倒计时
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-16 15:38
|
||||
*/
|
||||
public class CustomBusinessNodeTimeoutTriggerCmd extends AbstractCommand<Void> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String triggerId;
|
||||
private final String endTime;
|
||||
private final Map<String, Object> variables;
|
||||
|
||||
public CustomBusinessNodeTimeoutTriggerCmd(String triggerId, String endTime, Map<String, Object> variables) {
|
||||
this.triggerId = triggerId;
|
||||
this.endTime = endTime;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String paramToJsonString() {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("triggerId", triggerId);
|
||||
params.put("endTime", endTime);
|
||||
return JSON.toJSONString(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void execute(CommandContext commandContext) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration =
|
||||
CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
ExecutionEntity executionEntity = (ExecutionEntity) processEngineConfiguration.getRuntimeService().createExecutionQuery().executionId(triggerId).singleResult();
|
||||
if (Objects.isNull(executionEntity)) {
|
||||
return null;
|
||||
}
|
||||
String newEndTime = parseDateTimeWithTimeZone();
|
||||
|
||||
TimerEventDefinition timerEventDefinition = new TimerEventDefinition();
|
||||
timerEventDefinition.setTimeDate(newEndTime);
|
||||
|
||||
TimerJobEntity timerJob = TimerUtil.createTimerEntityForTimerEventDefinition(timerEventDefinition, executionEntity.getCurrentFlowElement(),
|
||||
true, executionEntity, AsyncActivityLeaveJobHandler.TYPE, TimerEventHandler.createConfiguration(executionEntity.getCurrentActivityId(),
|
||||
timerEventDefinition.getEndDate(), timerEventDefinition.getCalendarName()));
|
||||
if (timerJob != null) {
|
||||
timerJob.setCustomValues(JSON.toJSONString(new BpmnActivityTimeoutTriggerDTO(triggerId, endTime, variables)));
|
||||
CommandContextUtil.getTimerJobService().scheduleTimerJob(timerJob);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String parseDateTimeWithTimeZone() {
|
||||
DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
LocalDateTime localDateTime = LocalDateTime.parse(endTime, inputFormat);
|
||||
|
||||
// 转换为东八区的ZonedDateTime
|
||||
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
|
||||
|
||||
// 格式化为包含时区偏移量的ISO 8601字符串
|
||||
DateTimeFormatter outputFormat = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
|
||||
return zonedDateTime.format(outputFormat);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.workflow.core.engine.event;
|
||||
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-20 17:24
|
||||
*/
|
||||
public interface BizCallbackEvent extends FlowableEvent {
|
||||
String getActivityId();
|
||||
|
||||
String getActivityName();
|
||||
|
||||
String getProcessInstanceId();
|
||||
|
||||
String getProcessDefinitionId();
|
||||
|
||||
String getBusinessKey();
|
||||
|
||||
String getExecutionId();
|
||||
|
||||
Map<String, Object> getVariables();
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package cn.axzo.workflow.core.engine.event;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEventType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 业务节点回调事件
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-20 17:25
|
||||
*/
|
||||
public class BizCallbackEventImpl implements BizCallbackEvent {
|
||||
private final BizCallbackEventType type;
|
||||
private final String activityId;
|
||||
private final String activityName;
|
||||
private final String processInstanceId;
|
||||
private final String processDefinitionId;
|
||||
private final String businessKey;
|
||||
private final String executionId;
|
||||
private final Map<String, Object> variables;
|
||||
|
||||
public BizCallbackEventImpl(BizCallbackEventType type, String activityId, String activityName, String processInstanceId, String processDefinitionId, String businessKey, String executionId, Map<String, Object> variables) {
|
||||
this.type = type;
|
||||
this.activityId = activityId;
|
||||
this.activityName = activityName;
|
||||
this.processInstanceId = processInstanceId;
|
||||
this.processDefinitionId = processDefinitionId;
|
||||
this.businessKey = businessKey;
|
||||
this.executionId = executionId;
|
||||
this.variables = variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return type of event.
|
||||
*/
|
||||
@Override
|
||||
public FlowableEventType getType() {
|
||||
return BizCallbackEventType.CALLBACK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivityId() {
|
||||
return activityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getActivityName() {
|
||||
return activityName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcessInstanceId() {
|
||||
return processInstanceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProcessDefinitionId() {
|
||||
return processDefinitionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBusinessKey() {
|
||||
return businessKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecutionId() {
|
||||
return executionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getVariables() {
|
||||
return variables;
|
||||
}
|
||||
|
||||
public enum BizCallbackEventType implements FlowableEventType {
|
||||
CALLBACK,
|
||||
;
|
||||
public static final BizCallbackEventType[] EMPTY_ARRAY = new BizCallbackEventType[]{};
|
||||
|
||||
public static BizCallbackEventType[] getTypesFromString(String string) {
|
||||
List<BizCallbackEventType> result = new ArrayList<>();
|
||||
if (string != null && !string.isEmpty()) {
|
||||
String[] split = StringUtils.split(string, ",");
|
||||
for (String typeName : split) {
|
||||
boolean found = false;
|
||||
for (BizCallbackEventType type : values()) {
|
||||
if (typeName.toUpperCase().equals(type.name())) {
|
||||
result.add(type);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new FlowableIllegalArgumentException("Invalid event-type: " + typeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray(EMPTY_ARRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package cn.axzo.workflow.core.engine.job;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.event.BizCallbackEventImpl;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.engine.HistoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.TaskService;
|
||||
import org.flowable.engine.history.HistoricProcessInstance;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
import org.flowable.job.service.JobHandler;
|
||||
import org.flowable.job.service.impl.persistence.entity.JobEntity;
|
||||
import org.flowable.task.api.Task;
|
||||
import org.flowable.variable.api.delegate.VariableScope;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_ID_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 业务节点的触发离开的任务处理器
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-16 16:29
|
||||
*/
|
||||
@Slf4j
|
||||
public class AsyncActivityCallbackJobHandler extends AbstractJobHandler implements JobHandler {
|
||||
public static final String TYPE = "business-node-callback";
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
|
||||
log.warn("AsyncActivityLeaveJobHandler exec start...");
|
||||
BpmnActivityTimeoutCallbackDTO dto = JSON.parseObject(job.getCustomValues(), BpmnActivityTimeoutCallbackDTO.class);
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
|
||||
FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
|
||||
TaskService taskService = processEngineConfiguration.getTaskService();
|
||||
Task task = taskService.createTaskQuery().executionId(dto.getTriggerId()).singleResult();
|
||||
|
||||
HistoryService historyService = processEngineConfiguration.getHistoryService();
|
||||
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().includeProcessVariables()
|
||||
.processInstanceId(task.getProcessInstanceId()).singleResult();
|
||||
if (Objects.isNull(processInstance)) {
|
||||
throw new WorkflowEngineException(PROCESS_INSTANCE_ID_NOT_EXISTS, task.getProcessInstanceId());
|
||||
}
|
||||
RuntimeService runtimeService = processEngineConfiguration.getRuntimeService();
|
||||
runtimeService.setVariables(processInstance.getId(), dto.getVariables());
|
||||
|
||||
Map<String, Object> processVariables = new HashMap<>(processInstance.getProcessVariables());
|
||||
if (!CollectionUtils.isEmpty(dto.getVariables())) {
|
||||
processVariables.putAll(dto.getVariables());
|
||||
}
|
||||
eventDispatcher.dispatchEvent(new BizCallbackEventImpl(BizCallbackEventImpl.BizCallbackEventType.CALLBACK,
|
||||
task.getTaskDefinitionKey(), task.getName(),
|
||||
task.getProcessInstanceId(), task.getProcessDefinitionId(),
|
||||
processInstance.getBusinessKey(), dto.getTriggerId(),
|
||||
processVariables),
|
||||
processEngineConfiguration.getEngineCfgKey());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package cn.axzo.workflow.core.engine.job;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessActivityService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.impl.interceptor.CommandContext;
|
||||
import org.flowable.job.service.JobHandler;
|
||||
import org.flowable.job.service.impl.persistence.entity.JobEntity;
|
||||
import org.flowable.variable.api.delegate.VariableScope;
|
||||
|
||||
/**
|
||||
* 业务节点的触发离开的任务处理器
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-16 16:29
|
||||
*/
|
||||
@Slf4j
|
||||
public class AsyncActivityLeaveJobHandler extends AbstractJobHandler implements JobHandler {
|
||||
private final BpmnProcessActivityService bpmnProcessActivityService;
|
||||
public static final String TYPE = "business-node-leave-task";
|
||||
|
||||
public AsyncActivityLeaveJobHandler(BpmnProcessActivityService bpmnProcessActivityService) {
|
||||
this.bpmnProcessActivityService = bpmnProcessActivityService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
|
||||
log.warn("AsyncActivityLeaveJobHandler exec start...");
|
||||
BpmnActivityTimeoutTriggerDTO dto = JSON.parseObject(job.getCustomValues(), BpmnActivityTimeoutTriggerDTO.class);
|
||||
bpmnProcessActivityService.trigger(dto.getTriggerId());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
package cn.axzo.workflow.core.engine.listener;
|
||||
|
||||
import cn.axzo.workflow.core.common.context.ActivityOperationContext;
|
||||
import cn.axzo.workflow.core.engine.event.BizCallbackEvent;
|
||||
import cn.axzo.workflow.core.engine.event.BizCallbackEventImpl;
|
||||
import cn.axzo.workflow.core.listener.BpmnActivityEventListener;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.common.engine.api.delegate.event.AbstractFlowableEventListener;
|
||||
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.axzo.workflow.core.engine.event.BizCallbackEventImpl.BizCallbackEventType.CALLBACK;
|
||||
|
||||
/**
|
||||
* 业务节点回调事件
|
||||
*
|
||||
* @author wangli
|
||||
* @since 2024-08-20 17:47
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class EngineActivityCallbackEventListener extends AbstractFlowableEventListener {
|
||||
@Resource
|
||||
ObjectProvider<List<BpmnActivityEventListener>> activityListeners;
|
||||
|
||||
public static final Set<BizCallbackEventImpl.BizCallbackEventType> BIZ_CALLBACK_EVENTS =
|
||||
ImmutableSet.<BizCallbackEventImpl.BizCallbackEventType>builder()
|
||||
.add(CALLBACK)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public void onEvent(FlowableEvent flowableEvent) {
|
||||
if (flowableEvent instanceof BizCallbackEvent) {
|
||||
BizCallbackEvent event = (BizCallbackEvent) flowableEvent;
|
||||
BizCallbackEventImpl.BizCallbackEventType type = (BizCallbackEventImpl.BizCallbackEventType) event.getType();
|
||||
if (BIZ_CALLBACK_EVENTS.contains(type)) {
|
||||
switch (type) {
|
||||
case CALLBACK:
|
||||
getOrderedListeners().forEach(i -> i.onCallback(event));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<BpmnActivityEventListener> getOrderedListeners() {
|
||||
ActivityOperationContext context = new ActivityOperationContext();
|
||||
List<BpmnActivityEventListener> orderListeners = new ArrayList<>();
|
||||
activityListeners.ifAvailable(orderListeners::addAll);
|
||||
orderListeners.forEach(i -> i.setContext(context));
|
||||
return orderListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFailOnException() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package cn.axzo.workflow.core.listener;
|
||||
|
||||
import cn.axzo.workflow.core.common.context.OperationContext;
|
||||
import cn.axzo.workflow.core.engine.event.BizCallbackEvent;
|
||||
import cn.axzo.workflow.core.engine.event.BizSpecifyAssigneeEvent;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.core.Ordered;
|
||||
@ -36,6 +37,12 @@ public interface BpmnActivityEventListener extends OperationContext, Ordered {
|
||||
*/
|
||||
default void onTake(DelegateExecution execution) {}
|
||||
|
||||
/**
|
||||
* 节点定时回调
|
||||
*/
|
||||
default void onCallback(BizCallbackEvent event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点已取消
|
||||
*
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package cn.axzo.workflow.core.service;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import org.flowable.job.service.impl.persistence.entity.JobEntity;
|
||||
|
||||
@ -45,4 +47,20 @@ public interface BpmnProcessActivityService {
|
||||
* @param dto
|
||||
*/
|
||||
void setAssigneeAsync(BpmnActivitySetAssigneeDTO dto);
|
||||
|
||||
/**
|
||||
* 设置指定业务接口继续往下流转的触发时间
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
Boolean setTimeoutTrigger(BpmnActivityTimeoutTriggerDTO dto);
|
||||
|
||||
/**
|
||||
* 设置指定业务节点定时回调(仅通过 MQ 事件广播,自身状态不做任何改变)
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
Boolean setTimeOutCallback(BpmnActivityTimeoutCallbackDTO dto);
|
||||
}
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
package cn.axzo.workflow.core.service.impl;
|
||||
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomAbortProcessInstanceCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomBizSpecifyAssigneeToTaskCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomBusinessNodeTimeoutCallbackCmd;
|
||||
import cn.axzo.workflow.core.engine.cmd.CustomBusinessNodeTimeoutTriggerCmd;
|
||||
import cn.axzo.workflow.core.engine.job.AsyncBpmnProcessActivityJobHandler;
|
||||
import cn.axzo.workflow.core.service.BpmnProcessActivityService;
|
||||
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
|
||||
@ -130,4 +134,24 @@ public class BpmnProcessActivityServiceImpl implements BpmnProcessActivityServic
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean setTimeoutTrigger(BpmnActivityTimeoutTriggerDTO dto) {
|
||||
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
|
||||
commandExecutor.execute(new CustomBusinessNodeTimeoutTriggerCmd(dto.getTriggerId(), dto.getEndTime(),
|
||||
dto.getVariables()));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置指定业务节点定时回调
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean setTimeOutCallback(BpmnActivityTimeoutCallbackDTO dto) {
|
||||
CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
|
||||
commandExecutor.execute(new CustomBusinessNodeTimeoutCallbackCmd(dto.getTriggerId(), dto.getEndTime(), dto.getVariables()));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,8 @@ public class ExtAxPropertyServiceImpl implements ExtAxPropertyService {
|
||||
}
|
||||
QueryWrapper<ExtAxProperty> queryWrapper = new QueryWrapper<ExtAxProperty>()
|
||||
.eq("name", name);
|
||||
return Optional.ofNullable(mapper.selectOne(queryWrapper));
|
||||
Optional<ExtAxProperty> extAxProperty = Optional.ofNullable(mapper.selectOne(queryWrapper));
|
||||
return extAxProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -66,6 +66,7 @@ public class ErrorReportAspect implements Ordered {
|
||||
*/
|
||||
@Around(value = "@within(org.springframework.web.bind.annotation.RestController) || @within(org.springframework.stereotype.Service)")
|
||||
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
log.info("{}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
|
||||
Signature signature = joinPoint.getSignature();
|
||||
StopWatch watch = new StopWatch("running controller time");
|
||||
watch.start(signature.toShortString());
|
||||
|
||||
@ -8,6 +8,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO;
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessActivityDTO;
|
||||
import cn.axzo.workflow.core.common.context.ActivityOperationContext;
|
||||
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
|
||||
import cn.axzo.workflow.core.engine.event.BizCallbackEvent;
|
||||
import cn.axzo.workflow.core.engine.event.BizSpecifyAssigneeEvent;
|
||||
import cn.axzo.workflow.core.listener.AbstractBpmnEventListener;
|
||||
import cn.axzo.workflow.core.listener.BpmnActivityEventListener;
|
||||
@ -18,7 +19,6 @@ import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.engine.RepositoryService;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
|
||||
import org.flowable.engine.runtime.ProcessInstance;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
@ -40,6 +40,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_R
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.MQ_OWNERSHIP_PROCESS_DEFINITION_KEY;
|
||||
import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION;
|
||||
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED;
|
||||
import static cn.axzo.workflow.common.enums.ProcessActivityEventEnum.PROCESS_ACTIVITY_CALLBACK;
|
||||
import static cn.axzo.workflow.common.enums.ProcessActivityEventEnum.PROCESS_ACTIVITY_END;
|
||||
import static cn.axzo.workflow.common.enums.ProcessActivityEventEnum.PROCESS_ACTIVITY_START;
|
||||
import static cn.axzo.workflow.common.enums.ProcessActivityEventEnum.PROCESS_ACTIVITY_TAKE;
|
||||
@ -117,6 +118,35 @@ public class RocketMqBpmActivityEventListener extends AbstractBpmnEventListener<
|
||||
execution.getCurrentActivityId(), execution.getProcessInstanceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallback(BizCallbackEvent event) {
|
||||
log.info("RocketMqBpmActivityEventListener#onCallback...activityId: {}, processInstanceId: {}",
|
||||
event.getActivityId(), event.getProcessInstanceId());
|
||||
|
||||
// 特殊的自定义业务事件, 不能使用公共的 build 方法
|
||||
ProcessActivityDTO dto = new ProcessActivityDTO();
|
||||
dto.setType(PROCESS_ACTIVITY_CALLBACK);
|
||||
dto.setActivityId(event.getActivityId());
|
||||
dto.setActivityName(event.getActivityName());
|
||||
dto.setProcessInstanceId(event.getProcessInstanceId());
|
||||
dto.setProcessDefinitionId(event.getProcessDefinitionId());
|
||||
ProcessInstance processInstance = getContext().getProcessInstance(() ->
|
||||
runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(event.getProcessInstanceId())
|
||||
.singleResult());
|
||||
if (Objects.nonNull(processInstance)) {
|
||||
dto.setProcessDefinitionKey(processInstance.getProcessDefinitionKey());
|
||||
dto.setBusinessKey(processInstance.getBusinessKey());
|
||||
}
|
||||
dto.setTriggerId(event.getExecutionId());
|
||||
dto.setVariables(event.getVariables());
|
||||
dto.setWorkflowEngineVersion(String.valueOf(event.getVariables().getOrDefault(WORKFLOW_ENGINE_VERSION, FLOW_SERVER_VERSION_121)));
|
||||
sendMessageQueue(dto, PROCESS_ACTIVITY_CALLBACK);
|
||||
|
||||
log.info("RocketMqBpmActivityEventListener#onCallback...end, activityId: {}, processInstanceId: {}",
|
||||
event.getActivityId(), event.getProcessInstanceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnd(DelegateExecution execution) {
|
||||
log.info("RocketMqMessagePushEventListener#onEnd...activityId: {}, processInstanceId: {}",
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package cn.axzo.workflow.server.controller.web.bpmn;
|
||||
|
||||
import cn.axzo.workflow.client.feign.bpmn.ProcessActivityApi;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
|
||||
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
|
||||
@ -109,4 +111,28 @@ public class BpmnProcessActivityController implements ProcessActivityApi {
|
||||
}
|
||||
return CommonResponse.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该功能应该利用引擎的 TimerBoundaryEvent 来实现,但为了简便,先利用引擎的任务调度来实现
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/timeout/trigger")
|
||||
@Override
|
||||
public CommonResponse<Boolean> setTimeoutTrigger(@Validated @RequestBody BpmnActivityTimeoutTriggerDTO dto) {
|
||||
return CommonResponse.success(bpmnProcessActivityService.setTimeoutTrigger(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定业务节点设置定时回调
|
||||
*
|
||||
* @param dto
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/timeout/callback")
|
||||
@Override
|
||||
public CommonResponse<Boolean> setTimeoutCallback(@Validated @RequestBody BpmnActivityTimeoutCallbackDTO dto) {
|
||||
return CommonResponse.success(bpmnProcessActivityService.setTimeOutCallback(dto));
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,8 @@ logging:
|
||||
level:
|
||||
com.alibaba.nacos.client.config.impl: WARN
|
||||
org.flowable: INFO
|
||||
|
||||
server:
|
||||
shutdown: graceful
|
||||
---
|
||||
#开发环境
|
||||
spring:
|
||||
|
||||
@ -104,6 +104,7 @@ public class StarterBroadcastMQConfiguration {
|
||||
|
||||
@Override
|
||||
public void onMessage(MessageExt message) {
|
||||
// 处理 properties 配置进行事件过滤
|
||||
for (InnerMessageQueueHandleBeforeFilter filter : filters) {
|
||||
if (filter.doFilter(message)) {
|
||||
log.info("【{}】message has been filtered, messageId: {}", this.getClass().getSimpleName(), message.getMsgId());
|
||||
|
||||
@ -1,59 +1,38 @@
|
||||
package cn.axzo.workflow.starter.api;
|
||||
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
|
||||
import cn.axzo.workflow.common.util.ThreadUtil;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
import cn.axzo.workflow.common.annotation.InvokeMode;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.util.ThreadUtil;
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import cn.axzo.workflow.common.annotation.InvokeMode;
|
||||
import cn.axzo.workflow.common.annotation.Manageable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
/**
|
||||
* Workflow Engine Starter Core Service<br/>该类是根据 API 动态生成,不同版本可能会开放新的接口,或回收一些旧接口
|
||||
|
||||
@ -1,77 +1,65 @@
|
||||
package cn.axzo.workflow.starter.api;
|
||||
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
|
||||
import cn.axzo.workflow.common.util.ThreadUtil;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
import cn.axzo.workflow.client.config.CommonFeignConfiguration;
|
||||
import cn.axzo.workflow.common.annotation.InvokeMode;
|
||||
import cn.axzo.workflow.common.annotation.Manageable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonMetaInfo;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import java.util.List;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.RestBpmnProcessVariable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutCallbackDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.activity.BpmnActivityTimeoutTriggerDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.model.BpmnModelUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnActivitySetAssigneeDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAdminPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCancelDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCarbonCopyDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCheckApproverDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceCreateWithFormDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceMyPageReqVO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Map;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategoryConfigCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategoryConfigSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategoryCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategorySearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.category.CategoryUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.RestBpmnProcessVariable;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelDetailVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.model.BpmnModelExtVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceAdminPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstancePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryConfigItemVO;
|
||||
import cn.axzo.workflow.common.model.response.category.CategoryItemVO;
|
||||
import cn.axzo.workflow.common.util.ThreadUtil;
|
||||
import cn.axzo.workflow.starter.feign.ext.WorkflowEngineStarterFeignConfiguration;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.definition.BpmnProcessDefinitionUpdateDTO;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessDefinitionPageDTO;
|
||||
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.ASYNC;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
|
||||
/**
|
||||
* Workflow Engine Starter Management Service<br/>该类是根据 API 动态生成,不同版本可能会开放新的接口,或回收一些旧接口
|
||||
@ -230,6 +218,26 @@ public interface WorkflowManageService {
|
||||
@InvokeMode(SYNC)
|
||||
List<String> getModelTenantIds();
|
||||
|
||||
/**
|
||||
* 该功能应该利用引擎的 TimerBoundaryEvent 来实现,但为了简便,先利用引擎的任务调度来实现
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/process/activity/timeout/trigger")
|
||||
@Manageable
|
||||
@Operation(summary = "设置指定业务节点定时继续往下执行")
|
||||
Boolean setTimeoutTrigger(@Validated @RequestBody BpmnActivityTimeoutTriggerDTO dto);
|
||||
|
||||
/**
|
||||
* 为指定业务节点设置定时回调
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Manageable
|
||||
@PostMapping("/api/process/activity/timeout/callback")
|
||||
@Operation(summary = "设置指定业务节点定时回调")
|
||||
Boolean setTimeoutCallback(@Validated @RequestBody BpmnActivityTimeoutCallbackDTO dto);
|
||||
|
||||
/**
|
||||
* 创建审批流程并带上表单
|
||||
*
|
||||
|
||||
@ -6,7 +6,6 @@ import cn.axzo.workflow.common.model.response.mq.WorkflowEngineStarterRpcInvokeD
|
||||
import cn.axzo.workflow.starter.WorkflowEngineStarterProperties;
|
||||
import cn.axzo.workflow.starter.common.exception.WorkflowEngineStarterException;
|
||||
import cn.axzo.workflow.starter.mq.retry.producer.RpcInvokeEventProducer;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import feign.Client;
|
||||
import feign.MethodMetadata;
|
||||
@ -46,9 +45,9 @@ import java.util.Queue;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static cn.axzo.workflow.common.constant.StarterConstants.STARTER_INVOKE_MODE;
|
||||
import static cn.axzo.workflow.common.enums.RpcInvokeModeEnum.SYNC;
|
||||
import static cn.axzo.workflow.common.enums.WorkflowEngineEventEnum.WORKFLOW_ENGINE_STARTER;
|
||||
import static cn.axzo.workflow.common.constant.StarterConstants.STARTER_INVOKE_MODE;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
@ -88,12 +87,12 @@ public class ComplexInvokeClient implements Client {
|
||||
asyncInvoke(request);
|
||||
|
||||
return Response.builder()
|
||||
.status(HttpStatus.OK.value())
|
||||
.reason(HttpStatus.OK.getReasonPhrase())
|
||||
.headers(headers)
|
||||
.request(request)
|
||||
.body(body)
|
||||
.build();
|
||||
.status(HttpStatus.OK.value())
|
||||
.reason(HttpStatus.OK.getReasonPhrase())
|
||||
.headers(headers)
|
||||
.request(request)
|
||||
.body(body)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,7 +203,7 @@ public class ComplexInvokeClient implements Client {
|
||||
|
||||
private RpcInvokeModeEnum getInvokeMode(Request request) {
|
||||
Collection<String> invokeModel = request.headers().getOrDefault(STARTER_INVOKE_MODE,
|
||||
Collections.singletonList(starterProperties.getInvokeMode().name()));
|
||||
Collections.singletonList(starterProperties.getInvokeMode().name()));
|
||||
if (CollectionUtils.isEmpty(invokeModel)) {
|
||||
return starterProperties.getInvokeMode();
|
||||
} else if (invokeModel.size() > 1) {
|
||||
@ -214,8 +213,7 @@ public class ComplexInvokeClient implements Client {
|
||||
}
|
||||
|
||||
static Response.Body body = new Response.Body() {
|
||||
final ByteArrayInputStream inputStream = new ByteArrayInputStream(JSON.toJSONString(CommonResponse.success(HttpStatus.OK.value(), "Send MQ Success", null))
|
||||
.getBytes(UTF_8));
|
||||
final ByteArrayInputStream inputStream = new ByteArrayInputStream(JSON.toJSONString("Send MQ Success").getBytes(UTF_8));
|
||||
|
||||
@Override
|
||||
public Integer length() {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package cn.axzo.workflow.starter.feign.ext;
|
||||
|
||||
import cn.axzo.framework.jackson.utility.JSON;
|
||||
import cn.axzo.workflow.common.model.response.BpmPageResult;
|
||||
import cn.axzo.workflow.starter.common.exception.WorkflowEngineStarterException;
|
||||
import cn.axzo.workflow.starter.common.exception.WorkflowRpcInvokeException;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import com.google.common.collect.Lists;
|
||||
@ -72,6 +72,7 @@ final class WorkflowEngineStarterDecoder implements Decoder {
|
||||
wrappedType = ParameterizedTypeImpl.make(CommonResponse.class, new Type[]{type}, null);
|
||||
}
|
||||
Object decode = delegate.decode(response, wrappedType);
|
||||
log.info("workflow engine starter response :{}", JSON.toJSONString(decode));
|
||||
if (decode instanceof CommonResponse) {
|
||||
CommonResponse<?> commonResponse = (CommonResponse<?>) decode;
|
||||
if (response.status() == 202) {
|
||||
|
||||
@ -31,7 +31,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
//import static cn.axzo.framework.web.filter.BasicRecordExceptionFilter.MICRO_SERVER_RECORD_ERROR_GET_PARAM_NAME;
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_API_VERSION;
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_HTTP_CLIENT;
|
||||
import static cn.axzo.workflow.client.config.WorkflowRequestInterceptor.HEADER_HTTP_CLIENT_VALUE;
|
||||
@ -69,7 +68,7 @@ public class WorkflowEngineStarterFeignConfiguration {
|
||||
@Bean
|
||||
public RequestInterceptor workflowEngineStarterRequestInterceptor(WorkflowEngineStarterProperties starterProperties,
|
||||
Environment environment,
|
||||
String serviceVersion) {
|
||||
@Qualifier("serviceVersion") String serviceVersion) {
|
||||
return template -> {
|
||||
// 接入应用上报
|
||||
template.header(HEADER_SERVER_NAME, environment.getProperty("spring.application.name"));
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package cn.axzo.workflow.starter.handler;
|
||||
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.framework.rocketmq.EventConsumer;
|
||||
import cn.axzo.workflow.common.model.response.mq.MessagePushDTO;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
@ -13,6 +15,18 @@ import org.springframework.core.Ordered;
|
||||
*/
|
||||
public interface MessageNotificationEventHandler extends Ordered {
|
||||
|
||||
/**
|
||||
* 针对当前接口的实现进行过滤, 为 true 时,往下执行下面的方法
|
||||
*
|
||||
* @param dto
|
||||
* @param event
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
default boolean accept(MessagePushDTO dto, Event event, EventConsumer.Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 站内信推送
|
||||
*
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package cn.axzo.workflow.starter.handler;
|
||||
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.framework.rocketmq.EventConsumer;
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessActivityDTO;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
@ -18,6 +20,18 @@ import org.springframework.core.Ordered;
|
||||
*/
|
||||
public interface ProcessActivityEventHandler extends Ordered {
|
||||
|
||||
/**
|
||||
* 针对当前接口的实现进行过滤, 为 true 时,往下执行下面的方法
|
||||
*
|
||||
* @param dto
|
||||
* @param event
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
default boolean accept(ProcessActivityDTO dto, Event event, EventConsumer.Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点已启动
|
||||
*
|
||||
@ -34,6 +48,14 @@ public interface ProcessActivityEventHandler extends Ordered {
|
||||
default void onWaitAssignee(ProcessActivityDTO dto) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务节点回调
|
||||
*
|
||||
* @param dto
|
||||
*/
|
||||
default void onCallback(ProcessActivityDTO dto) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点已完成
|
||||
*
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package cn.axzo.workflow.starter.handler;
|
||||
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.framework.rocketmq.EventConsumer;
|
||||
import cn.axzo.workflow.client.feign.bpmn.ProcessInstanceApi;
|
||||
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO;
|
||||
@ -15,6 +17,18 @@ import org.springframework.core.Ordered;
|
||||
*/
|
||||
public interface ProcessInstanceEventHandler extends Ordered {
|
||||
|
||||
/**
|
||||
* 针对当前接口的实现进行过滤, 为 true 时,往下执行下面的方法
|
||||
*
|
||||
* @param dto
|
||||
* @param event
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
default boolean accept(ProcessInstanceDTO dto, Event event, EventConsumer.Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程实例创建成功后回调
|
||||
*
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package cn.axzo.workflow.starter.handler;
|
||||
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.framework.rocketmq.EventConsumer;
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessTaskDTO;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
@ -15,6 +17,18 @@ import org.springframework.core.Ordered;
|
||||
*/
|
||||
public interface ProcessTaskEventHandler extends Ordered {
|
||||
|
||||
/**
|
||||
* 针对当前接口的实现进行过滤, 为 true 时,往下执行下面的方法
|
||||
*
|
||||
* @param dto
|
||||
* @param event
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
default boolean accept(ProcessTaskDTO dto, Event event, EventConsumer.Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户任务已指派审核人
|
||||
*/
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package cn.axzo.workflow.starter.handler.filter;
|
||||
|
||||
import cn.axzo.workflow.common.model.response.mq.MessagePushDTO;
|
||||
import cn.axzo.workflow.starter.handler.MessageNotificationEventHandler;
|
||||
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
|
||||
|
||||
/**
|
||||
* MessageNotificationEvent 的自定义过滤接口
|
||||
* <p>
|
||||
* 该接口的实现,是会全局过滤,比如当应用需要监听多个流程模型时,全局过滤会不精确,所以我们还提供了针对 {@link MessageNotificationEventHandler#filter(MessagePushDTO)} 实例的专属过滤
|
||||
* <p>
|
||||
* 注意:Order 的顺序,遵循值越小越优先。(取值范围:Integer. MIN_VALUE - Integer. MAX_VALUE)
|
||||
*
|
||||
* @author wangli
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package cn.axzo.workflow.starter.handler.filter;
|
||||
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessActivityDTO;
|
||||
import cn.axzo.workflow.starter.handler.ProcessActivityEventHandler;
|
||||
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
|
||||
|
||||
/**
|
||||
* ProcessActivityEvent 自定义的过滤接口
|
||||
* <p>
|
||||
* 该接口的实现,是会全局过滤,比如当应用需要监听多个流程模型时,全局过滤会不精确,所以我们还提供了针对 {@link ProcessActivityEventHandler#filter(ProcessActivityDTO)} 实例的专属过滤
|
||||
* <p>
|
||||
* 注意:Order 的顺序,遵循值越小越优先。(取值范围:Integer. MIN_VALUE - Integer. MAX_VALUE)
|
||||
*
|
||||
* @author wangli
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package cn.axzo.workflow.starter.handler.filter;
|
||||
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO;
|
||||
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
|
||||
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
|
||||
|
||||
/**
|
||||
* ProcessInstanceEvent 自定义的过滤接口
|
||||
* <p>
|
||||
* 该接口的实现,是会全局过滤,比如当应用需要监听多个流程模型时,全局过滤会不精确,所以我们还提供了针对 {@link ProcessInstanceEventHandler#filter(ProcessInstanceDTO)} 实例的专属过滤
|
||||
* <p>
|
||||
* 注意:Order 的顺序,遵循值越小越优先。(取值范围:Integer. MIN_VALUE - Integer. MAX_VALUE)
|
||||
*
|
||||
* @author wangli
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package cn.axzo.workflow.starter.handler.filter;
|
||||
|
||||
import cn.axzo.workflow.common.model.response.mq.ProcessTaskDTO;
|
||||
import cn.axzo.workflow.starter.handler.ProcessTaskEventHandler;
|
||||
import cn.axzo.workflow.starter.mq.broadcast.filter.BasicMessageQueueFilter;
|
||||
|
||||
/**
|
||||
* ProcessTaskEvent 自定义的过滤接口
|
||||
* <p>
|
||||
* 该接口的实现,是会全局过滤,比如当应用需要监听多个流程模型时,全局过滤会不精确,所以我们还提供了针对 {@link ProcessTaskEventHandler#filter(ProcessTaskDTO)} 实例的专属过滤
|
||||
* <p>
|
||||
* 注意:Order 的顺序,遵循值越小越优先。(取值范围:Integer. MIN_VALUE - Integer. MAX_VALUE)
|
||||
*
|
||||
* @author wangli
|
||||
|
||||
@ -54,25 +54,23 @@ public abstract class AbstractInnerWorkflowListener<H extends Ordered, F extends
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event event, EventConsumer.Context context) {
|
||||
if (CollectionUtils.isEmpty(businessListeners)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Target convert = convert(event);
|
||||
|
||||
for (F filter : businessFilters) {
|
||||
if (filter.doFilter(event, context, convert)) {
|
||||
log.info("【{}】filtered message, messageId: {}", filter.getClass().getSimpleName(), context.getMsgId());
|
||||
return;
|
||||
if (!CollectionUtils.isEmpty(businessListeners)) {
|
||||
for (F filter : businessFilters) {
|
||||
if (filter.doFilter(event, context, convert)) {
|
||||
log.info("【{}】filtered message, messageId: {}", filter.getClass().getSimpleName(), context.getMsgId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onEvent(convert, context);
|
||||
onEvent(convert, event, context);
|
||||
}
|
||||
|
||||
protected abstract Target convert(Event event);
|
||||
|
||||
protected abstract void onEvent(Target data, EventConsumer.Context context);
|
||||
protected abstract void onEvent(Target data, Event event, EventConsumer.Context context);
|
||||
|
||||
@Override
|
||||
public boolean dispatch(Event event) {
|
||||
|
||||
@ -40,7 +40,7 @@ public class InnerActivityEventListener extends AbstractInnerWorkflowListener<Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(ProcessActivityDTO dto, EventConsumer.Context context) {
|
||||
public void onEvent(ProcessActivityDTO dto, Event event, EventConsumer.Context context) {
|
||||
log.debug("【{}】new message begin processing, messageId: {}",
|
||||
this.getClass().getSimpleName(), context.getMsgId());
|
||||
ProcessActivityEventEnum type = dto.getType();
|
||||
@ -53,6 +53,9 @@ public class InnerActivityEventListener extends AbstractInnerWorkflowListener<Pr
|
||||
case PROCESS_ACTIVITY_WAIT_ASSIGNEE:
|
||||
consumer = activityListener::onWaitAssignee;
|
||||
break;
|
||||
case PROCESS_ACTIVITY_CALLBACK:
|
||||
consumer = activityListener::onCallback;
|
||||
break;
|
||||
case PROCESS_ACTIVITY_TAKE:
|
||||
consumer = activityListener::onTake;
|
||||
break;
|
||||
@ -62,7 +65,9 @@ public class InnerActivityEventListener extends AbstractInnerWorkflowListener<Pr
|
||||
default:
|
||||
log.warn("unknown process activity event type: {}", type);
|
||||
}
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
if (activityListener.accept(dto, event, context)) {
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ public class InnerInstanceEventListener extends AbstractInnerWorkflowListener<Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(ProcessInstanceDTO dto, EventConsumer.Context context) {
|
||||
public void onEvent(ProcessInstanceDTO dto, Event event, EventConsumer.Context context) {
|
||||
log.debug("【{}】new message begin processing, messageId: {}",
|
||||
this.getClass().getSimpleName(), context.getMsgId());
|
||||
ProcessInstanceEventEnum type = dto.getType();
|
||||
@ -68,7 +68,9 @@ public class InnerInstanceEventListener extends AbstractInnerWorkflowListener<Pr
|
||||
default:
|
||||
log.warn("unknown process activity event type: {}", type);
|
||||
}
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
if (instanceListener.accept(dto, event, context)) {
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ public class InnerNotificationEventListener extends AbstractInnerWorkflowListene
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(MessagePushDTO dto, EventConsumer.Context context) {
|
||||
public void onEvent(MessagePushDTO dto, Event event, EventConsumer.Context context) {
|
||||
log.debug("【{}】new message begin processing, messageId: {}",
|
||||
this.getClass().getSimpleName(), context.getMsgId());
|
||||
ProcessMessagePushEventEnum type = dto.getType();
|
||||
@ -69,7 +69,9 @@ public class InnerNotificationEventListener extends AbstractInnerWorkflowListene
|
||||
default:
|
||||
log.warn("unknown message event type: {}", type);
|
||||
}
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
if (noticeListener.accept(dto, event, context)) {
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ public class InnerTaskEventListener extends AbstractInnerWorkflowListener<Proces
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(ProcessTaskDTO dto, EventConsumer.Context context) {
|
||||
public void onEvent(ProcessTaskDTO dto, Event event, EventConsumer.Context context) {
|
||||
log.debug("【{}】new message begin processing, messageId: {}",
|
||||
this.getClass().getSimpleName(), context.getMsgId());
|
||||
ProcessTaskEventEnum type = dto.getType();
|
||||
@ -60,7 +60,9 @@ public class InnerTaskEventListener extends AbstractInnerWorkflowListener<Proces
|
||||
default:
|
||||
log.warn("unknown task event type: {}", type);
|
||||
}
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
if (taskListener.accept(dto, event, context)) {
|
||||
listenerExecutor.execute(consumer, context, dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user