using Dapper; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Ordering.BackgroundTasks.Configuration; using Ordering.BackgroundTasks.IntegrationEvents; using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Threading; using System.Threading.Tasks; namespace Ordering.BackgroundTasks.Tasks { public class GracePeriodManagerService : BackgroundService { private readonly ILogger _logger; private readonly BackgroundTaskSettings _settings; private readonly IEventBus _eventBus; public GracePeriodManagerService(IOptions settings, IEventBus eventBus, ILogger logger) { _settings = settings?.Value ?? throw new ArgumentNullException(nameof(settings)); _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogDebug($"GracePeriodManagerService is starting."); stoppingToken.Register(() => _logger.LogDebug($"#1 GracePeriodManagerService background task is stopping.")); while (!stoppingToken.IsCancellationRequested) { _logger.LogDebug($"GracePeriodManagerService background task is doing background work."); CheckConfirmedGracePeriodOrders(); await Task.Delay(_settings.CheckUpdateTime, stoppingToken); } _logger.LogDebug($"GracePeriodManagerService background task is stopping."); await Task.CompletedTask; } private void CheckConfirmedGracePeriodOrders() { _logger.LogDebug($"Checking confirmed grace period orders"); var orderIds = GetConfirmedGracePeriodOrders(); foreach (var orderId in orderIds) { var confirmGracePeriodEvent = new GracePeriodConfirmedIntegrationEvent(orderId); _eventBus.Publish(confirmGracePeriodEvent); } } private IEnumerable GetConfirmedGracePeriodOrders() { IEnumerable orderIds = new List(); using (var conn = new SqlConnection(_settings.ConnectionString)) { try { conn.Open(); orderIds = conn.Query( @"SELECT Id FROM [ordering].[orders] WHERE DATEDIFF(minute, [OrderDate], GETDATE()) >= @GracePeriodTime AND [OrderStatusId] = 1", new { GracePeriodTime = _settings.GracePeriodTime }); } catch (SqlException exception) { _logger.LogCritical($"FATAL ERROR: Database connections could not be opened: {exception.Message}"); } } return orderIds; } } }