using System.Text; using System.Text.Json; using FabApprovalWorkerService.Models; using static System.Net.Mime.MediaTypeNames; namespace FabApprovalWorkerService.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 ?? throw new ArgumentNullException("IConfiguration not injected"); _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _baseUrl = Environment.GetEnvironmentVariable("MonInWorkerUrl") ?? throw new ArgumentNullException("MonInWorkerUrl environment variable not found"); if (!Int32.TryParse(Environment.GetEnvironmentVariable("MonInRetries"), out _retryLimit)) throw new ArgumentNullException("Valid MonInRetries environment variable not found"); if (!Int32.TryParse(Environment.GetEnvironmentVariable("MonInBackoffSeconds"), out _backoffInSeconds)) throw new ArgumentNullException("Valid MonInBackoffSeconds environment varialbe not found"); _resource = Environment.GetEnvironmentVariable("FabApprovalWorkerServiceMonInResource") ?? throw new ArgumentNullException("FabApprovalWorkerServiceMonInResource environment variable not found"); } public async void PostStatus(string statusName, StatusValue statusValue) { string url = _baseUrl + "status"; _logger.LogInformation("Attempting to send MonIn status request for resource {0} with name {1} and value {2} to url {3}", _resource, statusName, statusValue.ToString(), url); 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) { _logger.LogError("An exception occurred when attempting to send MonIn status request for resource {0} with name {1} and value {2} to url {3}. Exception: {4}", _resource, statusName, statusValue.ToString(), url, ex.Message); } } public async void PostCount(string metricName, double metricValue) { string url = _baseUrl + "count"; _logger.LogInformation("Attempting to send MonIn count request for resource {0} with name {1} and value {2} to url {3}", _resource, metricName, metricValue, url); 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) { _logger.LogError("An exception occurred when attempting to send MonIn count request for resource {0} with name {1} and value {2} to url {3}. Exception: {4}", _resource, metricName, metricValue, url, ex.Message); } } public async void PostAverage(string metricName, double metricValue) { string url = _baseUrl + "average"; _logger.LogInformation("Attempting to send MonIn average request for resource {0} with name {1} and value {2} to url {3}", _resource, metricName, metricValue, url); 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) { _logger.LogError("An exception occurred when attempting to send MonIn average request for resource {0} with name {1} and value {2} to url {3}. Exception: {4}", _resource, metricName, metricValue, url, ex.Message); } } }