From c3e1cfbf8d9938e11c6a3c45dba3d48f6083e015 Mon Sep 17 00:00:00 2001 From: Oscar Morales Date: Tue, 20 May 2025 13:25:53 -0600 Subject: [PATCH] Use Blueprint.Mongo package in module service --- .../Controllers/ModuleController.cs | 105 ++----- .../{IModuleService.cs => IModuleProvider.cs} | 16 +- .../Providers/Onboarding/ModuleProvider.cs | 153 +++++++++++ .../Providers/Onboarding/ModuleService.cs | 256 ------------------ .../ServiceCollectionExtensions.cs | 2 +- 5 files changed, 191 insertions(+), 341 deletions(-) rename Core.Thalos.Provider/Contracts/{IModuleService.cs => IModuleProvider.cs} (76%) create mode 100644 Core.Thalos.Provider/Providers/Onboarding/ModuleProvider.cs delete mode 100644 Core.Thalos.Provider/Providers/Onboarding/ModuleService.cs diff --git a/Core.Thalos.DAL.API/Controllers/ModuleController.cs b/Core.Thalos.DAL.API/Controllers/ModuleController.cs index 721bf5d..fb0966e 100644 --- a/Core.Thalos.DAL.API/Controllers/ModuleController.cs +++ b/Core.Thalos.DAL.API/Controllers/ModuleController.cs @@ -5,14 +5,15 @@ // *********************************************************************** using Asp.Versioning; +using Core.Blueprint.Mongo; using Core.Thalos.Adapters; using Core.Thalos.Adapters.Attributes; using Core.Thalos.Adapters.Common.Constants; -using Core.Thalos.Adapters.Common.Enums; -using Core.Thalos.Domain.Contexts.Onboarding.Request; using Core.Thalos.Provider.Contracts; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Graph; +using ModuleRequest = Core.Thalos.Domain.Contexts.Onboarding.Request.ModuleRequest; namespace LSA.Core.Kerberos.API.Controllers { @@ -24,7 +25,7 @@ namespace LSA.Core.Kerberos.API.Controllers [Produces(MimeTypes.ApplicationJson)] [Consumes(MimeTypes.ApplicationJson)] [ApiController] - public class ModuleController(IModuleService service, ILogger logger) : ControllerBase + public class ModuleController(IModuleProvider service) : ControllerBase { /// /// Gets all the modules. @@ -39,19 +40,10 @@ namespace LSA.Core.Kerberos.API.Controllers [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.DefaultScheme)] [Permission("ModuleManagement.Read, RoleManagement.Read")] - public async Task GetAllModulesAsync() + public async Task GetAllModulesAsync(CancellationToken cancellationToken) { - try - { - var result = await service.GetAllModulesService(); - - return Ok(result); - } - catch (Exception ex) - { - logger.LogError(ex, "Error in GetAllModulesAsync"); - return StatusCode(500, $"Internal server error, ErrorMessage: {ex.Message}"); - } + var result = await service.GetAllModules(cancellationToken).ConfigureAwait(false); + return Ok(result); } /// @@ -69,29 +61,15 @@ namespace LSA.Core.Kerberos.API.Controllers [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.DefaultScheme)] [Permission("ModuleManagement.Read")] - public async Task GetAllModulesByList([FromBody] string[] modules) + public async Task GetAllModulesByList([FromBody] string[] modules, CancellationToken cancellationToken) { if (modules == null || !modules.Any()) { return BadRequest("Module identifiers are required."); } - try - { - var result = await service.GetAllModulesByListService(modules); - - if (result == null || !result.Any()) - { - return NotFound("No modules found for the given identifiers."); - } - - return Ok(result); - } - catch (Exception ex) - { - logger.LogError(ex, "Error in GetAllModulesByList"); - return StatusCode(500, $"Internal server error, ErrorMessage: {ex.Message}"); - } + var result = await service.GetAllModulesByList(modules, cancellationToken).ConfigureAwait(false); + return Ok(result); } @@ -110,21 +88,16 @@ namespace LSA.Core.Kerberos.API.Controllers [ProducesResponseType(typeof(ModuleAdapter), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.DefaultScheme)] [Permission("ModuleManagement.Read")] - public async Task GetModuleByIdAsync([FromRoute] string id) + public async Task GetModuleByIdAsync([FromRoute] string _id, CancellationToken cancellationToken) { - try - { - var result = await service.GetModuleByIdService(id); + var result = await service.GetModuleById(_id, cancellationToken).ConfigureAwait(false); - if (result is null) return NotFound($"module with id: '{id}' not found"); - - return Ok(result); - } - catch (Exception ex) + if (result == null) { - logger.LogError(ex, "Error in GetModuleByIdAsync"); - return StatusCode(500, $"Internal server error, ErrorMessage: {ex.Message}"); + return NotFound("Entity not found"); } + + return Ok(result); } /// @@ -139,18 +112,10 @@ namespace LSA.Core.Kerberos.API.Controllers [ProducesResponseType(typeof(ModuleAdapter), StatusCodes.Status201Created)] [Authorize(AuthenticationSchemes = Schemes.DefaultScheme)] [Permission("ModuleManagement.Write")] - public async Task CreateModuleAsync([FromBody] ModuleRequest newModule) + public async Task CreateModuleAsync([FromBody] ModuleRequest newModule, CancellationToken cancellationToken) { - try - { - var result = await service.CreateModuleService(newModule).ConfigureAwait(false); - return Created("CreatedWithIdService", result); - } - catch (Exception ex) - { - logger.LogError(ex, "Error in CreateModuleAsync"); - return StatusCode(500, $"Internal server error, ErrorMessage: {ex.Message}"); - } + var result = await service.CreateModule(newModule, cancellationToken).ConfigureAwait(false); + return Created("CreatedWithIdAsync", result); } /// @@ -170,19 +135,16 @@ namespace LSA.Core.Kerberos.API.Controllers [ProducesResponseType(typeof(ModuleAdapter), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.DefaultScheme)] [Permission("ModuleManagement.Write")] - public async Task UpdateModuleAsync(ModuleAdapter entity, string id) + public async Task UpdateModuleAsync([FromRoute] string _id, ModuleAdapter entity, CancellationToken cancellationToken) { - try + if (_id != entity._Id?.ToString()) { - var result = await service.UpdateModuleService(entity, id); + return BadRequest("User ID mismatch"); + } - return Ok(result); - } - catch (Exception ex) - { - logger.LogError(ex, "Error in UpdateModuleAsync"); - return StatusCode(500, $"Internal server error, ErrorMessage: {ex.Message}"); - } + var result = await service.UpdateModule(entity, cancellationToken).ConfigureAwait(false); + + return Ok(result); } /// @@ -202,19 +164,10 @@ namespace LSA.Core.Kerberos.API.Controllers [ProducesResponseType(typeof(ModuleAdapter), StatusCodes.Status200OK)] [Authorize(AuthenticationSchemes = Schemes.DefaultScheme)] [Permission("ModuleManagement.Write")] - public async Task ChangeModuleStatus([FromRoute] string id, [FromRoute] StatusEnum newStatus) + public async Task ChangeModuleStatus([FromRoute] string id, [FromRoute] StatusEnum newStatus, CancellationToken cancellationToken) { - try - { - var result = await service.ChangeModuleStatusService(id, newStatus); - - return Ok(result); - } - catch (Exception ex) - { - logger.LogError(ex, "Error in ChangeModuleStatus"); - return StatusCode(500, $"Internal server error, ErrorMessage: {ex.Message}"); - } + var result = await service.ChangeModuleStatus(id, newStatus, cancellationToken).ConfigureAwait(false); + return Ok(result); } } } diff --git a/Core.Thalos.Provider/Contracts/IModuleService.cs b/Core.Thalos.Provider/Contracts/IModuleProvider.cs similarity index 76% rename from Core.Thalos.Provider/Contracts/IModuleService.cs rename to Core.Thalos.Provider/Contracts/IModuleProvider.cs index 4d3b64f..e6b8f61 100644 --- a/Core.Thalos.Provider/Contracts/IModuleService.cs +++ b/Core.Thalos.Provider/Contracts/IModuleProvider.cs @@ -3,13 +3,13 @@ // AgileWebs // // *********************************************************************** +using Core.Blueprint.Mongo; using Core.Thalos.Adapters; -using Core.Thalos.Adapters.Common.Enums; using Core.Thalos.Domain.Contexts.Onboarding.Request; namespace Core.Thalos.Provider.Contracts { - public interface IModuleService + public interface IModuleProvider { /// /// Creates a new Module. @@ -17,7 +17,7 @@ namespace Core.Thalos.Provider.Contracts /// The Module to be created. /// A representing /// the asynchronous execution of the service. - Task CreateModuleService(ModuleRequest newModule); + ValueTask CreateModule(ModuleRequest newModule, CancellationToken cancellationToken); /// /// Gets an Module by identifier. @@ -25,14 +25,14 @@ namespace Core.Thalos.Provider.Contracts /// The Module identifier. /// A representing /// the asynchronous execution of the service. - Task GetModuleByIdService(string id); + ValueTask GetModuleById(string _id, CancellationToken cancellationToken); /// /// Gets all the roles. /// /// A representing /// the asynchronous execution of the service. - Task> GetAllModulesService(); + ValueTask> GetAllModules(CancellationToken cancellationToken); /// /// Gets all the permissions by permissions identifier list. @@ -40,7 +40,7 @@ namespace Core.Thalos.Provider.Contracts /// The list of permissions identifiers. /// A representing /// the asynchronous execution of the service. - Task> GetAllModulesByListService(string[] permissions); + ValueTask> GetAllModulesByList(string[] modules, CancellationToken cancellationToken); /// /// Changes the status of the permission. @@ -50,7 +50,7 @@ namespace Core.Thalos.Provider.Contracts /// The updated entity. /// A representing /// the asynchronous execution of the service. - Task ChangeModuleStatusService(string id, StatusEnum newStatus); + ValueTask ChangeModuleStatus(string id, StatusEnum newStatus, CancellationToken cancellationToken); /// /// Updates a Module by id. @@ -59,6 +59,6 @@ namespace Core.Thalos.Provider.Contracts /// The Module identifier. /// A representing /// the asynchronous execution of the service. - Task UpdateModuleService(ModuleAdapter entity, string id); + ValueTask UpdateModule(ModuleAdapter entity, CancellationToken cancellationToken); } } diff --git a/Core.Thalos.Provider/Providers/Onboarding/ModuleProvider.cs b/Core.Thalos.Provider/Providers/Onboarding/ModuleProvider.cs new file mode 100644 index 0000000..a002270 --- /dev/null +++ b/Core.Thalos.Provider/Providers/Onboarding/ModuleProvider.cs @@ -0,0 +1,153 @@ +// *********************************************************************** +// +// AgileWebs +// +// *********************************************************************** +using Core.Thalos.Adapters; +using Core.Blueprint.Mongo; +using Core.Blueprint.Redis; +using Core.Blueprint.Redis.Helpers; +using Mapster; +using Microsoft.Extensions.Options; +using MongoDB.Driver; +using Core.Thalos.Provider.Contracts; +using Core.Thalos.Domain.Contexts.Onboarding.Request; + +namespace Core.Thalos.Provider.Providers.Onboarding +{ + /// + /// Handles all services and business rules related to . + /// + public class ModuleProvider : IModuleProvider + { + private readonly CollectionRepository repository; + private readonly CacheSettings cacheSettings; + private readonly IRedisCacheProvider cacheProvider; + + public ModuleProvider(CollectionRepository repository, + IRedisCacheProvider cacheProvider, IOptions cacheSettings) + { + this.repository = repository; + this.repository.CollectionInitialization(); + this.cacheSettings = cacheSettings.Value; + this.cacheProvider = cacheProvider; + } + + /// + /// Creates a new Module. + /// + /// The Module to be created. + /// A representing + /// the asynchronous execution of the service. + public async ValueTask CreateModule(ModuleRequest newModule, CancellationToken cancellationToken) + { + var moduleCollection = newModule.Adapt(); + + await repository.InsertOneAsync(moduleCollection); + + return moduleCollection; + } + + /// + /// Gets an Module by identifier. + /// + /// The Module identifier. + /// A representing + /// the asynchronous execution of the service.0 + public async ValueTask GetModuleById(string _id, CancellationToken cancellationToken) + { + var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetModuleById", _id); + var cachedData = await cacheProvider.GetAsync(cacheKey); + + if (cachedData is not null) { return cachedData; } + + var module = await repository.FindByIdAsync(_id); + + await cacheProvider.SetAsync(cacheKey, module); + + return module; + } + + /// + /// Gets all the modules. + /// + /// A representing + /// the asynchronous execution of the service. + public async ValueTask> GetAllModules(CancellationToken cancellationToken) + { + var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetModules"); + var cachedData = await cacheProvider.GetAsync>(cacheKey) ?? []; + + if (cachedData.Any()) return cachedData; + + var modules = await repository.AsQueryable(); + + await cacheProvider.SetAsync(cacheKey, modules); + + return modules; + } + + /// + /// Gets all the modules by modules identifier list. + /// + /// The list of modules identifiers. + /// A representing + /// the asynchronous execution of the service. + public async ValueTask> GetAllModulesByList(string[] modules, CancellationToken cancellationToken) + { + var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetAllModulesByList", modules); + + var cachedData = await cacheProvider.GetAsync>(cacheKey) ?? []; + + if (cachedData.Any()) return cachedData; + + var builder = Builders.Filter; + var filters = new List>(); + + if (modules == null || !modules.Any()) + { + filters.Add(builder.In(x => x.Id, modules)); + } + + var finalFilter = filters.Any() ? builder.And(filters) : builder.Empty; + + var modulesList = await repository.FilterByMongoFilterAsync(finalFilter); + + await cacheProvider.SetAsync(cacheKey, modulesList); + + return modulesList; + } + + + /// + /// Changes the status of the module. + /// + /// The module identifier. + /// The new status of the module. + /// A representing + /// the asynchronous execution of the service. + public async ValueTask ChangeModuleStatus(string id, Core.Blueprint.Mongo.StatusEnum newStatus, CancellationToken cancellationToken) + { + var entity = await repository.FindByIdAsync(id); + entity.Status = newStatus; + + await repository.ReplaceOneAsync(entity); + + return entity; + } + + /// + /// Updates a Module by id. + /// + /// The Module to be updated. + /// The Module identifier. + /// A representing + /// the asynchronous execution of the service. + public async ValueTask UpdateModule(ModuleAdapter entity, CancellationToken cancellationToken) + { + await repository.ReplaceOneAsync(entity); + + return entity; + } + } +} diff --git a/Core.Thalos.Provider/Providers/Onboarding/ModuleService.cs b/Core.Thalos.Provider/Providers/Onboarding/ModuleService.cs deleted file mode 100644 index 99561bf..0000000 --- a/Core.Thalos.Provider/Providers/Onboarding/ModuleService.cs +++ /dev/null @@ -1,256 +0,0 @@ -// *********************************************************************** -// -// AgileWebs -// -// *********************************************************************** -using Core.Thalos.Adapters; -using Core.Thalos.Adapters.Common.Constants; -using Core.Thalos.Adapters.Common.Enums; -using Core.Thalos.Domain.Contexts.Onboarding.Mappers; -using Core.Thalos.Domain.Contexts.Onboarding.Request; -using Core.Thalos.Infraestructure.Caching.Configs; -using Core.Thalos.Infraestructure.Caching.Contracts; -using Core.Thalos.Provider.Contracts; -using LSA.Core.Dapper.Service.Caching; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using MongoDB.Bson; -using MongoDB.Driver; - -namespace Core.Thalos.Provider.Providers.Onboarding -{ - /// - /// Handles all services and business rules related to . - /// - public class ModuleService(ILogger logger, IHttpContextAccessor httpContextAccessor, ICacheService cacheService, - IOptions cacheSettings, IMongoDatabase database) : IModuleService - { - private readonly CacheSettings _cacheSettings = cacheSettings.Value; - - /// - /// Creates a new Module. - /// - /// The Module to be created. - /// A representing - /// the asynchronous execution of the service. - public async Task CreateModuleService(ModuleRequest newModule) - { - try - { - var entity = newModule.ToAdapter(httpContextAccessor); - entity.Order = (entity.Order is not null) ? entity.Order : await GetLastOrderModule(newModule); - await database.GetCollection(CollectionNames.Module).InsertOneAsync(entity); - entity.Id = (entity as dynamic ?? "").Id.ToString(); - - return entity; - } - catch (Exception ex) - { - logger.LogError(ex, $"CreateModuleService: Error in getting data - {ex.Message}"); - throw new Exception(ex.Message, ex); - } - } - - /// - /// Gets an Module by identifier. - /// - /// The Module identifier. - /// A representing - /// the asynchronous execution of the service.0 - public async Task GetModuleByIdService(string id) - { - var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetModuleByIdService", id); - var cachedData = await cacheService.GetAsync(cacheKey); - - if (cachedData is not null) { return cachedData; } - - try - { - var filter = Builders.Filter.And( - Builders.Filter.Eq("_id", ObjectId.Parse(id)), - Builders.Filter.Eq("status", StatusEnum.Active.ToString()) - ); - - var module = await database.GetCollection(CollectionNames.Module) - .Find(filter) - .FirstOrDefaultAsync(); - - var cacheDuration = CacheHelper.GetCacheDuration(_cacheSettings); - - await cacheService.SetAsync(cacheKey, module, cacheDuration); - - return module; - } - catch (Exception ex) - { - logger.LogError(ex, $"GetModuleByIdService: Error in getting data - {ex.Message}"); - throw new Exception(ex.Message, ex); - } - } - - /// - /// Gets all the modules. - /// - /// A representing - /// the asynchronous execution of the service. - public async Task> GetAllModulesService() - { - var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetAllModulesService"); - var cachedData = await cacheService.GetAsync>(cacheKey) ?? []; - - if (cachedData.Any()) return cachedData; - - try - { - var filter = Builders.Filter.Eq("status", StatusEnum.Active.ToString()); - - var roles = await database.GetCollection(CollectionNames.Module) - .Find(filter) - .SortBy(m => m.Application) - .ThenBy(m => m.Order) - .ToListAsync(); - - var cacheDuration = CacheHelper.GetCacheDuration(_cacheSettings); - - await cacheService.SetAsync(cacheKey, roles, cacheDuration); - - return roles; - } - catch (Exception ex) - { - logger.LogError(ex, $"GetAllModulesService: Error in getting data - {ex.Message}"); - throw new Exception(ex.Message, ex); - } - } - - /// - /// Gets all the modules by modules identifier list. - /// - /// The list of modules identifiers. - /// A representing - /// the asynchronous execution of the service. - public async Task> GetAllModulesByListService(string[] modules) - { - var cacheKey = CacheKeyHelper.GenerateCacheKey(this, "GetAllModulesByListService", modules); - - var cachedData = await cacheService.GetAsync>(cacheKey); - - if (cachedData != null && cachedData.Any()) return cachedData; - - try - { - var objectIds = modules.Select(id => ObjectId.Parse(id)).ToArray(); - - var filter = Builders.Filter.In("_id", objectIds) - & Builders.Filter.Eq("status", StatusEnum.Active.ToString()); - - var roles = await database.GetCollection(CollectionNames.Module) - .Find(filter) - .SortBy(m => m.Application) - .ThenBy(m => m.Order) - .ToListAsync(); - - var cacheDuration = CacheHelper.GetCacheDuration(_cacheSettings); - - await cacheService.SetAsync(cacheKey, roles, cacheDuration); - - return roles; - } - catch (Exception ex) - { - logger.LogError(ex, $"GetAllModulesByListService: Error in getting data - {ex.Message}"); - throw new Exception(ex.Message, ex); - } - } - - - /// - /// Changes the status of the module. - /// - /// The module identifier. - /// The new status of the module. - /// A representing - /// the asynchronous execution of the service. - public async Task ChangeModuleStatusService(string id, StatusEnum newStatus) - { - try - { - var filter = Builders.Filter - .Eq("_id", ObjectId.Parse(id)); - - var update = Builders.Update - //.Set(v => v.Status, newStatus) - .Set(v => v.UpdatedBy, Helper.GetEmail(httpContextAccessor)) - .Set(v => v.UpdatedAt, DateTime.UtcNow); - - await database.GetCollection(CollectionNames.Module).UpdateOneAsync(filter, update); - - var updatedModule = await database.GetCollection(CollectionNames.Module) - .Find(filter) - .FirstOrDefaultAsync(); - - return updatedModule; - } - catch (Exception ex) - { - logger.LogError(ex, $"ChangeModuleStatusService: Error in getting data - {ex.Message}"); - throw new Exception(ex.Message, ex); - } - } - - /// - /// Updates a Module by id. - /// - /// The Module to be updated. - /// The Module identifier. - /// A representing - /// the asynchronous execution of the service. - public async Task UpdateModuleService(ModuleAdapter entity, string id) - { - try - { - var filter = Builders.Filter - .Eq("_id", ObjectId.Parse(id)); - - var update = Builders.Update - .Set(v => v.Name, entity.Name) - .Set(v => v.Description, entity.Description) - .Set(v => v.Icon, entity.Icon) - .Set(v => v.Route, entity.Route) - .Set(v => v.Order, entity.Order) - .Set(v => v.Application, entity.Application) - .Set(v => v.Status, entity.Status) - .Set(v => v.UpdatedBy, Helper.GetEmail(httpContextAccessor)) - .Set(v => v.UpdatedAt, DateTime.UtcNow); - - await database.GetCollection(CollectionNames.Module).UpdateOneAsync(filter, update); - - var updatedModule = await database.GetCollection(CollectionNames.Module) - .Find(filter) - .FirstOrDefaultAsync(); - - return updatedModule; - } - catch (Exception ex) - { - logger.LogError(ex, $"UpdateModuleService: Error in getting data - {ex.Message}"); - throw new Exception(ex.Message, ex); - } - } - - private async Task GetLastOrderModule(ModuleRequest newModule) - { - var filter = Builders.Filter.And( - Builders.Filter.Eq("status", StatusEnum.Active.ToString()), - Builders.Filter.Eq("application", newModule.Application.ToString())); - - var maxOrderModule = await database.GetCollection(CollectionNames.Module) - .Find(filter) - .SortByDescending(m => m.Order) - .FirstOrDefaultAsync(); - - return (maxOrderModule is not null && maxOrderModule.Order is not null) ? maxOrderModule.Order : 0; - } - } -} diff --git a/Core.Thalos.Provider/ServiceCollectionExtensions.cs b/Core.Thalos.Provider/ServiceCollectionExtensions.cs index 741b094..a34a73a 100644 --- a/Core.Thalos.Provider/ServiceCollectionExtensions.cs +++ b/Core.Thalos.Provider/ServiceCollectionExtensions.cs @@ -67,7 +67,7 @@ namespace Core.Thalos.Provider services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); return services; } -- 2.49.1