diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs index dfc805c06..c3e7cdd3e 100644 --- a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandlerTests.cs @@ -202,7 +202,7 @@ public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuc Assert.IsType(result); // Verifying that the logger was called for the "Success sending conversion" case - _mockLogger.Verify(x => x.Log(LogLevel.Information, + _mockLogger.Verify(x => x.Log(LogLevel.Error, // We're checking for an Information log It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending conversion project to complete with project urn")), // Check if the message contains the expected string diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs index d2baa4b71..c038ca22a 100644 --- a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandlerTests.cs @@ -204,7 +204,7 @@ public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuc Assert.IsType(result); // Verifying that the logger was called for the "Success sending conversion" case - _mockLogger.Verify(x => x.Log(LogLevel.Information, + _mockLogger.Verify(x => x.Log(LogLevel.Error, // We're checking for an Information log It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending conversion project to complete with project urn")), // Check if the message contains the expected string diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs index b74bf5b2f..bf585a9c2 100644 --- a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandlerTests.cs @@ -265,7 +265,7 @@ public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuc Assert.IsType(result); // Verifying that the logger was called for the "Success sending conversion" case - _mockLogger.Verify(x => x.Log(LogLevel.Information, + _mockLogger.Verify(x => x.Log(LogLevel.Error, // We're checking for an Information log It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending transfer project to complete with project urn")), // Check if the message contains the expected string diff --git a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs index 820ee0004..018f69239 100644 --- a/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs +++ b/Dfe.Academies.Academisation.Service.UnitTest/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandlerTests.cs @@ -261,7 +261,7 @@ public async Task Handle_ConversionProjectsExist_ErrorResponse_ReturnsCommandSuc Assert.IsType(result); // Verifying that the logger was called for the "Success sending conversion" case - _mockLogger.Verify(x => x.Log(LogLevel.Information, + _mockLogger.Verify(x => x.Log(LogLevel.Error, // We're checking for an Information log It.IsAny(), It.Is((v, t) => v.ToString().Contains("Error sending transfer project to complete with project urn")), // Check if the message contains the expected string diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs index 3a8827f9b..dfdd447e4 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteConversionProjectsCommandHandler.cs @@ -92,7 +92,7 @@ public async Task Handle(CreateCompleteConversionProjectsCommand { var errorResponse = await response.Content.ReadFromJsonAsync(); responseMessage = errorResponse.GetAllErrors(); - _logger.LogInformation("Error sending conversion project to complete with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); + _logger.LogError("Error sending conversion project to complete with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); } conversionProject.SetProjectSentToComplete(); diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs index 31c2c2659..69b183e92 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatConversionProjectsCommandHandler.cs @@ -95,7 +95,7 @@ public async Task Handle(CreateCompleteFormAMatConversionProjects { var errorResponse = await response.Content.ReadFromJsonAsync(); responseMessage = errorResponse.GetAllErrors(); - _logger.LogInformation("Error sending conversion project to complete with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); + _logger.LogError("Error sending conversion project to complete with project urn: {project} due to Status code {code} and Complete Validation Errors:" + responseMessage, completeObject.urn, response.StatusCode); } conversionProject.SetProjectSentToComplete(); diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs index b6bcd19c2..556b84d9f 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteFormAMatTransferProjectsCommandHandler.cs @@ -108,7 +108,7 @@ public async Task Handle(CreateCompleteFormAMatTransferProjectsCo var errorResponse = await response.Content.ReadFromJsonAsync(); responseMessage = errorResponse.GetAllErrors(); - _logger.LogInformation("Error sending transfer project to complete with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); + _logger.LogError("Error sending transfer project to complete with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); } transferProject.SetProjectSentToComplete(transferringAcademy.Ukprn); diff --git a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs index 135b8c87d..bf5f6ef09 100644 --- a/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs +++ b/Dfe.Academies.Academisation.Service/Commands/CompleteProject/CreateCompleteTransferProjectsCommandHandler.cs @@ -116,7 +116,7 @@ public async Task Handle(CreateCompleteTransferProjectsCommand re var errorResponse = await response.Content.ReadFromJsonAsync(); responseMessage = errorResponse.GetAllErrors(); - _logger.LogInformation("Error sending transfer project to complete with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); + _logger.LogError("Error sending transfer project to complete with project urn: {project} for transfering academy: {urn} due to Status code {code} and Complete Validation Errors:" + responseMessage, transferProject.Urn, establishment.Urn, response.StatusCode); } transferProject.SetProjectSentToComplete(transferringAcademy.Ukprn); diff --git a/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs b/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs index 361d610fc..7aeb709c6 100644 --- a/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs +++ b/Dfe.Academies.Academisation.WebApi/Services/CreateCompleteProjectsService.cs @@ -1,5 +1,5 @@ -using Dfe.Academies.Academisation.Service.Commands.CompleteProject; -using Dfe.Academies.Academisation.Service.Commands.FormAMat; +using System.Security.Cryptography; +using Dfe.Academies.Academisation.Service.Commands.CompleteProject; using Dfe.Academisation.CorrelationIdMiddleware; using MediatR; @@ -16,11 +16,16 @@ public CreateCompleteProjectsService(ILogger logg { _logger = logger; _factory = factory; - _delayInMilliseconds = config.GetValue("DatabasePollingDelay") ?? 10_000; + _delayInMilliseconds = config.GetValue("SendProjectsToCompletePollingDelay") ?? 60_000; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { + // delay start to prevent runtime colisions + var startDelayInSeconds = GetSecureRandomDelay(1, 60); + + await Task.Delay(startDelayInSeconds * 1000, stoppingToken); + while (!stoppingToken.IsCancellationRequested) { using (var scope = _factory.CreateScope()) @@ -45,24 +50,27 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) } catch (Exception ex) { - _logger.LogError("Error enriching conversions complete project", ex); + _logger.LogError("Error creating complete projects", ex); } - await Task.Delay(_delayInMilliseconds, stoppingToken); - - try - { - await mediator.Send(new CreateCompleteTransferProjectsCommand(), stoppingToken); - } - catch (Exception ex) - { - _logger.LogError("Error enriching transfers complete project", ex); - } - - await Task.Delay(_delayInMilliseconds, stoppingToken); + await Task.Delay(_delayInMilliseconds, stoppingToken); } } } } + + private int GetSecureRandomDelay(int minValue, int maxValue) + { + // Use RandomNumberGenerator to securely generate a random delay in the specified range + byte[] randomNumber = new byte[4]; + using (var rng = RandomNumberGenerator.Create()) + { + rng.GetBytes(randomNumber); + } + // Convert bytes to a positive integer + int randomValue = Math.Abs(BitConverter.ToInt32(randomNumber, 0)); + // Scale the random value to the specified range + return (randomValue % (maxValue - minValue + 1)) + minValue; + } } }