use of com.netflix.conductor.core.execution.tasks.SubWorkflow in project conductor by Netflix.
the class TestWorkflowExecutor method init.
@Before
public void init() {
TestConfiguration config = new TestConfiguration();
executionDAOFacade = mock(ExecutionDAOFacade.class);
metadataDAO = mock(MetadataDAO.class);
queueDAO = mock(QueueDAO.class);
workflowStatusListener = mock(WorkflowStatusListener.class);
ExternalPayloadStorageUtils externalPayloadStorageUtils = mock(ExternalPayloadStorageUtils.class);
executionLockService = mock(ExecutionLockService.class);
ObjectMapper objectMapper = new JsonMapperProvider().get();
ParametersUtils parametersUtils = new ParametersUtils();
Map<String, TaskMapper> taskMappers = new HashMap<>();
taskMappers.put("DECISION", new DecisionTaskMapper());
taskMappers.put("DYNAMIC", new DynamicTaskMapper(parametersUtils, metadataDAO));
taskMappers.put("FORK_JOIN", new ForkJoinTaskMapper());
taskMappers.put("JOIN", new JoinTaskMapper());
taskMappers.put("FORK_JOIN_DYNAMIC", new ForkJoinDynamicTaskMapper(parametersUtils, objectMapper, metadataDAO));
taskMappers.put("USER_DEFINED", new UserDefinedTaskMapper(parametersUtils, metadataDAO));
taskMappers.put("SIMPLE", new SimpleTaskMapper(parametersUtils));
taskMappers.put("SUB_WORKFLOW", new SubWorkflowTaskMapper(parametersUtils, metadataDAO));
taskMappers.put("EVENT", new EventTaskMapper(parametersUtils));
taskMappers.put("WAIT", new WaitTaskMapper(parametersUtils));
taskMappers.put("HTTP", new HTTPTaskMapper(parametersUtils, metadataDAO));
taskMappers.put("LAMBDA", new LambdaTaskMapper(parametersUtils, metadataDAO));
new SubWorkflow(new JsonMapperProvider().get());
new Lambda();
DeciderService deciderService = new DeciderService(parametersUtils, metadataDAO, externalPayloadStorageUtils, taskMappers, config);
MetadataMapperService metadataMapperService = new MetadataMapperService(metadataDAO);
workflowExecutor = new WorkflowExecutor(deciderService, metadataDAO, queueDAO, metadataMapperService, workflowStatusListener, executionDAOFacade, config, executionLockService, parametersUtils);
}
use of com.netflix.conductor.core.execution.tasks.SubWorkflow in project conductor by Netflix.
the class TestWorkflowExecutor method testUpdateParentWorkflow.
@Test
public void testUpdateParentWorkflow() {
// Case 1: When Subworkflow is in terminal state
// 1A: Parent Workflow is IN_PROGRESS
// Expectation: Parent workflow's Subworkflow task should complete
String workflowId = "test-workflow-Id";
String subWorkflowId = "test-subWorkflow-Id";
String parentWorkflowSubWFTaskId = "test-subworkflow-taskId";
WorkflowTask subWorkflowTask = new WorkflowTask();
subWorkflowTask.setWorkflowTaskType(TaskType.SUB_WORKFLOW);
subWorkflowTask.setType(TaskType.SUB_WORKFLOW.name());
subWorkflowTask.setTaskReferenceName("sub-workflow");
Task task = new Task();
task.setTaskType(subWorkflowTask.getType());
task.setTaskDefName(subWorkflowTask.getName());
task.setReferenceTaskName(subWorkflowTask.getTaskReferenceName());
task.setWorkflowInstanceId(workflowId);
task.setScheduledTime(System.currentTimeMillis());
task.setTaskId(parentWorkflowSubWFTaskId);
task.setStatus(Status.IN_PROGRESS);
task.setRetryCount(0);
task.setWorkflowTask(subWorkflowTask);
task.setOutputData(new HashMap<>());
task.setSubWorkflowId(subWorkflowId);
WorkflowDef def = new WorkflowDef();
def.setName("test");
Workflow parentWorkflow = new Workflow();
parentWorkflow.setWorkflowId(workflowId);
parentWorkflow.setWorkflowDefinition(def);
parentWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING);
parentWorkflow.setTasks(Arrays.asList(task));
Workflow subWorkflow = new Workflow();
subWorkflow.setWorkflowId("subworkflowId");
subWorkflow.setStatus(Workflow.WorkflowStatus.COMPLETED);
subWorkflow.setParentWorkflowTaskId(parentWorkflowSubWFTaskId);
subWorkflow.setWorkflowId(subWorkflowId);
when(executionDAOFacade.getTaskById(anyString())).thenReturn(task);
when(workflowExecutor.getWorkflow(subWorkflowId, false)).thenReturn(subWorkflow);
workflowExecutor.updateParentWorkflow(task, subWorkflow, parentWorkflow);
assertEquals(Status.COMPLETED, task.getStatus());
assertEquals(Workflow.WorkflowStatus.COMPLETED, subWorkflow.getStatus());
// updateParentWorkflow shouldn't call the decide on workflow, and hence it should still remain IN_PROGRESS
assertEquals(Workflow.WorkflowStatus.RUNNING, parentWorkflow.getStatus());
// 1B: Parent Workflow is in FAILED state
// Expectation: return false
parentWorkflow.setStatus(Workflow.WorkflowStatus.FAILED);
assertFalse(workflowExecutor.updateParentWorkflow(task, subWorkflow, parentWorkflow));
// Case 2: When Subworkflow is in non-terminal state
// 2A: Parent Workflow is in terminal state
// Expectation: Parent workflow and subworkflow task should be reset to IN_PROGRESS and RUNNING state respectively.
subWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING);
parentWorkflow.setStatus(Workflow.WorkflowStatus.FAILED);
workflowExecutor.updateParentWorkflow(task, subWorkflow, parentWorkflow);
assertEquals(Workflow.WorkflowStatus.RUNNING, subWorkflow.getStatus());
assertEquals(Status.IN_PROGRESS, task.getStatus());
assertEquals(Workflow.WorkflowStatus.RUNNING, parentWorkflow.getStatus());
// 2B: Parent Workflow is in non-terminal state
// Expectation: Parent workflow, Subworkflow and subworkflow task should remain in same state.
subWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING);
parentWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING);
task.setStatus(Status.IN_PROGRESS);
workflowExecutor.updateParentWorkflow(task, subWorkflow, parentWorkflow);
assertEquals(Workflow.WorkflowStatus.RUNNING, subWorkflow.getStatus());
assertEquals(Status.IN_PROGRESS, task.getStatus());
assertEquals(Workflow.WorkflowStatus.RUNNING, parentWorkflow.getStatus());
}
use of com.netflix.conductor.core.execution.tasks.SubWorkflow in project conductor by Netflix.
the class TestWorkflowRepairService method assertAsyncCompleteSystemTasksAreNotCheckedAgainstQueue.
@Test
public void assertAsyncCompleteSystemTasksAreNotCheckedAgainstQueue() {
Task task = new Task();
task.setTaskType("SUB_WORKFLOW");
task.setStatus(Task.Status.IN_PROGRESS);
task.setTaskId("abcd");
task.setCallbackAfterSeconds(60);
WorkflowSystemTask workflowSystemTask = new SubWorkflow();
assertTrue(workflowSystemTask.isAsyncComplete(task));
assertFalse(workflowRepairService.verifyAndRepairTask(task));
// Verify that queue message is never pushed for async complete system tasks
verify(queueDAO, never()).containsMessage(anyString(), anyString());
verify(queueDAO, never()).push(anyString(), anyString(), anyLong());
}
use of com.netflix.conductor.core.execution.tasks.SubWorkflow in project conductor by Netflix.
the class WorkflowExecutor method skipTasksAffectedByTerminateTask.
/**
* When a TERMINATE task runs, it only affects the workflow in which it runs; it does not do anything with
* in-progress tasks and subworkflows that are still running. This recursive method will ensure that all tasks within
* all subworkflows are set to SKIPPED status so they can complete.
* @param workflow a subworkflow within the hierarchy of the original workflow containing the TERMINATE task
*/
private void skipTasksAffectedByTerminateTask(Workflow workflow) {
if (!workflow.getStatus().isTerminal()) {
List<Task> tasksToBeUpdated = new ArrayList<>();
for (Task workflowTask : workflow.getTasks()) {
if (!workflowTask.getStatus().isTerminal()) {
workflowTask.setStatus(SKIPPED);
tasksToBeUpdated.add(workflowTask);
}
if (TaskType.SUB_WORKFLOW.name().equals(workflowTask.getTaskType()) && StringUtils.isNotBlank(workflowTask.getSubWorkflowId())) {
Workflow subWorkflow = executionDAOFacade.getWorkflowById(workflowTask.getSubWorkflowId(), true);
if (subWorkflow != null) {
skipTasksAffectedByTerminateTask(subWorkflow);
}
}
}
if (!tasksToBeUpdated.isEmpty()) {
executionDAOFacade.updateTasks(tasksToBeUpdated);
workflow.setStatus(Workflow.WorkflowStatus.TERMINATED);
workflow.setReasonForIncompletion("Parent workflow was terminated with a TERMINATE task");
executionDAOFacade.updateWorkflow(workflow);
}
}
}
use of com.netflix.conductor.core.execution.tasks.SubWorkflow in project conductor by Netflix.
the class AbstractWorkflowServiceTest method testSubWorkflowTaskToDomainWildcard.
@Test
public void testSubWorkflowTaskToDomainWildcard() {
Map<String, String> taskToDomain = new HashMap<>();
taskToDomain.put("*", "unittest");
createSubWorkflow(taskToDomain);
metadataService.getWorkflowDef(WF_WITH_SUB_WF, 1);
Map<String, Object> input = new HashMap<>();
input.put("param1", "param 1 value");
input.put("param3", "param 2 value");
input.put("wfName", LINEAR_WORKFLOW_T1_T2);
String workflowId = startOrLoadWorkflowExecution(WF_WITH_SUB_WF, 1, "test", input, null, null);
assertNotNull(workflowId);
Workflow workflow = workflowExecutionService.getExecutionStatus(workflowId, true);
assertNotNull(workflow);
Task task = workflowExecutionService.poll("junit_task_5", "test");
assertNotNull(task);
task.setStatus(COMPLETED);
workflowExecutionService.updateTask(task);
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
workflow = workflowExecutionService.getExecutionStatus(workflowId, true);
assertNotNull(workflow);
assertNotNull(workflow.getTasks());
// Simulating SystemTaskWorkerCoordinator to execute async system tasks
String subWorkflowTaskId = workflow.getTaskByRefName("a2").getTaskId();
workflowExecutor.executeSystemTask(dummySubWorkflowSystemTask, subWorkflowTaskId, 1);
workflow = workflowExecutionService.getExecutionStatus(workflowId, true);
task = workflow.getTasks().stream().filter(t -> t.getTaskType().equals(SUB_WORKFLOW.name())).findAny().get();
assertNotNull(task);
assertNotNull(task.getOutputData());
assertNotNull("Output: " + task.getOutputData().toString() + ", status: " + task.getStatus(), task.getSubWorkflowId());
assertNotNull(task.getInputData());
assertTrue(task.getInputData().containsKey("workflowInput"));
assertEquals(42, ((Map<String, Object>) task.getInputData().get("workflowInput")).get("param2"));
String subWorkflowId = task.getSubWorkflowId();
Workflow subWorkflow = workflowExecutionService.getExecutionStatus(subWorkflowId, true);
assertNotNull(subWorkflow);
assertNotNull(subWorkflow.getTasks());
assertEquals(workflowId, subWorkflow.getParentWorkflowId());
assertEquals(RUNNING, subWorkflow.getStatus());
task = workflowExecutionService.poll("junit_task_1", "test", "unittest");
task.setStatus(COMPLETED);
workflowExecutionService.updateTask(task);
task = workflowExecutionService.poll("junit_task_2", "test", "unittest");
assertEquals(subWorkflowId, task.getWorkflowInstanceId());
String uuid = UUID.randomUUID().toString();
task.getOutputData().put("uuid", uuid);
task.setStatus(COMPLETED);
workflowExecutionService.updateTask(task);
subWorkflow = workflowExecutionService.getExecutionStatus(subWorkflowId, true);
assertNotNull(subWorkflow);
assertEquals(WorkflowStatus.COMPLETED, subWorkflow.getStatus());
assertNotNull(subWorkflow.getOutput());
assertTrue(subWorkflow.getOutput().containsKey("o1"));
assertTrue(subWorkflow.getOutput().containsKey("o2"));
assertEquals("sub workflow input param1", subWorkflow.getOutput().get("o1"));
assertEquals(uuid, subWorkflow.getOutput().get("o2"));
assertEquals(taskToDomain, subWorkflow.getTaskToDomain());
// Execute again to re-evaluate the Subworkflow task.
workflowExecutor.executeSystemTask(dummySubWorkflowSystemTask, subWorkflowTaskId, 1);
task = workflowExecutionService.poll("junit_task_6", "test");
assertNotNull(task);
task.setStatus(COMPLETED);
workflowExecutionService.updateTask(task);
workflow = workflowExecutionService.getExecutionStatus(workflowId, true);
assertNotNull(workflow);
assertEquals(WorkflowStatus.COMPLETED, workflow.getStatus());
}
Aggregations