From e5ed1d50516d071aecaf2eda83f12c9ac12b87cd Mon Sep 17 00:00:00 2001 From: Ryan Dudley Date: Thu, 24 Oct 2024 14:43:23 -0400 Subject: [PATCH] added a auto deletion method --- .../Actions/AutoDeleteAction.cs | 65 +++++++++++++++++++ .../Controllers/AutoDeleteController.cs | 26 ++++++++ DatabaseProjectAPI/Program.cs | 9 +-- .../Services/DatrCleanupBackgroundService.cs | 38 +++++++++++ .../Services/StockQuoteBackgroundService.cs | 12 ++-- 5 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 DatabaseProjectAPI/Actions/AutoDeleteAction.cs create mode 100644 DatabaseProjectAPI/Controllers/AutoDeleteController.cs create mode 100644 DatabaseProjectAPI/Services/DatrCleanupBackgroundService.cs diff --git a/DatabaseProjectAPI/Actions/AutoDeleteAction.cs b/DatabaseProjectAPI/Actions/AutoDeleteAction.cs new file mode 100644 index 0000000..82a0476 --- /dev/null +++ b/DatabaseProjectAPI/Actions/AutoDeleteAction.cs @@ -0,0 +1,65 @@ +using DatabaseProjectAPI.DataContext; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace DatabaseProjectAPI.Actions; + + +public interface IAutoDeleteService +{ + Task DeleteOldStockHistory(); + Task DeleteOldApiCallLogs(); +} + + +public class AutoDeleteAction : IAutoDeleteService +{ + private readonly DpapiDbContext _dbContext; + private readonly ILogger _logger; + + public AutoDeleteAction(DpapiDbContext dbContext, ILogger logger) + { + _dbContext = dbContext; + _logger = logger; + } + + public async Task DeleteOldStockHistory() + { + var ninetyDaysAgo = DateTime.UtcNow.AddDays(-90); + + var oldStockHistories = await _dbContext.StockHistories + .Where(sh => sh.Timestamp < ninetyDaysAgo) + .ToListAsync(); + + if (oldStockHistories.Any()) + { + _dbContext.StockHistories.RemoveRange(oldStockHistories); + await _dbContext.SaveChangesAsync(); + _logger.LogInformation("{Count} old stock history records deleted.", oldStockHistories.Count); + } + else + { + _logger.LogInformation("No stock history records found to delete."); + } + } + + public async Task DeleteOldApiCallLogs() + { + var ninetyDaysAgo = DateTime.UtcNow.AddDays(-90); + + var oldApiCallLogs = await _dbContext.ApiCallLog + .Where(log => log.CallDate < ninetyDaysAgo) + .ToListAsync(); + + if (oldApiCallLogs.Any()) + { + _dbContext.ApiCallLog.RemoveRange(oldApiCallLogs); + await _dbContext.SaveChangesAsync(); + _logger.LogInformation("{Count} old API call log records deleted.", oldApiCallLogs.Count); + } + else + { + _logger.LogInformation("No API call log records found to delete."); + } + } +} \ No newline at end of file diff --git a/DatabaseProjectAPI/Controllers/AutoDeleteController.cs b/DatabaseProjectAPI/Controllers/AutoDeleteController.cs new file mode 100644 index 0000000..1d3e0c4 --- /dev/null +++ b/DatabaseProjectAPI/Controllers/AutoDeleteController.cs @@ -0,0 +1,26 @@ +using DatabaseProjectAPI.Actions; +using Microsoft.AspNetCore.Mvc; + +namespace DatabaseProjectAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class AutoDeleteController : ControllerBase + { + private readonly IAutoDeleteService _autoDeleteService; + + public AutoDeleteController(IAutoDeleteService autoDeleteService) + { + _autoDeleteService = autoDeleteService; + } + + [HttpDelete("cleanup")] + public async Task CleanupOldData() + { + await _autoDeleteService.DeleteOldStockHistory(); + await _autoDeleteService.DeleteOldApiCallLogs(); + + return Ok(new { message = "Old data cleanup completed." }); + } + } +} \ No newline at end of file diff --git a/DatabaseProjectAPI/Program.cs b/DatabaseProjectAPI/Program.cs index 39b58ab..1dc06af 100644 --- a/DatabaseProjectAPI/Program.cs +++ b/DatabaseProjectAPI/Program.cs @@ -39,8 +39,9 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); -// Register background service +builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddControllers(); @@ -49,11 +50,11 @@ var app = builder.Build(); -//if (app.Environment.IsDevelopment()) -//{ +if (app.Environment.IsDevelopment()) +{ app.UseSwagger(); app.UseSwaggerUI(); -//} +} app.UseHttpsRedirection(); app.UseAuthorization(); diff --git a/DatabaseProjectAPI/Services/DatrCleanupBackgroundService.cs b/DatabaseProjectAPI/Services/DatrCleanupBackgroundService.cs new file mode 100644 index 0000000..18aec82 --- /dev/null +++ b/DatabaseProjectAPI/Services/DatrCleanupBackgroundService.cs @@ -0,0 +1,38 @@ +using DatabaseProjectAPI.Actions; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace DatabaseProjectAPI.Services +{ + public class DataCleanupBackgroundService : BackgroundService + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; + + public DataCleanupBackgroundService(IServiceProvider serviceProvider, ILogger logger) + { + _serviceProvider = serviceProvider; + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("DataCleanupBackgroundService started at: {time}", DateTime.UtcNow); + + while (!stoppingToken.IsCancellationRequested) + { + using (var scope = _serviceProvider.CreateScope()) + { + var autoDeleteService = scope.ServiceProvider.GetRequiredService(); + + await autoDeleteService.DeleteOldStockHistory(); + await autoDeleteService.DeleteOldApiCallLogs(); + + _logger.LogInformation("Data cleanup completed at: {time}", DateTime.UtcNow); + } + + await Task.Delay(TimeSpan.FromDays(1), stoppingToken); + } + } + } +} \ No newline at end of file diff --git a/DatabaseProjectAPI/Services/StockQuoteBackgroundService.cs b/DatabaseProjectAPI/Services/StockQuoteBackgroundService.cs index 2a7de80..7ebb625 100644 --- a/DatabaseProjectAPI/Services/StockQuoteBackgroundService.cs +++ b/DatabaseProjectAPI/Services/StockQuoteBackgroundService.cs @@ -1,4 +1,5 @@ -using DatabaseProjectAPI.DataContext; +using DatabaseProjectAPI.Actions; +using DatabaseProjectAPI.DataContext; using DatabaseProjectAPI.Entities; using DatabaseProjectAPI.Helpers; @@ -14,7 +15,6 @@ public StockQuoteBackgroundService(IServiceProvider serviceProvider, ILogger(); var apiRequestLogger = scope.ServiceProvider.GetRequiredService(); + var autoDeleteService = scope.ServiceProvider.GetRequiredService(); + + await autoDeleteService.DeleteOldStockHistory(); + await autoDeleteService.DeleteOldApiCallLogs(); - // Check if API call has already been made today for market open or close if (IsMarketOpenTime(now) && !await apiRequestLogger.HasMadeApiCallToday("MarketOpen", "AAPL")) { await FetchAndSaveStockData(dbContext, apiRequestLogger, "MarketOpen", "AAPL"); @@ -38,8 +41,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) await FetchAndSaveStockData(dbContext, apiRequestLogger, "MarketClose", "AAPL"); } } - - await Task.Delay(TimeSpan.FromMinutes(60), stoppingToken); // Delay for 1 hour + await Task.Delay(TimeSpan.FromMinutes(60), stoppingToken); } } private async Task FetchAndSaveStockData(DpapiDbContext dbContext, IApiRequestLogger apiRequestLogger, string callType, string symbol)