diff --git a/parodos-model-api/src/main/java/com/redhat/parodos/workflow/enums/ParodosWorkStatus.java b/parodos-model-api/src/main/java/com/redhat/parodos/workflow/enums/ParodosWorkStatus.java index 4820c8c2d..234548b1f 100644 --- a/parodos-model-api/src/main/java/com/redhat/parodos/workflow/enums/ParodosWorkStatus.java +++ b/parodos-model-api/src/main/java/com/redhat/parodos/workflow/enums/ParodosWorkStatus.java @@ -24,6 +24,6 @@ */ public enum ParodosWorkStatus { - FAILED, COMPLETED, PENDING, IN_PROGRESS + FAILED, COMPLETED, PENDING, IN_PROGRESS, REJECTED } diff --git a/workflow-service-sdk/api/openapi.yaml b/workflow-service-sdk/api/openapi.yaml index d58164789..42655a1b8 100644 --- a/workflow-service-sdk/api/openapi.yaml +++ b/workflow-service-sdk/api/openapi.yaml @@ -766,6 +766,7 @@ components: - COMPLETED - PENDING - IN_PROGRESS + - REJECTED type: string type: enum: diff --git a/workflow-service-sdk/docs/WorkStatusResponseDTO.md b/workflow-service-sdk/docs/WorkStatusResponseDTO.md index 78d10ba73..15735966c 100644 --- a/workflow-service-sdk/docs/WorkStatusResponseDTO.md +++ b/workflow-service-sdk/docs/WorkStatusResponseDTO.md @@ -21,6 +21,7 @@ FAILED | "FAILED" COMPLETED | "COMPLETED" PENDING | "PENDING" IN_PROGRESS | "IN_PROGRESS" +REJECTED | "REJECTED" diff --git a/workflow-service-sdk/src/main/java/com/redhat/parodos/sdk/model/WorkStatusResponseDTO.java b/workflow-service-sdk/src/main/java/com/redhat/parodos/sdk/model/WorkStatusResponseDTO.java index cbf8a4f28..5a4ed5ce6 100644 --- a/workflow-service-sdk/src/main/java/com/redhat/parodos/sdk/model/WorkStatusResponseDTO.java +++ b/workflow-service-sdk/src/main/java/com/redhat/parodos/sdk/model/WorkStatusResponseDTO.java @@ -49,7 +49,9 @@ public enum StatusEnum { PENDING("PENDING"), - IN_PROGRESS("IN_PROGRESS"); + IN_PROGRESS("IN_PROGRESS"), + + REJECTED("REJECTED"); private String value; diff --git a/workflow-service/generated/openapi/openapi.json b/workflow-service/generated/openapi/openapi.json index 0c0a1b07e..104a49522 100644 --- a/workflow-service/generated/openapi/openapi.json +++ b/workflow-service/generated/openapi/openapi.json @@ -622,7 +622,7 @@ }, "status" : { "type" : "string", - "enum" : [ "FAILED", "COMPLETED", "PENDING", "IN_PROGRESS" ] + "enum" : [ "FAILED", "COMPLETED", "PENDING", "IN_PROGRESS", "REJECTED" ] }, "type" : { "type" : "string", diff --git a/workflow-service/src/main/java/com/redhat/parodos/workflow/definition/service/WorkFlowDefinitionServiceImpl.java b/workflow-service/src/main/java/com/redhat/parodos/workflow/definition/service/WorkFlowDefinitionServiceImpl.java index c2653f4ab..edb9fb7f5 100644 --- a/workflow-service/src/main/java/com/redhat/parodos/workflow/definition/service/WorkFlowDefinitionServiceImpl.java +++ b/workflow-service/src/main/java/com/redhat/parodos/workflow/definition/service/WorkFlowDefinitionServiceImpl.java @@ -247,6 +247,7 @@ private void getWorksFromWorkDefinition(List workFlowWor return; } responseDTOs.add(WorkDefinitionResponseDTO.fromWorkFlowTaskDefinition(wdt.get())); + break; case WORKFLOW: Optional wd = workFlowDefinitionRepository .findById(workFlowWorkDefinition.getWorkDefinitionId()); @@ -260,6 +261,7 @@ private void getWorksFromWorkDefinition(List workFlowWor responseDTOs.add(WorkDefinitionResponseDTO.fromWorkFlowDefinitionEntity(wd.get(), wdWorkFlowWorkDependencies)); + break; default: return; } diff --git a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegate.java b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegate.java index 4c7033d4e..1a96cf576 100644 --- a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegate.java +++ b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegate.java @@ -29,7 +29,6 @@ import com.redhat.parodos.workflow.execution.entity.WorkFlowTaskExecution; import com.redhat.parodos.workflow.execution.repository.WorkFlowRepository; import com.redhat.parodos.workflow.execution.repository.WorkFlowTaskRepository; -import com.redhat.parodos.workflow.task.enums.WorkFlowTaskStatus; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -148,12 +147,18 @@ private WorkStatusResponseDTO getWorkStatusResponseDTOFromWorkFlow(WorkFlowWorkD WorkFlowExecution workExecution = workFlowRepository.findFirstByMainWorkFlowExecutionAndWorkFlowDefinitionId( workFlowExecution, workFlowWorkDefinition.getWorkDefinitionId()); + /* * the workflow execution might be null when there is pending checker before it */ - ParodosWorkStatus workStatus = workExecution == null - || WorkFlowStatus.IN_PROGRESS.equals(workExecution.getStatus()) ? ParodosWorkStatus.PENDING - : ParodosWorkStatus.valueOf(workExecution.getStatus().name()); + ParodosWorkStatus workStatus; + + if (workExecution == null) { + workStatus = ParodosWorkStatus.PENDING; + } + else { + workStatus = ParodosWorkStatus.valueOf(workExecution.getStatus().name()); + } return WorkStatusResponseDTO.builder().name(workFlowDefinition.getName()).type(WorkType.WORKFLOW) .status(workStatus).works(new ArrayList<>()).workExecution(workExecution) @@ -175,9 +180,19 @@ private WorkStatusResponseDTO getWorkStatusResponseDTOFromWorkFlowTask( ParodosWorkStatus workStatus = ParodosWorkStatus.PENDING; if (workFlowTaskExecutionOptional.isPresent()) { - workStatus = WorkFlowTaskStatus.IN_PROGRESS.equals(workFlowTaskExecutionOptional.get().getStatus()) - ? ParodosWorkStatus.PENDING - : ParodosWorkStatus.valueOf(workFlowTaskExecutionOptional.get().getStatus().name()); + workStatus = ParodosWorkStatus.valueOf(workFlowTaskExecutionOptional.get().getStatus().name()); + if (workFlowTaskDefinition.getWorkFlowCheckerMappingDefinition() != null) { + workStatus = Optional + .ofNullable(workFlowRepository.findFirstByMainWorkFlowExecutionAndWorkFlowDefinitionId( + workFlowExecution.getMainWorkFlowExecution(), + workFlowTaskDefinition + .getWorkFlowCheckerMappingDefinition().getCheckWorkFlow().getId())) + .map(WorkFlowExecution::getStatus) + .map(checkerStatus -> WorkFlowStatus.FAILED.equals(checkerStatus) + ? ParodosWorkStatus.IN_PROGRESS : ParodosWorkStatus.valueOf(checkerStatus.name())) + .orElse(ParodosWorkStatus.COMPLETED.equals(workStatus) ? ParodosWorkStatus.IN_PROGRESS + : workStatus); + } } return WorkStatusResponseDTO.builder().name(workFlowTaskDefinition.getName()).type(WorkType.TASK) diff --git a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegateTest.java b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegateTest.java index 222dec0dc..55eadf93a 100644 --- a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegateTest.java +++ b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceDelegateTest.java @@ -1,5 +1,6 @@ package com.redhat.parodos.workflow.execution.service; +import com.redhat.parodos.workflow.definition.entity.WorkFlowCheckerMappingDefinition; import com.redhat.parodos.workflow.definition.entity.WorkFlowDefinition; import com.redhat.parodos.workflow.definition.entity.WorkFlowTaskDefinition; import com.redhat.parodos.workflow.definition.entity.WorkFlowWorkDefinition; @@ -16,9 +17,12 @@ import com.redhat.parodos.workflow.execution.repository.WorkFlowTaskRepository; import com.redhat.parodos.workflow.task.enums.WorkFlowTaskStatus; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -175,14 +179,14 @@ void testGetWorkFlowWorksStatus() { // sub workflow 1 assertEquals(workStatusResponseDTOs.get(0).getType(), WorkType.WORKFLOW); assertEquals(workStatusResponseDTOs.get(0).getName(), testSubWorkFlowDefinition1.getName()); - assertEquals(workStatusResponseDTOs.get(0).getStatus(), ParodosWorkStatus.PENDING); + assertEquals(workStatusResponseDTOs.get(0).getStatus(), ParodosWorkStatus.IN_PROGRESS); assertEquals(workStatusResponseDTOs.get(0).getWorks().size(), 1); // sub workflow 1 task 1 assertEquals(workStatusResponseDTOs.get(0).getWorks().get(0).getType(), WorkType.TASK); assertEquals(workStatusResponseDTOs.get(0).getWorks().get(0).getName(), testSubWorkFlowTaskDefinition1.getName()); - assertEquals(workStatusResponseDTOs.get(0).getWorks().get(0).getStatus(), ParodosWorkStatus.PENDING); + assertEquals(workStatusResponseDTOs.get(0).getWorks().get(0).getStatus(), ParodosWorkStatus.IN_PROGRESS); assertNull(workStatusResponseDTOs.get(0).getWorks().get(0).getWorks()); // workflow task 1 @@ -192,4 +196,223 @@ void testGetWorkFlowWorksStatus() { assertNull(workStatusResponseDTOs.get(1).getWorks()); } + @Nested + @DisplayName("Tests for workflow with checker") + class TestGetWorkFlowWorksStatusWithChecker { + + // master workflow vars + private static final String workFlowName = "testMasterWorkFlow"; + + private static final UUID masterWorkFlowExecutionId = UUID.randomUUID(); + + private static final UUID masterWorkFlowDefinitionId = UUID.randomUUID(); + + private static final UUID projectId = UUID.randomUUID(); + + // master workflow task vars + private static final String TEST_SUB_WORKFLOW_TASK_NAME = "testSubWorkFlowTask"; + + private static final UUID subWorkFlowTaskDefinitionId = UUID.randomUUID(); + + private static final UUID subWorkFlowTaskExecutionId = UUID.randomUUID(); + + // checker workflow vars + private static final UUID checkerWorkFlowExecutionId = UUID.randomUUID(); + + private static final UUID checkerWorkFlowDefinitionId = UUID.randomUUID(); + + private static final String checkerWorkFlowName = "testCheckerWorkFlow"; + + // checker workflow task vars + private static final String CHECKER_WORKFLOW_TASK_NAME_1 = "testWorkFlowTask1"; + + private static final UUID checkerWorkFlowTaskDefinitionId = UUID.randomUUID(); + + private static final UUID testCheckerWorkFlowTaskExecutionId1 = UUID.randomUUID(); + + private WorkFlowDefinition masterWorkflowDefinition; + + private WorkFlowExecution masterWorkflowExecution; + + private WorkFlowTaskDefinition masterWorkFlowTaskDefinition; + + private WorkFlowTaskExecution masterWorkFlowTaskExecution; + + private WorkFlowDefinition checkerWorkflowDefinition; + + private WorkFlowExecution checkerWorkflowExecution; + + private WorkFlowTaskDefinition checkerWorkFlowTaskDefinition; + + private WorkFlowTaskExecution checkerWorkFlowTaskExecution; + + private WorkFlowWorkDefinition masterWorkflowWorkDefinition; + + private WorkFlowWorkDefinition checkerWorkflowWorkDefinition; + + @BeforeEach + void beforeEach() { + setupCheckerWorkflow(); + setupMasterWorkflow(); + setupCheckerMapping(); + + Mockito.when( + workFlowWorkRepository.findByWorkFlowDefinitionIdOrderByCreateDateAsc(masterWorkFlowDefinitionId)) + .thenReturn(List.of(masterWorkflowWorkDefinition, checkerWorkflowWorkDefinition)); + + // master + Mockito.when(workFlowTaskRepository.findByWorkFlowExecutionIdAndWorkFlowTaskDefinitionId( + masterWorkFlowExecutionId, subWorkFlowTaskDefinitionId)) + .thenReturn(List.of(masterWorkFlowTaskExecution)); + + Mockito.when(workFlowTaskDefinitionRepository.findById(subWorkFlowTaskDefinitionId)) + .thenReturn(Optional.of(masterWorkFlowTaskDefinition)); + + Mockito.when( + workFlowWorkRepository.findByWorkFlowDefinitionIdOrderByCreateDateAsc(masterWorkFlowDefinitionId)) + .thenReturn(List.of(masterWorkflowWorkDefinition)); + + // checker + Mockito.when(workFlowTaskDefinitionRepository.findById(checkerWorkFlowTaskDefinitionId)) + .thenReturn(Optional.of(checkerWorkFlowTaskDefinition)); + + Mockito.when(workFlowTaskRepository.findByWorkFlowExecutionIdAndWorkFlowTaskDefinitionId( + masterWorkFlowExecutionId, checkerWorkFlowTaskDefinitionId)) + .thenReturn(List.of(checkerWorkFlowTaskExecution)); + + Mockito.when( + workFlowWorkRepository.findByWorkFlowDefinitionIdOrderByCreateDateAsc(checkerWorkFlowDefinitionId)) + .thenReturn(List.of(checkerWorkflowWorkDefinition)); + + Mockito.when(workFlowRepository.findFirstByMainWorkFlowExecutionAndWorkFlowDefinitionId( + Mockito.nullable(WorkFlowExecution.class), Mockito.eq(checkerWorkFlowDefinitionId))) + .thenReturn(checkerWorkflowExecution); + } + + @Test + void testGetWorkFlowWorksStatusWithChecker_when_checkerIsFailed_then_taskShouldBeInProgress() { + checkerWorkflowExecution.setStatus(WorkFlowStatus.FAILED); + + // then + List workStatusResponseDTOs = workFlowServiceDelegate + .getWorkFlowAndWorksStatus(masterWorkflowExecution, masterWorkflowDefinition); + + // workflow + assertNotNull(workStatusResponseDTOs); + assertEquals(workStatusResponseDTOs.size(), 1); + + // sub task + assertEquals(WorkType.TASK, workStatusResponseDTOs.get(0).getType()); + assertEquals(workStatusResponseDTOs.get(0).getName(), masterWorkFlowTaskDefinition.getName()); + assertEquals(ParodosWorkStatus.IN_PROGRESS, workStatusResponseDTOs.get(0).getStatus()); + assertNull(workStatusResponseDTOs.get(0).getWorks()); + } + + @Test + void testGetWorkFlowWorksStatusWithChecker_when_checkerIsCompleted_then_taskShouldBeCompleted() { + checkerWorkflowExecution.setStatus(WorkFlowStatus.COMPLETED); + + // then + List workStatusResponseDTOs = workFlowServiceDelegate + .getWorkFlowAndWorksStatus(masterWorkflowExecution, masterWorkflowDefinition); + + // workflow + assertNotNull(workStatusResponseDTOs); + assertEquals(workStatusResponseDTOs.size(), 1); + + // sub task + assertEquals(WorkType.TASK, workStatusResponseDTOs.get(0).getType()); + assertEquals(workStatusResponseDTOs.get(0).getName(), masterWorkFlowTaskDefinition.getName()); + assertEquals(ParodosWorkStatus.COMPLETED, workStatusResponseDTOs.get(0).getStatus()); + assertNull(workStatusResponseDTOs.get(0).getWorks()); + } + + @Test + void testGetWorkFlowWorksStatusWithChecker_when_checkerIsRejected_then_taskShouldBeRejected() { + checkerWorkflowExecution.setStatus(WorkFlowStatus.REJECTED); + + // then + List workStatusResponseDTOs = workFlowServiceDelegate + .getWorkFlowAndWorksStatus(masterWorkflowExecution, masterWorkflowDefinition); + + // workflow + assertNotNull(workStatusResponseDTOs); + assertEquals(workStatusResponseDTOs.size(), 1); + + // sub task + assertEquals(WorkType.TASK, workStatusResponseDTOs.get(0).getType()); + assertEquals(workStatusResponseDTOs.get(0).getName(), masterWorkFlowTaskDefinition.getName()); + assertEquals(ParodosWorkStatus.REJECTED, workStatusResponseDTOs.get(0).getStatus()); + assertNull(workStatusResponseDTOs.get(0).getWorks()); + } + + private void setupCheckerMapping() { + WorkFlowCheckerMappingDefinition workFlowCheckerMappingDefinition = WorkFlowCheckerMappingDefinition + .builder().cronExpression("test-cron").checkWorkFlow(checkerWorkflowDefinition) + .tasks(new ArrayList<>(List.of(masterWorkFlowTaskDefinition))).build(); + masterWorkFlowTaskDefinition.setWorkFlowCheckerMappingDefinition(workFlowCheckerMappingDefinition); + } + + private void setupCheckerWorkflow() { + // task definition + checkerWorkFlowTaskDefinition = WorkFlowTaskDefinition.builder().name(CHECKER_WORKFLOW_TASK_NAME_1).build(); + checkerWorkFlowTaskDefinition.setId(checkerWorkFlowTaskDefinitionId); + + // task execution + checkerWorkFlowTaskExecution = WorkFlowTaskExecution.builder() + .workFlowExecutionId(checkerWorkFlowExecutionId) + .workFlowTaskDefinitionId(checkerWorkFlowTaskDefinitionId).build(); + checkerWorkFlowTaskExecution.setId(testCheckerWorkFlowTaskExecutionId1); + + // checker workflow + // workflow definition + checkerWorkflowDefinition = WorkFlowDefinition.builder().name(checkerWorkFlowName).numberOfWorks(1) + .workFlowTaskDefinitions(List.of(checkerWorkFlowTaskDefinition)).build(); + checkerWorkflowDefinition.setId(checkerWorkFlowDefinitionId); + // workflow execution + checkerWorkflowExecution = WorkFlowExecution.builder().workFlowDefinitionId(checkerWorkFlowDefinitionId) + .status(WorkFlowStatus.FAILED).build(); + checkerWorkflowExecution.setId(checkerWorkFlowExecutionId); + + // workflowWork + checkerWorkflowWorkDefinition = WorkFlowWorkDefinition.builder() + .workDefinitionId(checkerWorkFlowTaskDefinitionId).workDefinitionType(WorkType.TASK) + .workFlowDefinition(checkerWorkflowDefinition).build(); + checkerWorkflowWorkDefinition.setId(UUID.randomUUID()); + + checkerWorkflowDefinition.setWorkFlowWorkDefinitions(List.of(checkerWorkflowWorkDefinition)); + } + + private void setupMasterWorkflow() { + + // workflow (master) + masterWorkflowDefinition = WorkFlowDefinition.builder().name(workFlowName).numberOfWorks(1).build(); + masterWorkflowDefinition.setId(masterWorkFlowDefinitionId); + + masterWorkflowExecution = WorkFlowExecution.builder().workFlowDefinitionId(masterWorkFlowDefinitionId) + .projectId(projectId).status(WorkFlowStatus.IN_PROGRESS).build(); + masterWorkflowExecution.setId(masterWorkFlowExecutionId); + + // sub task + // task definition + masterWorkFlowTaskDefinition = WorkFlowTaskDefinition.builder().name(TEST_SUB_WORKFLOW_TASK_NAME).build(); + masterWorkFlowTaskDefinition.setId(subWorkFlowTaskDefinitionId); + // link sub task to master + masterWorkflowDefinition.setWorkFlowTaskDefinitions(List.of(masterWorkFlowTaskDefinition)); + // sub task execution + masterWorkFlowTaskExecution = WorkFlowTaskExecution.builder().status(WorkFlowTaskStatus.IN_PROGRESS) + .workFlowExecutionId(masterWorkFlowExecutionId) + .workFlowTaskDefinitionId(subWorkFlowTaskDefinitionId).build(); + masterWorkFlowTaskExecution.setId(subWorkFlowTaskExecutionId); + + // workflow's works + masterWorkflowWorkDefinition = WorkFlowWorkDefinition.builder() + .workDefinitionId(subWorkFlowTaskDefinitionId).workDefinitionType(WorkType.TASK) + .workFlowDefinition(masterWorkflowDefinition).build(); + masterWorkflowWorkDefinition.setId(UUID.randomUUID()); + masterWorkflowDefinition.setWorkFlowWorkDefinitions(List.of(masterWorkflowWorkDefinition)); + } + + } + } \ No newline at end of file