using MesaFabApproval.API.Services; using MesaFabApproval.Shared.Models; using MesaFabApproval.Shared.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; namespace MesaFabApproval.API.Controllers; [ApiController] public class UserController : ControllerBase { private readonly ILogger _logger; private readonly IMonInWorkerClient _monInClient; private readonly IMemoryCache _cache; private readonly IUserService _userService; public UserController(ILogger logger, IMonInWorkerClient monInClient, IMemoryCache cache, IUserService userService) { _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected"); _cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected"); _userService = userService ?? throw new ArgumentNullException("IUserService not injected"); } [HttpGet] [Route("/user/loginId")] [Authorize] public async Task GetUserByLoginId(string loginId) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation("Attempting to get user by LoginID"); if (string.IsNullOrWhiteSpace(loginId)) throw new ArgumentException("LoginID cannot be null or empty"); User? user = _cache.Get($"user{loginId}"); if (user is null) { user = await _userService.GetUserByLoginId(loginId); _cache.Set($"user{loginId}", user, DateTimeOffset.Now.AddDays(1)); } if (user is not null) return Ok(user); throw new Exception($"User with LoginID {loginId} not found"); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = $"Invalid argument. {ex.Message}"; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get user by LoginID, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetUserByLoginId"; 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("/user/userId")] [Authorize] public async Task GetUserByUserId(int userId) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation("Attempting to get user by LoginID"); if (userId <= 0) throw new ArgumentException($"{userId} is not a valid user ID"); User? user = _cache.Get($"user{userId}"); if (user is null) { user = await _userService.GetUserByUserId(userId); _cache.Set($"user{userId}", user, DateTimeOffset.Now.AddDays(1)); } if (user is not null) return Ok(user); throw new Exception($"User with UserID {userId} not found"); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = $"Invalid argument. {ex.Message}"; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get user by User ID, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetUserByUserId"; 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("/users/active")] [Authorize] public async Task GetAllActiveUsers() { DateTime start = DateTime.Now; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation("Attempting to get all active users"); IEnumerable? activeUsers = _cache.Get>($"activeUsers"); if (activeUsers is null) { activeUsers = await _userService.GetAllActiveUsers(); _cache.Set($"activeUsers", activeUsers, DateTimeOffset.Now.AddDays(1)); } if (activeUsers is not null) return Ok(activeUsers); throw new Exception($"No active users found"); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get all active users, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetAllActiveUsers"; DateTime end = DateTime.Now; double millisecondsDiff = (end - start).TotalMilliseconds; _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); if (isInternalError) { _logger.LogError(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical); } else { _monInClient.PostStatus(metricName, StatusValue.Ok); } } } [HttpGet] [Route("/approver")] [Authorize] public async Task GetApproverUserIdsForSubRoleCategoryItem(string subRoleCategoryItem) { DateTime start = DateTime.Now; bool isArgumentError = false; bool isInternalError = false; string errorMessage = ""; try { _logger.LogInformation("Attempting to get approver user IDs"); if (string.IsNullOrWhiteSpace(subRoleCategoryItem)) throw new ArgumentException("SubRoleCategoryItem cannot be null or empty"); IEnumerable? approverUserIds = _cache.Get>($"approvers{subRoleCategoryItem}"); if (approverUserIds is null) { approverUserIds = await _userService.GetApproverUserIdsBySubRoleCategoryItem(subRoleCategoryItem); _cache.Set($"approvers{subRoleCategoryItem}", approverUserIds, DateTimeOffset.Now.AddDays(1)); } if (approverUserIds is not null) return Ok(approverUserIds); throw new Exception($"Approvers for SubRoleCategoryItem {subRoleCategoryItem} not found"); } catch (ArgumentException ex) { isArgumentError = true; errorMessage = $"Invalid argument. {ex.Message}"; return BadRequest(errorMessage); } catch (Exception ex) { isInternalError = true; errorMessage = $"Cannot get approver user IDs, because {ex.Message}"; return Problem(errorMessage); } finally { string metricName = "GetApproverUserIds"; 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); } } } }