Commit 3f8221ba845420160107cfedac30745751e3fb69

Authored by jason
1 parent b88c09f4

【功能新增】 新增异步 http 请求触发器

Showing 11 changed files with 211 additions and 54 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApi.java
@@ -20,4 +20,12 @@ public interface BpmProcessInstanceApi { @@ -20,4 +20,12 @@ public interface BpmProcessInstanceApi {
20 */ 20 */
21 String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO); 21 String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO);
22 22
  23 +
  24 + /**
  25 + * 异步 HTTP 请求触发器回调, 为了唤醒流程继续执行
  26 + *
  27 + * @param processInstanceId 流程实例编号
  28 + * @param callbackId 回调编号, 对应 ReceiveTask Id
  29 + */
  30 + void asyncHttpTriggerCallback(String processInstanceId, String callbackId);
23 } 31 }
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmTriggerTypeEnum.java
@@ -18,7 +18,8 @@ public enum BpmTriggerTypeEnum implements ArrayValuable<Integer> { @@ -18,7 +18,8 @@ public enum BpmTriggerTypeEnum implements ArrayValuable<Integer> {
18 18
19 HTTP_REQUEST(1, "发起 HTTP 请求"), 19 HTTP_REQUEST(1, "发起 HTTP 请求"),
20 FORM_UPDATE(2, "更新流程表单数据"), 20 FORM_UPDATE(2, "更新流程表单数据"),
21 - FORM_DELETE(3, "删除流程表单数据"); 21 + FORM_DELETE(3, "删除流程表单数据"),
  22 + ASYNC_HTTP_REQUEST(4, "发起异步 HTTP 请求");
22 23
23 /** 24 /**
24 * 触发器执行动作类型 25 * 触发器执行动作类型
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/api/task/BpmProcessInstanceApiImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.task; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.api.task;
2 2
3 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; 3 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
4 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; 4 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  5 +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
5 import org.springframework.stereotype.Service; 6 import org.springframework.stereotype.Service;
6 import org.springframework.validation.annotation.Validated; 7 import org.springframework.validation.annotation.Validated;
7 8
@@ -21,8 +22,16 @@ public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi { @@ -21,8 +22,16 @@ public class BpmProcessInstanceApiImpl implements BpmProcessInstanceApi {
21 @Resource 22 @Resource
22 private BpmProcessInstanceService processInstanceService; 23 private BpmProcessInstanceService processInstanceService;
23 24
  25 + @Resource
  26 + private BpmTaskService bpmTaskService;
  27 +
24 @Override 28 @Override
25 public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) { 29 public String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqDTO reqDTO) {
26 return processInstanceService.createProcessInstance(userId, reqDTO); 30 return processInstanceService.createProcessInstance(userId, reqDTO);
27 } 31 }
  32 +
  33 + @Override
  34 + public void asyncHttpTriggerCallback(String processInstanceId, String callbackId) {
  35 + bpmTaskService.triggerReceiveTask(processInstanceId, callbackId);
  36 + }
28 } 37 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.core.KeyValue; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.core.KeyValue;
4 import cn.iocoder.yudao.framework.common.validation.InEnum; 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
5 import cn.iocoder.yudao.module.bpm.enums.definition.*; 5 import cn.iocoder.yudao.module.bpm.enums.definition.*;
6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; 6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
  7 +import com.fasterxml.jackson.annotation.JsonIgnore;
7 import com.fasterxml.jackson.annotation.JsonInclude; 8 import com.fasterxml.jackson.annotation.JsonInclude;
8 import io.swagger.v3.oas.annotations.media.Schema; 9 import io.swagger.v3.oas.annotations.media.Schema;
9 import jakarta.validation.Valid; 10 import jakarta.validation.Valid;
@@ -123,6 +124,13 @@ public class BpmSimpleModelNodeVO { @@ -123,6 +124,13 @@ public class BpmSimpleModelNodeVO {
123 */ 124 */
124 private TriggerSetting triggerSetting; 125 private TriggerSetting triggerSetting;
125 126
  127 + /**
  128 + * 附加节点 Id, 该节点不从前端传入。 由程序生成. 由于当个节点无法完成功能。 需要附加节点来完成。
  129 + */
  130 + @JsonIgnore
  131 + private String attachNodeId; // 目前用于异步触发器节点。需要 UserTask 和 ReceiveTask(附加节点) 来完成
  132 +
  133 +
126 @Schema(description = "任务监听器") 134 @Schema(description = "任务监听器")
127 @Valid 135 @Valid
128 @Data 136 @Data
@@ -378,6 +386,10 @@ public class BpmSimpleModelNodeVO { @@ -378,6 +386,10 @@ public class BpmSimpleModelNodeVO {
378 @Schema(description = "请求返回处理设置", example = "[]") 386 @Schema(description = "请求返回处理设置", example = "[]")
379 private List<KeyValue<String, String>> response; 387 private List<KeyValue<String, String>> response;
380 388
  389 + /**
  390 + * 异步 Http 请求,需要指定回调 Id,用于回调执行. 由后端指定
  391 + */
  392 + private String callbackId;
381 } 393 }
382 394
383 @Schema(description = "流程表单触发器设置", example = "{}") 395 @Schema(description = "流程表单触发器设置", example = "{}")
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/listener/BpmTaskEventListener.java
@@ -109,8 +109,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { @@ -109,8 +109,7 @@ public class BpmTaskEventListener extends AbstractFlowableEngineEventListener {
109 // 2.2 延迟器超时处理 109 // 2.2 延迟器超时处理
110 } else if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventTypeEnum.DELAY_TIMER_TIMEOUT)) { 110 } else if (ObjectUtil.equal(bpmTimerBoundaryEventType, BpmBoundaryEventTypeEnum.DELAY_TIMER_TIMEOUT)) {
111 String taskKey = boundaryEvent.getAttachedToRefId(); 111 String taskKey = boundaryEvent.getAttachedToRefId();
112 - taskService.processDelayTimerTimeout(event.getProcessInstanceId(), taskKey); 112 + taskService.triggerReceiveTask(event.getProcessInstanceId(), taskKey);
113 } 113 }
114 } 114 }
115 -  
116 } 115 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
@@ -21,6 +21,7 @@ import org.springframework.util.MultiValueMap; @@ -21,6 +21,7 @@ import org.springframework.util.MultiValueMap;
21 21
22 import java.util.*; 22 import java.util.*;
23 23
  24 +import static cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum.ASYNC_HTTP_REQUEST;
