2024-11-15 09:28:21 -07:00

301 lines
13 KiB
C#

using System.Text;
using System.Text.Json;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
namespace MesaFabApproval.Client.Services;
public interface IApprovalService {
Task<int> GetRoleIdForRoleName(string roleName);
Task<IEnumerable<SubRole>> GetSubRolesForSubRoleName(string subRoleName, int roleId);
Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId);
Task CreateApproval(Approval approval);
Task UpdateApproval(Approval approval);
Task Approve(Approval approval);
Task Deny(Approval approval);
Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache);
Task<IEnumerable<Approval>> GetApprovalsForUserId(int userId, bool bypassCache);
}
public class ApprovalService : IApprovalService {
private readonly IMemoryCache _cache;
private readonly IHttpClientFactory _httpClientFactory;
public ApprovalService(IMemoryCache cache, IHttpClientFactory httpClientFactory) {
_cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected");
_httpClientFactory = httpClientFactory ??
throw new ArgumentNullException("IHttpClientFactory not injected");
}
public async Task CreateApproval(Approval approval) {
if (approval is null) throw new ArgumentNullException("approval cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Post, "approval");
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
Encoding.UTF8,
"application/json");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) {
throw new Exception($"Unable to create approval, because {responseMessage.ReasonPhrase}");
}
await GetApprovalsForIssueId(approval.IssueID, true);
await GetApprovalsForUserId(approval.UserID, true);
}
public async Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache) {
if (issueId <= 0) throw new ArgumentException($"{issueId} is not a valid issue ID");
IEnumerable<Approval>? approvals = null;
if (!bypassCache)
approvals = _cache.Get<IEnumerable<Approval>>($"approvals{issueId}");
if (approvals is null) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/issue?issueId={issueId}&bypassCache={bypassCache}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
approvals = JsonSerializer.Deserialize<IEnumerable<Approval>>(responseContent, jsonSerializerOptions) ??
throw new Exception("Unable to parse approvals from API response");
_cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(15));
} else {
throw new Exception($"Unable to get approvals, because {responseMessage.ReasonPhrase}");
}
}
foreach (Approval approval in approvals) {
if (approval.ItemStatus < 0)
approval.StatusMessage = "Denied";
if (approval.ItemStatus == 0)
approval.StatusMessage = "Assigned";
if (approval.ItemStatus > 0)
approval.StatusMessage = "Approved";
}
return approvals;
}
public async Task<IEnumerable<Approval>> GetApprovalsForUserId(int userId, bool bypassCache) {
if (userId <= 0) throw new ArgumentException($"{userId} is not a valid user ID");
IEnumerable<Approval>? approvals = null;
if (!bypassCache) approvals = _cache.Get<IEnumerable<Approval>>($"approvals{userId}");
if (approvals is null) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/user?userId={userId}&bypassCache={bypassCache}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
approvals = JsonSerializer.Deserialize<IEnumerable<Approval>>(responseContent, jsonSerializerOptions) ??
throw new Exception("Unable to parse approvals from API response");
_cache.Set($"approvals{userId}", approvals, DateTimeOffset.Now.AddMinutes(15));
} else {
throw new Exception($"Unable to get approvals, because {responseMessage.ReasonPhrase}");
}
}
foreach (Approval approval in approvals) {
if (approval.ItemStatus < 0)
approval.StatusMessage = "Denied";
if (approval.ItemStatus == 0)
approval.StatusMessage = "Assigned";
if (approval.ItemStatus > 0)
approval.StatusMessage = "Approved";
}
return approvals;
}
public async Task UpdateApproval(Approval approval) {
if (approval is null) throw new ArgumentNullException("approval cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Put, "approval");
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
Encoding.UTF8,
"application/json");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) {
throw new Exception($"Unable to update approval, because {responseMessage.ReasonPhrase}");
}
await GetApprovalsForIssueId(approval.IssueID, true);
await GetApprovalsForUserId(approval.UserID, true);
}
public async Task Approve(Approval approval) {
if (approval is null) throw new ArgumentNullException("approval cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Put, "approval/approve");
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
Encoding.UTF8,
"application/json");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) {
throw new Exception($"Approval failed, because {responseMessage.ReasonPhrase}");
}
await GetApprovalsForIssueId(approval.IssueID, true);
await GetApprovalsForUserId(approval.UserID, true);
}
public async Task Deny(Approval approval) {
if (approval is null) throw new ArgumentNullException("approval cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Put, "approval/deny");
requestMessage.Content = new StringContent(JsonSerializer.Serialize(approval),
Encoding.UTF8,
"application/json");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) {
throw new Exception($"Denial failed, because {responseMessage.ReasonPhrase}");
}
}
public async Task<int> GetRoleIdForRoleName(string roleName) {
if (string.IsNullOrWhiteSpace(roleName)) throw new ArgumentException("role name cannot be null or empty");
int roleId = _cache.Get<int>($"roleId{roleName}");
if (roleId <= 0) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/roleId?roleName={roleName}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
roleId = JsonSerializer.Deserialize<int>(responseContent, jsonSerializerOptions);
if (roleId <= 0)
throw new Exception($"unable to find role ID for {roleName}");
_cache.Set($"roleId{roleName}", roleId, DateTimeOffset.Now.AddMinutes(15));
} else {
throw new Exception($"Unable to get role ID, because {responseMessage.ReasonPhrase}");
}
}
return roleId;
}
public async Task<IEnumerable<SubRole>> GetSubRolesForSubRoleName(string subRoleName, int roleId) {
if (string.IsNullOrWhiteSpace(subRoleName)) throw new ArgumentException("role name cannot be null or empty");
if (roleId <= 0) throw new ArgumentException($"{roleId} is not a valid role ID");
IEnumerable<SubRole>? subRoles = _cache.Get<IEnumerable<SubRole>>($"subRoles{subRoleName}");
if (subRoles is null || subRoles.Count() <= 0) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/subRoles?subRoleName={subRoleName}&roleId={roleId}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
subRoles = JsonSerializer.Deserialize<IEnumerable<SubRole>>(responseContent, jsonSerializerOptions) ??
throw new Exception("Unable to parse sub roles from API response");
if (subRoles is not null && subRoles.Count() > 0) {
_cache.Set($"subRoles{subRoleName}", subRoles, DateTimeOffset.Now.AddMinutes(15));
} else {
throw new Exception($"unable to find sub roles for {subRoleName}");
}
} else {
throw new Exception($"Unable to get sub roles, because {responseMessage.ReasonPhrase}");
}
}
return subRoles;
}
public async Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId) {
if (subRoleId <= 0) throw new ArgumentException($"{subRoleId} is not a valid sub role ID");
IEnumerable<User>? members = _cache.Get<IEnumerable<User>>($"approvalMembers{subRoleId}");
if (members is null) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"approval/members?subRoleId={subRoleId}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
members = JsonSerializer.Deserialize<IEnumerable<User>>(responseContent, jsonSerializerOptions) ??
throw new Exception("Unable to parse users from API response");
if (members is null || members.Count() <= 0)
throw new Exception($"unable to find group members for sub role {subRoleId}");
_cache.Set($"approvalMembers{subRoleId}", members, DateTimeOffset.Now.AddMinutes(15));
} else {
throw new Exception($"Unable to get group members, because {responseMessage.ReasonPhrase}");
}
}
return members;
}
}