using System.Text; using System.Text.Json; using MesaFabApproval.Shared.Models; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using static System.Net.Mime.MediaTypeNames; namespace MesaFabApproval.Shared.Services; public interface IMonInWorkerClient { void PostAverage(string metricName, double metricValue); void PostCount(string metricName, double metricValue); void PostStatus(string statusName, StatusValue statusValue); } public class MonInWorkerClient : IMonInWorkerClient { private readonly IHttpClientFactory _httpClientFactory; private readonly IConfiguration _config; private readonly ILogger _logger; private readonly string _baseUrl; private readonly int _retryLimit = -1; private readonly int _backoffInSeconds = -1; private readonly string _resource; public MonInWorkerClient(IHttpClientFactory httpClientFactory, IConfiguration config, ILogger logger) { _httpClientFactory = httpClientFactory; if (_httpClientFactory is null) throw new ArgumentNullException("IHttpClientFactory not injected"); _config = config; if (_config is null) throw new ArgumentNullException("IConfiguration not injected"); _logger = logger; if (_logger is null) throw new ArgumentNullException("ILogger not injected"); _baseUrl = Environment.GetEnvironmentVariable("MonInWorkerUrl") ?? throw new ArgumentNullException("MonInWorkerUrl environment variable not found"); string monInRetries = Environment.GetEnvironmentVariable("MonInRetries") ?? throw new ArgumentNullException("MonInRetries environment variable not found"); if (!Int32.TryParse(monInRetries, out _retryLimit)) throw new ArgumentException("MonInReties environment variable not an integer"); string monInBackoffSeconds = Environment.GetEnvironmentVariable("MonInBackoffSeconds") ?? throw new ArgumentNullException("MonInBackoffSeconds environment variable not found"); if (!Int32.TryParse(monInBackoffSeconds, out _backoffInSeconds)) throw new ArgumentException("MonInBackoffSeconds environment variable not an integer"); _resource = Environment.GetEnvironmentVariable("FabApprovalApiMonInResource") ?? throw new ArgumentNullException("OIWizardMonInResource environment variable not found"); } public async void PostStatus(string statusName, StatusValue statusValue) { string url = _baseUrl + "status"; StringBuilder logBuilder = new(); logBuilder.Append($"Attempting to send MonIn status request for resource {_resource} "); logBuilder.Append($"with name {statusName} and value {statusValue.ToString()} to url {url}"); _logger.LogInformation(logBuilder.ToString()); try { bool success = false; int retries = _retryLimit; while (!success && retries > 0) { Task.Delay(TimeSpan.FromSeconds((_retryLimit - retries) * _backoffInSeconds)).Wait(); HttpClient httpClient = _httpClientFactory.CreateClient(); RawMonInStatusRequest statusRequest = new RawMonInStatusRequest() { resource = _resource, dateTime = DateTime.Now, statusName = statusName, statusValue = statusValue.ToString() }; StringContent statusRequestJson = new StringContent(JsonSerializer.Serialize(statusRequest), Encoding.UTF8, Application.Json); using HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(url, statusRequestJson); success = httpResponseMessage.IsSuccessStatusCode; retries--; } } catch (Exception ex) { StringBuilder errLogBuilder = new(); errLogBuilder.Append($"An exception occurred when attempting to send MonIn status request for resource {_resource} "); errLogBuilder.Append($"with name {statusName} and value {statusValue.ToString()} to url {url}. Exception: {ex.Message}"); _logger.LogError(errLogBuilder.ToString()); } } public async void PostCount(string metricName, double metricValue) { string url = _baseUrl + "count"; StringBuilder logMsgBuilder = new(); logMsgBuilder.Append($"Attempting to send MonIn count request for resource {_resource} "); logMsgBuilder.Append($"with name {metricName} and value {metricValue} to url {url}"); _logger.LogInformation(logMsgBuilder.ToString()); try { bool success = false; int retries = _retryLimit; while (!success && retries > 0) { Task.Delay(TimeSpan.FromSeconds((_retryLimit - retries) * _backoffInSeconds)).Wait(); HttpClient httpClient = _httpClientFactory.CreateClient(); MonInMetricRequest metricRequest = new MonInMetricRequest() { resource = _resource, dateTime = DateTime.Now, metricName = metricName, metricValue = metricValue }; StringContent metricRequestJson = new StringContent(JsonSerializer.Serialize(metricRequest), Encoding.UTF8, Application.Json); using HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(url, metricRequestJson); success = httpResponseMessage.IsSuccessStatusCode; retries--; } } catch (Exception ex) { StringBuilder errMsgBuilder = new(); errMsgBuilder.Append($"An exception occurred when attempting to send MonIn count request for resource {_resource} "); errMsgBuilder.Append($"with name {metricName} and value {metricValue} to url {url}. Exception: {ex.Message}"); _logger.LogError(errMsgBuilder.ToString()); } } public async void PostAverage(string metricName, double metricValue) { string url = _baseUrl + "average"; StringBuilder logMsgBuilder = new(); logMsgBuilder.Append($"Attempting to send MonIn average request for resource {_resource} "); logMsgBuilder.Append($"with name {metricName} and value {metricValue} to url {url}"); _logger.LogInformation(logMsgBuilder.ToString()); try { bool success = false; int retries = _retryLimit; while (!success && retries > 0) { Task.Delay(TimeSpan.FromSeconds((_retryLimit - retries) * _backoffInSeconds)).Wait(); HttpClient httpClient = _httpClientFactory.CreateClient(); MonInMetricRequest metricRequest = new MonInMetricRequest() { resource = _resource, dateTime = DateTime.Now, metricName = metricName, metricValue = metricValue }; StringContent metricRequestJson = new StringContent(JsonSerializer.Serialize(metricRequest), Encoding.UTF8, Application.Json); using HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(url, metricRequestJson); success = httpResponseMessage.IsSuccessStatusCode; retries--; } } catch (Exception ex) { StringBuilder errMsgBuilder = new(); errMsgBuilder.Append($"An exception occurred when attempting to send MonIn average request for resource {_resource} "); errMsgBuilder.Append($"with name {metricName} and value {metricValue} to url {url}. Exception: {ex.Message}"); _logger.LogError(errMsgBuilder.ToString()); } } }