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<ApprovalController> _logger; private readonly IApprovalService _approvalService; private readonly IMonInWorkerClient _monInClient; public ApprovalController(ILogger<ApprovalController> 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<IActionResult> 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<IActionResult> 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<Approval> 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<IActionResult> 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<Approval> 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<IActionResult> 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<User> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<SubRole> 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); } } } }