Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions DatabaseProjectAPI/Actions/AutoDeleteAction.cs
Original file line number Diff line number Diff line change
@@ -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<AutoDeleteAction> _logger;

public AutoDeleteAction(DpapiDbContext dbContext, ILogger<AutoDeleteAction> 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.");
}
}
}
26 changes: 26 additions & 0 deletions DatabaseProjectAPI/Controllers/AutoDeleteController.cs
Original file line number Diff line number Diff line change
@@ -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<IActionResult> CleanupOldData()
{
await _autoDeleteService.DeleteOldStockHistory();
await _autoDeleteService.DeleteOldApiCallLogs();

return Ok(new { message = "Old data cleanup completed." });
}
}
}
9 changes: 5 additions & 4 deletions DatabaseProjectAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@
builder.Services.AddTransient<ITrackedStockAction, TrackedStockAction>();
builder.Services.AddTransient<IStockHistoryAction, StockHistoryAction>();
builder.Services.AddTransient<IApiRequestLogger, ApiRequestLogger>();
builder.Services.AddTransient<IAutoDeleteService, AutoDeleteAction>();

// Register background service
builder.Services.AddHostedService<DataCleanupBackgroundService>();
builder.Services.AddHostedService<StockQuoteBackgroundService>();

builder.Services.AddControllers();
Expand All @@ -49,11 +50,11 @@

var app = builder.Build();

//if (app.Environment.IsDevelopment())
//{
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
//}
}

app.UseHttpsRedirection();
app.UseAuthorization();
Expand Down
38 changes: 38 additions & 0 deletions DatabaseProjectAPI/Services/DatrCleanupBackgroundService.cs
Original file line number Diff line number Diff line change
@@ -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<DataCleanupBackgroundService> _logger;

public DataCleanupBackgroundService(IServiceProvider serviceProvider, ILogger<DataCleanupBackgroundService> 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<IAutoDeleteService>();

await autoDeleteService.DeleteOldStockHistory();
await autoDeleteService.DeleteOldApiCallLogs();

_logger.LogInformation("Data cleanup completed at: {time}", DateTime.UtcNow);
}

await Task.Delay(TimeSpan.FromDays(1), stoppingToken);
}
}
}
}
12 changes: 7 additions & 5 deletions DatabaseProjectAPI/Services/StockQuoteBackgroundService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DatabaseProjectAPI.DataContext;
using DatabaseProjectAPI.Actions;
using DatabaseProjectAPI.DataContext;
using DatabaseProjectAPI.Entities;
using DatabaseProjectAPI.Helpers;

Expand All @@ -14,7 +15,6 @@ public StockQuoteBackgroundService(IServiceProvider serviceProvider, ILogger<Sto
_serviceProvider = serviceProvider;
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("StockQuoteBackgroundService started at: {time}", DateTime.UtcNow);
Expand All @@ -27,8 +27,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var dbContext = scope.ServiceProvider.GetRequiredService<DpapiDbContext>();
var apiRequestLogger = scope.ServiceProvider.GetRequiredService<IApiRequestLogger>();
var autoDeleteService = scope.ServiceProvider.GetRequiredService<IAutoDeleteService>();

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");
Expand All @@ -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)
Expand Down
Loading