24 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*; 25 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.*;
25 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.*; 26 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils.*;
26 import static cn.iocoder.yudao.module.bpm.service.task.listener.BpmUserTaskListener.DELEGATE_EXPRESSION; 27 import static cn.iocoder.yudao.module.bpm.service.task.listener.BpmUserTaskListener.DELEGATE_EXPRESSION;
@@ -164,8 +165,15 @@ public class SimpleModelUtils { @@ -164,8 +165,15 @@ public class SimpleModelUtils {
164 // 情况一:有“子”节点,则建立连线 165 // 情况一:有“子”节点,则建立连线
165 // 情况二:没有“子节点”,则直接跟 targetNodeId 建立连线。例如说,结束节点、条件分支(分支节点的孩子节点或聚合节点)的最后一个节点 166 // 情况二:没有“子节点”,则直接跟 targetNodeId 建立连线。例如说,结束节点、条件分支(分支节点的孩子节点或聚合节点)的最后一个节点
166 String finalTargetNodeId = isChildNodeValid ? childNode.getId() : targetNodeId; 167 String finalTargetNodeId = isChildNodeValid ? childNode.getId() : targetNodeId;
167 - SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), finalTargetNodeId);  
168 - process.addFlowElement(sequenceFlow); 168 +
  169 + if (StrUtil.isEmpty(node.getAttachNodeId())) {
  170 + SequenceFlow sequenceFlow = buildBpmnSequenceFlow(node.getId(), finalTargetNodeId);
  171 + process.addFlowElement(sequenceFlow);
  172 + } else {
  173 + // 如果有附加节点. 需要先建立和附加节点的连线。再建立附加节点和目标节点的连线
  174 + List<SequenceFlow> sequenceFlows = buildAttachNodeSequenceFlow(node.getId(), node.getAttachNodeId(), finalTargetNodeId);
  175 + sequenceFlows.forEach(process::addFlowElement);
  176 + }
