From 79828d46b13d303451d43eff400f1e44da8df5bd Mon Sep 17 00:00:00 2001 From: jboinembalome Date: Mon, 21 Sep 2020 17:49:49 +0200 Subject: [PATCH] Ajout des logs dans l'api engagement --- Controllers/EngagementsApi.cs | 127 +++++++++++++----- .../EngagementIncompatibleIdException.cs | 40 ++++++ Exceptions/EngagementInvalidException.cs | 40 ++++++ Exceptions/EngagementNotFoundException.cs | 40 ++++++ Services/EngagementService.cs | 92 ++++++++----- 5 files changed, 272 insertions(+), 67 deletions(-) create mode 100644 Exceptions/EngagementIncompatibleIdException.cs create mode 100644 Exceptions/EngagementInvalidException.cs create mode 100644 Exceptions/EngagementNotFoundException.cs diff --git a/Controllers/EngagementsApi.cs b/Controllers/EngagementsApi.cs index 46ce2ed..30814e3 100644 --- a/Controllers/EngagementsApi.cs +++ b/Controllers/EngagementsApi.cs @@ -20,6 +20,9 @@ using Microsoft.AspNetCore.Authorization; using IO.Swagger.DTO; using EPAServeur.IServices; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using EPAServeur.Exceptions; +using Microsoft.EntityFrameworkCore; namespace IO.Swagger.Controllers { @@ -30,10 +33,13 @@ namespace IO.Swagger.Controllers public class EngagementsApiController : ControllerBase { private readonly IEngagementService engagementService; + private readonly ILogger logger; - public EngagementsApiController(IEngagementService _engagementService) + + public EngagementsApiController(IEngagementService _engagementService, ILogger _logger) { engagementService = _engagementService; + logger = _logger; } /// /// @@ -54,20 +60,27 @@ namespace IO.Swagger.Controllers [SwaggerOperation("GetEngagements")] [SwaggerResponse(statusCode: 200, type: typeof(List), description: "OK")] [SwaggerResponse(statusCode: 403, type: typeof(ErreurDTO), description: "Acces interdit")] - public virtual IActionResult GetEngagements([FromQuery][Required()]bool? asc, [FromQuery][Required()]int? numPage, [FromQuery][Required()]int? parPAge, [FromQuery]long? idAgence, [FromQuery]string texte, [FromQuery]string tri) + public virtual async Task GetEngagements([FromQuery][Required()]bool? asc, [FromQuery][Required()]int? numPage, [FromQuery][Required()]int? parPAge, [FromQuery]long? idAgence, [FromQuery]string texte, [FromQuery]string tri) { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - IEnumerable engagements = engagementService.GetEngagements(asc, numPage, parPAge, idAgence, texte, tri); - if (engagements == null) + logger.LogInformation("Récupération de la liste des engagements."); + + IEnumerable engagements = null; + + try { - ErreurDTO erreur = new ErreurDTO() - { - Code = "404", - Message = "Aucun engagement" - }; - return NotFound(erreur); + engagements = await engagementService.GetEngagementsAsync(asc, numPage, parPAge, idAgence, texte, tri); + } + catch (ArgumentNullException) + { + logger.LogError("Un des arguments passés dans la requête pour récupérer la liste des engagements est invalide."); + } + catch (Exception) + { + logger.LogError("Une erreur inconnue est survenue lors de la récupération de la liste des engagements."); } + logger.LogInformation("Liste des engagements récupérée."); + return Ok(engagements); } @@ -90,20 +103,27 @@ namespace IO.Swagger.Controllers [SwaggerOperation("GetEngagementsEnAttente")] [SwaggerResponse(statusCode: 200, type: typeof(List), description: "OK")] [SwaggerResponse(statusCode: 403, type: typeof(ErreurDTO), description: "Acces interdit")] - public virtual IActionResult GetEngagementsEnAttente([FromQuery][Required()]bool? asc, [FromQuery][Required()]int? numPage, [FromQuery][Required()]int? parPAge, [FromQuery]long? idAgence, [FromQuery]string texte, [FromQuery]string tri) + public virtual async Task GetEngagementsEnAttente([FromQuery][Required()]bool? asc, [FromQuery][Required()]int? numPage, [FromQuery][Required()]int? parPAge, [FromQuery]long? idAgence, [FromQuery]string texte, [FromQuery]string tri) { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - IEnumerable engagements = engagementService.GetEngagementsEnAttente(asc, numPage, parPAge, idAgence, texte, tri); - if (engagements == null) + logger.LogInformation("Récupération de la liste des engagements en attente."); + + IEnumerable engagements = null; + + try { - ErreurDTO erreur = new ErreurDTO() - { - Code = "404", - Message = "Aucun engagement en attente" - }; - return NotFound(erreur); + engagements = await engagementService.GetEngagementsEnAttenteAsync(asc, numPage, parPAge, idAgence, texte, tri); + } + catch (ArgumentNullException) + { + logger.LogError("Un des arguments passés dans la requête pour récupérer la liste des engagements en attente est invalide."); + } + catch (Exception) + { + logger.LogError("Une erreur inconnue est survenue lors de la récupération de la liste des engagements en attente."); } + logger.LogInformation("Liste des engagements en attente récupérée."); + return Ok(engagements); } @@ -128,17 +148,24 @@ namespace IO.Swagger.Controllers [SwaggerResponse(statusCode: 403, type: typeof(ErreurDTO), description: "Acces interdit")] public virtual async Task GetEngagementsRepondus([FromQuery][Required()]bool? asc, [FromQuery][Required()]int? numPage, [FromQuery][Required()]int? parPAge, [FromQuery]long? idAgence, [FromQuery]string texte, [FromQuery]string tri) { - //TODO: Uncomment the next line to return response 200 or use other options such as return this.NotFound(), return this.BadRequest(..), ... - IEnumerable engagements = await engagementService.GetEngagementsRepondus(asc, numPage, parPAge, idAgence, texte, tri); - if (engagements == null) + logger.LogInformation("Récupération de la liste des engagements répondus."); + + IEnumerable engagements = null; + + try { - ErreurDTO erreur = new ErreurDTO() - { - Code = "404", - Message = "Aucun engagement en repondu" - }; - return NotFound(erreur); + engagements = await engagementService.GetEngagementsRepondusAsync(asc, numPage, parPAge, idAgence, texte, tri); + } + catch (ArgumentNullException) + { + logger.LogError("Un des arguments passés dans la requête pour récupérer la liste des engagements répondus est invalide."); } + catch (Exception) + { + logger.LogError("Une erreur inconnue est survenue lors de la récupération de la liste des engagements répondus."); + } + + logger.LogInformation("Liste des engagements répondus récupérée."); return Ok(engagements); } @@ -159,11 +186,43 @@ namespace IO.Swagger.Controllers [SwaggerResponse(statusCode: 403, type: typeof(ErreurDTO), description: "Acces interdit")] public virtual async Task RepondreEngagement([FromBody]EngagementDTO body, [FromRoute][Required]long? idEngagement) { - //if (body != null && body.Realise == false && string.IsNullOrWhiteSpace(body.RaisonNonRealisable)) - // return null; // A traiter ! Retourner une erreur + logger.LogInformation("Tentative de mise à jour de l'engagement {idEngagement}.", idEngagement); + + EngagementDTO engagement = null; + + try + { + engagement = await engagementService.RepondreEngagementAsync(body, idEngagement); + } + catch (EngagementInvalidException ex) + { + logger.LogWarning("Des données sont manquants, l'engagement {idEngagement} ne peut pas être mise à jour.", idEngagement); + ErreurDTO erreur = new ErreurDTO() + { + Code = "400", + Message = ex.Message + }; + return BadRequest(erreur); + } + catch (EngagementIncompatibleIdException) + { + logger.LogError("L'id de l'engagement à mettre à jour {body.Id} et l'id de l'engagement avec les nouvelles informations {idEngagement} sont différents.", body.Id, idEngagement); + } + catch (DbUpdateConcurrencyException) + { + logger.LogError("L'engagement {idEngagement} n'a pas pu être mise à jour car il est pris par une autre ressource.", idEngagement); + } + catch (DbUpdateException) + { + logger.LogError("Une erreur est survenue dans la base de données lors de la mise à jour de l'engagement {idEngagement}.", idEngagement); + } + catch (Exception) + { + logger.LogError("Une erreur inconnue est survenue lors de la mise à jour de l'engagement {idEngagement}.", idEngagement); + } + + logger.LogInformation("Mise à jour de l'engagement {idEngagement} réussie."); - EngagementDTO engagement = await engagementService.RepondreEngagement(body, idEngagement); - return Ok(engagement); } } diff --git a/Exceptions/EngagementIncompatibleIdException.cs b/Exceptions/EngagementIncompatibleIdException.cs new file mode 100644 index 0000000..d11a25b --- /dev/null +++ b/Exceptions/EngagementIncompatibleIdException.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EPAServeur.Exceptions +{ + /// + /// Exception à jeter lorsque l'id de l'engagement avec les données à mettre à jour et l'id de l'engagement à mettre sont différents + /// + public class EngagementIncompatibleIdException : Exception + { + /// + /// Initialise une nouvelle instance de la classe class. + /// + public EngagementIncompatibleIdException() + { + + } + + /// + /// Initialise une nouvelle instance de la classe class. + /// + /// + public EngagementIncompatibleIdException(string message) : base(message) + { + + } + + /// + /// Initialise une nouvelle instance de la classe class. + /// + /// + /// + public EngagementIncompatibleIdException(string message, Exception inner) : base(message, inner) + { + + } + } +} diff --git a/Exceptions/EngagementInvalidException.cs b/Exceptions/EngagementInvalidException.cs new file mode 100644 index 0000000..15e974a --- /dev/null +++ b/Exceptions/EngagementInvalidException.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EPAServeur.Exceptions +{ + /// + /// Exception à jeter lorsqu'un engagement est invalide + /// + public class EngagementInvalidException : Exception + { + /// + /// Initialise une nouvelle instance de la classe class. + /// + public EngagementInvalidException() + { + + } + + /// + /// Initialise une nouvelle instance de la classe class. + /// + /// + public EngagementInvalidException(string message) : base(message) + { + + } + + /// + /// Initialise une nouvelle instance de la classe class. + /// + /// + /// + public EngagementInvalidException(string message, Exception inner) : base(message, inner) + { + + } + } +} diff --git a/Exceptions/EngagementNotFoundException.cs b/Exceptions/EngagementNotFoundException.cs new file mode 100644 index 0000000..365f553 --- /dev/null +++ b/Exceptions/EngagementNotFoundException.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EPAServeur.Exceptions +{ + /// + /// Exception à jeter lorsqu'un engagement n'a pas été trouvé + /// + public class EngagementNotFoundException : Exception + { + /// + /// Initialise une nouvelle instance de la classe class. + /// + public EngagementNotFoundException() + { + + } + + /// + /// Initialise une nouvelle instance de la classe class. + /// + /// + public EngagementNotFoundException(string message) : base(message) + { + + } + + /// + /// Initialise une nouvelle instance de la classe class. + /// + /// + /// + public EngagementNotFoundException(string message, Exception inner) : base(message, inner) + { + + } + } +} diff --git a/Services/EngagementService.cs b/Services/EngagementService.cs index 320b0de..cab7c58 100644 --- a/Services/EngagementService.cs +++ b/Services/EngagementService.cs @@ -1,4 +1,5 @@ using EPAServeur.Context; +using EPAServeur.Exceptions; using EPAServeur.IServices; using EPAServeur.Models.EP; using EPAServeur.Models.Formation; @@ -57,8 +58,8 @@ namespace EPAServeur.Services else engagements = epContext.Engagement.Include(engagement => engagement.Ep); - if (engagements == null) - return null; + if (engagements == null || engagements.Count() == 0) + return new List(); var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); @@ -82,12 +83,13 @@ namespace EPAServeur.Services else engagements = await epContext.Engagement.Include(engagement => engagement.Ep).ToListAsync(); - if (engagements == null) - return null; + if (engagements == null || engagements.Count() == 0) + return new List(); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); + var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTOAsync(engagement)); + var results = await Task.WhenAll(engagementDTOs); - return engagementDTOs; + return results; } public IEnumerable GetEngagementsEnAttente(bool? asc, int? numPage, int? parPAge, long? idAgence, string texte, string tri) @@ -107,8 +109,8 @@ namespace EPAServeur.Services else engagements = epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.Realise == null).ToList(); - if (engagements == null) - return null; + if (engagements == null || engagements.Count() == 0) + return new List(); var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); @@ -132,13 +134,13 @@ namespace EPAServeur.Services else engagements = await epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.Realise == null).ToListAsync(); + if (engagements == null || engagements.Count() == 0) + return new List(); - if (engagements == null) - return null; + var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTOAsync(engagement)); + var results = await Task.WhenAll(engagementDTOs); - var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); - - return engagementDTOs; + return results; } public IEnumerable GetEngagementsRepondus(bool? asc, int? numPage, int? parPAge, long? idAgence, string texte, string tri) @@ -158,9 +160,8 @@ namespace EPAServeur.Services else engagements = epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.Realise != null && engagement.Modalite.ToLower().Contains(texte)); - - if (engagements == null) - return null; + if (engagements == null || engagements.Count() == 0) + return new List(); var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTO(engagement)); @@ -184,8 +185,8 @@ namespace EPAServeur.Services else engagements = await epContext.Engagement.Include(engagement => engagement.Ep).Where(engagement => engagement.Realise != null && engagement.Modalite.ToLower().Contains(texte)).ToListAsync(); - if (engagements == null) - return null; + if (engagements == null || engagements.Count() == 0) + return new List(); var engagementDTOs = engagements.Where(engagement => engagement.Modalite.ToLower().Contains(texte)).Select(engagement => GetEngagementDTOAsync(engagement)); var results = await Task.WhenAll(engagementDTOs); @@ -203,22 +204,36 @@ namespace EPAServeur.Services { if (!IsEngagementValide(engagementDTO)) - return null; + throw new EngagementInvalidException("Impossible de répondre à l'engagement, des données sont manquants."); + + if (engagementDTO.Realise == false && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable)) + throw new EngagementInvalidException("Impossible de répondre à l'engagement, une raison doit être rensignée lorsqu'un engagement n'est pas réalisé."); + + if (engagementDTO == null && !engagementDTO.Id.HasValue && engagementDTO.Id.Value != idEngagement) + throw new EngagementIncompatibleIdException(); - if (engagementDTO.Id != idEngagement) - return null; Engagement engagement = epContext.Engagement.Include(engagement => engagement.Ep).FirstOrDefault(engagement => engagement.Id == idEngagement); if (engagement == null) - return null; + throw new EngagementNotFoundException(); engagement.Realise = engagementDTO.Realise; - if (engagement.Realise == false) + switch (engagement.Realise) { - engagement.Realisable = engagementDTO.Realisable; - engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; + case true: + engagement.Realisable = engagementDTO.Realisable; + engagement.RaisonNonRealisable = null; + break; + case false: + engagement.Realisable = engagementDTO.Realisable; + engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; + break; + default: + engagement.Realisable = null; + engagement.RaisonNonRealisable = null; + break; } epContext.SaveChanges(); @@ -237,22 +252,33 @@ namespace EPAServeur.Services { if (!IsEngagementValide(engagementDTO)) - return null; + throw new EngagementInvalidException("Impossible de répondre à l'engagement, des données sont manquants."); + + if (engagementDTO.Realise == false && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable)) + throw new EngagementInvalidException("Impossible de répondre à l'engagement, une raison doit être rensignée lorsqu'un engagement n'est pas réalisé."); - if (engagementDTO.Id != idEngagement) - return null; Engagement engagement = await epContext.Engagement.Include(engagement => engagement.Ep).FirstOrDefaultAsync(engagement => engagement.Id == idEngagement); if (engagement == null) - return null; + throw new EngagementNotFoundException(); engagement.Realise = engagementDTO.Realise; - if (engagement.Realise == false) + switch (engagement.Realise) { - engagement.Realisable = engagementDTO.Realisable; - engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; + case true: + engagement.Realisable = engagementDTO.Realisable; + engagement.RaisonNonRealisable = null; + break; + case false: + engagement.Realisable = engagementDTO.Realisable; + engagement.RaisonNonRealisable = engagementDTO.RaisonNonRealisable; + break; + default: + engagement.Realisable = null; + engagement.RaisonNonRealisable = null; + break; } await epContext.SaveChangesAsync(); @@ -266,7 +292,7 @@ namespace EPAServeur.Services #region Méthodes Privée private bool IsEngagementValide(EngagementDTO engagementDTO) { - return !(engagementDTO == null || engagementDTO.Id == null || engagementDTO.Action == null || engagementDTO.DatePrevisionnelle == null || engagementDTO.Dispositif == null || engagementDTO.Modalite == null || (engagementDTO.Realise == false && string.IsNullOrWhiteSpace(engagementDTO.RaisonNonRealisable))); + return !(engagementDTO == null || engagementDTO.Id == null || engagementDTO.Action == null || engagementDTO.DatePrevisionnelle == null || engagementDTO.Dispositif == null || engagementDTO.Modalite == null); } #region Object to DTO