using ECMJobRunner.Application.Common.Exceptions; using ECMJobRunner.Application.Common.Interfaces; using ECMJobRunner.Domain.Interfaces; using MediatR; using System; using System.Threading; using System.Threading.Tasks; namespace ECMJobRunner.Application.Profiles.Commands { /// /// Command to trigger DEX job batch for a profile /// Executes all SQL jobs associated with a profile ID /// public class TriggeringProfileJobBatchCommand : IRequest { /// /// Profile ID to trigger all associated SQL jobs /// public long ProfileId { get; set; } } /// /// Handler for TriggeringDEXJobBatchCommand /// Retrieves all SQL jobs for a profile and executes them sequentially /// Validates that the profile is active before execution /// public class TriggeringDEXJobBatchCommandHandler(ICfgProfileRepository profileRepo, IProfileSqlJobRepository jobRepo, ISender sender) : IRequestHandler { /// /// Handles the TriggeringDEXJobBatchCommand /// Creates a unique batch ID and triggers individual job commands /// /// The command containing the profile ID /// Cancellation token /// Unit value indicating completion /// Thrown when the profile is not active public async Task Handle(TriggeringProfileJobBatchCommand request, CancellationToken cancellationToken) { var batchId = CreateBatchId(); // Retrieve the profile to check if it's active var profile = await profileRepo.GetByIdAsync(request.ProfileId, cancellationToken); // Check if profile exists and is active if (profile == null) { throw new InvalidOperationException($"Profile with ID {request.ProfileId} not found."); } if (!profile.Active) { throw new InactiveProfileException(profile.Id, profile.ProfileName, batchId); } // Retrieve all jobs for the profile var jobs = await jobRepo.FindAsync(j => j.ProfileId == request.ProfileId, cancellationToken); foreach (var job in jobs) { await sender.Send(new TriggeringProfileJobCommand { Job = job, BatchId = batchId }, cancellationToken); } return Unit.Value; } /// /// Creates a unique batch ID based on current timestamp /// /// 20-character timestamp string (yyyyMMddHHmmssfffffff truncated to 20 chars) public static string CreateBatchId() { // Format: "yyyy" : Year (4 digits) // "MM" : Month (2 digits) // "dd" : Day (2 digits) // "HH" : Hour (24-hour format, 2 digits) // "mm" : Minute (2 digits) // "ss" : Second (2 digits) // "fffffff": Fractions of a second / 100-nanoseconds (7 digits) string fullBatchId = DateTime.Now.ToString("yyyyMMddHHmmssfffffff"); // Limit to 20 characters as per specification return fullBatchId.Substring(0, 20); } } }