diff --git a/AS1024.GeoFeed.Core/AS1024.GeoFeed.Core.csproj b/AS1024.GeoFeed.Core/AS1024.GeoFeed.Core.csproj index c4da98b..09884c4 100644 --- a/AS1024.GeoFeed.Core/AS1024.GeoFeed.Core.csproj +++ b/AS1024.GeoFeed.Core/AS1024.GeoFeed.Core.csproj @@ -1,9 +1,10 @@ - + net8.0 enable enable + Library diff --git a/AS1024.GeoFeed.Core/GeoFeedLogic/GeoFeedReturn.cs b/AS1024.GeoFeed.Core/GeoFeedLogic/GeoFeedReturn.cs new file mode 100644 index 0000000..b9f5030 --- /dev/null +++ b/AS1024.GeoFeed.Core/GeoFeedLogic/GeoFeedReturn.cs @@ -0,0 +1,70 @@ +using System.Text; +using AS1024.GeoFeed.Core.Interfaces; +using AS1024.GeoFeed.Core.Tools; +using AS1024.GeoFeed.Models; +using Microsoft.Extensions.Caching.Memory; + +namespace AS1024.GeoFeed.Core.GeoFeedLogic +{ + public class GeoFeedReturn + { + private const string GeoFeedCacheKey = "GeoFeedData"; + private readonly IGeoFeedProvider provider; + private readonly ILogger logger; + private readonly IGeoFeedPersistentCacheProvider cacheProvider; + private readonly IMemoryCache memoryCache; + private readonly IWebHostEnvironment environment; + + public GeoFeedReturn(IGeoFeedProvider provider, + ILogger logger, + IGeoFeedPersistentCacheProvider cacheProvider, + IMemoryCache memoryCache, + IWebHostEnvironment environment) + { + this.provider = provider; + this.logger = logger; + this.cacheProvider = cacheProvider; + this.memoryCache = memoryCache; + this.environment = environment; + } + + public async Task GetGeoFeed() + { + bool isCached = true; + try + { + if (!memoryCache.TryGetValue(GeoFeedCacheKey, out List? feed)) + { + isCached = false; + feed = await provider.GetGeoFeedData(); + if (environment.IsProduction()) + { + MemoryCacheEntryOptions cacheEntryOptions = new MemoryCacheEntryOptions() + .SetSlidingExpiration(TimeSpan.FromMinutes(15)); + memoryCache.Set(GeoFeedCacheKey, feed, cacheEntryOptions); + } + } + + return Results.File(Encoding.UTF8.GetBytes(feed.ToGeoFeedCsv(true, isCached)), + "text/csv", + "geofeed.csv"); + + } + catch (HttpRequestException ex) + { + logger.LogWarning($"Temporary failure of retrieving GeoData from upstream. {ex}"); + string geoFeedData = cacheProvider.GetGeoFeed(); + + return Results.File(Encoding.UTF8.GetBytes(geoFeedData), + "text/csv", + "geofeed.csv"); + } + catch (Exception ex) + { + logger.LogError($"Error: {ex}"); + } + + return Results.NoContent(); + } + } +} diff --git a/AS1024.GeoFeed.MinimalAPI/Program.cs b/AS1024.GeoFeed.MinimalAPI/Program.cs index 9ce80bd..9f094a9 100644 --- a/AS1024.GeoFeed.MinimalAPI/Program.cs +++ b/AS1024.GeoFeed.MinimalAPI/Program.cs @@ -1,4 +1,5 @@ using AS1024.GeoFeed.Core.CacheService; +using AS1024.GeoFeed.Core.GeoFeedLogic; using AS1024.GeoFeed.Core.GeoFeedPreloader; using AS1024.GeoFeed.Core.Interfaces; using AS1024.GeoFeed.Core.Tools; @@ -18,6 +19,7 @@ namespace AS1024.GeoFeed.MinimalAPI builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddTransient(); + builder.Services.AddScoped(); builder.Services.AddMemoryCache(); builder.Services.AddLogging(); builder.Services.AddHttpClient(); @@ -26,66 +28,15 @@ namespace AS1024.GeoFeed.MinimalAPI }); var app = builder.Build(); - app.Map("/geofeed.csv", async (IGeoFeedProvider provider, - ILogger logger, - IGeoFeedPersistentCacheProvider cacheProvider, - IMemoryCache memoryCache, - IWebHostEnvironment environment) => { - return await GeoFeedDataRunner(provider, logger, cacheProvider, memoryCache, environment); - }); + app.Map("/geofeed.csv", async (GeoFeedReturn feedReturn) => { + return await feedReturn.GetGeoFeed(); + }); - app.Map("/geofeed", async (IGeoFeedProvider provider, - ILogger logger, - IGeoFeedPersistentCacheProvider cacheProvider, - IMemoryCache memoryCache, - IWebHostEnvironment environment) => { - return await GeoFeedDataRunner(provider, logger, cacheProvider, memoryCache, environment); - }); + app.Map("/geofeed", async (GeoFeedReturn feedReturn) => { + return await feedReturn.GetGeoFeed(); + }); app.Run(); } - - protected static async Task GeoFeedDataRunner(IGeoFeedProvider provider, - ILogger logger, - IGeoFeedPersistentCacheProvider cacheProvider, - IMemoryCache memoryCache, - IWebHostEnvironment environment) - { - bool isCached = true; - try - { - if (!memoryCache.TryGetValue("GeoFeedData", out List? feed)) - { - isCached = false; - feed = await provider.GetGeoFeedData(); - if (environment.IsProduction()) - { - MemoryCacheEntryOptions cacheEntryOptions = new MemoryCacheEntryOptions() - .SetSlidingExpiration(TimeSpan.FromMinutes(15)); - memoryCache.Set("GeoFeedData", feed, cacheEntryOptions); - } - } - - return Results.File(Encoding.UTF8.GetBytes(feed.ToGeoFeedCsv(true, isCached)), - "text/csv", - "geofeed.csv"); - - } - catch (HttpRequestException ex) - { - logger.LogWarning($"Temporary failure of retrieving GeoData from upstream. {ex}"); - string geoFeedData = cacheProvider.GetGeoFeed(); - - return Results.File(Encoding.UTF8.GetBytes(geoFeedData), - "text/csv", - "geofeed.csv"); - } - catch (Exception ex) - { - logger.LogError($"Error: {ex}"); - } - - return Results.NoContent(); - } } } diff --git a/AS1024.GeoFeed/Controllers/GeofeedController.cs b/AS1024.GeoFeed/Controllers/GeofeedController.cs index 82ff5eb..a1d914a 100644 --- a/AS1024.GeoFeed/Controllers/GeofeedController.cs +++ b/AS1024.GeoFeed/Controllers/GeofeedController.cs @@ -1,9 +1,5 @@ using Microsoft.AspNetCore.Mvc; -using AS1024.GeoFeed.Core.Interfaces; -using Microsoft.Extensions.Caching.Memory; -using AS1024.GeoFeed.Models; -using System.Text; -using AS1024.GeoFeed.Core.Tools; +using AS1024.GeoFeed.Core.GeoFeedLogic; namespace AS1024.GeoFeed.Controllers { @@ -13,77 +9,18 @@ namespace AS1024.GeoFeed.Controllers public class GeofeedController : ControllerBase { - private readonly IGeoFeedProvider builder; - private readonly IMemoryCache memoryCache; - private readonly IWebHostEnvironment environment; - private readonly ILogger logger; - private readonly IGeoFeedPersistentCacheProvider geoFeedPersistentCache; - private const string GeoFeedCacheKey = "GeoFeedData"; + private readonly GeoFeedReturn feedReturn; - public GeofeedController(IGeoFeedProvider builder, - IMemoryCache memoryCache, - IWebHostEnvironment environment, - ILogger logger, - IGeoFeedPersistentCacheProvider geoFeedPersistentCache) { - this.logger = logger; - this.geoFeedPersistentCache = geoFeedPersistentCache; - this.builder = builder; - this.memoryCache = memoryCache; - this.environment = environment; + public GeofeedController(GeoFeedReturn feedReturn) + { + this.feedReturn = feedReturn; } [HttpGet] [Route("")] - public async Task Get() + public async Task Get() { - bool isCached = true; - try - { - if (!memoryCache.TryGetValue(GeoFeedCacheKey, out List? feed)) - { - isCached = false; - feed = await builder.GetGeoFeedData(); - if (environment.IsProduction()) - { - MemoryCacheEntryOptions cacheEntryOptions = new MemoryCacheEntryOptions() - .SetSlidingExpiration(TimeSpan.FromMinutes(15)); - memoryCache.Set(GeoFeedCacheKey, feed, cacheEntryOptions); - } - } - - return ReturnFile(feed, isCached); - } catch (HttpRequestException ex) - { - logger.LogWarning($"Temporary failure of retrieving GeoData from upstream. {ex}"); - var cachedData = geoFeedPersistentCache.GetGeoFeed(); - return ReturnFile(cachedData); - } - - catch (Exception ex) - { - logger.LogError($"Geofeed generation failed. Exception: {ex}"); - return StatusCode(500); - } - - } - - [NonAction] - private IActionResult ReturnFile(List? feed, bool isCached = false) - { - string csvContent = feed.ToGeoFeedCsv(true, isCached); // Assuming ToGeoFeedCsv() returns a string in CSV format. - return ReturnFile(csvContent); - } - - [NonAction] - private IActionResult ReturnFile(string csvContent) - { - byte[] contentBytes = Encoding.UTF8.GetBytes(csvContent); - string contentType = "text/csv"; - - return new FileContentResult(contentBytes, contentType) - { - FileDownloadName = "geofeed.csv" - }; + return await feedReturn.GetGeoFeed(); } } } diff --git a/AS1024.GeoFeed/Program.cs b/AS1024.GeoFeed/Program.cs index 3f6a36b..8124417 100644 --- a/AS1024.GeoFeed/Program.cs +++ b/AS1024.GeoFeed/Program.cs @@ -4,6 +4,7 @@ using AS1024.GeoFeed.Core.GeoFeedProviders; using Microsoft.EntityFrameworkCore; using AS1024.GeoFeed.Core.GeoFeedSqliteLocalCache; using AS1024.GeoFeed.Core.CacheService; +using AS1024.GeoFeed.Core.GeoFeedLogic; namespace AS1024.GeoFeed { @@ -15,6 +16,7 @@ namespace AS1024.GeoFeed builder.Services.AddHostedService(); builder.Services.AddTransient(); + builder.Services.AddScoped(); builder.Services.AddDbContext( options => {