using AutomationDAL.CustomCode.Agent; using AutomationDAL.DTO.Agent; using GB5Shared.DTO.Framework.Login; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using Microsoft.Extensions.Logging; namespace AutomationBLL.Agent; public class AgentBLL : IAgentBLL { private static readonly string[] ValidLocationTypes = { "OnPrem", "Cloud" }; private static readonly string[] ValidStatuses = { "Online", "Offline", "Busy" }; private readonly IAgentDAL _dal; private readonly ILogger _logger; public AgentBLL(IAgentDAL dal, ILogger logger) { _dal = dal; _logger = logger; } public async Task Heartbeat(AgentDTO dto, LoginDTO login, CancellationToken ct) { try { if (string.IsNullOrWhiteSpace(dto.AgentName)) throw new InvalidOperationException("AgentName is required."); if (!ValidLocationTypes.Contains(dto.LocationType)) throw new InvalidOperationException($"LocationType must be one of: {string.Join(", ", ValidLocationTypes)}"); if (!ValidStatuses.Contains(dto.Status)) throw new InvalidOperationException($"Status must be one of: {string.Join(", ", ValidStatuses)}"); GB5Trace.Step("agent-heartbeat", new { dto.AgentName, dto.Status }); int agentId = await _dal.UpsertHeartbeat(dto, login, ct).ConfigureAwait(false); return $"{SuccessResponse.SaveSuccessMessage} {agentId}"; } catch (Exception ex) { GB5Trace.MarkFailed("agent-heartbeat-failed", ex); _logger.LogError(ex, "Heartbeat failed for AgentName {AgentName}", dto.AgentName); throw; } } public async Task> GetAll(LoginDTO login, CancellationToken ct) => await _dal.GetAll(login, ct).ConfigureAwait(false); }