|
|
|
|
using MediatR;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using X1.Application.Features.TaskExecution.Events.NodeExecutionEvents;
|
|
|
|
|
using X1.Domain.Events;
|
|
|
|
|
using X1.Domain.Entities.TestCase;
|
|
|
|
|
|
|
|
|
|
namespace X1.Application.Features.TaskExecution.Events.ControllerHandlers;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 启动流程控制器处理器
|
|
|
|
|
/// 处理测试流程启动相关的节点执行事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class StartFlowControllerHandler : INotificationHandler<StartFlowExecutionEvent>
|
|
|
|
|
{
|
|
|
|
|
private readonly IMediator _mediator;
|
|
|
|
|
private readonly ILogger<StartFlowControllerHandler> _logger;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 初始化启动流程控制器处理器
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="mediator">MediatR 中介者</param>
|
|
|
|
|
/// <param name="logger">日志记录器</param>
|
|
|
|
|
public StartFlowControllerHandler(IMediator mediator, ILogger<StartFlowControllerHandler> logger)
|
|
|
|
|
{
|
|
|
|
|
_mediator = mediator;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 处理启动流程节点执行事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="notification">节点执行事件</param>
|
|
|
|
|
/// <param name="cancellationToken">取消令牌</param>
|
|
|
|
|
/// <returns>处理任务</returns>
|
|
|
|
|
public async Task Handle(StartFlowExecutionEvent notification, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation("开始执行启动流程,任务执行ID: {TaskExecutionId}, 节点ID: {NodeId}, 运行时编码: {RuntimeCode}",
|
|
|
|
|
notification.TaskExecutionId, notification.NodeId, notification.RuntimeCode);
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// 1. 更新节点状态为运行中
|
|
|
|
|
await UpdateNodeStatusAsync(notification.NodeId, NodeExecutionStatus.Running);
|
|
|
|
|
|
|
|
|
|
// 2. 执行启动流程业务逻辑
|
|
|
|
|
var result = await ExecuteStartFlowAsync(notification, cancellationToken);
|
|
|
|
|
|
|
|
|
|
// 3. 创建执行结果
|
|
|
|
|
var executionResult = new NodeExecutionResult
|
|
|
|
|
{
|
|
|
|
|
TaskExecutionId = notification.TaskExecutionId,
|
|
|
|
|
NodeId = notification.NodeId,
|
|
|
|
|
StepMapping = StepMapping.StartFlow,
|
|
|
|
|
Status = NodeExecutionStatus.Completed,
|
|
|
|
|
IsSuccess = true,
|
|
|
|
|
ResultData = result,
|
|
|
|
|
ExecutorId = notification.ExecutorId,
|
|
|
|
|
RuntimeCode = notification.RuntimeCode,
|
|
|
|
|
CreatedAt = DateTime.UtcNow
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 4. 发布完成事件
|
|
|
|
|
await PublishCompletedEventAsync(notification, executionResult, cancellationToken);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("启动流程执行成功,任务执行ID: {TaskExecutionId}, 节点ID: {NodeId}",
|
|
|
|
|
notification.TaskExecutionId, notification.NodeId);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex, "启动流程执行失败,任务执行ID: {TaskExecutionId}, 节点ID: {NodeId}",
|
|
|
|
|
notification.TaskExecutionId, notification.NodeId);
|
|
|
|
|
|
|
|
|
|
// 发布失败事件
|
|
|
|
|
await PublishFailedEventAsync(notification, ex.Message, cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 执行启动流程业务逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="notification">事件通知</param>
|
|
|
|
|
/// <param name="cancellationToken">取消令牌</param>
|
|
|
|
|
/// <returns>执行结果</returns>
|
|
|
|
|
private async Task<string> ExecuteStartFlowAsync(StartFlowExecutionEvent notification, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
// TODO: 实现具体的启动流程逻辑
|
|
|
|
|
// 这里应该调用实际的启动流程服务
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("正在执行启动流程,运行时编码: {RuntimeCode}", notification.RuntimeCode);
|
|
|
|
|
|
|
|
|
|
// 模拟异步操作
|
|
|
|
|
await Task.Delay(500, cancellationToken);
|
|
|
|
|
|
|
|
|
|
// 模拟成功结果
|
|
|
|
|
var result = new
|
|
|
|
|
{
|
|
|
|
|
Status = "Success",
|
|
|
|
|
Message = "测试流程启动成功",
|
|
|
|
|
Timestamp = DateTime.UtcNow,
|
|
|
|
|
RuntimeCode = notification.RuntimeCode,
|
|
|
|
|
FlowInitialized = true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return System.Text.Json.JsonSerializer.Serialize(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 更新节点状态
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="nodeId">节点ID</param>
|
|
|
|
|
/// <param name="status">新状态</param>
|
|
|
|
|
/// <returns>更新任务</returns>
|
|
|
|
|
private async Task UpdateNodeStatusAsync(string nodeId, NodeExecutionStatus status)
|
|
|
|
|
{
|
|
|
|
|
// TODO: 实现节点状态更新逻辑
|
|
|
|
|
// 这里应该更新数据库中的节点状态
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation("更新节点状态,节点ID: {NodeId}, 新状态: {Status}", nodeId, status);
|
|
|
|
|
|
|
|
|
|
// 模拟异步操作
|
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发布完成事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="notification">原始事件</param>
|
|
|
|
|
/// <param name="result">执行结果</param>
|
|
|
|
|
/// <param name="cancellationToken">取消令牌</param>
|
|
|
|
|
/// <returns>发布任务</returns>
|
|
|
|
|
private async Task PublishCompletedEventAsync(StartFlowExecutionEvent notification, NodeExecutionResult result, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
var completedEvent = new NodeExecutionCompletedEvent
|
|
|
|
|
{
|
|
|
|
|
TaskExecutionId = notification.TaskExecutionId,
|
|
|
|
|
NodeId = notification.NodeId,
|
|
|
|
|
StepMapping = StepMapping.StartFlow,
|
|
|
|
|
ExecutorId = notification.ExecutorId,
|
|
|
|
|
RuntimeCode = notification.RuntimeCode,
|
|
|
|
|
ScenarioCode = notification.ScenarioCode,
|
|
|
|
|
ScenarioId = notification.ScenarioId,
|
|
|
|
|
FlowName = notification.FlowName,
|
|
|
|
|
FlowId = notification.FlowId,
|
|
|
|
|
Result = result,
|
|
|
|
|
Timestamp = DateTime.UtcNow
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await _mediator.Publish(completedEvent, cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发布失败事件
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="notification">原始事件</param>
|
|
|
|
|
/// <param name="errorMessage">错误消息</param>
|
|
|
|
|
/// <param name="cancellationToken">取消令牌</param>
|
|
|
|
|
/// <returns>发布任务</returns>
|
|
|
|
|
private async Task PublishFailedEventAsync(StartFlowExecutionEvent notification, string errorMessage, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
var failedEvent = new NodeExecutionFailedEvent
|
|
|
|
|
{
|
|
|
|
|
TaskExecutionId = notification.TaskExecutionId,
|
|
|
|
|
NodeId = notification.NodeId,
|
|
|
|
|
StepMapping = StepMapping.StartFlow,
|
|
|
|
|
ExecutorId = notification.ExecutorId,
|
|
|
|
|
RuntimeCode = notification.RuntimeCode,
|
|
|
|
|
ScenarioCode = notification.ScenarioCode,
|
|
|
|
|
ScenarioId = notification.ScenarioId,
|
|
|
|
|
FlowName = notification.FlowName,
|
|
|
|
|
FlowId = notification.FlowId,
|
|
|
|
|
ErrorMessage = errorMessage,
|
|
|
|
|
ErrorCode = "START_FLOW_ERROR",
|
|
|
|
|
Timestamp = DateTime.UtcNow
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await _mediator.Publish(failedEvent, cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
}
|