Created PendingOOOStatusWorker
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Worker">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
@ -10,6 +10,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<Optimize>False</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<Optimize>True</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
@ -17,17 +21,21 @@
|
||||
<PackageReference Include="CsvHelper" Version="31.0.0" />
|
||||
<PackageReference Include="Dapper" Version="2.1.28" />
|
||||
<PackageReference Include="Dapper.Contrib" Version="2.0.78" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="NLog" Version="5.2.8" />
|
||||
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
|
||||
<PackageReference Include="Quartz" Version="3.8.1" />
|
||||
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.8.1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EditorConfigFiles Remove="C:\Users\tuckerc\FabApprovalWorkerService\.editorconfig" />
|
||||
<EditorConfigFiles Remove=".\.editorconfig" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="C:\Users\tuckerc\FabApprovalWorkerService\.editorconfig" />
|
||||
<None Include=".\.editorconfig" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
9
FabApprovalWorkerService/Models/MonInMetricRequest.cs
Normal file
9
FabApprovalWorkerService/Models/MonInMetricRequest.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace FabApprovalWorkerService.Models;
|
||||
|
||||
public class MonInMetricRequest
|
||||
{
|
||||
public required string resource { get; set; }
|
||||
public required DateTime dateTime { get; set; }
|
||||
public required string metricName { get; set; }
|
||||
public required double metricValue { get; set; }
|
||||
}
|
10
FabApprovalWorkerService/Models/OOOTemp.cs
Normal file
10
FabApprovalWorkerService/Models/OOOTemp.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace FabApprovalWorkerService.Models;
|
||||
|
||||
public class OOOTemp {
|
||||
public required int ID { get; set; }
|
||||
public required int OOOUserID { get; set; }
|
||||
public int DelegatedTo { get; set; }
|
||||
public required DateTime OOOStartDate { get; set; }
|
||||
public required DateTime OOOExpirationDate { get; set; }
|
||||
public bool Processed { get; set; } = false;
|
||||
}
|
9
FabApprovalWorkerService/Models/RawMonInStatusRequest.cs
Normal file
9
FabApprovalWorkerService/Models/RawMonInStatusRequest.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace FabApprovalWorkerService.Models;
|
||||
|
||||
public class RawMonInStatusRequest
|
||||
{
|
||||
public required string resource { get; set; }
|
||||
public required DateTime dateTime { get; set; }
|
||||
public required string statusName { get; set; }
|
||||
public required string statusValue { get; set; }
|
||||
}
|
10
FabApprovalWorkerService/Models/StatusValue.cs
Normal file
10
FabApprovalWorkerService/Models/StatusValue.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace FabApprovalWorkerService.Models;
|
||||
|
||||
public enum StatusValue {
|
||||
Up,
|
||||
Ok,
|
||||
Warning,
|
||||
Critical,
|
||||
Down,
|
||||
Unknown
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
using CsvHelper.Configuration.Attributes;
|
||||
|
||||
namespace FabApprovalWorkerService.Models;
|
||||
public class TrainingRecord {
|
||||
[Name("Item ID")]
|
||||
[Index(0)]
|
||||
public string ItemId { get; set; }
|
||||
[Name("Item Type")]
|
||||
[Index(1)]
|
||||
public string? ItemType { get; set; }
|
||||
[Name("Revision Date")]
|
||||
[Index(2)]
|
||||
public DateTime? RevisionDate { get; set; }
|
||||
[Name("Title")]
|
||||
[Index(3)]
|
||||
public string? Title { get; set; }
|
||||
[Name("User ID")]
|
||||
[Index(4)]
|
||||
public string? UserId { get; set; }
|
||||
[Name("Last Name")]
|
||||
[Index(5)]
|
||||
public string LastName { get; set; }
|
||||
[Name("First Name")]
|
||||
[Index(6)]
|
||||
public string FirstName { get; set; }
|
||||
[Name("Middle Name")]
|
||||
[Index(7)]
|
||||
public string? MiddleName { get; set; }
|
||||
[Name("Completion Status ID")]
|
||||
[Index(8)]
|
||||
public string? CompletionStatusId { get; set; }
|
||||
[Name("Completion Status")]
|
||||
[Index(9)]
|
||||
public string? CompletionStatus { get; set; }
|
||||
[Name("Completion Date")]
|
||||
[Index(10)]
|
||||
public DateTime CompletionDate { get; set; }
|
||||
}
|
8
FabApprovalWorkerService/Models/UserSubRole.cs
Normal file
8
FabApprovalWorkerService/Models/UserSubRole.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace FabApprovalWorkerService.Models;
|
||||
|
||||
public class UserSubRole {
|
||||
public required int UserSubRoleID { get; set; }
|
||||
public required int UserID { get; set; }
|
||||
public required int SubRoleID { get; set; }
|
||||
public bool Delegated { get; set; } = false;
|
||||
}
|
@ -1,26 +1,53 @@
|
||||
using FabApprovalWorkerService.Services;
|
||||
using FabApprovalWorkerService.Workers;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
using NLog.Extensions.Logging;
|
||||
|
||||
using System.Data.SqlClient;
|
||||
using Quartz;
|
||||
|
||||
using System.Data;
|
||||
using FabApprovalWorkerService.Services;
|
||||
|
||||
IHostBuilder builder = Host.CreateDefaultBuilder(args)
|
||||
.ConfigureLogging((hostContext, logging) => {
|
||||
logging.ClearProviders();
|
||||
logging.SetMinimumLevel(LogLevel.Trace);
|
||||
logging.AddNLog();
|
||||
})
|
||||
.ConfigureServices((hostContext, services) => {
|
||||
services.AddHostedService<UserCertificationUpdateWorker>();
|
||||
services.AddTransient<IDbConnection>(db => new SqlConnection(
|
||||
hostContext.Configuration.GetConnectionString("Default")));
|
||||
services.AddScoped<IDalService, DalService>();
|
||||
services.AddScoped<IUserService, UserService>();
|
||||
});
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
IHost host = builder.Build();
|
||||
host.Run();
|
||||
builder.Logging.ClearProviders();
|
||||
builder.Logging.SetMinimumLevel(LogLevel.Trace);
|
||||
builder.Logging.AddNLog();
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
#if DEBUG
|
||||
builder.Services.AddScoped<IDbConnection>(db => new SqliteConnection(
|
||||
builder.Configuration.GetConnectionString("Default")));
|
||||
#else
|
||||
builder.Services.AddScoped<IDbConnection>(db => new SqlConnection(
|
||||
builder.Configuration.GetConnectionString("Default")));
|
||||
#endif
|
||||
|
||||
builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>();
|
||||
builder.Services.AddScoped<IDalService, DalService>();
|
||||
builder.Services.AddScoped<IUserService, UserService>();
|
||||
|
||||
builder.Services.AddQuartz(q => {
|
||||
JobKey updateCertDataJobKey = new JobKey("Pending OOO status job");
|
||||
q.AddJob<PendingOOOStatusWorker>(opts => opts
|
||||
.WithIdentity(updateCertDataJobKey)
|
||||
);
|
||||
q.AddTrigger(opts => opts
|
||||
.ForJob(updateCertDataJobKey)
|
||||
.WithIdentity("Pending OOO status trigger")
|
||||
.WithSimpleSchedule(x => x
|
||||
.WithIntervalInMinutes(10)
|
||||
.RepeatForever()
|
||||
)
|
||||
.StartNow()
|
||||
);
|
||||
});
|
||||
|
||||
builder.Services.AddQuartzHostedService(opt => {
|
||||
opt.WaitForJobsToComplete = true;
|
||||
});
|
||||
|
||||
WebApplication app = builder.Build();
|
||||
app.Run();
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
{
|
||||
"profiles": {
|
||||
"FabApprovalWorkerService": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"environmentVariables": {
|
||||
"DOTNET_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"nativeDebugging": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json"
|
||||
}
|
@ -1,15 +1,21 @@
|
||||
using Dapper;
|
||||
using Dapper.Contrib.Extensions;
|
||||
|
||||
using FabApprovalWorkerService.Models;
|
||||
|
||||
using System.Data;
|
||||
|
||||
namespace FabApprovalWorkerService.Services;
|
||||
|
||||
public interface IDalService {
|
||||
Task<IEnumerable<T>> QueryAsync<T>(string sql);
|
||||
Task<bool> UpdateAsync<T>(ICollection<T> collection);
|
||||
Task<int> ExecuteAsync(string sql);
|
||||
}
|
||||
|
||||
public class DalService : IDalService {
|
||||
private static readonly int RETRIES = 3;
|
||||
private static readonly int BACKOFF_SECONDS_INTERVAL = 30;
|
||||
|
||||
private readonly IDbConnection _dbConnection;
|
||||
private readonly ILogger<DalService> _logger;
|
||||
|
||||
@ -22,35 +28,73 @@ public class DalService : IDalService {
|
||||
|
||||
public async Task<IEnumerable<T>> QueryAsync<T>(string sql) {
|
||||
if (sql is null) throw new ArgumentNullException("sql cannot be null");
|
||||
try {
|
||||
_logger.LogInformation("Attempting to perform query with {sql}", sql);
|
||||
|
||||
_dbConnection.Open();
|
||||
return await _dbConnection.QueryAsync<T>(sql);
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred while attempting to perform a query. Exception: {ex}",
|
||||
ex.Message);
|
||||
int remainingRetries = RETRIES;
|
||||
bool queryWasSuccessful = false;
|
||||
Exception exception = null;
|
||||
IEnumerable<T> result = new List<T>();
|
||||
while (!queryWasSuccessful && remainingRetries > 0) {
|
||||
int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL;
|
||||
Task.Delay(backoffSeconds * 1000).Wait();
|
||||
|
||||
throw;
|
||||
} finally {
|
||||
_dbConnection.Close();
|
||||
try {
|
||||
_logger.LogInformation("Attempting to perform query with {sql}. Remaining retries: {remainingRetries}",
|
||||
sql,
|
||||
remainingRetries);
|
||||
|
||||
using (_dbConnection) {
|
||||
result = await _dbConnection.QueryAsync<T>(sql);
|
||||
}
|
||||
|
||||
queryWasSuccessful = true;
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred while attempting to perform a query. Exception: {ex}",
|
||||
ex.Message);
|
||||
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!queryWasSuccessful && exception is not null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateAsync<T>(ICollection<T> collection) {
|
||||
if (collection is null) throw new ArgumentNullException("collection cannot be null");
|
||||
try {
|
||||
_logger.LogInformation("Attempting to perform a bulk update");
|
||||
public async Task<int> ExecuteAsync(string sql) {
|
||||
if (sql is null) throw new ArgumentNullException("sql cannot be null");
|
||||
|
||||
_dbConnection.Open();
|
||||
return await _dbConnection.UpdateAsync<ICollection<T>>(collection);
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred while attempting to perform a bulk update. Exception: {ex}",
|
||||
ex.Message);
|
||||
int remainingRetries = RETRIES;
|
||||
bool queryWasSuccessful = false;
|
||||
Exception exception = null;
|
||||
int rowsAffected = 0;
|
||||
while (!queryWasSuccessful && remainingRetries > 0) {
|
||||
int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL;
|
||||
Task.Delay(backoffSeconds * 1000).Wait();
|
||||
|
||||
throw;
|
||||
} finally {
|
||||
_dbConnection.Close();
|
||||
try {
|
||||
_logger.LogInformation("Attempting to execute {sql}. Remaining retries: {remainingRetries}",
|
||||
sql,
|
||||
remainingRetries);
|
||||
|
||||
using (_dbConnection) {
|
||||
rowsAffected = await _dbConnection.ExecuteAsync(sql);
|
||||
}
|
||||
|
||||
queryWasSuccessful = true;
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred while attempting to execute a query. Exception: {ex}",
|
||||
ex.Message);
|
||||
|
||||
exception = ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (!queryWasSuccessful && exception is not null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return rowsAffected;
|
||||
}
|
||||
}
|
||||
|
3
FabApprovalWorkerService/Services/IMonInWorkerClient.cs
Normal file
3
FabApprovalWorkerService/Services/IMonInWorkerClient.cs
Normal file
@ -0,0 +1,3 @@
|
||||
using FabApprovalWorkerService.Models;
|
||||
|
||||
namespace FabApprovalWorkerService.Services;
|
181
FabApprovalWorkerService/Services/MonInWorkerClient.cs
Normal file
181
FabApprovalWorkerService/Services/MonInWorkerClient.cs
Normal file
@ -0,0 +1,181 @@
|
||||
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<MonInWorkerClient> _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<MonInWorkerClient> 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 = _config["MonIn:workerUrl"];
|
||||
if (_baseUrl is null) throw new ArgumentNullException("MonIn:workerUrl not found in config");
|
||||
|
||||
Int32.TryParse(_config["MonIn:retries"], out _retryLimit);
|
||||
if (_retryLimit == -1) throw new ArgumentNullException("MonIn:retries not found in config");
|
||||
|
||||
Int32.TryParse(_config["MonIn:backoffInSeconds"], out _backoffInSeconds);
|
||||
if (_backoffInSeconds == -1) throw new ArgumentNullException("MonIn:backoffInSeconds not found in config");
|
||||
|
||||
_resource = _config["MonIn:resource"];
|
||||
if (_resource is null) throw new ArgumentNullException("MonIn:resource not found in config");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
using CsvHelper;
|
||||
|
||||
using FabApprovalWorkerService.Models;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace FabApprovalWorkerService.Services;
|
||||
|
||||
public interface ITrainingRecordService {
|
||||
IEnumerable<TrainingRecord> ScrapeRecordsFromCsvFile(CsvReader csvReader);
|
||||
ConcurrentDictionary<(string, string), TrainingRecord> SortAndFilterTrainingRecordsByCompletionDate(IEnumerable<TrainingRecord> trainingRecords);
|
||||
}
|
||||
public class TrainingRecordService {
|
||||
private readonly ILogger<TrainingRecordService> _logger;
|
||||
|
||||
public TrainingRecordService(ILogger<TrainingRecordService> logger) {
|
||||
_logger = logger;
|
||||
if (_logger is null) throw new ArgumentNullException("ILogger not injected");
|
||||
}
|
||||
|
||||
public IEnumerable<TrainingRecord> ScrapeTrainingRecordsFromCsvFile([DisallowNull] CsvReader csvReader) {
|
||||
if (csvReader is null) throw new ArgumentNullException("csvReader cannot be null");
|
||||
|
||||
try {
|
||||
_logger.LogInformation("Attempting to scrape training records from CSV file");
|
||||
|
||||
using (csvReader) {
|
||||
return csvReader.GetRecords<TrainingRecord>();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to scrape training records from CSV file. Exception: {ex}",
|
||||
ex.Message);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public ConcurrentDictionary<(string, string), TrainingRecord> SortAndFilterTrainingRecordsByCompletionDate([DisallowNull] IEnumerable<TrainingRecord> trainingRecords) {
|
||||
if (trainingRecords is null) throw new ArgumentNullException("trainingRecords cannot be null");
|
||||
|
||||
ConcurrentDictionary<(string, string), TrainingRecord> recordsMap = new();
|
||||
|
||||
try {
|
||||
_logger.LogInformation("Attempting to sort and filter training records");
|
||||
|
||||
IOrderedEnumerable<TrainingRecord> sortedRecords = trainingRecords.OrderByDescending(t => t.UserId)
|
||||
.ThenBy(t => t.ItemId)
|
||||
.ThenByDescending(t => t.CompletionDate);
|
||||
|
||||
foreach (TrainingRecord trainingRecord in sortedRecords) {
|
||||
if (!recordsMap.TryGetValue((trainingRecord.FirstName + trainingRecord.LastName, trainingRecord.ItemId), out TrainingRecord? existingRecord)) {
|
||||
recordsMap[(trainingRecord.FirstName + trainingRecord.LastName, trainingRecord.ItemId)] = trainingRecord;
|
||||
}
|
||||
}
|
||||
|
||||
return recordsMap;
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to sort and filter training records. Exception: {ex}", ex.Message);
|
||||
|
||||
return recordsMap;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,65 +1,224 @@
|
||||
using Dapper;
|
||||
using Dapper.Contrib.Extensions;
|
||||
using FabApprovalWorkerService.Models;
|
||||
|
||||
using FabApprovalWorkerService.Models;
|
||||
|
||||
using System.Data;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
|
||||
namespace FabApprovalWorkerService.Services;
|
||||
|
||||
public interface IUserService {
|
||||
Task<Dictionary<string, User>> GetAllUsers();
|
||||
Task<bool> UpdateUserCertificationData([DisallowNull] ICollection<User> users);
|
||||
Task<List<OOOTemp>> GetAllPendingOOOUsersAsync();
|
||||
Task<bool> IsUserAlreadyOOO(int userId);
|
||||
Task<bool> IsDelegatorAlreadyDelegatedTo(int userId);
|
||||
Task<bool> InsertDelegatedRoles(int userId);
|
||||
Task<bool> UpdateUserSubRoles(int userId, int delegatedUserId);
|
||||
Task<bool> DelegateApprovalsForUser(int userId, int delegatedUserId);
|
||||
Task<bool> FlagUserAsOOO(OOOTemp oooTemp);
|
||||
Task<bool> SetOOOTempProcessed(OOOTemp oOOTemp);
|
||||
Task<List<User>> GetAllActiveOOOUsersAsync();
|
||||
}
|
||||
|
||||
public class UserService : IUserService {
|
||||
private static readonly int PENDING_ITEM_STATUS = 0;
|
||||
private static readonly int DENITED_ITEM_STATUS = 2;
|
||||
|
||||
private readonly ILogger<UserService> _logger;
|
||||
private IDalService _dalService;
|
||||
private readonly IDalService _dalService;
|
||||
|
||||
public UserService(ILogger<UserService> logger, IDalService dalService) {
|
||||
_logger = logger;
|
||||
if (_logger is null)
|
||||
throw new ArgumentNullException("ILogger not injected");
|
||||
|
||||
_dalService = dalService;
|
||||
if (_dalService is null)
|
||||
throw new ArgumentNullException("IDalService not injected");
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, User>> GetAllUsers() {
|
||||
Dictionary<string, User> users = new Dictionary<string, User>();
|
||||
|
||||
public async Task<List<User>> GetAllActiveOOOUsersAsync() {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to get all users");
|
||||
_logger.LogInformation("Attempting to get all active OOO users.");
|
||||
|
||||
string sql = "select * from users;";
|
||||
string sql = "select * from Users where OOO = 1;";
|
||||
|
||||
IEnumerable<User> enumerableUsers = await _dalService.QueryAsync<User>(sql);
|
||||
users = enumerableUsers.ToDictionary(u => u.FirstName + u.LastName, u => u);
|
||||
|
||||
if (!users.Any()) {
|
||||
throw new Exception("No users returned from the database");
|
||||
} else {
|
||||
_logger.LogInformation("Successfully retrieved the users");
|
||||
}
|
||||
|
||||
return users;
|
||||
return (await _dalService.QueryAsync<User>(sql)).ToList();
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to get all users. Exception: {ex}", ex.Message);
|
||||
return users;
|
||||
_logger.LogError("An exception occurred when attempting to get all active OOO users. Exception: {0}",
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateUserCertificationData([DisallowNull] ICollection<User> users) {
|
||||
if (users is null) throw new ArgumentNullException("users cannot be null");
|
||||
|
||||
public async Task<List<OOOTemp>> GetAllPendingOOOUsersAsync() {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to update user cert data");
|
||||
_logger.LogInformation("Attempting to get all pending OOO users.");
|
||||
|
||||
bool result = await _dalService.UpdateAsync(users);
|
||||
string sql = string.Format("select * from OOOTemp where Processed = 0 and OOOStartDate <= '{0}';", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
_logger.LogInformation("User cert data updated successfully: {result}", result);
|
||||
|
||||
return result;
|
||||
return (await _dalService.QueryAsync<OOOTemp>(sql)).ToList();
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to update user cert data. Exception: {ex}", ex.Message);
|
||||
return false;
|
||||
_logger.LogError("An exception occurred when attempting to get all pending OOO users. Exception: {0}",
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> IsUserAlreadyOOO(int userId) {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to determine if user {userId} is already OOO", userId);
|
||||
|
||||
if (userId <= 0) {
|
||||
throw new ArgumentException(string.Format("User Id {0} is not a valid user Id", userId));
|
||||
} else {
|
||||
string sql = string.Format("select * from Users where OOO = 1 and UserID = {0}", userId);
|
||||
|
||||
return (await _dalService.QueryAsync<User>(sql)).Count() > 0;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to determine if user {userId} is already OOO. Exception: {ex}",
|
||||
userId,
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> IsDelegatorAlreadyDelegatedTo(int userId) {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to determine if user {userId} is already OOO.", userId);
|
||||
|
||||
if (userId <= 0) {
|
||||
_logger.LogInformation("DelegatedTo is {id}, which is not an active user Id", userId);
|
||||
return false;
|
||||
} else {
|
||||
string sql = string.Format("select * from Users where DelegatedTo = {0}", userId);
|
||||
|
||||
return (await _dalService.QueryAsync<User>(sql)).Count() > 0;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to determine if user {userId} is already delegated to. Exception: {ex}",
|
||||
userId,
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> InsertDelegatedRoles(int userId) {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to add delegated roles for OOO user {id}", userId);
|
||||
|
||||
if (userId <= 0) {
|
||||
throw new ArgumentException(string.Format("User Id {0} is not a valid user Id", userId));
|
||||
} else {
|
||||
StringBuilder queryBuilder = new StringBuilder();
|
||||
|
||||
string sql = string.Format("select * from UserSubRole where UserID = {0}", userId);
|
||||
|
||||
List<UserSubRole> userSubRoles = (await _dalService.QueryAsync<UserSubRole>(sql)).ToList();
|
||||
|
||||
foreach (UserSubRole role in userSubRoles) {
|
||||
queryBuilder.Clear();
|
||||
queryBuilder.Append("insert into OOODelegatedRoles (UserID, DelegatedSubRoleID, InsertTimeStamp, Active) ");
|
||||
queryBuilder.AppendFormat("values ({0}, {1}, '{2}', 1);", userId, role.SubRoleID, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
await _dalService.ExecuteAsync(queryBuilder.ToString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to add delegated roles for OOO user {userId}. Exception: {ex}",
|
||||
userId,
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateUserSubRoles(int userId, int delegatedUserId) {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to update sub roles for user {userId} to delegated user {delegatedUserId}",
|
||||
userId,
|
||||
delegatedUserId);
|
||||
if (userId <= 0) {
|
||||
throw new ArgumentException(string.Format("User Id {0} is not a valid user Id", userId));
|
||||
} else if (delegatedUserId <= 0) {
|
||||
throw new ArgumentException(string.Format("Delegated user Id {0} is not a valid user Id", delegatedUserId));
|
||||
} else {
|
||||
string sql = String.Format("update UserSubRole set UserID = {0}, Delegated = 1 where UserID = {1}", delegatedUserId, userId);
|
||||
|
||||
await _dalService.ExecuteAsync(sql);
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to update sub roles for user {userId} to delegated user {delegatedUserId}. Exception: {ex}",
|
||||
userId,
|
||||
delegatedUserId,
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DelegateApprovalsForUser(int userId, int delegatedUserId) {
|
||||
try {
|
||||
_logger.LogInformation("Attempting to delegate approvals for user {userId} to delegated user {delegatedUserId}",
|
||||
userId,
|
||||
delegatedUserId);
|
||||
if (userId <= 0) {
|
||||
throw new ArgumentException(string.Format("User Id {0} is not a valid user Id", userId));
|
||||
} else if (delegatedUserId <= 0) {
|
||||
throw new ArgumentException(string.Format("Delegated user Id {0} is not a valid user Id", delegatedUserId));
|
||||
} else {
|
||||
string sql = String.Format("update Approval set UserID = {0}, Delegated = 1 where UserID = {1} and (ItemStatus = {2} or ItemStatus = {3})",
|
||||
delegatedUserId,
|
||||
userId,
|
||||
PENDING_ITEM_STATUS,
|
||||
DENITED_ITEM_STATUS);
|
||||
|
||||
await _dalService.ExecuteAsync(sql);
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to delegate approvals for user {userId} to delegated user {delegatedUserId}. Exception: {ex}",
|
||||
userId,
|
||||
delegatedUserId,
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> FlagUserAsOOO(OOOTemp oooTemp) {
|
||||
try {
|
||||
if (oooTemp is null) throw new ArgumentNullException("oooTemp cannot be null");
|
||||
|
||||
_logger.LogInformation("Attempting to flag user {id} as OOO", oooTemp.OOOUserID);
|
||||
|
||||
StringBuilder queryBuilder = new StringBuilder();
|
||||
queryBuilder.Append("update Users set OOO = 1, ");
|
||||
queryBuilder.AppendFormat("OOOStartDate = '{0}', ", oooTemp.OOOStartDate);
|
||||
queryBuilder.AppendFormat("OOOExpirationDate = '{0}', ", oooTemp.OOOExpirationDate);
|
||||
queryBuilder.AppendFormat("DelegatedTo = {0} ", oooTemp.DelegatedTo);
|
||||
queryBuilder.AppendFormat("where UserID = {0}", oooTemp.OOOUserID);
|
||||
|
||||
return (await _dalService.ExecuteAsync(queryBuilder.ToString())) > 0;
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to flag user as OOO. Exception: {ex}",
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> SetOOOTempProcessed(OOOTemp oooTemp) {
|
||||
try {
|
||||
if (oooTemp is null) throw new ArgumentNullException("oooTemp cannot be null");
|
||||
|
||||
_logger.LogInformation("Attempting to set OOOTemp {id} Processed to {processed}", oooTemp.ID, oooTemp.Processed);
|
||||
|
||||
string sql = string.Format("update OOOTemp set Processed = {0} where ID = {1}", oooTemp.Processed, oooTemp.ID);
|
||||
|
||||
return (await _dalService.ExecuteAsync(sql)) > 0;
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to flag user as OOO. Exception: {ex}",
|
||||
ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
drop table if exists Approval;
|
||||
|
||||
create table Approval (
|
||||
ApprovalID integer primary key,
|
||||
IssueID integer not null,
|
||||
UserID integer not null,
|
||||
ItemStatus integer default 0,
|
||||
Delegated integer default 0
|
||||
);
|
||||
|
||||
insert into Approval (IssueID, UserID)
|
||||
values (1, 15),
|
||||
(2, 34),
|
||||
(3, 2),
|
||||
(4, 19);
|
@ -0,0 +1,9 @@
|
||||
drop table if exists OOODelegatedRoles;
|
||||
|
||||
create table OOODelegatedRoles (
|
||||
OOOID integer primary key,
|
||||
UserID integer not null,
|
||||
DelegatedSubRoleID integer not null,
|
||||
InsertTimeStamp text not null,
|
||||
Active integer default 0
|
||||
);
|
16
FabApprovalWorkerService/SetupScripts/CreateOOOTempTable.sql
Normal file
16
FabApprovalWorkerService/SetupScripts/CreateOOOTempTable.sql
Normal file
@ -0,0 +1,16 @@
|
||||
drop table if exists OOOTemp;
|
||||
|
||||
create table OOOTemp (
|
||||
ID INTEGER primary key,
|
||||
OOOUserID INTEGER not null,
|
||||
DelegatedTo INTEGER not null,
|
||||
OOOStartDate TEXT not null,
|
||||
OOOExpirationDate TEXT not null,
|
||||
Processed INTEGER default 0
|
||||
);
|
||||
|
||||
insert into OOOTemp (OOOUserID, DelegatedTo, OOOStartDate, OOOExpirationDate)
|
||||
values (15, 22, '2024-03-19 00:00:00', '2024-04-19 00:00:00'),
|
||||
(34, 19, '2024-03-19 00:00:00', '2024-04-19 00:00:00'),
|
||||
(2, 15, '2024-03-19 00:00:00', '2024-04-01 00:00:00'),
|
||||
(19, 18, '2024-04-01 00:00:00', '2033-06-01 00:00:00');
|
@ -0,0 +1,14 @@
|
||||
drop table if exists UserSubRole;
|
||||
|
||||
create table UserSubRole (
|
||||
UserSubRoleID integer primary key,
|
||||
UserID integer not null,
|
||||
SubRoleID integer not null,
|
||||
Delegated integer default 0
|
||||
);
|
||||
|
||||
insert into UserSubRole (UserID, SubRoleID)
|
||||
values (15, 1),
|
||||
(34, 19),
|
||||
(2, 5),
|
||||
(19, 3);
|
73
FabApprovalWorkerService/SetupScripts/CreateUserTable.sql
Normal file
73
FabApprovalWorkerService/SetupScripts/CreateUserTable.sql
Normal file
@ -0,0 +1,73 @@
|
||||
drop table if exists Users;
|
||||
|
||||
create table Users (
|
||||
UserID INTEGER primary key,
|
||||
LoginID TEXT not null,
|
||||
FirstName TEXT not null,
|
||||
LastName TEXT not null,
|
||||
Email TEXT not null,
|
||||
Notify INTEGER default 0,
|
||||
IsAdmin INTEGER default 0,
|
||||
OOO INTEGER default 0,
|
||||
OOOStartDate TEXT,
|
||||
OOOExpirationDate TEXT,
|
||||
DelegatedTo INTEGER,
|
||||
CanViewITAR INTEGER default 1,
|
||||
IsManager INTEGER default 0,
|
||||
IsCleansCertified INTEGER default 0,
|
||||
IsAnyLevelCertified INTEGER default 0,
|
||||
IsPackagingLabelingCertified INTEGER default 0,
|
||||
IsEpiProCertified INTEGER default 0,
|
||||
IsFqaCertified INTEGER default 0,
|
||||
IsFqaAssessmentCertified INTEGER default 0,
|
||||
IsActive INTEGER default 1
|
||||
);
|
||||
|
||||
insert into Users (LoginID, FirstName, LastName, Email)
|
||||
values ('AsRa', 'Ra', 'As', 'email'),
|
||||
('AuTr', 'Tr', 'Au', 'email'),
|
||||
('AyNi', 'Ni', 'Ay', 'email'),
|
||||
('BaGr', 'Gr', 'Ba', 'email'),
|
||||
('BaGu', 'Gu', 'Ba', 'email'),
|
||||
('BeTo', 'To', 'Be', 'email'),
|
||||
('BeBr', 'Br', 'Be', 'email'),
|
||||
('BrKy', 'Ky', 'Br', 'email'),
|
||||
('CaSh', 'Sh', 'Ca', 'email'),
|
||||
('CaRe', 'Re', 'Ca', 'email'),
|
||||
('CaSt', 'St', 'Ca', 'email'),
|
||||
('ClNi', 'Ni', 'Cl', 'email'),
|
||||
('DaMi', 'Mi', 'Da', 'email'),
|
||||
('FuJe', 'Je', 'Fu', 'email'),
|
||||
('GaAl', 'Al', 'Ga', 'email'),
|
||||
('GoAs', 'As', 'Go', 'email'),
|
||||
('GoRu', 'Ru', 'Go', 'email'),
|
||||
('GoOr', 'Or', 'Go', 'email'),
|
||||
('HaAn', 'An', 'Ha', 'email'),
|
||||
('HaPa', 'Pa', 'Ha', 'email'),
|
||||
('HoJu', 'Ju', 'Ho', 'email'),
|
||||
('HoDe', 'De', 'Ho', 'email'),
|
||||
('HoVi', 'Vi', 'Ho', 'email'),
|
||||
('InCa', 'Ca', 'In', 'email'),
|
||||
('JaMi', 'Mi', 'Ja', 'email'),
|
||||
('LeTh', 'Th', 'Le', 'email'),
|
||||
('LeHa', 'Ha', 'Le', 'email'),
|
||||
('LoAn', 'An', 'Lo', 'email'),
|
||||
('LoCh', 'Ch', 'Lo', 'email'),
|
||||
('LuDa', 'Da', 'Lu', 'email'),
|
||||
('MaBr', 'Br', 'Ma', 'email'),
|
||||
('MaDa', 'Da', 'Ma', 'email'),
|
||||
('MaDo', 'Do', 'Ma', 'email'),
|
||||
('McJu', 'Ju', 'Mc', 'email'),
|
||||
('MeGi', 'Gi', 'Me', 'email'),
|
||||
('MiSh', 'Sh', 'Mi', 'email'),
|
||||
('MoBa', 'Ba', 'Mo', 'email'),
|
||||
('MuTi', 'Ti', 'Mu', 'email'),
|
||||
('OtMa', 'Ma', 'Ot', 'email'),
|
||||
('PeAl', 'Al', 'Pe', 'email'),
|
||||
('RiCy', 'Cy', 'Ri', 'email'),
|
||||
('RoAp', 'Ap', 'Ro', 'email'),
|
||||
('SoAb', 'Ab', 'So', 'email'),
|
||||
('VaMi', 'Mi', 'Va', 'email'),
|
||||
('VuTh', 'Th', 'Va', 'email'),
|
||||
('WeWi', 'Wi', 'We', 'email'),
|
||||
('ZaNi', 'Ni', 'Za', 'email');
|
7
FabApprovalWorkerService/SetupScripts/SetupDb.bat
Normal file
7
FabApprovalWorkerService/SetupScripts/SetupDb.bat
Normal file
@ -0,0 +1,7 @@
|
||||
md D:\FabApprovalWorkerService
|
||||
sqlite3 D:\FabApprovalWorkerService\LocalDb.db < .\CreateUserTable.sql
|
||||
sqlite3 D:\FabApprovalWorkerService\LocalDb.db < .\CreateOOOTempTable.sql
|
||||
sqlite3 D:\FabApprovalWorkerService\LocalDb.db < .\CreateUserSubRoleTable.sql
|
||||
sqlite3 D:\FabApprovalWorkerService\LocalDb.db < .\CreateOOODelegatedRolesTable.sql
|
||||
sqlite3 D:\FabApprovalWorkerService\LocalDb.db < .\CreateApprovalTable.sql
|
||||
pause
|
81
FabApprovalWorkerService/Workers/PendingOOOStatusWorker.cs
Normal file
81
FabApprovalWorkerService/Workers/PendingOOOStatusWorker.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using FabApprovalWorkerService.Models;
|
||||
using FabApprovalWorkerService.Services;
|
||||
|
||||
using Quartz;
|
||||
|
||||
using System.Text;
|
||||
|
||||
namespace FabApprovalWorkerService.Workers;
|
||||
|
||||
public sealed class PendingOOOStatusWorker : IJob {
|
||||
private readonly ILogger<PendingOOOStatusWorker> _logger;
|
||||
private readonly IMonInWorkerClient _monInClient;
|
||||
private readonly IUserService _userService;
|
||||
|
||||
public PendingOOOStatusWorker(ILogger<PendingOOOStatusWorker> logger,
|
||||
IMonInWorkerClient monInClient,
|
||||
IUserService userService) {
|
||||
_logger = logger;
|
||||
if (_logger is null)
|
||||
throw new ArgumentNullException("ILogger not injected");
|
||||
|
||||
_monInClient = monInClient;
|
||||
if (_monInClient is null) {
|
||||
throw new ArgumentNullException("IMonInWorkerClient not injected");
|
||||
}
|
||||
|
||||
_userService = userService;
|
||||
if (_userService is null)
|
||||
throw new ArgumentNullException("IUserService not injected");
|
||||
}
|
||||
|
||||
public async Task Execute(IJobExecutionContext context) {
|
||||
DateTime start = DateTime.Now;
|
||||
bool isInternalError = false;
|
||||
StringBuilder errorMessage = new();
|
||||
string metricName = "PendingOOOStatusWorker";
|
||||
|
||||
try {
|
||||
_logger.LogInformation("Attempting to set OOO status for users pending earlier than now");
|
||||
|
||||
List<OOOTemp> pendingOOOUsers = await _userService.GetAllPendingOOOUsersAsync();
|
||||
|
||||
foreach (OOOTemp oooTemp in pendingOOOUsers) {
|
||||
Task<bool> userAlreadyOOO = _userService.IsUserAlreadyOOO(oooTemp.OOOUserID);
|
||||
Task<bool> delegateAlreadyADelegate = _userService.IsDelegatorAlreadyDelegatedTo(oooTemp.DelegatedTo);
|
||||
|
||||
if (!userAlreadyOOO.Result && !delegateAlreadyADelegate.Result) {
|
||||
List<Task> enableOOOTasks = new();
|
||||
enableOOOTasks.Add(_userService.InsertDelegatedRoles(oooTemp.OOOUserID));
|
||||
enableOOOTasks.Add(_userService.UpdateUserSubRoles(oooTemp.OOOUserID, oooTemp.DelegatedTo));
|
||||
enableOOOTasks.Add(_userService.DelegateApprovalsForUser(oooTemp.OOOUserID, oooTemp.DelegatedTo));
|
||||
Task enableOOOTasksResult = Task.WhenAll(enableOOOTasks);
|
||||
|
||||
if (enableOOOTasksResult.IsCompletedSuccessfully) {
|
||||
bool userIsNowOOO = await _userService.FlagUserAsOOO(oooTemp);
|
||||
if (userIsNowOOO) {
|
||||
oooTemp.Processed = true;
|
||||
await _userService.SetOOOTempProcessed(oooTemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("Successfully set OOO status for users pending earlier than now");
|
||||
} catch (Exception ex) {
|
||||
_logger.LogError("An exception occurred when attempting to set OOO status for users pending earlier than now. Exception: {ex}",
|
||||
ex.StackTrace);
|
||||
isInternalError = true;
|
||||
} finally {
|
||||
DateTime end = DateTime.Now;
|
||||
double latencyInMS = (end - start).TotalMilliseconds;
|
||||
_monInClient.PostAverage(metricName + "Latency", latencyInMS);
|
||||
|
||||
if (isInternalError) {
|
||||
_monInClient.PostStatus(metricName, StatusValue.Critical);
|
||||
} else {
|
||||
_monInClient.PostStatus(metricName, StatusValue.Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
namespace FabApprovalWorkerService.Workers;
|
||||
|
||||
public class UserCertificationUpdateWorker : BackgroundService {
|
||||
private readonly ILogger<UserCertificationUpdateWorker> _logger;
|
||||
|
||||
public UserCertificationUpdateWorker(ILogger<UserCertificationUpdateWorker> logger) {
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
|
||||
while (!stoppingToken.IsCancellationRequested) {
|
||||
if (_logger.IsEnabled(LogLevel.Information)) {
|
||||
_logger.LogInformation("UserCertificationUpdateWorker running at: {time}", DateTimeOffset.Now);
|
||||
}
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,10 @@
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Default": "Data Source=MESTSV02EC.infineon.com\\TEST1,50572;Integrated Security=False;Initial Catalog=FabApprovalSystem;User ID=fab_approval_admin_test;Password=Fab_approval_admin_test2023!;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False; Min Pool Size=15"
|
||||
"Default": "Data Source=D:\\FabApprovalWorkerService\\LocalDb.db"
|
||||
},
|
||||
"MonIn": {
|
||||
"resource": "FAB_APPROVAL_WORKER_SERVICE_MES_OP_FE_TEST",
|
||||
"workerUrl": "https://mestsa008.infineon.com:7851/"
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,14 @@
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"Default": "Data Source=MESTSV02EC.infineon.com\\TEST1,50572;Integrated Security=False;Initial Catalog=FabApprovalSystem;User ID=fab_approval_admin_test;Password=Fab_approval_admin_test2023!;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False; Min Pool Size=15"
|
||||
},
|
||||
"MonIn": {
|
||||
"resource": "FAB_APPROVAL_WORKER_SERVICE_MES_OP_FE",
|
||||
"workerUrl": "https://messa014.infineon.com:7851/",
|
||||
"retries": 3,
|
||||
"backoffInSeconds": 30
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
xsi:type="File"
|
||||
fileName="d:\logs\FabApprovalWorkerService\log.txt"
|
||||
archiveFilename="d:\logs\FabApprovalWorkerService\archive\log-${shortdate}.txt"
|
||||
maxArchiveFiles="15"
|
||||
maxArchiveFiles="30"
|
||||
archiveEvery="Day"
|
||||
/>
|
||||
<target
|
||||
|
Reference in New Issue
Block a user