123 lines
4.2 KiB
C#
123 lines
4.2 KiB
C#
using Microsoft.Extensions.Caching.Memory;
|
|
using MongoDB.Driver;
|
|
using OnlyOneAccessTemplate.Models;
|
|
|
|
namespace OnlyOneAccessTemplate.Services
|
|
{
|
|
public class ModuleService : IModuleService
|
|
{
|
|
private readonly IMongoDatabase _database;
|
|
private readonly HttpClient _httpClient;
|
|
private readonly IMemoryCache _cache;
|
|
private readonly ILogger<ModuleService> _logger;
|
|
private readonly IMongoCollection<ModuleConfig> _moduleCollection;
|
|
|
|
public ModuleService(
|
|
IMongoDatabase database,
|
|
HttpClient httpClient,
|
|
IMemoryCache cache,
|
|
ILogger<ModuleService> logger)
|
|
{
|
|
_database = database;
|
|
_httpClient = httpClient;
|
|
_cache = cache;
|
|
_logger = logger;
|
|
_moduleCollection = _database.GetCollection<ModuleConfig>("modules");
|
|
}
|
|
|
|
public async Task<ModuleConfig?> GetModuleConfigAsync(string moduleId)
|
|
{
|
|
try
|
|
{
|
|
var filter = Builders<ModuleConfig>.Filter.And(
|
|
Builders<ModuleConfig>.Filter.Eq(x => x.ModuleId, moduleId),
|
|
Builders<ModuleConfig>.Filter.Eq(x => x.IsActive, true)
|
|
);
|
|
|
|
return await _moduleCollection.Find(filter).FirstOrDefaultAsync();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Erro ao buscar configuração do módulo {ModuleId}", moduleId);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<string> GetModuleContentAsync(string moduleId)
|
|
{
|
|
var cacheKey = $"module_content_{moduleId}";
|
|
|
|
if (_cache.TryGetValue(cacheKey, out string? cachedContent) && !string.IsNullOrEmpty(cachedContent))
|
|
{
|
|
return cachedContent;
|
|
}
|
|
|
|
var config = await GetModuleConfigAsync(moduleId);
|
|
if (config == null)
|
|
{
|
|
return "<p>Módulo não encontrado.</p>";
|
|
}
|
|
|
|
var content = await FetchContentFromUrlAsync(config.Url, config.Headers);
|
|
|
|
// Cache por X minutos conforme configuração
|
|
_cache.Set(cacheKey, content, TimeSpan.FromMinutes(config.CacheMinutes));
|
|
|
|
return content;
|
|
}
|
|
|
|
public async Task<string> FetchContentFromUrlAsync(string url, Dictionary<string, string>? headers = null)
|
|
{
|
|
try
|
|
{
|
|
using var request = new HttpRequestMessage(HttpMethod.Get, url);
|
|
|
|
if (headers != null)
|
|
{
|
|
foreach (var header in headers)
|
|
{
|
|
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
|
}
|
|
}
|
|
|
|
using var response = await _httpClient.SendAsync(request);
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
return await response.Content.ReadAsStringAsync();
|
|
}
|
|
|
|
_logger.LogWarning("Falha ao buscar conteúdo de {Url}. Status: {StatusCode}", url, response.StatusCode);
|
|
return "<p>Conteúdo temporariamente indisponível.</p>";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Erro ao buscar conteúdo de {Url}", url);
|
|
return "<p>Erro ao carregar conteúdo.</p>";
|
|
}
|
|
}
|
|
|
|
public async Task<List<ModuleConfig>> GetAllActiveModulesAsync()
|
|
{
|
|
var filter = Builders<ModuleConfig>.Filter.Eq(x => x.IsActive, true);
|
|
return await _moduleCollection.Find(filter).ToListAsync();
|
|
}
|
|
|
|
public async Task SaveModuleConfigAsync(ModuleConfig config)
|
|
{
|
|
config.UpdatedAt = DateTime.UtcNow;
|
|
|
|
if (string.IsNullOrEmpty(config.Id))
|
|
{
|
|
config.CreatedAt = DateTime.UtcNow;
|
|
await _moduleCollection.InsertOneAsync(config);
|
|
}
|
|
else
|
|
{
|
|
var filter = Builders<ModuleConfig>.Filter.Eq(x => x.Id, config.Id);
|
|
await _moduleCollection.ReplaceOneAsync(filter, config);
|
|
}
|
|
}
|
|
}
|
|
}
|