From e23dd75c3c25702691b6a4ddeac664ac1bb5f2ef Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 15:16:33 +0800 Subject: [PATCH 01/20] =?UTF-8?q?hotfix/improve-batch-operation=20-=20?= =?UTF-8?q?=E9=99=90=E5=88=B6=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C=E5=90=8C?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/conf/FlowableConfiguration.java | 9 +- .../core/engine/cmd/AbstractCommand.java | 12 ++ .../cmd/CustomAbortProcessInstanceCmd.java | 10 +- .../core/engine/cmd/CustomApproveTaskCmd.java | 16 +- .../cmd/CustomCancelProcessInstanceCmd.java | 12 +- .../engine/cmd/CustomRejectionTaskCmd.java | 18 ++- .../CustomLockProcessInstanceInterceptor.java | 148 ++++++++++++++++++ 7 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index 15302a561..1860b1b7b 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -3,6 +3,7 @@ package cn.axzo.workflow.core.conf; import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory; import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory; import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator; +import cn.axzo.workflow.core.engine.interceptor.CustomLockProcessInstanceInterceptor; import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler; import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler; import cn.axzo.workflow.core.engine.job.AsyncBpmnProcessActivityJobHandler; @@ -30,6 +31,8 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; import java.time.Duration; import java.util.List; @@ -56,7 +59,8 @@ public class FlowableConfiguration { BpmnProcessActivityService bpmnProcessActivityService, List jobProcessors, NacosServiceManager nacosServiceManager, - NacosDiscoveryProperties nacosDiscoveryProperties) { + NacosDiscoveryProperties nacosDiscoveryProperties, + StringRedisTemplate redisTemplate) { return configuration -> { configuration.setEnableHistoricTaskLogging(true); configuration.setHistoryLevel(HistoryLevel.AUDIT); @@ -92,6 +96,9 @@ public class FlowableConfiguration { new CustomWorkflowEngineExceptionHandler(), new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); + configuration.setCustomPreCommandInterceptors(Lists.newArrayList( + new CustomLockProcessInstanceInterceptor(redisTemplate) + )); }; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java new file mode 100644 index 000000000..ed5aae60b --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java @@ -0,0 +1,12 @@ +package cn.axzo.workflow.core.engine.cmd; + +/** + * TODO + * + * @author wangli + * @since 2024/7/1 13:59 + */ +public abstract class AbstractCommand { + + public abstract String getProcessInstanceId(); +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java index 15a121697..0bd434a7a 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java @@ -44,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir * @author wangli * @since 2024/1/2 18:19 */ -public class CustomAbortProcessInstanceCmd implements Command, Serializable { +public class CustomAbortProcessInstanceCmd extends AbstractCommand implements Command, Serializable { private final String processInstanceId; private final String tenantId; private final String reason; @@ -102,4 +102,12 @@ public class CustomAbortProcessInstanceCmd implements Command, Serializabl runtimeService.setVariable(task.getProcessInstanceId(), TASK_COMPLETE_OPERATION_TYPE + task.getId(), ABORTED); return null; } + + @Override + public String getProcessInstanceId() { + if (StringUtils.hasText(processInstanceId)) { + return processInstanceId; + } + return null; + } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java index 9bdaabe5f..f891b67a4 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java @@ -10,6 +10,7 @@ import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.impl.context.Context; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.task.api.Task; import org.flowable.task.api.history.HistoricTaskInstance; @@ -38,7 +39,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @author wangli * @since 2024/1/4 15:50 */ -public class CustomApproveTaskCmd implements Command, Serializable { +public class CustomApproveTaskCmd extends AbstractCommand implements Command, Serializable { private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskCmd.class); private final String taskId; @@ -146,4 +147,17 @@ public class CustomApproveTaskCmd implements Command, Serializable { } } + @Override + public String getProcessInstanceId() { + ProcessEngineConfigurationImpl processEngineConfiguration = + CommandContextUtil.getProcessEngineConfiguration(Context.getCommandContext()); + HistoricTaskInstanceQuery taskQuery = + processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); + + HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult(); + if (Objects.isNull(historicTaskInstance)) { + return null; + } + return historicTaskInstance.getProcessInstanceId(); + } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java index 93c447265..540378165 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java @@ -1,5 +1,6 @@ package cn.axzo.workflow.core.engine.cmd; +import cn.axzo.framework.context.validation.SpringValidator; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation; @@ -12,6 +13,7 @@ import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.task.api.Task; +import org.springframework.util.StringUtils; import java.io.Serializable; import java.util.HashMap; @@ -41,7 +43,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir * @author wangli * @since 2024/1/2 18:19 */ -public class CustomCancelProcessInstanceCmd implements Command, Serializable { +public class CustomCancelProcessInstanceCmd extends AbstractCommand implements Command, Serializable { private final String processInstanceId; private final String tenantId; private final String reason; @@ -102,4 +104,12 @@ public class CustomCancelProcessInstanceCmd implements Command, Serializab addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已撤回"); return null; } + + @Override + public String getProcessInstanceId() { + if (StringUtils.hasText(processInstanceId)) { + return processInstanceId; + } + return null; + } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java index b1f559d6c..7b47c6c1d 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java @@ -11,6 +11,7 @@ import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.flowable.engine.impl.context.Context; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.task.api.Task; import org.flowable.task.api.history.HistoricTaskInstance; @@ -21,6 +22,7 @@ import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG; @@ -42,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @author wangli * @since 2024/1/4 13:36 */ -public class CustomRejectionTaskCmd implements Command, Serializable { +public class CustomRejectionTaskCmd extends AbstractCommand implements Command, Serializable { private final String taskId; private final String advice; @@ -99,4 +101,18 @@ public class CustomRejectionTaskCmd implements Command, Serializable { .planOperation(new DeleteProcessInstanceOperation(commandContext, task.getProcessInstanceId(), extAxHiTaskInstService)); } + + @Override + public String getProcessInstanceId() { + ProcessEngineConfigurationImpl processEngineConfiguration = + CommandContextUtil.getProcessEngineConfiguration(Context.getCommandContext()); + HistoricTaskInstanceQuery taskQuery = + processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); + + HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult(); + if (Objects.isNull(historicTaskInstance)) { + return null; + } + return historicTaskInstance.getProcessInstanceId(); + } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java new file mode 100644 index 000000000..cb9f25af6 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -0,0 +1,148 @@ +package cn.axzo.workflow.core.engine.interceptor; + +import cn.axzo.workflow.core.engine.cmd.AbstractCommand; +import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandConfig; +import org.flowable.common.engine.impl.interceptor.CommandExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisStringCommands; +import org.springframework.data.redis.connection.ReturnType; +import org.springframework.data.redis.core.RedisConnectionUtils; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.types.Expiration; + +import java.nio.charset.Charset; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * 增加一个拦截器,用来控制多个操作,不允许同时操作同一个实例 + * + * @author wangli + * @since 2024/7/1 13:51 + */ +public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterceptor { + private String key_prefix = "operation:processInstance:"; + /** + * 解锁脚本,原子操作 + */ + private static final String unlockScript = + "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" + + "then\n" + + " return redis.call(\"del\",KEYS[1])\n" + + "else\n" + + " return 0\n" + + "end"; + private static final Logger log = LoggerFactory.getLogger(CustomLockProcessInstanceInterceptor.class); + private final StringRedisTemplate redisTemplate; + + public CustomLockProcessInstanceInterceptor(StringRedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + @Override + public T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { + if (AbstractCommand.class.isAssignableFrom(command.getClass())) { + AbstractCommand abstractCommand = (AbstractCommand) command; + String token = null; + try { + do { + token = getLock(abstractCommand.getProcessInstanceId(), 10 * 1000, 11 * 1000); + } while (Objects.isNull(token)); + return next.execute(config, command, commandExecutor); + } finally { + if (token != null) { + unlock(abstractCommand.getProcessInstanceId(), token); + } + } + } + return next.execute(config, command, commandExecutor); + } + + /** + * 加锁,有阻塞 + * + * @param name key的值 + * @param expire 过期时间 + * @param timeout 加锁执行超时时间 + * @return + */ + public String getLock(String name, long expire, long timeout) { + long startTime = System.currentTimeMillis(); //获取开始时间 + String token; + //规定的时间内,循环获取有值的token + do { + token = tryGetLock(name, expire); //获取秘钥Key + if (token == null) { + if ((System.currentTimeMillis() - startTime) > (timeout - 50)) + break; + try { + Thread.sleep(50); //try 50毫秒 per sec milliseconds + } catch (InterruptedException e) { + log.warn("getLock error: {}", e.getMessage(), e); + return null; + } + } + } while (token == null); + return token; + } + + /** + * 加锁,无阻塞 + * + * @param name 设置key + * @param expire + * @return + */ + public String tryGetLock(String name, long expire) { + //获取UUID值为value + String token = UUID.randomUUID().toString(); + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection conn = factory.getConnection(); + try { + Boolean result = conn.set(name.getBytes(Charset.forName("UTF-8")), //设置name为key + token.getBytes(Charset.forName("UTF-8")), //设置token为value +// Expiration.from(expire, TimeUnit.MILLISECONDS), //设置过期时间:MILLISECONDS毫秒 + Expiration.persistent(), + RedisStringCommands.SetOption.SET_IF_ABSENT); //如果name不存在创建 + if (result != null && result) + return token; + } finally { + RedisConnectionUtils.releaseConnection(conn, factory); + } + return null; + } + + /** + * 功能描述:使用Lua脚本解锁 + * + * @MethodName: unlock + * @MethodParam: [name, token] + * @Return: boolean + * @Author: yyalin + * @CreateDate: 2023/7/17 18:41 + */ + public boolean unlock(String name, String token) { + byte[][] keysAndArgs = new byte[2][]; + keysAndArgs[0] = name.getBytes(Charset.forName("UTF-8")); //lock_key + keysAndArgs[1] = token.getBytes(Charset.forName("UTF-8")); //token的值,也即唯一标识符 + RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); + RedisConnection conn = factory.getConnection(); + try { + Long result = (Long) conn.scriptingCommands().eval(unlockScript.getBytes(Charset.forName("UTF-8")), + ReturnType.INTEGER, 1, keysAndArgs); + if (result != null && result > 0) + return true; + } finally { + RedisConnectionUtils.releaseConnection(conn, factory); + } + return false; + } + + +} From 018c4bb9eb64f05729ab9039d537c323e7448453 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 15:17:36 +0800 Subject: [PATCH 02/20] =?UTF-8?q?hotfix/improve-batch-operation=20-=20?= =?UTF-8?q?=E9=99=90=E5=88=B6=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C=E5=90=8C?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/CustomLockProcessInstanceInterceptor.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java index cb9f25af6..5906ff39f 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -18,7 +18,6 @@ import org.springframework.data.redis.core.types.Expiration; import java.nio.charset.Charset; import java.util.Objects; import java.util.UUID; -import java.util.concurrent.TimeUnit; /** * 增加一个拦截器,用来控制多个操作,不允许同时操作同一个实例 @@ -27,7 +26,7 @@ import java.util.concurrent.TimeUnit; * @since 2024/7/1 13:51 */ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterceptor { - private String key_prefix = "operation:processInstance:"; + private static final String KEY_PREFIX = "operation:processInstance:"; /** * 解锁脚本,原子操作 */ @@ -52,7 +51,7 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce String token = null; try { do { - token = getLock(abstractCommand.getProcessInstanceId(), 10 * 1000, 11 * 1000); + token = getLock(KEY_PREFIX + abstractCommand.getProcessInstanceId(), 10 * 1000, 11 * 1000); } while (Objects.isNull(token)); return next.execute(config, command, commandExecutor); } finally { From 284ac47e7d1146e144a8c7a61befd0e21d21efad Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 15:39:01 +0800 Subject: [PATCH 03/20] =?UTF-8?q?update=20-=20=E5=B0=86=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=86=85=E6=AD=A3=E5=B8=B8=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=90=9E=E5=B9=B6,=20=E4=BD=86=E4=BB=8D?= =?UTF-8?q?=E7=84=B6=E8=AE=B0=E5=BD=95=E5=BC=82=E5=B8=B8=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomWorkflowEngineExceptionHandler.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java index 352b104ec..80ef948ed 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/exception/handle/CustomWorkflowEngineExceptionHandler.java @@ -19,15 +19,16 @@ public class CustomWorkflowEngineExceptionHandler implements AsyncRunnableExecut @Override public boolean handleException(JobServiceConfiguration jobServiceConfiguration, JobInfo job, Throwable e) { Throwable rootCause = getRootCause(e); - if (rootCause.getClass().isAssignableFrom(WorkflowEngineException.class)) { - WorkflowEngineException workflowEngineException = (WorkflowEngineException) rootCause; - if (Objects.equals(workflowEngineException.getCode(), "99806020")) { - log.info("AsyncApproveTaskJobHandler execute exception code: {} info: {}", - workflowEngineException.getCode(), rootCause.getMessage(), rootCause); - return true; - } - } - return false; +// if (rootCause.getClass().isAssignableFrom(WorkflowEngineException.class)) { +// WorkflowEngineException workflowEngineException = (WorkflowEngineException) rootCause; +// if (Objects.equals(workflowEngineException.getCode(), "99806020")) { +// log.info("AsyncApproveTaskJobHandler execute exception code: {} info: {}", +// workflowEngineException.getCode(), rootCause.getMessage(), rootCause); +// return true; +// } +// } + log.warn("Async Runnable Execution Exception: {}", rootCause.getMessage(), e); + return WorkflowEngineException.class.isAssignableFrom(rootCause.getClass()); } private Throwable getRootCause(Throwable throwable) { From 959361af554396de4004d227db77626f261d691e Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 20:31:35 +0800 Subject: [PATCH 04/20] =?UTF-8?q?update=20-=20=E6=9A=82=E6=97=B6=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=AE=9E=E4=BE=8B=20ID=20=E5=88=86=E5=B8=83=E5=BC=8F?= =?UTF-8?q?=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/workflow/core/conf/FlowableConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index 1860b1b7b..fe8f1ea90 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -97,7 +97,7 @@ public class FlowableConfiguration { new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); configuration.setCustomPreCommandInterceptors(Lists.newArrayList( - new CustomLockProcessInstanceInterceptor(redisTemplate) +// new CustomLockProcessInstanceInterceptor(redisTemplate) )); }; } From c81ff4e58da5af992ba731d64d068ca9d36a2379 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 20:45:10 +0800 Subject: [PATCH 05/20] =?UTF-8?q?update=20-=20=E6=9A=82=E6=97=B6=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=AE=9E=E4=BE=8B=20ID=20=E5=88=86=E5=B8=83=E5=BC=8F?= =?UTF-8?q?=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/CustomLockProcessInstanceInterceptor.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java index 5906ff39f..a96d5687d 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -52,9 +52,11 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce try { do { token = getLock(KEY_PREFIX + abstractCommand.getProcessInstanceId(), 10 * 1000, 11 * 1000); + log.info(" threadName: {}, token: {}", Thread.currentThread().getName(), token); } while (Objects.isNull(token)); return next.execute(config, command, commandExecutor); } finally { + log.info("finally unlock threadName: {}, token: {}", Thread.currentThread().getName(), token); if (token != null) { unlock(abstractCommand.getProcessInstanceId(), token); } @@ -111,6 +113,10 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce RedisStringCommands.SetOption.SET_IF_ABSENT); //如果name不存在创建 if (result != null && result) return token; + } catch (Exception e) { + unlock(name, token); + log.warn("tryGetLock error: {}", e.getMessage(), e); + return null; } finally { RedisConnectionUtils.releaseConnection(conn, factory); } From 278d4d989d57b4d90dfb9d257cef060da4980730 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 20:49:49 +0800 Subject: [PATCH 06/20] =?UTF-8?q?update=20-=20=E6=B5=8B=E8=AF=95=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/workflow/core/conf/FlowableConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index fe8f1ea90..1860b1b7b 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -97,7 +97,7 @@ public class FlowableConfiguration { new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); configuration.setCustomPreCommandInterceptors(Lists.newArrayList( -// new CustomLockProcessInstanceInterceptor(redisTemplate) + new CustomLockProcessInstanceInterceptor(redisTemplate) )); }; } From 439a2ceac511a3dbb9799df6e1b5d7d5d44a554f Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Mon, 1 Jul 2024 20:55:30 +0800 Subject: [PATCH 07/20] =?UTF-8?q?update=20-=20=E6=B5=8B=E8=AF=95=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/CustomLockProcessInstanceInterceptor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java index a96d5687d..44294fc89 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -45,7 +45,7 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce } @Override - public T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { + public final T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { if (AbstractCommand.class.isAssignableFrom(command.getClass())) { AbstractCommand abstractCommand = (AbstractCommand) command; String token = null; @@ -143,6 +143,10 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce ReturnType.INTEGER, 1, keysAndArgs); if (result != null && result > 0) return true; + } catch (Exception e) { + log.warn("unlock error: {}", e.getMessage(), e); +// unlock(name, token); + return false; } finally { RedisConnectionUtils.releaseConnection(conn, factory); } From 67865c8be0cef11e31fd640da50149e5426e6784 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Tue, 2 Jul 2024 09:41:00 +0800 Subject: [PATCH 08/20] =?UTF-8?q?update=20-=20=E6=B5=8B=E8=AF=95=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomLockProcessInstanceInterceptor.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java index 44294fc89..6638e1698 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -1,6 +1,7 @@ package cn.axzo.workflow.core.engine.interceptor; import cn.axzo.workflow.core.engine.cmd.AbstractCommand; +import liquibase.pro.packaged.T; import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandConfig; @@ -58,7 +59,7 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce } finally { log.info("finally unlock threadName: {}, token: {}", Thread.currentThread().getName(), token); if (token != null) { - unlock(abstractCommand.getProcessInstanceId(), token); + unlock(KEY_PREFIX + abstractCommand.getProcessInstanceId(), token); } } } @@ -141,16 +142,22 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce try { Long result = (Long) conn.scriptingCommands().eval(unlockScript.getBytes(Charset.forName("UTF-8")), ReturnType.INTEGER, 1, keysAndArgs); - if (result != null && result > 0) + if (result != null && result > 0) { return true; + } else { + throw new IllegalStateException("unLock ProcessInstance fail"); + } } catch (Exception e) { log.warn("unlock error: {}", e.getMessage(), e); -// unlock(name, token); - return false; + try { + Thread.sleep(1000L); + } catch (InterruptedException ex) { + // ignore + } + return unlock(name, token); } finally { RedisConnectionUtils.releaseConnection(conn, factory); } - return false; } From 8326f878e5084b98c52f7463b3fd13f075e57912 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Tue, 2 Jul 2024 09:48:02 +0800 Subject: [PATCH 09/20] =?UTF-8?q?update=20-=20=E6=B5=8B=E8=AF=95=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomLockProcessInstanceInterceptor.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java index 6638e1698..fedcdaa15 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -17,6 +17,7 @@ import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.types.Expiration; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Objects; import java.util.UUID; @@ -107,15 +108,18 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); RedisConnection conn = factory.getConnection(); try { - Boolean result = conn.set(name.getBytes(Charset.forName("UTF-8")), //设置name为key - token.getBytes(Charset.forName("UTF-8")), //设置token为value + Boolean result = conn.set(name.getBytes(StandardCharsets.UTF_8), //设置name为key + token.getBytes(StandardCharsets.UTF_8), //设置token为value // Expiration.from(expire, TimeUnit.MILLISECONDS), //设置过期时间:MILLISECONDS毫秒 Expiration.persistent(), RedisStringCommands.SetOption.SET_IF_ABSENT); //如果name不存在创建 - if (result != null && result) + log.info("tryGetLock result: {}", result); + if (Objects.isNull(result)) { + throw new IllegalStateException("tryGetLock processInstance fail"); + } + if (result) return token; } catch (Exception e) { - unlock(name, token); log.warn("tryGetLock error: {}", e.getMessage(), e); return null; } finally { @@ -142,11 +146,10 @@ public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterce try { Long result = (Long) conn.scriptingCommands().eval(unlockScript.getBytes(Charset.forName("UTF-8")), ReturnType.INTEGER, 1, keysAndArgs); - if (result != null && result > 0) { - return true; - } else { - throw new IllegalStateException("unLock ProcessInstance fail"); + if (Objects.isNull(result)) { + throw new IllegalStateException("unLock processInstance fail"); } + return result > 0; } catch (Exception e) { log.warn("unlock error: {}", e.getMessage(), e); try { From d8f428150c340ba48c1caeeffc3eaed42535f39c Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Tue, 2 Jul 2024 10:41:37 +0800 Subject: [PATCH 10/20] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=A2=84=E6=B5=8B=E6=B5=81=E7=A8=8B=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E7=BB=93=E6=9D=9F=E5=AF=BC=E8=87=B4=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cmd/CustomCarbonCopyUserSelectorCmd.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java index f43a8bb8b..3e5f736f7 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java @@ -10,6 +10,7 @@ import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.CustomProperty; import org.flowable.bpmn.model.ServiceTask; import org.flowable.common.engine.impl.interceptor.Command; @@ -33,6 +34,7 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO; import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE; @@ -45,6 +47,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDup * @author wangli * @since 18/03/2024 11:33 */ +@Slf4j public class CustomCarbonCopyUserSelectorCmd implements Command>, Serializable { private static final long serialVersionUID = 1L; @@ -97,6 +100,17 @@ public class CustomCarbonCopyUserSelectorCmd implements Command hisVarInst = processEngineConfiguration.getHistoryService().createHistoricVariableInstanceQuery() + .processInstanceId(processInstanceId) + .variableName(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + serviceTask.getId()).list(); + if (!CollectionUtils.isEmpty(hisVarInst)) { + return (List) hisVarInst.get(0).getValue(); + } + log.warn("executions is empty,get historic task assigner list empty,processInstanceId: {},serviceTaskId: {}", processInstanceId, serviceTask.getId()); + return Collections.emptyList(); + } List assigners = new ArrayList<>(); carbons.forEach(carbon -> { CarbonCopyObjectType carbonCopyObjectType = carbon.getCarbonCopyObjectType(); From fcbdd78ff1d06a6958a803d625768cec9ca0eb8f Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Tue, 2 Jul 2024 11:06:48 +0800 Subject: [PATCH 11/20] =?UTF-8?q?update=20-=20=E6=B5=8B=E8=AF=95=E5=88=86?= =?UTF-8?q?=E5=B8=83=E5=BC=8F=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/workflow/core/conf/FlowableConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index 1860b1b7b..fe8f1ea90 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -97,7 +97,7 @@ public class FlowableConfiguration { new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); configuration.setCustomPreCommandInterceptors(Lists.newArrayList( - new CustomLockProcessInstanceInterceptor(redisTemplate) +// new CustomLockProcessInstanceInterceptor(redisTemplate) )); }; } From 8a0affbf44b87a02b3ba3918130cf62a22c4f741 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Tue, 2 Jul 2024 18:20:29 +0800 Subject: [PATCH 12/20] =?UTF-8?q?update=20-=20=E7=A7=BB=E9=99=A4=E8=AF=BB?= =?UTF-8?q?=20API=20=E7=9A=84=E9=98=B2=E9=87=8D=E6=8F=90=E4=BA=A4=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/web/bpmn/BpmnProcessInstanceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java index af74fb7ef..173adfd8b 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessInstanceController.java @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.annotations.Operation; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.history.HistoricProcessInstance; +import org.springframework.cache.annotation.CachePut; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -268,7 +269,6 @@ public class BpmnProcessInstanceController implements ProcessInstanceApi { @Operation(summary = "获取指定流程实例的流程变量") @GetMapping("/cooperation-org") @Override - @RepeatSubmit public CommonResponse> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId, @Nullable String tenantId) { HistoricProcessInstance processInstance = bpmnProcessInstanceService.getProcessInstance(processInstanceId, From 78cf58423d95e0f5b980bc4d7cdec1464bdb2e3d Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Tue, 2 Jul 2024 19:04:01 +0800 Subject: [PATCH 13/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/conf/FlowableConfiguration.java | 3 +- .../CustomLockProcessInstanceInterceptor.java | 193 +++++------------- 2 files changed, 56 insertions(+), 140 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index fe8f1ea90..769d3651a 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -23,6 +23,7 @@ import com.alibaba.cloud.nacos.NacosServiceManager; import com.google.common.collect.Lists; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.common.engine.impl.history.HistoryLevel; +import org.flowable.common.engine.impl.interceptor.RetryInterceptor; import org.flowable.form.spring.SpringFormEngineConfiguration; import org.flowable.job.service.JobProcessor; import org.flowable.spring.SpringProcessEngineConfiguration; @@ -97,7 +98,7 @@ public class FlowableConfiguration { new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); configuration.setCustomPreCommandInterceptors(Lists.newArrayList( -// new CustomLockProcessInstanceInterceptor(redisTemplate) + new CustomLockProcessInstanceInterceptor() )); }; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java index fedcdaa15..f15ab3040 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java @@ -1,25 +1,12 @@ package cn.axzo.workflow.core.engine.interceptor; -import cn.axzo.workflow.core.engine.cmd.AbstractCommand; -import liquibase.pro.packaged.T; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.exceptions.PersistenceException; +import org.flowable.common.engine.api.FlowableException; import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandConfig; import org.flowable.common.engine.impl.interceptor.CommandExecutor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.redis.connection.RedisConnection; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.connection.RedisStringCommands; -import org.springframework.data.redis.connection.ReturnType; -import org.springframework.data.redis.core.RedisConnectionUtils; -import org.springframework.data.redis.core.StringRedisTemplate; -import org.springframework.data.redis.core.types.Expiration; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Objects; -import java.util.UUID; /** * 增加一个拦截器,用来控制多个操作,不允许同时操作同一个实例 @@ -27,141 +14,69 @@ import java.util.UUID; * @author wangli * @since 2024/7/1 13:51 */ +@Slf4j public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterceptor { - private static final String KEY_PREFIX = "operation:processInstance:"; - /** - * 解锁脚本,原子操作 - */ - private static final String unlockScript = - "if redis.call(\"get\",KEYS[1]) == ARGV[1]\n" - + "then\n" - + " return redis.call(\"del\",KEYS[1])\n" - + "else\n" - + " return 0\n" - + "end"; - private static final Logger log = LoggerFactory.getLogger(CustomLockProcessInstanceInterceptor.class); - private final StringRedisTemplate redisTemplate; - public CustomLockProcessInstanceInterceptor(StringRedisTemplate redisTemplate) { - this.redisTemplate = redisTemplate; - } + protected int numOfRetries = 3; + protected int waitTimeInMs = 50; + protected int waitIncreaseFactor = 5; @Override - public final T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { - if (AbstractCommand.class.isAssignableFrom(command.getClass())) { - AbstractCommand abstractCommand = (AbstractCommand) command; - String token = null; - try { - do { - token = getLock(KEY_PREFIX + abstractCommand.getProcessInstanceId(), 10 * 1000, 11 * 1000); - log.info(" threadName: {}, token: {}", Thread.currentThread().getName(), token); - } while (Objects.isNull(token)); - return next.execute(config, command, commandExecutor); - } finally { - log.info("finally unlock threadName: {}, token: {}", Thread.currentThread().getName(), token); - if (token != null) { - unlock(KEY_PREFIX + abstractCommand.getProcessInstanceId(), token); - } - } - } - return next.execute(config, command, commandExecutor); - } + public T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { + long waitTime = waitTimeInMs; + int failedAttempts = 0; - /** - * 加锁,有阻塞 - * - * @param name key的值 - * @param expire 过期时间 - * @param timeout 加锁执行超时时间 - * @return - */ - public String getLock(String name, long expire, long timeout) { - long startTime = System.currentTimeMillis(); //获取开始时间 - String token; - //规定的时间内,循环获取有值的token do { - token = tryGetLock(name, expire); //获取秘钥Key - if (token == null) { - if ((System.currentTimeMillis() - startTime) > (timeout - 50)) - break; - try { - Thread.sleep(50); //try 50毫秒 per sec milliseconds - } catch (InterruptedException e) { - log.warn("getLock error: {}", e.getMessage(), e); - return null; - } + if (failedAttempts > 0) { + log.warn("Waiting for {}ms before retrying the command.", waitTime); + waitBeforeRetry(waitTime); + waitTime *= waitIncreaseFactor; } - } while (token == null); - return token; - } - /** - * 加锁,无阻塞 - * - * @param name 设置key - * @param expire - * @return - */ - public String tryGetLock(String name, long expire) { - //获取UUID值为value - String token = UUID.randomUUID().toString(); - RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); - RedisConnection conn = factory.getConnection(); - try { - Boolean result = conn.set(name.getBytes(StandardCharsets.UTF_8), //设置name为key - token.getBytes(StandardCharsets.UTF_8), //设置token为value -// Expiration.from(expire, TimeUnit.MILLISECONDS), //设置过期时间:MILLISECONDS毫秒 - Expiration.persistent(), - RedisStringCommands.SetOption.SET_IF_ABSENT); //如果name不存在创建 - log.info("tryGetLock result: {}", result); - if (Objects.isNull(result)) { - throw new IllegalStateException("tryGetLock processInstance fail"); - } - if (result) - return token; - } catch (Exception e) { - log.warn("tryGetLock error: {}", e.getMessage(), e); - return null; - } finally { - RedisConnectionUtils.releaseConnection(conn, factory); - } - return null; - } - - /** - * 功能描述:使用Lua脚本解锁 - * - * @MethodName: unlock - * @MethodParam: [name, token] - * @Return: boolean - * @Author: yyalin - * @CreateDate: 2023/7/17 18:41 - */ - public boolean unlock(String name, String token) { - byte[][] keysAndArgs = new byte[2][]; - keysAndArgs[0] = name.getBytes(Charset.forName("UTF-8")); //lock_key - keysAndArgs[1] = token.getBytes(Charset.forName("UTF-8")); //token的值,也即唯一标识符 - RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); - RedisConnection conn = factory.getConnection(); - try { - Long result = (Long) conn.scriptingCommands().eval(unlockScript.getBytes(Charset.forName("UTF-8")), - ReturnType.INTEGER, 1, keysAndArgs); - if (Objects.isNull(result)) { - throw new IllegalStateException("unLock processInstance fail"); - } - return result > 0; - } catch (Exception e) { - log.warn("unlock error: {}", e.getMessage(), e); try { - Thread.sleep(1000L); - } catch (InterruptedException ex) { - // ignore + + // try to execute the command + return next.execute(config, command, commandExecutor); + + } catch (PersistenceException e) { + log.error("Caught persistence exception: {}", e.getMessage(), e); } - return unlock(name, token); - } finally { - RedisConnectionUtils.releaseConnection(conn, factory); + + failedAttempts++; + } while (failedAttempts <= numOfRetries); + + throw new FlowableException(numOfRetries + " retries failed with FlowableOptimisticLockingException. Giving up."); + } + + protected void waitBeforeRetry(long waitTime) { + try { + Thread.sleep(waitTime); + } catch (InterruptedException e) { + log.error("I am interrupted while waiting for a retry."); } } + public void setNumOfRetries(int numOfRetries) { + this.numOfRetries = numOfRetries; + } + public void setWaitIncreaseFactor(int waitIncreaseFactor) { + this.waitIncreaseFactor = waitIncreaseFactor; + } + + public void setWaitTimeInMs(int waitTimeInMs) { + this.waitTimeInMs = waitTimeInMs; + } + + public int getNumOfRetries() { + return numOfRetries; + } + + public int getWaitIncreaseFactor() { + return waitIncreaseFactor; + } + + public int getWaitTimeInMs() { + return waitTimeInMs; + } } From 5334b67e644930291e4a19bd1f7ae8845c00d439 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 10:47:22 +0800 Subject: [PATCH 14/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/code/FlowableEngineRespCode.java | 2 + .../workflow/core/common/utils/TraceUtil.java | 24 +++++ .../core/conf/FlowableConfiguration.java | 6 +- .../core/engine/cmd/AbstractCommand.java | 7 +- .../CustomAbortProcessInstanceAsyncCmd.java | 10 +- .../cmd/CustomAbortProcessInstanceCmd.java | 20 ++-- .../engine/cmd/CustomApproveTaskAsyncCmd.java | 10 +- .../core/engine/cmd/CustomApproveTaskCmd.java | 30 +++--- .../CustomBizSpecifyAssigneeToTaskCmd.java | 13 ++- .../CustomCancelProcessInstanceAsyncCmd.java | 10 +- .../cmd/CustomCancelProcessInstanceCmd.java | 20 ++-- .../cmd/CustomCarbonCopyUserSelectorCmd.java | 13 ++- .../core/engine/cmd/CustomCommentTaskCmd.java | 16 +++- .../cmd/CustomCompleteDummyTaskCmd.java | 16 +++- .../CustomCountersignUserTaskAsyncCmd.java | 11 ++- .../cmd/CustomCountersignUserTaskCmd.java | 18 +++- .../engine/cmd/CustomCreateDummyTaskCmd.java | 16 +++- .../CustomForecastUserTaskAssigneeCmd.java | 12 ++- ...ustomNoticeDestinationUserSelectorCmd.java | 15 ++- .../cmd/CustomRejectionTaskAsyncCmd.java | 11 ++- .../engine/cmd/CustomRejectionTaskCmd.java | 28 +++--- .../cmd/CustomTransferUserTaskAsyncCmd.java | 12 ++- .../engine/cmd/CustomTransferUserTaskCmd.java | 16 +++- .../CustomLockProcessInstanceInterceptor.java | 82 ----------------- .../interceptor/CustomRetryInterceptor.java | 92 +++++++++++++++++++ .../support/ExpressionConditionCmd.java | 14 ++- .../engine/impl/cmd/CreateAttachmentCmd.java | 21 ++++- workflow-engine-server/pom.xml | 8 +- .../common/filter/HttpTraceLogFilter.java | 18 +++- 29 files changed, 406 insertions(+), 165 deletions(-) create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/TraceUtil.java delete mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java index 91443883f..c712329cb 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java @@ -18,6 +18,8 @@ public enum FlowableEngineRespCode implements IModuleRespCode { ENGINE_USER_TASK_TYPE_NOT_SUPPORT("003", "审批指定方式暂不支持"), ENGINE_USER_TASK_PARAM_ERROR("004", "构建后的查询审批人入参为空. 任务节点【nodeId:{}】, 该节点选择的\"审批人所在范围\"是:【{}】,请检查 cooperationOrg 参数"), ENGINE_NOTICE_CUSTOM_FLOW_ELEMENT_ERROR("005", "查询通知目标用户前参数发生异常,未获取到 WorkspaceType"), + ENGINE_ASYNC_COMMAND_EXECUTION_ERROR("006", "引擎出现 SQL 相关异常, 异常信息:【{}】"), + ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP("007", "命令重试尝试【{}】次仍然失败,并出现 PersistenceException, 将放弃"), ; private String code; diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/TraceUtil.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/TraceUtil.java new file mode 100644 index 000000000..86fd83f41 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/TraceUtil.java @@ -0,0 +1,24 @@ +package cn.axzo.workflow.core.common.utils; + +import org.slf4j.MDC; +import org.springframework.util.StringUtils; + +import static cn.axzo.workflow.common.constant.LogFieldConstants.X_REQUEST_ID; +import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC; + +/** + * 获取 TraceId + * + * @author wangli + * @since 2024/7/3 10:14 + */ +public final class TraceUtil { + + private TraceUtil() { + } + + public static String traceId() { + String xRequestId = MDC.get(X_REQUEST_ID); + return StringUtils.hasText(xRequestId) ? xRequestId : MDC.get(CTX_LOG_ID_MDC); + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java index 769d3651a..ed8ec8a02 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java @@ -3,7 +3,7 @@ package cn.axzo.workflow.core.conf; import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory; import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory; import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator; -import cn.axzo.workflow.core.engine.interceptor.CustomLockProcessInstanceInterceptor; +import cn.axzo.workflow.core.engine.interceptor.CustomRetryInterceptor; import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler; import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler; import cn.axzo.workflow.core.engine.job.AsyncBpmnProcessActivityJobHandler; @@ -23,7 +23,6 @@ import com.alibaba.cloud.nacos.NacosServiceManager; import com.google.common.collect.Lists; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.common.engine.impl.history.HistoryLevel; -import org.flowable.common.engine.impl.interceptor.RetryInterceptor; import org.flowable.form.spring.SpringFormEngineConfiguration; import org.flowable.job.service.JobProcessor; import org.flowable.spring.SpringProcessEngineConfiguration; @@ -32,7 +31,6 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import java.time.Duration; @@ -98,7 +96,7 @@ public class FlowableConfiguration { new CustomAsyncRunnableExceptionExceptionHandler())); configuration.setCommandContextFactory(new CustomCommandContextFactory()); configuration.setCustomPreCommandInterceptors(Lists.newArrayList( - new CustomLockProcessInstanceInterceptor() + new CustomRetryInterceptor() )); }; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java index ed5aae60b..491c72cb8 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/AbstractCommand.java @@ -1,12 +1,15 @@ package cn.axzo.workflow.core.engine.cmd; + +import org.flowable.common.engine.impl.interceptor.Command; + /** * TODO * * @author wangli * @since 2024/7/1 13:59 */ -public abstract class AbstractCommand { +public abstract class AbstractCommand implements Command { - public abstract String getProcessInstanceId(); + public abstract String paramToJsonString(); } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceAsyncCmd.java index 4dbc65b81..ec87d66fa 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceAsyncCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceAsyncCmd.java @@ -4,7 +4,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbo import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler; import cn.hutool.json.JSONUtil; -import org.flowable.common.engine.impl.interceptor.Command; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.HistoryService; import org.flowable.engine.history.HistoricProcessInstance; @@ -23,7 +23,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_ABORT; import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS; -public class CustomAbortProcessInstanceAsyncCmd implements Command, Serializable { +public class CustomAbortProcessInstanceAsyncCmd extends AbstractCommand implements Serializable { private final BpmnProcessInstanceAbortDTO dto; @@ -31,6 +31,11 @@ public class CustomAbortProcessInstanceAsyncCmd implements Command, Serial this.dto = dto; } + @Override + public String paramToJsonString() { + return JSON.toJSONString(dto); + } + @Override public Void execute(CommandContext commandContext) { String processInstanceId = dto.getProcessInstanceId(); @@ -80,4 +85,5 @@ public class CustomAbortProcessInstanceAsyncCmd implements Command, Serial jobService.createAsyncJob(job, false); jobService.scheduleAsyncJob(job); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java index 0bd434a7a..91020386c 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomAbortProcessInstanceCmd.java @@ -4,6 +4,8 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; +import com.alibaba.fastjson.JSON; +import liquibase.pro.packaged.V; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.HistoryService; @@ -44,7 +46,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir * @author wangli * @since 2024/1/2 18:19 */ -public class CustomAbortProcessInstanceCmd extends AbstractCommand implements Command, Serializable { +public class CustomAbortProcessInstanceCmd extends AbstractCommand implements Serializable { private final String processInstanceId; private final String tenantId; private final String reason; @@ -58,6 +60,15 @@ public class CustomAbortProcessInstanceCmd extends AbstractCommand implements Co this.extAxHiTaskInstService = extAxHiTaskInstService; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("tenantId", tenantId); + params.put("reason", reason); + return JSON.toJSONString(params); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -103,11 +114,4 @@ public class CustomAbortProcessInstanceCmd extends AbstractCommand implements Co return null; } - @Override - public String getProcessInstanceId() { - if (StringUtils.hasText(processInstanceId)) { - return processInstanceId; - } - return null; - } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java index 0f5d57be6..8c23dc946 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskAsyncCmd.java @@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler; import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.TaskService; @@ -18,6 +19,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask; @@ -28,7 +31,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @author wangli * @since 2024/1/4 15:50 */ -public class CustomApproveTaskAsyncCmd implements Command, Serializable { +public class CustomApproveTaskAsyncCmd extends AbstractCommand implements Serializable { private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskAsyncCmd.class); private final BpmnTaskAuditDTO dto; @@ -37,6 +40,11 @@ public class CustomApproveTaskAsyncCmd implements Command, Serializable { this.dto = dto; } + @Override + public String paramToJsonString() { + return JSON.toJSONString(dto); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java index f891b67a4..427be70d2 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomApproveTaskCmd.java @@ -4,6 +4,7 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeType; import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; @@ -21,7 +22,9 @@ import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import java.io.Serializable; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; @@ -39,7 +42,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @author wangli * @since 2024/1/4 15:50 */ -public class CustomApproveTaskCmd extends AbstractCommand implements Command, Serializable { +public class CustomApproveTaskCmd extends AbstractCommand implements Serializable { private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskCmd.class); private final String taskId; @@ -63,6 +66,18 @@ public class CustomApproveTaskCmd extends AbstractCommand implements Command nodeTypes; + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("taskId", taskId); + params.put("advice", advice); + params.put("operationDesc", operationDesc); + params.put("attachmentList", JSON.toJSONString(attachmentList)); + params.put("approver", JSON.toJSONString(approver)); + params.put("nextApprover", JSON.toJSONString(nextApprover)); + params.put("nodeTypes", JSON.toJSONString(nodeTypes)); + return JSON.toJSONString(params); + } public CustomApproveTaskCmd(BpmnTaskAuditDTO dto) { this(dto, null); @@ -147,17 +162,4 @@ public class CustomApproveTaskCmd extends AbstractCommand implements Command, Serializable { +public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand implements Serializable { private final String executionId; private final List addedAssigners; @@ -41,6 +44,14 @@ public class CustomBizSpecifyAssigneeToTaskCmd implements Command, Seri this.addedAssigners = addedAssigners; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("executionId", executionId); + params.put("addedAssigners", addedAssigners); + return JSON.toJSONString(params); + } + @Override public Boolean execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceAsyncCmd.java index b99ec73f3..38e8174f8 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceAsyncCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceAsyncCmd.java @@ -5,7 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.job.AsyncCancelProcessInstanceHandler; import cn.hutool.json.JSONUtil; -import org.flowable.common.engine.impl.interceptor.Command; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.HistoryService; import org.flowable.engine.history.HistoricProcessInstance; @@ -23,7 +23,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_CANCEL; import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS; -public class CustomCancelProcessInstanceAsyncCmd implements Command, Serializable { +public class CustomCancelProcessInstanceAsyncCmd extends AbstractCommand implements Serializable { private final BpmnProcessInstanceCancelDTO dto; @@ -31,6 +31,11 @@ public class CustomCancelProcessInstanceAsyncCmd implements Command, Seria this.dto = dto; } + @Override + public String paramToJsonString() { + return JSON.toJSONString(dto); + } + @Override public Void execute(CommandContext commandContext) { String processInstanceId = dto.getProcessInstanceId(), tenantId = dto.getTenantId(); @@ -81,4 +86,5 @@ public class CustomCancelProcessInstanceAsyncCmd implements Command, Seria jobService.createAsyncJob(job, false); jobService.scheduleAsyncJob(job); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java index 540378165..500a3a83b 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCancelProcessInstanceCmd.java @@ -5,6 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.HistoryService; @@ -43,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir * @author wangli * @since 2024/1/2 18:19 */ -public class CustomCancelProcessInstanceCmd extends AbstractCommand implements Command, Serializable { +public class CustomCancelProcessInstanceCmd extends AbstractCommand implements Serializable { private final String processInstanceId; private final String tenantId; private final String reason; @@ -60,6 +61,16 @@ public class CustomCancelProcessInstanceCmd extends AbstractCommand implements C this.extAxHiTaskInstService = extAxHiTaskInstService; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("tenantId", tenantId); + params.put("reason", reason); + params.put("initiator", initiator); + return JSON.toJSONString(params); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -105,11 +116,4 @@ public class CustomCancelProcessInstanceCmd extends AbstractCommand implements C return null; } - @Override - public String getProcessInstanceId() { - if (StringUtils.hasText(processInstanceId)) { - return processInstanceId; - } - return null; - } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java index 3e5f736f7..8e126d1a2 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java @@ -28,6 +28,7 @@ import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -48,7 +49,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDup * @since 18/03/2024 11:33 */ @Slf4j -public class CustomCarbonCopyUserSelectorCmd implements Command>, Serializable { +public class CustomCarbonCopyUserSelectorCmd extends AbstractCommand> implements Serializable { private static final long serialVersionUID = 1L; private final String processInstanceId; @@ -86,6 +87,15 @@ public class CustomCarbonCopyUserSelectorCmd implements Command params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("carbons", carbons); + params.put("serviceVersion", serviceVersion); + return JSON.toJSONString(params); + } + @Override public List execute(CommandContext commandContext) { if (CollectionUtils.isEmpty(carbons)) { @@ -224,5 +234,4 @@ public class CustomCarbonCopyUserSelectorCmd implements Command, Serializable { +public class CustomCommentTaskCmd extends AbstractCommand implements Serializable { private final String processInstanceId; private final BpmnTaskDelegateAssigner operator; private final String comment; @@ -63,6 +66,17 @@ public class CustomCommentTaskCmd implements Command, Serializable { this.extAxHiTaskInstService = extAxHiTaskInstService; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("operator", operator); + params.put("comment", comment); + params.put("commentExt", commentExt); + params.put("attachmentList", attachmentList); + return JSON.toJSONString(params); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java index 6a9f920af..a00361cbf 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCompleteDummyTaskCmd.java @@ -5,6 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; @@ -16,7 +17,9 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.io.Serializable; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; @@ -30,7 +33,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.DUMMY_TASK_NOT_ * @author wangli * @since 2023/12/27 11:24 */ -public class CustomCompleteDummyTaskCmd implements Command, Serializable { +public class CustomCompleteDummyTaskCmd extends AbstractCommand implements Serializable { private final String processInstanceId; private final String taskId; private final String flowNodeName; @@ -46,6 +49,16 @@ public class CustomCompleteDummyTaskCmd implements Command, Serializable { this.extAxHiTaskInstService = extAxHiTaskInstService; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("taskId", taskId); + params.put("flowNodeName", flowNodeName); + params.put("operationDesc", operationDesc); + return JSON.toJSONString(params); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -93,4 +106,5 @@ public class CustomCompleteDummyTaskCmd implements Command, Serializable { taskService.setOwner(i.getId(), null); }); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java index 81956e9e7..f347c124d 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskAsyncCmd.java @@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO; import cn.axzo.workflow.core.engine.job.AsyncCountersignUserTaskJobHandler; import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.TaskService; @@ -16,17 +17,24 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask; import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated; -public class CustomCountersignUserTaskAsyncCmd implements Command, Serializable { +public class CustomCountersignUserTaskAsyncCmd extends AbstractCommand implements Serializable { private final BpmnTaskCountersignDTO dto; public CustomCountersignUserTaskAsyncCmd(BpmnTaskCountersignDTO dto) { this.dto = dto; } + @Override + public String paramToJsonString() { + return JSON.toJSONString(dto); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -66,4 +74,5 @@ public class CustomCountersignUserTaskAsyncCmd implements Command, Seriali jobService.createAsyncJob(job, false); jobService.scheduleAsyncJob(job); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java index 329b022cf..877cad88d 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCountersignUserTaskCmd.java @@ -6,6 +6,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; @@ -19,7 +20,9 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import java.io.Serializable; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; @@ -39,7 +42,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @since 2023/12/25 14:05 */ @Slf4j -public class CustomCountersignUserTaskCmd implements Command, Serializable { +public class CustomCountersignUserTaskCmd extends AbstractCommand implements Serializable { private final BpmnCountersignTypeEnum countersignType; private final String originTaskId; @@ -62,6 +65,18 @@ public class CustomCountersignUserTaskCmd implements Command, Serializable this.extAxHiTaskInstService = extAxHiTaskInstService; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("countersignType", countersignType.getType()); + params.put("originTaskId", originTaskId); + params.put("originTaskAssignee", originTaskAssignee); + params.put("advice", advice); + params.put("attachmentList", JSON.toJSONString(attachmentList)); + params.put("targetTaskAssigneeList", JSON.toJSONString(targetTaskAssigneeList)); + return JSON.toJSONString(params); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -139,4 +154,5 @@ public class CustomCountersignUserTaskCmd implements Command, Serializable addComment(commandContext, virtualTask, COMMENT_TYPE_OPERATION_DESC, message.toString()); batchAddAttachment(commandContext, task.getProcessInstanceId(), task.getId(), attachmentList, originTaskAssignee); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCreateDummyTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCreateDummyTaskCmd.java index ba6cda820..f1973b35b 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCreateDummyTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCreateDummyTaskCmd.java @@ -5,6 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.cfg.IdGenerator; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.common.engine.impl.interceptor.Command; @@ -21,7 +22,9 @@ import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; @@ -41,7 +44,7 @@ import static org.flowable.task.api.Task.DEFAULT_PRIORITY; * @author wangli * @since 2023/12/27 10:21 */ -public class CustomCreateDummyTaskCmd implements Command, Serializable { +public class CustomCreateDummyTaskCmd extends AbstractCommand implements Serializable { private final String processInstanceId; private final String flowNodeName; private final String operationDesc; @@ -57,6 +60,16 @@ public class CustomCreateDummyTaskCmd implements Command, Serializable { this.extAxHiTaskInstService = extAxHiTaskInstService; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("flowNodeName", flowNodeName); + params.put("operationDesc", operationDesc); + params.put("operator", operator); + return JSON.toJSONString(params); + } + /** * 在同一个实例下,不允许创建多个执行中的虚拟任务节点 * @@ -139,4 +152,5 @@ public class CustomCreateDummyTaskCmd implements Command, Serializable { }); } } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java index bb6070b5c..a17379858 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomForecastUserTaskAssigneeCmd.java @@ -19,7 +19,9 @@ import org.springframework.util.CollectionUtils; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify; @@ -30,7 +32,7 @@ import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApprove * @since 2023/12/11 17:56 */ @Slf4j -public class CustomForecastUserTaskAssigneeCmd implements Command>, Serializable { +public class CustomForecastUserTaskAssigneeCmd extends AbstractCommand> implements Serializable { private final String processInstanceId; private final UserTask userTask; private final EngineExecutionStartListener engineExecutionStartListener; @@ -42,6 +44,13 @@ public class CustomForecastUserTaskAssigneeCmd implements Command params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + return JSON.toJSONString(params); + } + @Override public List execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -81,4 +90,5 @@ public class CustomForecastUserTaskAssigneeCmd implements Command>, Serializable { +public class CustomNoticeDestinationUserSelectorCmd extends AbstractCommand> implements Serializable { private static final long serialVersionUID = 1L; private final EngineExecutionStartListener engineExecutionStartListener; private final BpmnHistoricTaskInstanceConverter historicTaskInstanceConverter; @@ -63,6 +64,17 @@ public class CustomNoticeDestinationUserSelectorCmd implements Command params = new HashMap<>(); + params.put("serviceVersion", serviceVersion); + params.put("workspaceType", workspaceType); + params.put("noticeProperty", noticeProperty); + params.put("processInstanceId", processInstanceId); + params.put("initiator", initiator); + return JSON.toJSONString(params); + } + @Override public List execute(CommandContext commandContext) { if (!noticeProperty.getSendMessage()) { @@ -170,5 +182,4 @@ public class CustomNoticeDestinationUserSelectorCmd implements Command, Serializable { +public class CustomRejectionTaskAsyncCmd extends AbstractCommand implements Serializable { private final BpmnTaskAuditDTO dto; public CustomRejectionTaskAsyncCmd(BpmnTaskAuditDTO dto) { this.dto = dto; } + @Override + public String paramToJsonString() { + return JSON.toJSONString(dto); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -69,4 +75,5 @@ public class CustomRejectionTaskAsyncCmd implements Command, Serializable jobService.createAsyncJob(job, false); jobService.scheduleAsyncJob(job); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java index 7b47c6c1d..610d2df65 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomRejectionTaskCmd.java @@ -6,7 +6,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; -import org.flowable.common.engine.impl.interceptor.Command; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; @@ -44,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @author wangli * @since 2024/1/4 13:36 */ -public class CustomRejectionTaskCmd extends AbstractCommand implements Command, Serializable { +public class CustomRejectionTaskCmd extends AbstractCommand implements Serializable { private final String taskId; private final String advice; @@ -62,6 +62,17 @@ public class CustomRejectionTaskCmd extends AbstractCommand implements Command params = new HashMap<>(); + params.put("taskId", taskId); + params.put("advice", advice); + params.put("attachmentList", attachmentList); + params.put("approver", approver); + params.put("nodeTypes", nodeTypes); + return JSON.toJSONString(params); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = @@ -102,17 +113,4 @@ public class CustomRejectionTaskCmd extends AbstractCommand implements Command, Serializable { +public class CustomTransferUserTaskAsyncCmd extends AbstractCommand implements Serializable { private final BpmnTaskTransferDTO dto; @@ -32,6 +34,11 @@ public class CustomTransferUserTaskAsyncCmd implements Command, Serializab this.dto = dto; } + @Override + public String paramToJsonString() { + return JSON.toJSONString(dto); + } + @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); @@ -65,4 +72,5 @@ public class CustomTransferUserTaskAsyncCmd implements Command, Serializab jobService.createAsyncJob(job, false); jobService.scheduleAsyncJob(job); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java index 18c558946..5cf121307 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomTransferUserTaskCmd.java @@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd; import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.common.engine.impl.interceptor.Command; @@ -18,7 +19,9 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.util.StringUtils; import java.io.Serializable; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -43,7 +46,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask * @author wangli * @since 2023/12/22 10:22 */ -public class CustomTransferUserTaskCmd implements Command, Serializable { +public class CustomTransferUserTaskCmd extends AbstractCommand implements Serializable { private final String originTaskId; private final BpmnTaskDelegateAssigner originTaskAssignee; @@ -60,6 +63,16 @@ public class CustomTransferUserTaskCmd implements Command, Serializable { this.targetTaskAssignee = targetTaskAssignee; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("originTaskId", originTaskId); + params.put("originTaskAssignee", originTaskAssignee); + params.put("advice", advice); + params.put("attachmentList", attachmentList); + params.put("targetTaskAssignee", targetTaskAssignee); + return JSON.toJSONString(params); + } @Override public Void execute(CommandContext commandContext) { @@ -125,4 +138,5 @@ public class CustomTransferUserTaskCmd implements Command, Serializable { INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(), originAssingeeList); } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java deleted file mode 100644 index f15ab3040..000000000 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomLockProcessInstanceInterceptor.java +++ /dev/null @@ -1,82 +0,0 @@ -package cn.axzo.workflow.core.engine.interceptor; - -import lombok.extern.slf4j.Slf4j; -import org.apache.ibatis.exceptions.PersistenceException; -import org.flowable.common.engine.api.FlowableException; -import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor; -import org.flowable.common.engine.impl.interceptor.Command; -import org.flowable.common.engine.impl.interceptor.CommandConfig; -import org.flowable.common.engine.impl.interceptor.CommandExecutor; - -/** - * 增加一个拦截器,用来控制多个操作,不允许同时操作同一个实例 - * - * @author wangli - * @since 2024/7/1 13:51 - */ -@Slf4j -public class CustomLockProcessInstanceInterceptor extends AbstractCommandInterceptor { - - protected int numOfRetries = 3; - protected int waitTimeInMs = 50; - protected int waitIncreaseFactor = 5; - - @Override - public T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { - long waitTime = waitTimeInMs; - int failedAttempts = 0; - - do { - if (failedAttempts > 0) { - log.warn("Waiting for {}ms before retrying the command.", waitTime); - waitBeforeRetry(waitTime); - waitTime *= waitIncreaseFactor; - } - - try { - - // try to execute the command - return next.execute(config, command, commandExecutor); - - } catch (PersistenceException e) { - log.error("Caught persistence exception: {}", e.getMessage(), e); - } - - failedAttempts++; - } while (failedAttempts <= numOfRetries); - - throw new FlowableException(numOfRetries + " retries failed with FlowableOptimisticLockingException. Giving up."); - } - - protected void waitBeforeRetry(long waitTime) { - try { - Thread.sleep(waitTime); - } catch (InterruptedException e) { - log.error("I am interrupted while waiting for a retry."); - } - } - - public void setNumOfRetries(int numOfRetries) { - this.numOfRetries = numOfRetries; - } - - public void setWaitIncreaseFactor(int waitIncreaseFactor) { - this.waitIncreaseFactor = waitIncreaseFactor; - } - - public void setWaitTimeInMs(int waitTimeInMs) { - this.waitTimeInMs = waitTimeInMs; - } - - public int getNumOfRetries() { - return numOfRetries; - } - - public int getWaitIncreaseFactor() { - return waitIncreaseFactor; - } - - public int getWaitTimeInMs() { - return waitTimeInMs; - } -} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java new file mode 100644 index 000000000..62094a5c0 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java @@ -0,0 +1,92 @@ +package cn.axzo.workflow.core.engine.interceptor; + +import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import cn.axzo.workflow.core.common.utils.TraceUtil; +import cn.axzo.workflow.core.engine.cmd.AbstractCommand; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.exceptions.PersistenceException; +import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandConfig; +import org.flowable.common.engine.impl.interceptor.CommandExecutor; + +import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_ASYNC_COMMAND_EXECUTION_ERROR; +import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP; + +/** + * 基于 RetryInterceptor 的命令重试拦截器, 本意想用来处理多人同时操作同一个任务, 但会存在超过重试次数后,会丢弃原有的命令. + * + * @author wangli + * @since 2024/7/1 13:51 + */ +@Slf4j +public class CustomRetryInterceptor extends AbstractCommandInterceptor { + + protected int numOfRetries = 3; + protected int waitTimeInMs = 60; + protected int waitIncreaseFactor = 5; + + @Override + public T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { + try { + long waitTime = waitTimeInMs; + int failedAttempts = 0; + do { + if (failedAttempts > 0) { + log.warn("Waiting for {}ms before retrying the command.", waitTime); + waitBeforeRetry(waitTime); + waitTime *= waitIncreaseFactor; + } + + try { + // try to execute the command + if (AbstractCommand.class.isAssignableFrom(command.getClass())) { + log.info("traceId:{} Executing command params: {}", TraceUtil.traceId(), + ((AbstractCommand) command).paramToJsonString()); + } + return next.execute(config, command, commandExecutor); + + } catch (PersistenceException e) { + log.warn("Caught persistence exception: {}", e.getMessage(), e); + } + + failedAttempts++; + } while (failedAttempts <= numOfRetries); + throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP, String.valueOf(numOfRetries)); + } catch (Throwable e) { + throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_ERROR, e.getMessage()); + } + } + + protected void waitBeforeRetry(long waitTime) { + try { + Thread.sleep(waitTime); + } catch (InterruptedException e) { + log.warn("I am interrupted while waiting for a retry."); + } + } + + public void setNumOfRetries(int numOfRetries) { + this.numOfRetries = numOfRetries; + } + + public void setWaitIncreaseFactor(int waitIncreaseFactor) { + this.waitIncreaseFactor = waitIncreaseFactor; + } + + public void setWaitTimeInMs(int waitTimeInMs) { + this.waitTimeInMs = waitTimeInMs; + } + + public int getNumOfRetries() { + return numOfRetries; + } + + public int getWaitIncreaseFactor() { + return waitIncreaseFactor; + } + + public int getWaitTimeInMs() { + return waitTimeInMs; + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/ExpressionConditionCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/ExpressionConditionCmd.java index 672db4e0a..54c7080b3 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/ExpressionConditionCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/support/ExpressionConditionCmd.java @@ -1,7 +1,9 @@ package cn.axzo.workflow.core.service.support; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import cn.axzo.workflow.core.engine.cmd.AbstractCommand; import cn.azxo.framework.common.utils.StringUtils; +import com.alibaba.fastjson.JSON; import org.flowable.common.engine.api.delegate.Expression; import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandContext; @@ -10,6 +12,8 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EXECUTION_LOST_ID_ERROR; @@ -20,7 +24,7 @@ import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EX * @author wangli * @since 2023/10/9 19:30 */ -public class ExpressionConditionCmd implements Command, Serializable { +public class ExpressionConditionCmd extends AbstractCommand implements Serializable { protected final RuntimeService runtimeService; protected final ProcessEngineConfigurationImpl processEngineConfiguration; protected final String processInstanceId; @@ -35,6 +39,14 @@ public class ExpressionConditionCmd implements Command, Serializable { this.exp = exp; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("processInstanceId", processInstanceId); + params.put("exp", exp); + return JSON.toJSONString(params); + } + @Override public Boolean execute(CommandContext commandContext) { Expression expression = processEngineConfiguration.getExpressionManager().createExpression(this.exp); diff --git a/workflow-engine-core/src/main/java/org/flowable/engine/impl/cmd/CreateAttachmentCmd.java b/workflow-engine-core/src/main/java/org/flowable/engine/impl/cmd/CreateAttachmentCmd.java index aa30f0396..9f0f63f53 100644 --- a/workflow-engine-core/src/main/java/org/flowable/engine/impl/cmd/CreateAttachmentCmd.java +++ b/workflow-engine-core/src/main/java/org/flowable/engine/impl/cmd/CreateAttachmentCmd.java @@ -1,5 +1,8 @@ package org.flowable.engine.impl.cmd; +import cn.axzo.workflow.core.engine.cmd.AbstractCommand; +import com.alibaba.fastjson.JSON; +import liquibase.pro.packaged.M; import org.flowable.common.engine.api.FlowableException; import org.flowable.common.engine.api.FlowableObjectNotFoundException; import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; @@ -22,6 +25,9 @@ import org.flowable.task.api.Task; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import java.io.InputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; /** * 覆盖 Flowable 自带的 CreateAttachmentCmd, 由于 Flowable 5 的实现导致异常,需要覆盖 @@ -29,7 +35,7 @@ import java.io.InputStream; * @author Tom Baeyens * @author Joram Barrez */ -public class CreateAttachmentCmd implements Command { +public class CreateAttachmentCmd extends AbstractCommand implements Serializable { protected String attachmentType; protected String taskId; @@ -50,6 +56,19 @@ public class CreateAttachmentCmd implements Command { this.url = url; } + @Override + public String paramToJsonString() { + Map params = new HashMap<>(); + params.put("attachmentType", attachmentType); + params.put("taskId", taskId); + params.put("processInstanceId", processInstanceId); + params.put("attachmentName", attachmentName); + params.put("attachmentDescription", attachmentDescription); +// params.put("content", content); + params.put("url", url); + return JSON.toJSONString(params); + } + @Override public Attachment execute(CommandContext commandContext) { diff --git a/workflow-engine-server/pom.xml b/workflow-engine-server/pom.xml index 279ccf123..80e18794a 100644 --- a/workflow-engine-server/pom.xml +++ b/workflow-engine-server/pom.xml @@ -95,10 +95,10 @@ cn.axzo.maokai maokai-api - - cn.axzo.tyr - tyr-api - + + + + cn.axzo.karma karma-api diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java index 1af797b06..ac540b2b4 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java @@ -9,6 +9,7 @@ import org.apache.skywalking.apm.toolkit.trace.TraceContext; import org.slf4j.MDC; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; @@ -18,6 +19,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import static cn.axzo.workflow.common.constant.LogFieldConstants.X_REQUEST_ID; +import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC; /** * Http接口日志记录 @@ -44,18 +46,18 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered } else { MDC.put(X_REQUEST_ID, requestId); } - String ctxLogId = request.getHeader(Constants.CTX_LOG_ID_MDC); + String ctxLogId = request.getHeader(CTX_LOG_ID_MDC); if (Strings.isNullOrEmpty(ctxLogId)) { - MDC.put(Constants.CTX_LOG_ID_MDC, getTraceId()); + MDC.put(CTX_LOG_ID_MDC, getTraceId()); } else { - MDC.put(Constants.CTX_LOG_ID_MDC, ctxLogId); + MDC.put(CTX_LOG_ID_MDC, ctxLogId); } try { filterChain.doFilter(request, response); } finally { - response.setHeader(Constants.CTX_LOG_ID_MDC, MDC.get(Constants.CTX_LOG_ID_MDC)); - response.setHeader(X_REQUEST_ID, MDC.get(Constants.CTX_LOG_ID_MDC)); + response.setHeader(CTX_LOG_ID_MDC, MDC.get(CTX_LOG_ID_MDC)); + response.setHeader(X_REQUEST_ID, MDC.get(CTX_LOG_ID_MDC)); MDC.clear(); } } @@ -64,4 +66,10 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered String contextTraceId = TraceContext.traceId(); return Strings.isNullOrEmpty(contextTraceId) ? IdUtil.fastSimpleUUID() : contextTraceId; } + + public static String traceId() { + String xRequestId = MDC.get(X_REQUEST_ID); + return StringUtils.hasText(xRequestId) ? xRequestId : MDC.get(CTX_LOG_ID_MDC); + + } } From 5d330942663a841cbf4adc9e8dc1aa4242c3e171 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 10:49:06 +0800 Subject: [PATCH 15/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/core/engine/interceptor/CustomRetryInterceptor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java index 62094a5c0..2cfb37dc5 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java @@ -41,6 +41,7 @@ public class CustomRetryInterceptor extends AbstractCommandInterceptor { try { // try to execute the command if (AbstractCommand.class.isAssignableFrom(command.getClass())) { + // 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行. log.info("traceId:{} Executing command params: {}", TraceUtil.traceId(), ((AbstractCommand) command).paramToJsonString()); } From 1065db0f6f08e31af0883a83b6a8ab1322a49ad0 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 11:04:54 +0800 Subject: [PATCH 16/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/interceptor/CustomRetryInterceptor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java index 2cfb37dc5..fa286a8c4 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java @@ -53,10 +53,11 @@ public class CustomRetryInterceptor extends AbstractCommandInterceptor { failedAttempts++; } while (failedAttempts <= numOfRetries); - throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP, String.valueOf(numOfRetries)); } catch (Throwable e) { + log.error("Caught exception: {}", e.getMessage(), e); throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_ERROR, e.getMessage()); } + throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP, String.valueOf(numOfRetries)); } protected void waitBeforeRetry(long waitTime) { From eb3914a838fecadf0f5464640c00d5754487e213 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 11:05:05 +0800 Subject: [PATCH 17/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/workflow/server/common/filter/HttpTraceLogFilter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java index ac540b2b4..d8452d23b 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/filter/HttpTraceLogFilter.java @@ -1,6 +1,5 @@ package cn.axzo.workflow.server.common.filter; -import cn.azxo.framework.common.constatns.Constants; import cn.hutool.core.util.IdUtil; import com.google.common.base.Strings; import lombok.extern.slf4j.Slf4j; From f9069f9b1fa6e228fac880b83f3490ff08a88794 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 11:29:12 +0800 Subject: [PATCH 18/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptor/CustomRetryInterceptor.java | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java index fa286a8c4..093f1d108 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/interceptor/CustomRetryInterceptor.java @@ -10,7 +10,6 @@ import org.flowable.common.engine.impl.interceptor.Command; import org.flowable.common.engine.impl.interceptor.CommandConfig; import org.flowable.common.engine.impl.interceptor.CommandExecutor; -import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_ASYNC_COMMAND_EXECUTION_ERROR; import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP; /** @@ -28,35 +27,31 @@ public class CustomRetryInterceptor extends AbstractCommandInterceptor { @Override public T execute(CommandConfig config, Command command, CommandExecutor commandExecutor) { - try { - long waitTime = waitTimeInMs; - int failedAttempts = 0; - do { - if (failedAttempts > 0) { - log.warn("Waiting for {}ms before retrying the command.", waitTime); - waitBeforeRetry(waitTime); - waitTime *= waitIncreaseFactor; + long waitTime = waitTimeInMs; + int failedAttempts = 0; + do { + if (failedAttempts > 0) { + log.warn("Waiting for {}ms before retrying the command.", waitTime); + waitBeforeRetry(waitTime); + waitTime *= waitIncreaseFactor; + } + + try { + // try to execute the command + if (AbstractCommand.class.isAssignableFrom(command.getClass())) { + // 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行. + log.info("traceId:{} Executing command params: {}", TraceUtil.traceId(), + ((AbstractCommand) command).paramToJsonString()); } + return next.execute(config, command, commandExecutor); - try { - // try to execute the command - if (AbstractCommand.class.isAssignableFrom(command.getClass())) { - // 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行. - log.info("traceId:{} Executing command params: {}", TraceUtil.traceId(), - ((AbstractCommand) command).paramToJsonString()); - } - return next.execute(config, command, commandExecutor); + } catch (PersistenceException e) { + log.warn("Caught persistence exception: {}", e.getMessage(), e); + } - } catch (PersistenceException e) { - log.warn("Caught persistence exception: {}", e.getMessage(), e); - } + failedAttempts++; + } while (failedAttempts <= numOfRetries); - failedAttempts++; - } while (failedAttempts <= numOfRetries); - } catch (Throwable e) { - log.error("Caught exception: {}", e.getMessage(), e); - throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_ERROR, e.getMessage()); - } throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP, String.valueOf(numOfRetries)); } From 6db32fff3860330349a789a392dff01614457191 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 11:32:40 +0800 Subject: [PATCH 19/20] =?UTF-8?q?update=20-=20=E8=A7=A3=E5=86=B3=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E4=BB=BB=E5=8A=A1=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E4=B8=AA=E5=AE=9E=E4=BE=8B,=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E4=BA=8B=E5=8A=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/workflow/core/common/code/FlowableEngineRespCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java index c712329cb..e82a9f833 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/FlowableEngineRespCode.java @@ -19,7 +19,7 @@ public enum FlowableEngineRespCode implements IModuleRespCode { ENGINE_USER_TASK_PARAM_ERROR("004", "构建后的查询审批人入参为空. 任务节点【nodeId:{}】, 该节点选择的\"审批人所在范围\"是:【{}】,请检查 cooperationOrg 参数"), ENGINE_NOTICE_CUSTOM_FLOW_ELEMENT_ERROR("005", "查询通知目标用户前参数发生异常,未获取到 WorkspaceType"), ENGINE_ASYNC_COMMAND_EXECUTION_ERROR("006", "引擎出现 SQL 相关异常, 异常信息:【{}】"), - ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP("007", "命令重试尝试【{}】次仍然失败,并出现 PersistenceException, 将放弃"), + ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP("007", "命令重试尝试【{}】次仍然失败,并出现异常, 将放弃"), ; private String code; From 7bb157c0b6d1a60c20b23a45d59192f5b4f55662 Mon Sep 17 00:00:00 2001 From: wangli <274027703@qq.com> Date: Wed, 3 Jul 2024 13:43:56 +0800 Subject: [PATCH 20/20] =?UTF-8?q?remove=20-=20=E7=A7=BB=E9=99=A4=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E6=97=A0=E7=94=A8=E7=9A=84=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/hook/NacosShutdownHook.java | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/hook/NacosShutdownHook.java diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/hook/NacosShutdownHook.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/hook/NacosShutdownHook.java deleted file mode 100644 index b2eaa31a8..000000000 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/common/hook/NacosShutdownHook.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.axzo.workflow.server.common.hook; - -import org.springframework.context.SmartLifecycle; - -/** - * TODO - * - * @author wangli - * @since 2024/6/6 14:35 - */ -public class NacosShutdownHook implements SmartLifecycle { - @Override - public void start() { - - } - - @Override - public void stop() { - - } - - @Override - public boolean isRunning() { - return false; - } -}