using MesaFabApproval.API.Services; using MesaFabApproval.Shared.Models; using MesaFabApproval.Shared.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace MesaFabApproval.API.Controllers; [ApiController] [Authorize] public class ApprovalController : ControllerBase { private readonly ILogger _logger; private readonly IApprovalService _approvalService; private readonly IMonInWorkerClient _monInClient; public ApprovalController(ILogger logger, IApprovalService approvalService, IMonInWorkerClient monInClient) { _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected"); } [HttpPost] [Route("approval")] public async Task CreateApproval(Approval approval) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation("Attempting to generate a new approval"); if (approval is null) throw new ArgumentNullException("Approval cannot be null"); await _approvalService.CreateApproval(approval); return Ok(); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot create new approval, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "CreateApproval"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpGet] [Route("approval/issue")] public async Task GetApprovalsForIssueId(int issueId, bool bypassCache) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"Attempting to get approvals for issue {issueId}"); if (issueId <= 0) throw new ArgumentException($"{issueId} is not a valid issue ID"); IEnumerable approvals = await _approvalService.GetApprovalsForIssueId(issueId, bypassCache); return Ok(approvals); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get approvals, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetApprovalsForIssueId"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpGet] [Route("approval/user")] public async Task GetApprovalsForUserId(int userId, bool bypassCache) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"Attempting to get approvals for user ID {userId}"); if (userId <= 0) throw new ArgumentException($"{userId} is not a valid user ID"); IEnumerable approvals = await _approvalService.GetApprovalsForUserId(userId, bypassCache); return Ok(approvals); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get approvals, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetApprovalsForUserId"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpGet] [Route("approval/members")] public async Task GetApprovalGroupMembers(int subRoleId) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"Attempting to get approval group members for group {subRoleId}"); if (subRoleId <= 0) throw new ArgumentException($"{subRoleId} is not a valid sub role ID"); IEnumerable members = await _approvalService.GetApprovalGroupMembers(subRoleId); return Ok(members); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get approval group members, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetApprovalsGroupMembers"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpPut] [Route("approval")] public async Task UpdateApproval(Approval approval) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"Attempting to update approval"); if (approval is null) throw new ArgumentNullException($"approval cannot be null"); await _approvalService.UpdateApproval(approval); return Ok(); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot update approval, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "UpdateApproval"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpPut] [Route("approval/approve")] public async Task Approve(Approval approval) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"attempting to submit approval"); if (approval is null) throw new ArgumentNullException($"approval cannot be null"); await _approvalService.Approve(approval); return Ok(); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot approve, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "Approve"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpPut] [Route("approval/deny")] public async Task Deny(Approval approval) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"attempting to deny approval"); if (approval is null) throw new ArgumentNullException($"approval cannot be null"); await _approvalService.Deny(approval); return Ok(); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Approval denial failed, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "Deny"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpGet] [Route("approval/roleId")] public async Task GetRoleIdForRoleName(string roleName) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"Attempting to get role ID by role name"); if (string.IsNullOrWhiteSpace(roleName)) throw new ArgumentException("role name cannot be null or empty"); int roleId = await _approvalService.GetRoleIdForRoleName(roleName); return Ok(roleId); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get role ID, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetRoleIdForRoleName"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpGet] [Route("approval/subRoles")] public async Task GetSubRolesForSubRoleName(string subRoleName, int roleId) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation($"Attempting to get sub roles by sub role name"); if (string.IsNullOrWhiteSpace(subRoleName)) throw new ArgumentException("sub role name cannot be null or empty"); if (roleId <= 0) throw new ArgumentException($"{roleId} is not a valid role ID"); IEnumerable subRoles = await _approvalService.GetSubRolesForSubRoleName(subRoleName, roleId); return Ok(subRoles); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = ex.Message; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get role ID, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetSubRoleIdForSubRoleName"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isArgumentError) { _logger.LogWarning(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Ok); } else if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } }