diff --git a/Elecciones-Web/src/Elecciones.Worker/Worker.cs b/Elecciones-Web/src/Elecciones.Worker/Worker.cs index 11fd437..1dcdb5b 100644 --- a/Elecciones-Web/src/Elecciones.Worker/Worker.cs +++ b/Elecciones-Web/src/Elecciones.Worker/Worker.cs @@ -20,6 +20,10 @@ public class Worker : BackgroundService private readonly ILogger _logger; private readonly IElectoralApiService _apiService; private readonly IServiceProvider _serviceProvider; + // --- VARIABLES DE ESTADO PARA EL TOKEN --- + private string? _authToken; + // Usamos DateTimeOffset para manejar correctamente las zonas horarias. + private DateTimeOffset _tokenExpiration = DateTimeOffset.MinValue; public Worker(ILogger logger, IElectoralApiService apiService, IServiceProvider serviceProvider) { @@ -28,6 +32,36 @@ public class Worker : BackgroundService _serviceProvider = serviceProvider; } + /// + /// Obtiene un token de autenticación válido, solicitando uno nuevo solo si el actual + /// no existe o ha expirado. + /// + private async Task GetValidAuthTokenAsync(CancellationToken stoppingToken) + { + // Comprobamos si el token es nulo o si la fecha de expiración ya pasó. + // Añadimos un buffer de seguridad de 1 minuto para renovarlo un poco antes. + if (string.IsNullOrEmpty(_authToken) || DateTimeOffset.UtcNow >= _tokenExpiration.AddMinutes(-1)) + { + _logger.LogInformation("Token no válido o a punto de expirar. Solicitando uno nuevo..."); + var tokenResponse = await _apiService.GetAuthTokenAsync(); // Asumimos que el ApiService devuelve el objeto completo + + if (tokenResponse?.Data?.AccessToken != null) + { + _authToken = tokenResponse.Data.AccessToken; + // Calculamos la nueva fecha de expiración. La API nos da la duración en segundos. + _tokenExpiration = DateTimeOffset.UtcNow.AddSeconds(tokenResponse.Data.ExpiresIn); + _logger.LogInformation("Nuevo token obtenido. Válido hasta: {expiration}", _tokenExpiration); + } + else + { + _logger.LogError("CRÍTICO: No se pudo obtener un nuevo token de autenticación."); + _authToken = null; // Nos aseguramos de que el token viejo se invalide + } + } + + return _authToken; + } + /// /// Método principal del worker que se ejecuta en segundo plano. /// @@ -48,10 +82,11 @@ public class Worker : BackgroundService var cicloInicio = DateTime.UtcNow; cicloContador++; - var authToken = await _apiService.GetAuthTokenAsync(); + var authToken = await GetValidAuthTokenAsync(stoppingToken); + if (string.IsNullOrEmpty(authToken)) { - _logger.LogError("CRÍTICO: No se pudo obtener el token. Reintentando en 1 minuto..."); + _logger.LogError("No se pudo obtener un token válido. Reintentando en 1 minuto..."); await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); continue; } @@ -112,8 +147,8 @@ public class Worker : BackgroundService { _logger.LogInformation("Iniciando sincronización de catálogos maestros..."); - // PASO 1: Obtener el token de autenticación. Sin él, no podemos hacer nada. - var authToken = await _apiService.GetAuthTokenAsync(); + var authToken = await GetValidAuthTokenAsync(stoppingToken); + if (string.IsNullOrEmpty(authToken) || stoppingToken.IsCancellationRequested) { _logger.LogError("No se pudo obtener token para la sincronización de catálogos. La operación se cancela.");