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;
///
/// 启动流程控制器处理器
/// 处理测试流程启动相关的节点执行事件
///
public class StartFlowControllerHandler : INotificationHandler
{
private readonly IMediator _mediator;
private readonly ILogger _logger;
///
/// 初始化启动流程控制器处理器
///
/// MediatR 中介者
/// 日志记录器
public StartFlowControllerHandler(IMediator mediator, ILogger logger)
{
_mediator = mediator;
_logger = logger;
}
///
/// 处理启动流程节点执行事件
///
/// 节点执行事件
/// 取消令牌
/// 处理任务
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);
}
}
///
/// 执行启动流程业务逻辑
///
/// 事件通知
/// 取消令牌
/// 执行结果
private async Task 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);
}
///
/// 更新节点状态
///
/// 节点ID
/// 新状态
/// 更新任务
private async Task UpdateNodeStatusAsync(string nodeId, NodeExecutionStatus status)
{
// TODO: 实现节点状态更新逻辑
// 这里应该更新数据库中的节点状态
_logger.LogInformation("更新节点状态,节点ID: {NodeId}, 新状态: {Status}", nodeId, status);
// 模拟异步操作
await Task.CompletedTask;
}
///
/// 发布完成事件
///
/// 原始事件
/// 执行结果
/// 取消令牌
/// 发布任务
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);
}
///
/// 发布失败事件
///
/// 原始事件
/// 错误消息
/// 取消令牌
/// 发布任务
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);
}
}