111
This commit is contained in:
parent
3dc944d255
commit
7bbdeefa9b
@ -105,6 +105,7 @@ public enum ResponseCode {
|
|||||||
WORKFLOW_INSTANCE_ALREADY_COMPLETED(2711, "workflow.instance.already.completed"),
|
WORKFLOW_INSTANCE_ALREADY_COMPLETED(2711, "workflow.instance.already.completed"),
|
||||||
WORKFLOW_INSTANCE_ALREADY_CANCELED(2712, "workflow.instance.already.canceled"),
|
WORKFLOW_INSTANCE_ALREADY_CANCELED(2712, "workflow.instance.already.canceled"),
|
||||||
WORKFLOW_INSTANCE_NOT_RUNNING(2713, "workflow.instance.not.running"),
|
WORKFLOW_INSTANCE_NOT_RUNNING(2713, "workflow.instance.not.running"),
|
||||||
|
WORKFLOW_INSTANCE_NOT_PAUSED(2714, "workflow.instance.not.paused"),
|
||||||
WORKFLOW_NODE_NOT_FOUND(2720, "workflow.node.not.found"),
|
WORKFLOW_NODE_NOT_FOUND(2720, "workflow.node.not.found"),
|
||||||
WORKFLOW_NODE_TYPE_NOT_SUPPORTED(2721, "workflow.node.type.not.supported"),
|
WORKFLOW_NODE_TYPE_NOT_SUPPORTED(2721, "workflow.node.type.not.supported"),
|
||||||
WORKFLOW_NODE_CONFIG_INVALID(2722, "workflow.node.config.invalid"),
|
WORKFLOW_NODE_CONFIG_INVALID(2722, "workflow.node.config.invalid"),
|
||||||
|
|||||||
@ -60,9 +60,8 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
// 2. 创建工作流实例
|
// 2. 创建工作流实例
|
||||||
WorkflowInstance instance = new WorkflowInstance();
|
WorkflowInstance instance = new WorkflowInstance();
|
||||||
instance.setDefinition(definition);
|
instance.setDefinition(definition);
|
||||||
// 设置工作流实例状态
|
// 设置工作流实例初始状态为 PENDING
|
||||||
instance.setStatus(WorkflowInstanceStatusEnum.RUNNING);
|
instance.setStatus(WorkflowInstanceStatusEnum.PENDING);
|
||||||
instance.setStartTime(LocalDateTime.now());
|
|
||||||
workflowInstanceRepository.save(instance);
|
workflowInstanceRepository.save(instance);
|
||||||
|
|
||||||
// 3. 创建工作流上下文
|
// 3. 创建工作流上下文
|
||||||
@ -71,8 +70,10 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
variables.forEach((key, value) -> context.setVariable(key, value));
|
variables.forEach((key, value) -> context.setVariable(key, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 创建开始节点实例
|
// 4. 创建开始节点实例并启动工作流
|
||||||
NodeInstance startNode = createStartNode(definition, instance.getId());
|
NodeInstance startNode = createStartNode(definition, instance.getId());
|
||||||
|
instance.start();
|
||||||
|
workflowInstanceRepository.save(instance);
|
||||||
executeNode(startNode.getId());
|
executeNode(startNode.getId());
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
@ -85,8 +86,7 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_NOT_FOUND));
|
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_NOT_FOUND));
|
||||||
|
|
||||||
WorkflowInstance instance = nodeInstance.getWorkflowInstance();
|
WorkflowInstance instance = nodeInstance.getWorkflowInstance();
|
||||||
// 检查工作流实例状态
|
if (!instance.canExecuteNode()) {
|
||||||
if (instance.getStatus() != WorkflowInstanceStatusEnum.RUNNING) {
|
|
||||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,15 +100,32 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
// 2. 执行节点
|
// 2. 执行节点
|
||||||
WorkflowContext context = workflowContextFactory.create(instance);
|
WorkflowContext context = workflowContextFactory.create(instance);
|
||||||
executor.execute(nodeInstance, context);
|
executor.execute(nodeInstance, context);
|
||||||
|
|
||||||
|
// 3. 更新节点状态
|
||||||
nodeInstance.setStatus(NodeStatusEnum.COMPLETED);
|
nodeInstance.setStatus(NodeStatusEnum.COMPLETED);
|
||||||
nodeInstance.setEndTime(LocalDateTime.now());
|
nodeInstance.setEndTime(LocalDateTime.now());
|
||||||
nodeInstanceRepository.save(nodeInstance);
|
nodeInstanceRepository.save(nodeInstance);
|
||||||
|
|
||||||
|
// 4. 检查是否所有节点都已完成
|
||||||
|
List<NodeInstance> uncompletedNodes = nodeInstanceRepository.findByWorkflowInstanceIdAndStatusNot(
|
||||||
|
instance.getId(), NodeStatusEnum.COMPLETED);
|
||||||
|
|
||||||
|
if (uncompletedNodes.isEmpty()) {
|
||||||
|
instance.complete();
|
||||||
|
workflowInstanceRepository.save(instance);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
// 更新节点状态为失败
|
||||||
nodeInstance.setStatus(NodeStatusEnum.FAILED);
|
nodeInstance.setStatus(NodeStatusEnum.FAILED);
|
||||||
nodeInstance.setEndTime(LocalDateTime.now());
|
nodeInstance.setEndTime(LocalDateTime.now());
|
||||||
nodeInstance.setError(e.getMessage());
|
nodeInstance.setError(e.getMessage());
|
||||||
nodeInstanceRepository.save(nodeInstance);
|
nodeInstanceRepository.save(nodeInstance);
|
||||||
|
|
||||||
|
// 更新工作流实例状态
|
||||||
|
instance.updateError(e.getMessage());
|
||||||
|
workflowInstanceRepository.save(instance);
|
||||||
|
|
||||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
throw new WorkflowEngineException(ResponseCode.WORKFLOW_NODE_EXECUTION_FAILED, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,29 +159,20 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
||||||
|
|
||||||
// 检查工作流实例状态
|
// 检查工作流实例状态
|
||||||
if (instance.getStatus() != WorkflowInstanceStatusEnum.RUNNING) {
|
if (!instance.canTerminate()) {
|
||||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 终止所有运行中的节点
|
// 终止所有运行中的节点
|
||||||
List<NodeInstance> runningNodes = nodeInstanceRepository.findByWorkflowInstanceIdAndStatus(
|
List<NodeInstance> runningNodes = nodeInstanceRepository.findByWorkflowInstanceIdAndStatus(
|
||||||
instanceId, NodeStatusEnum.RUNNING);
|
instanceId, NodeStatusEnum.RUNNING);
|
||||||
|
|
||||||
WorkflowContext context = workflowContextFactory.create(instance);
|
|
||||||
for (NodeInstance node : runningNodes) {
|
for (NodeInstance node : runningNodes) {
|
||||||
NodeExecutor executor = nodeExecutors.get(node.getNodeType());
|
|
||||||
if (executor != null) {
|
|
||||||
executor.terminate(node, context);
|
|
||||||
}
|
|
||||||
node.setStatus(NodeStatusEnum.TERMINATED);
|
node.setStatus(NodeStatusEnum.TERMINATED);
|
||||||
node.setEndTime(LocalDateTime.now());
|
node.setEndTime(LocalDateTime.now());
|
||||||
nodeInstanceRepository.save(node);
|
nodeInstanceRepository.save(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新工作流实例状态
|
instance.terminate(reason);
|
||||||
instance.setStatus(WorkflowInstanceStatusEnum.TERMINATED);
|
|
||||||
instance.setEndTime(LocalDateTime.now());
|
|
||||||
instance.setError(reason);
|
|
||||||
workflowInstanceRepository.save(instance);
|
workflowInstanceRepository.save(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,22 +182,11 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
WorkflowInstance instance = workflowInstanceRepository.findById(instanceId)
|
WorkflowInstance instance = workflowInstanceRepository.findById(instanceId)
|
||||||
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
||||||
|
|
||||||
// 检查工作流实例状态
|
if (!instance.canPause()) {
|
||||||
if (instance.getStatus() != WorkflowInstanceStatusEnum.RUNNING) {
|
|
||||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暂停所有运行中的节点
|
instance.pause();
|
||||||
List<NodeInstance> runningNodes = nodeInstanceRepository.findByWorkflowInstanceIdAndStatus(
|
|
||||||
instanceId, NodeStatusEnum.RUNNING);
|
|
||||||
|
|
||||||
for (NodeInstance node : runningNodes) {
|
|
||||||
node.setStatus(NodeStatusEnum.PAUSED);
|
|
||||||
nodeInstanceRepository.save(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新工作流实例状态
|
|
||||||
instance.setStatus(WorkflowInstanceStatusEnum.PAUSED);
|
|
||||||
workflowInstanceRepository.save(instance);
|
workflowInstanceRepository.save(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,24 +196,51 @@ public class DefaultWorkflowEngine implements WorkflowEngine {
|
|||||||
WorkflowInstance instance = workflowInstanceRepository.findById(instanceId)
|
WorkflowInstance instance = workflowInstanceRepository.findById(instanceId)
|
||||||
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
||||||
|
|
||||||
// 检查工作流实例状态
|
if (!instance.canResume()) {
|
||||||
if (instance.getStatus() != WorkflowInstanceStatusEnum.PAUSED) {
|
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.resume();
|
||||||
|
workflowInstanceRepository.save(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void retryWorkflow(Long instanceId) {
|
||||||
|
WorkflowInstance instance = workflowInstanceRepository.findById(instanceId)
|
||||||
|
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
||||||
|
|
||||||
|
if (!instance.canRetry()) {
|
||||||
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
throw new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_RUNNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 恢复所有暂停的节点
|
// 重试工作流实例
|
||||||
List<NodeInstance> pausedNodes = nodeInstanceRepository.findByWorkflowInstanceIdAndStatus(
|
instance.retry();
|
||||||
instanceId, NodeStatusEnum.PAUSED);
|
workflowInstanceRepository.save(instance);
|
||||||
|
|
||||||
for (NodeInstance node : pausedNodes) {
|
// 获取失败的节点
|
||||||
node.setStatus(NodeStatusEnum.RUNNING);
|
List<NodeInstance> failedNodes = nodeInstanceRepository.findByWorkflowInstanceIdAndStatus(
|
||||||
|
instanceId, NodeStatusEnum.FAILED);
|
||||||
|
|
||||||
|
// 重试失败的节点
|
||||||
|
for (NodeInstance node : failedNodes) {
|
||||||
|
node.setStatus(NodeStatusEnum.PENDING);
|
||||||
|
node.setError(null);
|
||||||
nodeInstanceRepository.save(node);
|
nodeInstanceRepository.save(node);
|
||||||
executeNode(node.getId());
|
executeNode(node.getId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 更新工作流实例状态
|
@Override
|
||||||
instance.setStatus(WorkflowInstanceStatusEnum.RUNNING);
|
@Transactional
|
||||||
workflowInstanceRepository.save(instance);
|
public void checkTimeout(Long instanceId, long timeoutMillis) {
|
||||||
|
WorkflowInstance instance = workflowInstanceRepository.findById(instanceId)
|
||||||
|
.orElseThrow(() -> new WorkflowEngineException(ResponseCode.WORKFLOW_INSTANCE_NOT_FOUND));
|
||||||
|
|
||||||
|
if (instance.isTimeout(timeoutMillis)) {
|
||||||
|
String error = "Workflow execution timeout after " + timeoutMillis + " milliseconds";
|
||||||
|
terminateWorkflow(instanceId, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NodeInstance createStartNode(WorkflowDefinition definition, Long instanceId) {
|
private NodeInstance createStartNode(WorkflowDefinition definition, Long instanceId) {
|
||||||
|
|||||||
@ -38,4 +38,16 @@ public interface WorkflowEngine {
|
|||||||
* 恢复工作流实例
|
* 恢复工作流实例
|
||||||
*/
|
*/
|
||||||
void resumeWorkflow(Long instanceId);
|
void resumeWorkflow(Long instanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重试工作流实例
|
||||||
|
*/
|
||||||
|
void retryWorkflow(Long instanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查工作流实例是否超时
|
||||||
|
* @param instanceId 工作流实例ID
|
||||||
|
* @param timeoutMillis 超时时间(毫秒)
|
||||||
|
*/
|
||||||
|
void checkTimeout(Long instanceId, long timeoutMillis);
|
||||||
}
|
}
|
||||||
@ -81,10 +81,87 @@ public class WorkflowDefinition extends Entity<Long> {
|
|||||||
@OneToMany(mappedBy = "workflowDefinition", cascade = CascadeType.ALL, orphanRemoval = true)
|
@OneToMany(mappedBy = "workflowDefinition", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
private List<NodeDefinition> nodes = new ArrayList<>();
|
private List<NodeDefinition> nodes = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
@Column(nullable = false)
|
||||||
|
private Integer version = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取流转配置
|
* 获取流转配置
|
||||||
*/
|
*/
|
||||||
public String getTransitionConfig() {
|
public String getTransitionConfig() {
|
||||||
return transitionConfig;
|
return transitionConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以发布
|
||||||
|
*/
|
||||||
|
public boolean canPublish() {
|
||||||
|
return status == WorkflowDefinitionStatusEnum.DRAFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以禁用
|
||||||
|
*/
|
||||||
|
public boolean canDisable() {
|
||||||
|
return status == WorkflowDefinitionStatusEnum.PUBLISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以启用
|
||||||
|
*/
|
||||||
|
public boolean canEnable() {
|
||||||
|
return status == WorkflowDefinitionStatusEnum.DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以更新
|
||||||
|
*/
|
||||||
|
public boolean canUpdate() {
|
||||||
|
return status == WorkflowDefinitionStatusEnum.DRAFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布工作流定义
|
||||||
|
*/
|
||||||
|
public void publish() {
|
||||||
|
if (!canPublish()) {
|
||||||
|
throw new IllegalStateException("Cannot publish workflow definition in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowDefinitionStatusEnum.PUBLISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 禁用工作流定义
|
||||||
|
*/
|
||||||
|
public void disable() {
|
||||||
|
if (!canDisable()) {
|
||||||
|
throw new IllegalStateException("Cannot disable workflow definition in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowDefinitionStatusEnum.DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用工作流定义
|
||||||
|
*/
|
||||||
|
public void enable() {
|
||||||
|
if (!canEnable()) {
|
||||||
|
throw new IllegalStateException("Cannot enable workflow definition in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowDefinitionStatusEnum.PUBLISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新版本
|
||||||
|
*/
|
||||||
|
public WorkflowDefinition createNewVersion() {
|
||||||
|
WorkflowDefinition newVersion = new WorkflowDefinition();
|
||||||
|
newVersion.setCode(this.code);
|
||||||
|
newVersion.setName(this.name);
|
||||||
|
newVersion.setDescription(this.description);
|
||||||
|
newVersion.setVersion(this.version + 1);
|
||||||
|
newVersion.setStatus(WorkflowDefinitionStatusEnum.DRAFT);
|
||||||
|
return newVersion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -25,6 +25,12 @@ public class WorkflowInstance extends Entity<Long> {
|
|||||||
@JoinColumn(name = "workflow_definition_id", nullable = false)
|
@JoinColumn(name = "workflow_definition_id", nullable = false)
|
||||||
private WorkflowDefinition workflowDefinition;
|
private WorkflowDefinition workflowDefinition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工作流定义ID,用于查询优化
|
||||||
|
*/
|
||||||
|
@Column(name = "workflow_definition_id", insertable = false, updatable = false)
|
||||||
|
private Long workflowDefinitionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 项目环境ID
|
* 项目环境ID
|
||||||
*/
|
*/
|
||||||
@ -68,4 +74,176 @@ public class WorkflowInstance extends Entity<Long> {
|
|||||||
public void setDefinition(WorkflowDefinition definition) {
|
public void setDefinition(WorkflowDefinition definition) {
|
||||||
this.workflowDefinition = definition;
|
this.workflowDefinition = definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以启动
|
||||||
|
*/
|
||||||
|
public boolean canStart() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.CREATED || status == WorkflowInstanceStatusEnum.PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以暂停
|
||||||
|
*/
|
||||||
|
public boolean canPause() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以恢复
|
||||||
|
*/
|
||||||
|
public boolean canResume() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以终止
|
||||||
|
*/
|
||||||
|
public boolean canTerminate() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.RUNNING ||
|
||||||
|
status == WorkflowInstanceStatusEnum.PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以完成
|
||||||
|
*/
|
||||||
|
public boolean canComplete() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以执行节点
|
||||||
|
*/
|
||||||
|
public boolean canExecuteNode() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启动工作流实例
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
if (!canStart()) {
|
||||||
|
throw new IllegalStateException("Cannot start workflow instance in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowInstanceStatusEnum.RUNNING;
|
||||||
|
this.startTime = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 暂停工作流实例
|
||||||
|
*/
|
||||||
|
public void pause() {
|
||||||
|
if (!canPause()) {
|
||||||
|
throw new IllegalStateException("Cannot pause workflow instance in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowInstanceStatusEnum.PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复工作流实例
|
||||||
|
*/
|
||||||
|
public void resume() {
|
||||||
|
if (!canResume()) {
|
||||||
|
throw new IllegalStateException("Cannot resume workflow instance in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowInstanceStatusEnum.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 终止工作流实例
|
||||||
|
*/
|
||||||
|
public void terminate(String reason) {
|
||||||
|
if (!canTerminate()) {
|
||||||
|
throw new IllegalStateException("Cannot terminate workflow instance in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowInstanceStatusEnum.TERMINATED;
|
||||||
|
this.endTime = LocalDateTime.now();
|
||||||
|
this.error = reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成工作流实例
|
||||||
|
*/
|
||||||
|
public void complete() {
|
||||||
|
if (!canComplete()) {
|
||||||
|
throw new IllegalStateException("Cannot complete workflow instance in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowInstanceStatusEnum.COMPLETED;
|
||||||
|
this.endTime = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记工作流实例为失败
|
||||||
|
*/
|
||||||
|
public void fail(String error) {
|
||||||
|
this.status = WorkflowInstanceStatusEnum.FAILED;
|
||||||
|
this.endTime = LocalDateTime.now();
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查工作流实例是否处于活动状态
|
||||||
|
*/
|
||||||
|
public boolean isActive() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.RUNNING ||
|
||||||
|
status == WorkflowInstanceStatusEnum.PENDING ||
|
||||||
|
status == WorkflowInstanceStatusEnum.PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查工作流实例是否已经结束
|
||||||
|
*/
|
||||||
|
public boolean isEnded() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.COMPLETED ||
|
||||||
|
status == WorkflowInstanceStatusEnum.TERMINATED ||
|
||||||
|
status == WorkflowInstanceStatusEnum.FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查工作流实例是否可以重试
|
||||||
|
*/
|
||||||
|
public boolean canRetry() {
|
||||||
|
return status == WorkflowInstanceStatusEnum.FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重试工作流实例
|
||||||
|
*/
|
||||||
|
public void retry() {
|
||||||
|
if (!canRetry()) {
|
||||||
|
throw new IllegalStateException("Cannot retry workflow instance in " + status + " status");
|
||||||
|
}
|
||||||
|
this.status = WorkflowInstanceStatusEnum.PENDING;
|
||||||
|
this.error = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取工作流实例的运行时长(毫秒)
|
||||||
|
*/
|
||||||
|
public long getDuration() {
|
||||||
|
if (startTime == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LocalDateTime end = endTime != null ? endTime : LocalDateTime.now();
|
||||||
|
return java.time.Duration.between(startTime, end).toMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查工作流实例是否超时
|
||||||
|
* @param timeoutMillis 超时时间(毫秒)
|
||||||
|
*/
|
||||||
|
public boolean isTimeout(long timeoutMillis) {
|
||||||
|
return startTime != null && getDuration() > timeoutMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工作流实例的错误信息
|
||||||
|
*/
|
||||||
|
public void updateError(String error) {
|
||||||
|
this.error = error;
|
||||||
|
if (this.status == WorkflowInstanceStatusEnum.RUNNING) {
|
||||||
|
this.status = WorkflowInstanceStatusEnum.FAILED;
|
||||||
|
this.endTime = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -28,4 +28,9 @@ public interface INodeInstanceRepository extends IBaseRepository<NodeInstance, L
|
|||||||
List<NodeInstance> findByWorkflowInstanceId(Long workflowInstanceId);
|
List<NodeInstance> findByWorkflowInstanceId(Long workflowInstanceId);
|
||||||
|
|
||||||
void deleteByWorkflowInstanceId(Long workflowInstanceId);
|
void deleteByWorkflowInstanceId(Long workflowInstanceId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询不是指定状态的节点实例
|
||||||
|
*/
|
||||||
|
List<NodeInstance> findByWorkflowInstanceIdAndStatusNot(Long workflowInstanceId, NodeStatusEnum status);
|
||||||
}
|
}
|
||||||
@ -7,6 +7,8 @@ import org.springframework.data.jpa.repository.Query;
|
|||||||
import org.springframework.data.repository.query.Param;
|
import org.springframework.data.repository.query.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,12 +24,38 @@ public interface IWorkflowInstanceRepository extends IBaseRepository<WorkflowIns
|
|||||||
List<WorkflowInstance> findByStatusIn(@Param("statuses") List<WorkflowInstanceStatusEnum> statuses);
|
List<WorkflowInstance> findByStatusIn(@Param("statuses") List<WorkflowInstanceStatusEnum> statuses);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据工作流定义ID和状态查询工作流实例数量
|
* 根据工作流定义ID和状态查询工作流实例
|
||||||
*/
|
*/
|
||||||
long countByDefinitionIdAndStatus(Long definitionId, WorkflowInstanceStatusEnum status);
|
List<WorkflowInstance> findByWorkflowDefinitionIdAndStatus(Long workflowDefinitionId, WorkflowInstanceStatusEnum status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据工作流定义ID和状态统计工作流实例数量
|
||||||
|
*/
|
||||||
|
Long countByWorkflowDefinitionIdAndStatus(Long workflowDefinitionId, WorkflowInstanceStatusEnum status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询项目环境的工作流实例
|
* 查询项目环境的工作流实例
|
||||||
*/
|
*/
|
||||||
List<WorkflowInstance> findByProjectEnvIdAndDeletedFalseOrderByCreateTimeDesc(Long projectEnvId);
|
List<WorkflowInstance> findByProjectEnvIdAndDeletedFalseOrderByCreateTimeDesc(Long projectEnvId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找超过指定时间未完成的工作流实例
|
||||||
|
*/
|
||||||
|
@Query("SELECT wi FROM WorkflowInstance wi WHERE wi.status = :status AND wi.startTime < :beforeTime")
|
||||||
|
List<WorkflowInstance> findTimeoutInstances(@Param("status") WorkflowInstanceStatusEnum status,
|
||||||
|
@Param("beforeTime") LocalDateTime beforeTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找指定工作流定义下所有未结束的实例
|
||||||
|
*/
|
||||||
|
@Query("SELECT wi FROM WorkflowInstance wi WHERE wi.workflowDefinitionId = :definitionId AND wi.status IN :activeStatuses")
|
||||||
|
List<WorkflowInstance> findActiveInstancesByDefinitionId(@Param("definitionId") Long definitionId,
|
||||||
|
@Param("activeStatuses") Collection<WorkflowInstanceStatusEnum> activeStatuses);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计指定工作流定义下所有未结束的实例数量
|
||||||
|
*/
|
||||||
|
@Query("SELECT COUNT(wi) FROM WorkflowInstance wi WHERE wi.workflowDefinitionId = :definitionId AND wi.status IN :activeStatuses")
|
||||||
|
Long countActiveInstancesByDefinitionId(@Param("definitionId") Long definitionId,
|
||||||
|
@Param("activeStatuses") Collection<WorkflowInstanceStatusEnum> activeStatuses);
|
||||||
}
|
}
|
||||||
@ -204,6 +204,7 @@ workflow.instance.not.found=工作流实例不存在
|
|||||||
workflow.instance.already.completed=工作流实例已完成
|
workflow.instance.already.completed=工作流实例已完成
|
||||||
workflow.instance.already.canceled=工作流实例已取消
|
workflow.instance.already.canceled=工作流实例已取消
|
||||||
workflow.instance.not.running=工作流实例未运行
|
workflow.instance.not.running=工作流实例未运行
|
||||||
|
workflow.instance.not.paused=工作流实例不是暂停状态
|
||||||
|
|
||||||
workflow.node.not.found=工作流节点不存在
|
workflow.node.not.found=工作流节点不存在
|
||||||
workflow.node.type.not.supported=不支持的节点类型
|
workflow.node.type.not.supported=不支持的节点类型
|
||||||
|
|||||||
@ -24,6 +24,7 @@ workflow.instance.not.found=Workflow instance not found
|
|||||||
workflow.instance.already.completed=Workflow instance already completed
|
workflow.instance.already.completed=Workflow instance already completed
|
||||||
workflow.instance.already.canceled=Workflow instance already canceled
|
workflow.instance.already.canceled=Workflow instance already canceled
|
||||||
workflow.instance.not.running=Workflow instance is not running
|
workflow.instance.not.running=Workflow instance is not running
|
||||||
|
workflow.instance.not.paused=Workflow instance is not paused
|
||||||
|
|
||||||
workflow.node.not.found=Workflow node not found
|
workflow.node.not.found=Workflow node not found
|
||||||
workflow.node.type.not.supported=Unsupported node type
|
workflow.node.type.not.supported=Unsupported node type
|
||||||
|
|||||||
@ -113,6 +113,7 @@ workflow.instance.not.found=工作流实例不存在
|
|||||||
workflow.instance.already.completed=工作流实例已完成
|
workflow.instance.already.completed=工作流实例已完成
|
||||||
workflow.instance.already.canceled=工作流实例已取消
|
workflow.instance.already.canceled=工作流实例已取消
|
||||||
workflow.instance.not.running=工作流实例未运行
|
workflow.instance.not.running=工作流实例未运行
|
||||||
|
workflow.instance.not.paused=工作流实例未暂停
|
||||||
|
|
||||||
workflow.node.not.found=工作流节点不存在
|
workflow.node.not.found=工作流节点不存在
|
||||||
workflow.node.type.not.supported=不支持的节点类型
|
workflow.node.type.not.supported=不支持的节点类型
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
|
|||||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
import com.qqchen.deploy.backend.workflow.enums.NodeStatusEnum;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnum;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.WorkflowStatusEnum;
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowDefinitionStatusEnum;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnum;
|
||||||
import com.qqchen.deploy.backend.workflow.repository.INodeInstanceRepository;
|
import com.qqchen.deploy.backend.workflow.repository.INodeInstanceRepository;
|
||||||
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
|
||||||
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
|
||||||
@ -79,8 +80,9 @@ class DefaultWorkflowEngineTest {
|
|||||||
variables.put("key1", "value1");
|
variables.put("key1", "value1");
|
||||||
|
|
||||||
WorkflowDefinition definition = new WorkflowDefinition();
|
WorkflowDefinition definition = new WorkflowDefinition();
|
||||||
|
definition.setId(1L);
|
||||||
definition.setCode(workflowCode);
|
definition.setCode(workflowCode);
|
||||||
definition.setStatus(WorkflowStatusEnum.PUBLISHED);
|
definition.setStatus(WorkflowDefinitionStatusEnum.PUBLISHED);
|
||||||
|
|
||||||
NodeInstance startNode = new NodeInstance();
|
NodeInstance startNode = new NodeInstance();
|
||||||
startNode.setId(1L);
|
startNode.setId(1L);
|
||||||
@ -99,7 +101,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
|
|
||||||
// 验证结果
|
// 验证结果
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(WorkflowStatusEnum.RUNNING, result.getStatus());
|
assertEquals(WorkflowInstanceStatusEnum.RUNNING, result.getStatus());
|
||||||
assertNotNull(result.getStartTime());
|
assertNotNull(result.getStartTime());
|
||||||
|
|
||||||
verify(workflowDefinitionRepository).findByCodeAndDeletedFalse(workflowCode);
|
verify(workflowDefinitionRepository).findByCodeAndDeletedFalse(workflowCode);
|
||||||
@ -129,7 +131,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
String workflowCode = "draft-workflow";
|
String workflowCode = "draft-workflow";
|
||||||
WorkflowDefinition definition = new WorkflowDefinition();
|
WorkflowDefinition definition = new WorkflowDefinition();
|
||||||
definition.setCode(workflowCode);
|
definition.setCode(workflowCode);
|
||||||
definition.setStatus(WorkflowStatusEnum.DRAFT);
|
definition.setStatus(WorkflowDefinitionStatusEnum.DRAFT);
|
||||||
|
|
||||||
// 配置Mock行为
|
// 配置Mock行为
|
||||||
when(workflowDefinitionRepository.findByCodeAndDeletedFalse(workflowCode)).thenReturn(definition);
|
when(workflowDefinitionRepository.findByCodeAndDeletedFalse(workflowCode)).thenReturn(definition);
|
||||||
@ -150,7 +152,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
nodeInstance.setStatus(NodeStatusEnum.PENDING);
|
nodeInstance.setStatus(NodeStatusEnum.PENDING);
|
||||||
|
|
||||||
WorkflowInstance instance = new WorkflowInstance();
|
WorkflowInstance instance = new WorkflowInstance();
|
||||||
instance.setStatus(WorkflowStatusEnum.RUNNING);
|
instance.setStatus(WorkflowInstanceStatusEnum.RUNNING);
|
||||||
nodeInstance.setWorkflowInstance(instance);
|
nodeInstance.setWorkflowInstance(instance);
|
||||||
|
|
||||||
// 配置Mock行为
|
// 配置Mock行为
|
||||||
@ -192,7 +194,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
nodeInstance.setNodeType(NodeTypeEnum.TASK);
|
nodeInstance.setNodeType(NodeTypeEnum.TASK);
|
||||||
|
|
||||||
WorkflowInstance instance = new WorkflowInstance();
|
WorkflowInstance instance = new WorkflowInstance();
|
||||||
instance.setStatus(WorkflowStatusEnum.COMPLETED);
|
instance.setStatus(WorkflowInstanceStatusEnum.COMPLETED);
|
||||||
nodeInstance.setWorkflowInstance(instance);
|
nodeInstance.setWorkflowInstance(instance);
|
||||||
|
|
||||||
// 配置Mock行为
|
// 配置Mock行为
|
||||||
@ -212,7 +214,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
|
|
||||||
WorkflowInstance instance = new WorkflowInstance();
|
WorkflowInstance instance = new WorkflowInstance();
|
||||||
instance.setId(instanceId);
|
instance.setId(instanceId);
|
||||||
instance.setStatus(WorkflowStatusEnum.RUNNING);
|
instance.setStatus(WorkflowInstanceStatusEnum.RUNNING);
|
||||||
|
|
||||||
NodeInstance runningNode = new NodeInstance();
|
NodeInstance runningNode = new NodeInstance();
|
||||||
runningNode.setNodeType(NodeTypeEnum.TASK);
|
runningNode.setNodeType(NodeTypeEnum.TASK);
|
||||||
@ -228,7 +230,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
workflowEngine.terminateWorkflow(instanceId, reason);
|
workflowEngine.terminateWorkflow(instanceId, reason);
|
||||||
|
|
||||||
// 验证结果
|
// 验证结果
|
||||||
assertEquals(WorkflowStatusEnum.TERMINATED, instance.getStatus());
|
assertEquals(WorkflowInstanceStatusEnum.TERMINATED, instance.getStatus());
|
||||||
assertEquals(reason, instance.getError());
|
assertEquals(reason, instance.getError());
|
||||||
assertNotNull(instance.getEndTime());
|
assertNotNull(instance.getEndTime());
|
||||||
assertEquals(NodeStatusEnum.TERMINATED, runningNode.getStatus());
|
assertEquals(NodeStatusEnum.TERMINATED, runningNode.getStatus());
|
||||||
@ -247,7 +249,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
Long instanceId = 1L;
|
Long instanceId = 1L;
|
||||||
WorkflowInstance instance = new WorkflowInstance();
|
WorkflowInstance instance = new WorkflowInstance();
|
||||||
instance.setId(instanceId);
|
instance.setId(instanceId);
|
||||||
instance.setStatus(WorkflowStatusEnum.RUNNING);
|
instance.setStatus(WorkflowInstanceStatusEnum.RUNNING);
|
||||||
|
|
||||||
NodeInstance runningNode = new NodeInstance();
|
NodeInstance runningNode = new NodeInstance();
|
||||||
runningNode.setStatus(NodeStatusEnum.RUNNING);
|
runningNode.setStatus(NodeStatusEnum.RUNNING);
|
||||||
@ -261,7 +263,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
workflowEngine.pauseWorkflow(instanceId);
|
workflowEngine.pauseWorkflow(instanceId);
|
||||||
|
|
||||||
// 验证结果
|
// 验证结果
|
||||||
assertEquals(WorkflowStatusEnum.PAUSED, instance.getStatus());
|
assertEquals(WorkflowInstanceStatusEnum.PAUSED, instance.getStatus());
|
||||||
assertEquals(NodeStatusEnum.PAUSED, runningNode.getStatus());
|
assertEquals(NodeStatusEnum.PAUSED, runningNode.getStatus());
|
||||||
|
|
||||||
verify(workflowInstanceRepository).findById(instanceId);
|
verify(workflowInstanceRepository).findById(instanceId);
|
||||||
@ -276,7 +278,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
Long instanceId = 1L;
|
Long instanceId = 1L;
|
||||||
WorkflowInstance instance = new WorkflowInstance();
|
WorkflowInstance instance = new WorkflowInstance();
|
||||||
instance.setId(instanceId);
|
instance.setId(instanceId);
|
||||||
instance.setStatus(WorkflowStatusEnum.PAUSED);
|
instance.setStatus(WorkflowInstanceStatusEnum.PAUSED);
|
||||||
|
|
||||||
NodeInstance pausedNode = new NodeInstance();
|
NodeInstance pausedNode = new NodeInstance();
|
||||||
pausedNode.setId(2L);
|
pausedNode.setId(2L);
|
||||||
@ -294,7 +296,7 @@ class DefaultWorkflowEngineTest {
|
|||||||
workflowEngine.resumeWorkflow(instanceId);
|
workflowEngine.resumeWorkflow(instanceId);
|
||||||
|
|
||||||
// 验证结果
|
// 验证结果
|
||||||
assertEquals(WorkflowStatusEnum.RUNNING, instance.getStatus());
|
assertEquals(WorkflowInstanceStatusEnum.RUNNING, instance.getStatus());
|
||||||
assertEquals(NodeStatusEnum.RUNNING, pausedNode.getStatus());
|
assertEquals(NodeStatusEnum.RUNNING, pausedNode.getStatus());
|
||||||
|
|
||||||
verify(workflowInstanceRepository).findById(instanceId);
|
verify(workflowInstanceRepository).findById(instanceId);
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
|||||||
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
import com.qqchen.deploy.backend.framework.exception.BusinessException;
|
||||||
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
|
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
|
||||||
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
|
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
|
||||||
import com.qqchen.deploy.backend.workflow.enums.WorkflowStatusEnum;
|
import com.qqchen.deploy.backend.workflow.enums.WorkflowDefinitionStatusEnum;
|
||||||
import com.qqchen.deploy.backend.workflow.repository.INodeDefinitionRepository;
|
import com.qqchen.deploy.backend.workflow.repository.INodeDefinitionRepository;
|
||||||
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
|
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
|
||||||
import com.qqchen.deploy.backend.workflow.service.impl.WorkflowDefinitionServiceImpl;
|
import com.qqchen.deploy.backend.workflow.service.impl.WorkflowDefinitionServiceImpl;
|
||||||
@ -52,7 +52,7 @@ class WorkflowDefinitionServiceTest {
|
|||||||
entity.setId(1L);
|
entity.setId(1L);
|
||||||
entity.setCode("TEST-WF");
|
entity.setCode("TEST-WF");
|
||||||
entity.setName("Test Workflow");
|
entity.setName("Test Workflow");
|
||||||
entity.setStatus(WorkflowStatusEnum.DRAFT);
|
entity.setStatus(WorkflowDefinitionStatusEnum.DRAFT);
|
||||||
entity.setEnabled(true);
|
entity.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ class WorkflowDefinitionServiceTest {
|
|||||||
WorkflowDefinitionDTO result = workflowDefinitionService.create(dto);
|
WorkflowDefinitionDTO result = workflowDefinitionService.create(dto);
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(WorkflowStatusEnum.DRAFT, result.getStatus());
|
assertEquals(WorkflowDefinitionStatusEnum.DRAFT, result.getStatus());
|
||||||
assertTrue(result.getEnabled());
|
assertTrue(result.getEnabled());
|
||||||
verify(workflowDefinitionRepository).existsByCodeAndDeletedFalse(dto.getCode());
|
verify(workflowDefinitionRepository).existsByCodeAndDeletedFalse(dto.getCode());
|
||||||
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
||||||
@ -81,21 +81,21 @@ class WorkflowDefinitionServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void publish_Success() {
|
void publish_Success() {
|
||||||
entity.setStatus(WorkflowStatusEnum.DRAFT);
|
entity.setStatus(WorkflowDefinitionStatusEnum.DRAFT);
|
||||||
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
||||||
when(workflowDefinitionRepository.save(any(WorkflowDefinition.class))).thenReturn(entity);
|
when(workflowDefinitionRepository.save(any(WorkflowDefinition.class))).thenReturn(entity);
|
||||||
|
|
||||||
WorkflowDefinitionDTO result = workflowDefinitionService.publish(1L);
|
WorkflowDefinitionDTO result = workflowDefinitionService.publish(1L);
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(WorkflowStatusEnum.PUBLISHED, result.getStatus());
|
assertEquals(WorkflowDefinitionStatusEnum.PUBLISHED, result.getStatus());
|
||||||
verify(workflowDefinitionRepository).findById(1L);
|
verify(workflowDefinitionRepository).findById(1L);
|
||||||
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void publish_NotDraft_ThrowsException() {
|
void publish_NotDraft_ThrowsException() {
|
||||||
entity.setStatus(WorkflowStatusEnum.PUBLISHED);
|
entity.setStatus(WorkflowDefinitionStatusEnum.PUBLISHED);
|
||||||
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
||||||
|
|
||||||
BusinessException exception = assertThrows(BusinessException.class,
|
BusinessException exception = assertThrows(BusinessException.class,
|
||||||
@ -105,28 +105,28 @@ class WorkflowDefinitionServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void disable_Success() {
|
void disable_Success() {
|
||||||
entity.setStatus(WorkflowStatusEnum.PUBLISHED);
|
entity.setStatus(WorkflowDefinitionStatusEnum.PUBLISHED);
|
||||||
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
||||||
when(workflowDefinitionRepository.save(any(WorkflowDefinition.class))).thenReturn(entity);
|
when(workflowDefinitionRepository.save(any(WorkflowDefinition.class))).thenReturn(entity);
|
||||||
|
|
||||||
WorkflowDefinitionDTO result = workflowDefinitionService.disable(1L);
|
WorkflowDefinitionDTO result = workflowDefinitionService.disable(1L);
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(WorkflowStatusEnum.DISABLED, result.getStatus());
|
assertEquals(WorkflowDefinitionStatusEnum.DISABLED, result.getStatus());
|
||||||
verify(workflowDefinitionRepository).findById(1L);
|
verify(workflowDefinitionRepository).findById(1L);
|
||||||
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void enable_Success() {
|
void enable_Success() {
|
||||||
entity.setStatus(WorkflowStatusEnum.DISABLED);
|
entity.setStatus(WorkflowDefinitionStatusEnum.DISABLED);
|
||||||
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
when(workflowDefinitionRepository.findById(anyLong())).thenReturn(Optional.of(entity));
|
||||||
when(workflowDefinitionRepository.save(any(WorkflowDefinition.class))).thenReturn(entity);
|
when(workflowDefinitionRepository.save(any(WorkflowDefinition.class))).thenReturn(entity);
|
||||||
|
|
||||||
WorkflowDefinitionDTO result = workflowDefinitionService.enable(1L);
|
WorkflowDefinitionDTO result = workflowDefinitionService.enable(1L);
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(WorkflowStatusEnum.PUBLISHED, result.getStatus());
|
assertEquals(WorkflowDefinitionStatusEnum.PUBLISHED, result.getStatus());
|
||||||
verify(workflowDefinitionRepository).findById(1L);
|
verify(workflowDefinitionRepository).findById(1L);
|
||||||
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
verify(workflowDefinitionRepository).save(any(WorkflowDefinition.class));
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ class WorkflowDefinitionServiceTest {
|
|||||||
WorkflowDefinitionDTO result = workflowDefinitionService.createNewVersion(1L);
|
WorkflowDefinitionDTO result = workflowDefinitionService.createNewVersion(1L);
|
||||||
|
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(WorkflowStatusEnum.DRAFT, result.getStatus());
|
assertEquals(WorkflowDefinitionStatusEnum.DRAFT, result.getStatus());
|
||||||
assertTrue(result.getEnabled());
|
assertTrue(result.getEnabled());
|
||||||
verify(workflowDefinitionRepository).findById(1L);
|
verify(workflowDefinitionRepository).findById(1L);
|
||||||
verify(workflowDefinitionRepository).findLatestVersionByCode(entity.getCode());
|
verify(workflowDefinitionRepository).findLatestVersionByCode(entity.getCode());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user