diff --git a/src/Shared/Shared/Wrappers/StatsPagedResponse.cs b/src/Shared/Shared/Wrappers/StatsPagedResponse.cs index 129f2824d..222ee5fda 100644 --- a/src/Shared/Shared/Wrappers/StatsPagedResponse.cs +++ b/src/Shared/Shared/Wrappers/StatsPagedResponse.cs @@ -20,6 +20,7 @@ public class StatsPagedResponse : PagedResponse public DateTime PeriodStart { get; set; } public DateTime PeriodEnd { get; set; } public long TotalExecutions { get; set; } + public long TotalSucceeded { get; set; } public long TotalFailures { get; set; } public long TotalInprogress { get; set; } public double AverageTotalExecutionSeconds { get; set; } diff --git a/src/WorkflowManager/Database/Interfaces/ITaskExecutionStatsRepository.cs b/src/WorkflowManager/Database/Interfaces/ITaskExecutionStatsRepository.cs index 344304726..94ed069bf 100644 --- a/src/WorkflowManager/Database/Interfaces/ITaskExecutionStatsRepository.cs +++ b/src/WorkflowManager/Database/Interfaces/ITaskExecutionStatsRepository.cs @@ -70,6 +70,14 @@ public interface ITaskExecutionStatsRepository /// The count of all records in range Task GetStatsStatusCountAsync(DateTime start, DateTime endTime, string status = "", string workflowId = "", string taskId = ""); + /// + /// Returns all stats in Succeeded status. + /// + /// start of the range. + /// end of the range. + /// All stats that succeeded + Task GetStatsStatusSucceededCountAsync(DateTime startTime, DateTime endTime, string workflowId = "", string taskId = ""); + /// /// Returns all stats in Failed or PartialFail status. /// diff --git a/src/WorkflowManager/Database/Repositories/TaskExecutionStatsRepository.cs b/src/WorkflowManager/Database/Repositories/TaskExecutionStatsRepository.cs index 4c6a2c32b..3bcce4957 100644 --- a/src/WorkflowManager/Database/Repositories/TaskExecutionStatsRepository.cs +++ b/src/WorkflowManager/Database/Repositories/TaskExecutionStatsRepository.cs @@ -220,6 +220,19 @@ public async Task GetStatsStatusCountAsync(DateTime start, DateTime endTim (statusNull || T.Status == status)); } + public async Task GetStatsStatusSucceededCountAsync(DateTime startTime, DateTime endTime, string workflowId = "", string taskId = "") + { + var workflowNull = string.IsNullOrWhiteSpace(workflowId); + var taskIdNull = string.IsNullOrWhiteSpace(taskId); + + return await _taskExecutionStatsCollection.CountDocumentsAsync(T => + T.StartedUTC >= startTime.ToUniversalTime() && + T.StartedUTC <= endTime.ToUniversalTime() && + (workflowNull || T.WorkflowId == workflowId) && + (taskIdNull || T.TaskId == taskId) && + T.Status == TaskExecutionStatus.Succeeded.ToString()); + } + public async Task GetStatsStatusFailedCountAsync(DateTime startTime, DateTime endTime, string workflowId = "", string taskId = "") { var workflowNull = string.IsNullOrWhiteSpace(workflowId); diff --git a/src/WorkflowManager/WorkflowManager/Controllers/TaskStatsController.cs b/src/WorkflowManager/WorkflowManager/Controllers/TaskStatsController.cs index c67d984d1..e82d31f42 100644 --- a/src/WorkflowManager/WorkflowManager/Controllers/TaskStatsController.cs +++ b/src/WorkflowManager/WorkflowManager/Controllers/TaskStatsController.cs @@ -87,6 +87,7 @@ public async Task GetOverviewAsync([FromQuery] DateTime startTime try { + var successes = _repository.GetStatsStatusSucceededCountAsync(startTime, endTime); var fails = _repository.GetStatsStatusFailedCountAsync(startTime, endTime); var running = _repository.GetStatsStatusCountAsync(startTime, endTime, TaskExecutionStatus.Accepted.ToString()); var rangeCount = _repository.GetStatsStatusCountAsync(startTime, endTime); @@ -98,6 +99,7 @@ public async Task GetOverviewAsync([FromQuery] DateTime startTime PeriodStart = startTime, PeriodEnd = endTime, TotalExecutions = (int)rangeCount.Result, + TotalSucceeded = (int)successes.Result, TotalFailures = (int)fails.Result, TotalInprogress = running.Result, AverageTotalExecutionSeconds = Math.Round(stats.Result.avgTotalExecution, 2), @@ -149,6 +151,7 @@ public async Task GetStatsAsync([FromQuery] TimeFilter filter, st try { var allStats = _repository.GetStatsAsync(filter.StartTime, filter.EndTime, pageSize, filter.PageNumber, workflowId ?? string.Empty, taskId ?? string.Empty); + var successes = _repository.GetStatsStatusSucceededCountAsync(filter.StartTime, filter.EndTime, workflowId ?? string.Empty, taskId ?? string.Empty); var fails = _repository.GetStatsStatusFailedCountAsync(filter.StartTime, filter.EndTime, workflowId ?? string.Empty, taskId ?? string.Empty); var rangeCount = _repository.GetStatsStatusCountAsync(filter.StartTime, filter.EndTime, string.Empty, workflowId ?? string.Empty, taskId ?? string.Empty); var stats = _repository.GetAverageStats(filter.StartTime, filter.EndTime, workflowId ?? string.Empty, taskId ?? string.Empty); @@ -168,6 +171,7 @@ public async Task GetStatsAsync([FromQuery] TimeFilter filter, st res.PeriodStart = filter.StartTime; res.PeriodEnd = filter.EndTime; res.TotalExecutions = rangeCount.Result; + res.TotalSucceeded = successes.Result; res.TotalFailures = fails.Result; res.TotalInprogress = running.Result; res.AverageTotalExecutionSeconds = Math.Round(stats.Result.avgTotalExecution, 2); diff --git a/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_Workflow_1_Task_2_.snap b/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_Workflow_1_Task_2_.snap index 2d1785ec3..5ed9bf381 100644 --- a/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_Workflow_1_Task_2_.snap +++ b/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_Workflow_1_Task_2_.snap @@ -17,6 +17,7 @@ "periodStart": "2023-01-01T00:00:00", "periodEnd": "2023-04-26T15:01:01.2301205+01:00", "totalExecutions": 1, + "totalSucceeded": 1, "totalFailures": 0, "totalInprogress": 1, "averageTotalExecutionSeconds": 30.0, diff --git a/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_workflow_1_task_1_.snap b/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_workflow_1_task_1_.snap index 486a51fc8..9a8c20021 100644 --- a/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_workflow_1_task_1_.snap +++ b/tests/IntegrationTests/TaskManager.IntegrationTests/Features/__snapshots__/ExecutionStatsFeature.ExecutionStatsForATaskAreReturned_workflow_1_task_1_.snap @@ -17,6 +17,7 @@ "periodStart": "2023-01-01T00:00:00", "periodEnd": "2023-04-26T15:01:01.0902241+01:00", "totalExecutions": 5, + "totalSucceeded": 3, "totalFailures": 1, "totalInprogress": 1, "averageTotalExecutionSeconds": 30.0, diff --git a/tests/UnitTests/WorkflowManager.Tests/Controllers/TaskExecutionStatsControllerTests.cs b/tests/UnitTests/WorkflowManager.Tests/Controllers/TaskExecutionStatsControllerTests.cs index 09a8a3c03..424994737 100644 --- a/tests/UnitTests/WorkflowManager.Tests/Controllers/TaskExecutionStatsControllerTests.cs +++ b/tests/UnitTests/WorkflowManager.Tests/Controllers/TaskExecutionStatsControllerTests.cs @@ -93,7 +93,7 @@ public async Task GetListAsync_PayloadsExist_ReturnsList() [Fact] public async Task GetStatsOverviewAsync_ServiceException_ReturnProblem() { - _repo.Setup(w => w.GetStatsStatusFailedCountAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ThrowsAsync(new Exception()); + _repo.Setup(w => w.GetStatsStatusSucceededCountAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).ThrowsAsync(new Exception()); var result = await StatsController.GetOverviewAsync(It.IsAny(), It.IsAny()); @@ -138,6 +138,22 @@ public async Task GetStatsAsync_Pass_All_Arguments_To_GetStatsAsync_In_Repo() ); } + [Fact] + public async Task GetStatsAsync_Pass_All_Arguments_To_GetStatsStatusSucceededCountAsync_in_Repo() + { + var startTime = new DateTime(2023, 4, 4); + var endTime = new DateTime(2023, 4, 5); + + var result = await StatsController.GetStatsAsync(new TimeFilter { StartTime = startTime, EndTime = endTime }, "workflow", "task"); + + _repo.Verify(v => v.GetStatsStatusSucceededCountAsync( + It.Is(d => d.Equals(startTime)), + It.Is(d => d.Equals(endTime)), + It.Is(s => s.Equals("workflow")), + It.Is(s => s.Equals("task")))); + } + + [Fact] public async Task GetStatsAsync_Pass_All_Arguments_To_GetStatsStatusFailedCountAsync_in_Repo() { @@ -200,6 +216,21 @@ public async Task GetOverviewAsync_Pass_All_Arguments_To_GetStatsCountAsync_in_R It.Is(s => s.Equals("")))); } + [Fact] + public async Task GetOverviewAsync_Pass_All_Arguments_To_GetStatsStatusSucceededCountAsync_in_Repo() + { + var startTime = new DateTime(2023, 4, 4); + var endTime = new DateTime(2023, 4, 5); + + var result = await StatsController.GetOverviewAsync(startTime, endTime); + + _repo.Verify(v => v.GetStatsStatusSucceededCountAsync( + It.Is(d => d.Equals(startTime)), + It.Is(d => d.Equals(endTime)), + It.Is(s => s.Equals("")), + It.Is(s => s.Equals("")))); + } + [Fact] public async Task GetOverviewAsync_Pass_All_Arguments_To_GetStatsStatusFailedCountAsync_in_Repo() {