using System.Text.Json; using System.Text.Json.Serialization; using FinlyticAssets.Models; using FinlyticAssets.Util; namespace FinlyticAssets.Services; /// /// Provides methods for generating and maintaining the indexed asset reference file used for pre-filtering. /// public interface IAssetsIndexService { /// /// Recreates the index file containing basic asset identifiers (ISIN and Name) for all active, valid assets. /// /// A token to monitor for cancellation requests. /// A task that represents the asynchronous operation. public Task ReCreateIndexFileAsync(CancellationToken cancellationToken); } /// /// Implements the to maintain local asset index references. /// public class AssetsIndexService : IAssetsIndexService { private readonly ILogger _logger; private readonly IAssetsDbService _assetsDbService; /// /// Initializes a new instance of the class. /// /// The logger for documenting indexing events and errors. /// The database service to query the assets from. public AssetsIndexService(ILogger logger, IAssetsDbService assetsDbService) { _logger = logger; _assetsDbService = assetsDbService; } /// public async Task ReCreateIndexFileAsync(CancellationToken cancellationToken) { try { var assets = await _assetsDbService.GetAllValidAssetsAsync(); if (assets == null || !assets.Any()) { _logger.LogWarning("No valid assets found in the database to index."); return; } var indexAssets = assets.Select(a => new AssetIndex(a.Isin, a.Name)).ToList(); var directoryPath = Volumes.IndexRelativePath; var filePath = Path.Combine(directoryPath, "index.json"); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true)) { await JsonSerializer.SerializeAsync(fileStream, indexAssets, cancellationToken: cancellationToken); } _logger.LogInformation("Successfully recreated asset index file with {Count} entries at {Path}", indexAssets.Count, filePath); } catch (IOException ex) { _logger.LogError(ex, "Disk I/O error occurred while writing the asset index file."); throw; } catch (JsonException ex) { _logger.LogError(ex, "Failed to serialize the asset index data to JSON."); throw; } catch (Exception ex) { _logger.LogError(ex, "An unexpected error occurred while recreating the asset index file."); throw; } } }