169 177
170 // 因为有子节点,递归调用后续子节点 178 // 因为有子节点,递归调用后续子节点
171 if (isChildNodeValid) { 179 if (isChildNodeValid) {
@@ -174,6 +182,19 @@ public class SimpleModelUtils { @@ -174,6 +182,19 @@ public class SimpleModelUtils {
174 } 182 }
175 183
176 /** 184 /**
  185 + * 构建有附加节点的连线
  186 + *
  187 + * @param nodeId 当前节点 Id
  188 + * @param attachNodeId 附属节点 Id
  189 + * @param targetNodeId 目标节点 Id
  190 + */
  191 + private static List<SequenceFlow> buildAttachNodeSequenceFlow(String nodeId, String attachNodeId, String targetNodeId) {
  192 + SequenceFlow sequenceFlow = buildBpmnSequenceFlow(nodeId, attachNodeId, null, null, null);
  193 + SequenceFlow attachSequenceFlow = buildBpmnSequenceFlow(attachNodeId, targetNodeId, null, null, null);
  194 + return CollUtil.newArrayList(sequenceFlow, attachSequenceFlow);
  195 + }
  196 +
  197 + /**
177 * 遍历条件节点,构建 SequenceFlow 元素 198 * 遍历条件节点,构建 SequenceFlow 元素
178 * 199 *
179 * @param process Bpmn 流程 200 * @param process Bpmn 流程
@@ -723,23 +744,38 @@ public class SimpleModelUtils { @@ -723,23 +744,38 @@ public class SimpleModelUtils {
723 public static class TriggerNodeConvert implements NodeConvert { 744 public static class TriggerNodeConvert implements NodeConvert {
724 745
725 @Override 746 @Override
726 - public ServiceTask convert(BpmSimpleModelNodeVO node) { 747 + public List<? extends FlowElement> convertList(BpmSimpleModelNodeVO node) {
  748 + List<FlowElement> flowElements = new ArrayList<>(2);
727 // 触发器使用 ServiceTask 来实现 749 // 触发器使用 ServiceTask 来实现
728 ServiceTask serviceTask = new ServiceTask(); 750 ServiceTask serviceTask = new ServiceTask();
729 serviceTask.setId(node.getId()); 751 serviceTask.setId(node.getId());
730 serviceTask.setName(node.getName()); 752 serviceTask.setName(node.getName());
731 serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION); 753 serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
732 serviceTask.setImplementation("${" + BpmTriggerTaskDelegate.BEAN_NAME + "}"); 754 serviceTask.setImplementation("${" + BpmTriggerTaskDelegate.BEAN_NAME + "}");
733 - if (node.getTriggerSetting() != null) {  
734 - addExtensionElement(serviceTask, TRIGGER_TYPE, node.getTriggerSetting().getType());  
735 - if (node.getTriggerSetting().getHttpRequestSetting() != null) {  
736 - addExtensionElementJson(serviceTask, TRIGGER_PARAM, node.getTriggerSetting().getHttpRequestSetting());  
737 - }  
738 - if (node.getTriggerSetting().getFormSettings() != null) {  
739 - addExtensionElementJson(serviceTask, TRIGGER_PARAM, node.getTriggerSetting().getFormSettings());  
740 - } 755 + Assert.notNull(node.getTriggerSetting(), "触发器节点设置不能为空");
  756 +
  757 + addExtensionElement(serviceTask, TRIGGER_TYPE, node.getTriggerSetting().getType());
  758 + flowElements.add(serviceTask);
  759 + // 异步 HTTP 请求。需要附加一个 ReceiveTask、发起请求后、等待回调执行
  760 + if (ASYNC_HTTP_REQUEST.getType().equals(node.getTriggerSetting().getType())) {
  761 + String attachNodeId = "Activity_" + IdUtil.fastUUID();
  762 + ReceiveTask receiveTask = new ReceiveTask();
  763 + receiveTask.setId(attachNodeId);
  764 + receiveTask.setName("异步 HTTP 请求");
  765 + node.setAttachNodeId(attachNodeId);
  766 + // 设置 receiveId
  767 + Assert.notNull(node.getTriggerSetting().getHttpRequestSetting(), "触发器 http 请求设置不能为空");
  768 + node.getTriggerSetting().getHttpRequestSetting().setCallbackId(attachNodeId);
  769 + flowElements.add(receiveTask);
741 } 770 }
742 - return serviceTask; 771 +
  772 + if (node.getTriggerSetting().getHttpRequestSetting() != null) {
  773 + addExtensionElementJson(serviceTask, TRIGGER_PARAM, node.getTriggerSetting().getHttpRequestSetting());
  774 + }
  775 + if (node.getTriggerSetting().getFormSettings() != null) {
  776 + addExtensionElementJson(serviceTask, TRIGGER_PARAM, node.getTriggerSetting().getFormSettings());
  777 + }
  778 + return flowElements;
743 } 779 }
744 780
745 @Override 781 @Override
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
@@ -277,11 +277,11 @@ public interface BpmTaskService { @@ -277,11 +277,11 @@ public interface BpmTaskService {
277 void processTaskTimeout(String processInstanceId, String taskDefineKey, Integer handlerType); 277 void processTaskTimeout(String processInstanceId, String taskDefineKey, Integer handlerType);
278 278
279 /** 279 /**
280 - * 处理 延迟器 超时事件 280 + * 触发 ReceiveTask, 让流程继续执行
281 * 281 *
282 * @param processInstanceId 流程示例编号 282 * @param processInstanceId 流程示例编号
283 * @param taskDefineKey 任务 Key 283 * @param taskDefineKey 任务 Key
284 */ 284 */
285 - void processDelayTimerTimeout(String processInstanceId, String taskDefineKey); 285 + void triggerReceiveTask(String processInstanceId, String taskDefineKey);
286 286
287 } 287 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -1309,7 +1309,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -1309,7 +1309,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
1309 } 1309 }
1310 1310
1311 @Override 1311 @Override
1312 - public void processDelayTimerTimeout(String processInstanceId, String taskDefineKey) { 1312 + public void triggerReceiveTask(String processInstanceId, String taskDefineKey) {
1313 Execution execution = runtimeService.createExecutionQuery() 1313 Execution execution = runtimeService.createExecutionQuery()
1314 .processInstanceId(processInstanceId) 1314 .processInstanceId(processInstanceId)
1315 .activityId(taskDefineKey) 1315 .activityId(taskDefineKey)
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmAbstractHttpRequestTrigger.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.trigger;
  2 +
  3 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
  4 +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;
  5 +import jakarta.annotation.Resource;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.flowable.engine.runtime.ProcessInstance;
  8 +import org.springframework.http.HttpEntity;
  9 +import org.springframework.http.HttpMethod;
  10 +import org.springframework.http.ResponseEntity;
  11 +import org.springframework.util.LinkedMultiValueMap;
  12 +import org.springframework.util.MultiValueMap;
  13 +import org.springframework.web.client.RestClientException;
  14 +import org.springframework.web.client.RestTemplate;
  15 +
  16 +import java.util.List;
  17 +import java.util.Map;
  18 +
  19 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;
  20 +
  21 +/**
  22 + * BPM 发送 HTTP 请求触发器抽象类
  23 + *
  24 + * @author jason
  25 + */
  26 +@Slf4j
  27 +public abstract class BpmAbstractHttpRequestTrigger implements BpmTrigger {
  28 +
  29 + @Resource
  30 + private RestTemplate restTemplate;
  31 +
  32 + protected ResponseEntity<String> sendHttpRequest(String url,
  33 + MultiValueMap<String, String> headers,
  34 + MultiValueMap<String, String> body) {
  35 + // TODO @芋艿:要不要抽象一个 Http 请求的工具类,方便复用呢?
  36 + // 3. 发起请求
  37 + HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
  38 + ResponseEntity<String> responseEntity = null;
  39 + try {
  40 + responseEntity = restTemplate.exchange(url, HttpMethod.POST,
  41 + requestEntity, String.class);
  42 + log.info("[sendHttpRequest][HTTP 触发器,请求头:{},请求体:{},响应结果:{}]", headers, body, responseEntity);
  43 + } catch (RestClientException e) {
  44 + log.error("[sendHttpRequest][HTTP 触发器,请求头:{},请求体:{},请求出错:{}]", headers, body, e.getMessage());
  45 + }
  46 + return responseEntity;
  47 + }
  48 +
  49 + protected MultiValueMap<String, String> buildHttpHeaders(ProcessInstance processInstance,
  50 + List<BpmSimpleModelNodeVO.HttpRequestParam> headerSettings) {
  51 + Map<String, Object> processVariables = processInstance.getProcessVariables();
  52 + MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
  53 + headers.add(HEADER_TENANT_ID, processInstance.getTenantId());
  54 + SimpleModelUtils.addHttpRequestParam(headers, headerSettings, processVariables);
  55 + return headers;
  56 + }
  57 +
  58 + protected MultiValueMap<String, String> buildHttpBody(ProcessInstance processInstance,
  59 + List<BpmSimpleModelNodeVO.HttpRequestParam> bodySettings) {
  60 + Map<String, Object> processVariables = processInstance.getProcessVariables();
  61 + MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
  62 + SimpleModelUtils.addHttpRequestParam(body, bodySettings, processVariables);
  63 + body.add("processInstanceId", processInstance.getId());
  64 + return body;
  65 + }
  66 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmAsyncHttpRequestTrigger.java 0 → 100644
  1 +package cn.iocoder.yudao.module.bpm.service.task.trigger;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  4 +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO;
  5 +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;
  6 +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
  7 +import jakarta.annotation.Resource;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.flowable.engine.runtime.ProcessInstance;
  10 +import org.springframework.stereotype.Component;
  11 +import org.springframework.util.MultiValueMap;
  12 +
  13 +/**
  14 + * BPM 发送异步 HTTP 请求触发器
  15 + *
  16 + * @author jason
  17 + */
  18 +@Component
  19 +@Slf4j
  20 +public class BpmAsyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger {
  21 +
  22 + @Resource
  23 + private BpmProcessInstanceService processInstanceService;
  24 +
  25 + @Override
  26 + public BpmTriggerTypeEnum getType() {
  27 + return BpmTriggerTypeEnum.ASYNC_HTTP_REQUEST;
  28 + }
  29 +
  30 + @Override
  31 + public void execute(String processInstanceId, String param) {
  32 + // 1. 解析 http 请求配置
  33 + BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting setting = JsonUtils.parseObject(param,
  34 + BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting.class);
  35 + if (setting == null) {
  36 + log.error("[execute][流程({}) HTTP 异步触发器请求配置为空]", processInstanceId);
  37 + return;
  38 + }
  39 +
  40 + // 2.1 设置请求头
  41 + ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
  42 + MultiValueMap<String, String> headers = buildHttpHeaders(processInstance, setting.getHeader());
  43 + // 2.2 设置请求体
  44 + MultiValueMap<String, String> body = buildHttpBody(processInstance, setting.getBody());
  45 + body.add("callbackId", setting.getCallbackId()); // 异步请求 callbackId 需要传给被调用方. 用于回调执行
  46 +
  47 + // 3. 发起请求
  48 + sendHttpRequest(setting.getUrl(), headers, body);
  49 + }
  50 +}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmHttpRequestTrigger.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/trigger/BpmSyncHttpRequestTrigger.java
@@ -7,42 +7,31 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -7,42 +7,31 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 7 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting; 8 import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TriggerSetting.HttpRequestTriggerSetting;
9 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum; 9 import cn.iocoder.yudao.module.bpm.enums.definition.BpmTriggerTypeEnum;
10 -import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.SimpleModelUtils;  
11 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; 10 import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
12 import com.fasterxml.jackson.core.type.TypeReference; 11 import com.fasterxml.jackson.core.type.TypeReference;
13 import jakarta.annotation.Resource; 12 import jakarta.annotation.Resource;
14 import lombok.extern.slf4j.Slf4j; 13 import lombok.extern.slf4j.Slf4j;
15 import org.flowable.engine.runtime.ProcessInstance; 14 import org.flowable.engine.runtime.ProcessInstance;
16 -import org.springframework.http.HttpEntity;  
17 -import org.springframework.http.HttpMethod;  
18 import org.springframework.http.ResponseEntity; 15 import org.springframework.http.ResponseEntity;
19 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
20 -import org.springframework.util.LinkedMultiValueMap;  
21 import org.springframework.util.MultiValueMap; 17 import org.springframework.util.MultiValueMap;
22 -import org.springframework.web.client.RestClientException;  
23 -import org.springframework.web.client.RestTemplate;  
24 18
25 import java.util.HashMap; 19 import java.util.HashMap;
26 import java.util.List; 20 import java.util.List;
27 import java.util.Map; 21 import java.util.Map;
28 22
29 -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID;  
30 -  
31 /** 23 /**
32 - * BPM 发送 HTTP 请求触发器 24 + * BPM 发送同步 HTTP 请求触发器
33 * 25 *
34 * @author jason 26 * @author jason
35 */ 27 */
36 @Component 28 @Component
37 @Slf4j 29 @Slf4j
38 -public class BpmHttpRequestTrigger implements BpmTrigger { 30 +public class BpmSyncHttpRequestTrigger extends BpmAbstractHttpRequestTrigger {
39 31
40 @Resource 32 @Resource
41 private BpmProcessInstanceService processInstanceService; 33 private BpmProcessInstanceService processInstanceService;
42 34
43 - @Resource  
44 - private RestTemplate restTemplate;  
45 -  
46 @Override 35 @Override
47 public BpmTriggerTypeEnum getType() { 36 public BpmTriggerTypeEnum getType() {
48 return BpmTriggerTypeEnum.HTTP_REQUEST; 37 return BpmTriggerTypeEnum.HTTP_REQUEST;
@@ -56,40 +45,27 @@ public class BpmHttpRequestTrigger implements BpmTrigger { @@ -56,40 +45,27 @@ public class BpmHttpRequestTrigger implements BpmTrigger {
56 log.error("[execute][流程({}) HTTP 触发器请求配置为空]", processInstanceId); 45 log.error("[execute][流程({}) HTTP 触发器请求配置为空]", processInstanceId);
57 return; 46 return;
58 } 47 }
  48 +
59 // 2.1 设置请求头 49 // 2.1 设置请求头
60 ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId); 50 ProcessInstance processInstance = processInstanceService.getProcessInstance(processInstanceId);
61 - Map<String, Object> processVariables = processInstance.getProcessVariables();  
62 - MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();  
63 - headers.add(HEADER_TENANT_ID, processInstance.getTenantId());  
64 - SimpleModelUtils.addHttpRequestParam(headers, setting.getHeader(), processVariables); 51 + MultiValueMap<String, String> headers = buildHttpHeaders(processInstance, setting.getHeader());
65 // 2.2 设置请求体 52 // 2.2 设置请求体
66 - MultiValueMap<String, String> body = new LinkedMultiValueMap<>();  
67 - SimpleModelUtils.addHttpRequestParam(body, setting.getBody(), processVariables);  
68 - body.add("processInstanceId", processInstanceId); 53 + MultiValueMap<String, String> body = buildHttpBody(processInstance, setting.getBody());
69 54
70 - // TODO @芋艿:要不要抽象一个 Http 请求的工具类,方便复用呢?  
71 // 3. 发起请求 55 // 3. 发起请求
72 - HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);  
73 - ResponseEntity<String> responseEntity;  
74 - try {  
75 - responseEntity = restTemplate.exchange(setting.getUrl(), HttpMethod.POST,  
76 - requestEntity, String.class);  
77 - log.info("[execute][HTTP 触发器,请求头:{},请求体:{},响应结果:{}]", headers, body, responseEntity);  
78 - } catch (RestClientException e) {  
79 - log.error("[execute][HTTP 触发器,请求头:{},请求体:{},请求出错:{}]", headers, body, e.getMessage());  
80 - return;  
81 - } 56 + ResponseEntity<String> responseEntity = sendHttpRequest(setting.getUrl(), headers, body);
82 57
83 // 4.1 判断是否需要解析返回值 58 // 4.1 判断是否需要解析返回值
84 - if (StrUtil.isEmpty(responseEntity.getBody()) 59 + if (responseEntity == null || StrUtil.isEmpty(responseEntity.getBody())
85 || !responseEntity.getStatusCode().is2xxSuccessful() 60 || !responseEntity.getStatusCode().is2xxSuccessful()
86 || CollUtil.isEmpty(setting.getResponse())) { 61 || CollUtil.isEmpty(setting.getResponse())) {
87 return; 62 return;
88 } 63 }
89 // 4.2 解析返回值, 返回值必须符合 CommonResult 规范。 64 // 4.2 解析返回值, 返回值必须符合 CommonResult 规范。
90 CommonResult<Map<String, Object>> respResult = JsonUtils.parseObjectQuietly( 65 CommonResult<Map<String, Object>> respResult = JsonUtils.parseObjectQuietly(
91 - responseEntity.getBody(), new TypeReference<>() {});  
92 - if (respResult == null || !respResult.isSuccess()){ 66 + responseEntity.getBody(), new TypeReference<>() {
  67 + });
  68 + if (respResult == null || !respResult.isSuccess()) {
93 return; 69 return;
94 } 70 }
95 // 4.3 获取需要更新的流程变量 71 // 4.3 获取需要更新的流程变量
@@ -103,11 +79,11 @@ public class BpmHttpRequestTrigger implements BpmTrigger { @@ -103,11 +79,11 @@ public class BpmHttpRequestTrigger implements BpmTrigger {
103 /** 79 /**
104 * 从请求返回值获取需要更新的流程变量 80 * 从请求返回值获取需要更新的流程变量
105 * 81 *
106 - * @param result 请求返回结果 82 + * @param result 请求返回结果
107 * @param responseSettings 返回设置 83 * @param responseSettings 返回设置
108 * @return 需要更新的流程变量 84 * @return 需要更新的流程变量
109 */ 85 */
110 - private Map<String, Object> getNeedUpdatedVariablesFromResponse(Map<String,Object> result, 86 + private Map<String, Object> getNeedUpdatedVariablesFromResponse(Map<String, Object> result,
111 List<KeyValue<String, String>> responseSettings) { 87 List<KeyValue<String, String>> responseSettings) {
112 Map<String, Object> updateVariables = new HashMap<>(); 88 Map<String, Object> updateVariables = new HashMap<>();
113 if (CollUtil.isEmpty(result)) { 89 if (CollUtil.isEmpty(result)) {