using FabApprovalWorkerService.Models; using FabApprovalWorkerService.Services; using Infineon.Monitoring.MonA; using Quartz; using System.Text; namespace FabApprovalWorkerService.Workers; public class CertificationTrainingGroupWorker : IJob { private static readonly int MAX_RETRIES = 3; private static readonly int BACKOFF_SECONDS = 30; private readonly ILogger _logger; private readonly ITrainingService _trainingService; private readonly IUserService _userService; private readonly IMonInClient _monInClient; private readonly string _siProductionGroupName; private readonly string _cleansTrainingGroupName; private readonly string _asmHtrTrainingGroupName; private readonly string _epiProTrainingGroupName; private readonly string _fqaTrainingGroupName; private readonly string _packagingAndLabelingTrainingGroupName; public CertificationTrainingGroupWorker(ILogger logger, ITrainingService trainingService, IUserService userService, IMonInClient monInClient) { _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _trainingService = trainingService ?? throw new ArgumentNullException("ITrainingService not injected"); _userService = userService ?? throw new ArgumentNullException("IUserService not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected"); _siProductionGroupName = Environment.GetEnvironmentVariable("SiProductionTrainingGroupName") ?? throw new ArgumentNullException("SiProductionTrainingGroupName environment variable not found"); _asmHtrTrainingGroupName = Environment.GetEnvironmentVariable("AsmHtrTrainingGroupName") ?? throw new ArgumentNullException("AsmHtrTrainingGroupName environment variable not found"); _cleansTrainingGroupName = Environment.GetEnvironmentVariable("CleansTrainingGroupName") ?? throw new ArgumentNullException("CleansTrainingGroupName environment variable not found"); _epiProTrainingGroupName = Environment.GetEnvironmentVariable("EpiProTrainingGroupName") ?? throw new ArgumentNullException("EpiProTrainingGroupName environment variable not found"); _fqaTrainingGroupName = Environment.GetEnvironmentVariable("FqaTrainingGroupName") ?? throw new ArgumentNullException("FqaTrainingGroupName environment variable not found"); _packagingAndLabelingTrainingGroupName = Environment.GetEnvironmentVariable("PackagingAndLabelingTrainingGroupName") ?? throw new ArgumentNullException("PackagingAndLabelingTrainingGroupName environment variable not found"); } public async Task Execute(IJobExecutionContext context) { DateTime start = DateTime.Now; bool isInternalError = false; string metricName = "CertificationTrainingGroupWorker"; try { int remainingRetries = MAX_RETRIES; bool isSuccessful = false; while (!isSuccessful && remainingRetries > 0) { await Task.Delay((MAX_RETRIES - remainingRetries--) * BACKOFF_SECONDS); _logger.LogInformation($"Attempting to update certification training group membership. Remaining retries: {remainingRetries}"); _logger.LogInformation("Deleting ASM/HTR training group members"); int asmHtrGroupId = await _trainingService.GetTrainingGroupIdByName(_asmHtrTrainingGroupName); await _trainingService.DeleteAllUsersFromTrainingGroup(asmHtrGroupId); _logger.LogInformation("Deleting EpiPro training group members"); int epiProGroupId = await _trainingService.GetTrainingGroupIdByName(_epiProTrainingGroupName); await _trainingService.DeleteAllUsersFromTrainingGroup(epiProGroupId); _logger.LogInformation("Deleting FQA training group members"); int fqaGroupId = await _trainingService.GetTrainingGroupIdByName(_fqaTrainingGroupName); await _trainingService.DeleteAllUsersFromTrainingGroup(fqaGroupId); _logger.LogInformation("Deleting Packaging & Labeling training group members"); int packagingAndLabelingGroupId = await _trainingService.GetTrainingGroupIdByName(_packagingAndLabelingTrainingGroupName); await _trainingService.DeleteAllUsersFromTrainingGroup(packagingAndLabelingGroupId); _logger.LogInformation("Deleting Cleans training group members"); int cleansGroupId = await _trainingService.GetTrainingGroupIdByName(_cleansTrainingGroupName); await _trainingService.DeleteAllUsersFromTrainingGroup(cleansGroupId); IEnumerable certRecords = await _trainingService.GetUserCertificationRecords(); if (certRecords is null || certRecords.Count() == 0) throw new ArgumentNullException("certRecords cannot be null or empty"); int siProductionTrainingGroupId = await _trainingService.GetTrainingGroupIdByName(_siProductionGroupName); List queryTasks = new(); foreach (UserCertificationRecord record in certRecords) { _logger.LogInformation($"Processing cert record {{{record}}}"); if (record is not null) { User? user; try { user = await _userService.GetUserByEmail(record.Email); } catch (Exception ex) { user = null; StringBuilder errMsgBuilder = new(); errMsgBuilder.Append($"An exception occurred when attempting to get user for email {record.Email}. "); errMsgBuilder.Append($"Exception: {ex.Message}"); } if (user is not null && user.IsActive) { bool userIsInSiProduction = await _trainingService.IsUserMemberOfTrainingGroup(user.UserID, siProductionTrainingGroupId); if (userIsInSiProduction) { if (record.IsEpiProCertified) queryTasks.Add(_trainingService.AddUserToTrainingGroup(epiProGroupId, user)); if (record.IsPackagingLabelingCertified) queryTasks.Add(_trainingService.AddUserToTrainingGroup(packagingAndLabelingGroupId, user)); if (record.IsCleansCertified) queryTasks.Add(_trainingService.AddUserToTrainingGroup(cleansGroupId, user)); if (record.IsFqaCertified) queryTasks.Add(_trainingService.AddUserToTrainingGroup(fqaGroupId, user)); if (record.IsAnyLevelCertified) queryTasks.Add(_trainingService.AddUserToTrainingGroup(asmHtrGroupId, user)); } } } } await Task.WhenAll(queryTasks); isSuccessful = true; } if (isSuccessful) { _logger.LogInformation("Successfully updated certification training group membership."); } else { throw new Exception("Unable to update certification training group membership."); } } catch (Exception ex) { StringBuilder errMsgBuilder = new(); errMsgBuilder.Append("An exception occurred when attempting to update certification training group membership. "); errMsgBuilder.Append($"Exception: {ex.Message}"); _logger.LogError(errMsgBuilder.ToString()); isInternalError = true; } finally { DateTime end = DateTime.Now; double latencyInMS = (end - start).TotalMilliseconds; _monInClient.PostMetric(metricName + "Latency", latencyInMS); if (isInternalError) { _monInClient.PostStatus(metricName, State.Critical); } else { _monInClient.PostStatus(metricName, State.Ok); } } } }