DeciderService.DeciderOutcome outcome = deciderService.decide(workflow); if (outcome.isComplete) { completeWorkflow(workflow); return true; setTaskDomains(tasksToBeScheduled, workflow); List<Task> tasksToBeUpdated = outcome.tasksToBeUpdated; List<Task> tasksToBeRequeued = outcome.tasksToBeRequeued; addTaskToQueue(tasksToBeRequeued); tasksToBeScheduled = dedupAndAddTasks(workflow, tasksToBeScheduled); stateChanged = scheduleTask(workflow, tasksToBeScheduled) || stateChanged; decide(workflowId); terminate(workflow, twe); return true; } catch (RuntimeException e) {
@Test public void testDeciderUpdate() { metadataService.getWorkflowDef(LINEAR_WORKFLOW_T1_T2, 1); String correlationId = "unit_test_1" + UUID.randomUUID().toString(); Map<String, Object> input = new HashMap<String, Object>(); String inputParam1 = "p1 value"; input.put("param1", inputParam1); input.put("param2", "p2 value"); String wfid = startOrLoadWorkflowExecution(LINEAR_WORKFLOW_T1_T2, 1, correlationId, input, null, null); assertNotNull(wfid); Workflow workflow = workflowExecutor.getWorkflow(wfid, false); long updated1 = workflow.getUpdateTime(); Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS); workflowExecutor.decide(wfid); workflow = workflowExecutor.getWorkflow(wfid, false); long updated2 = workflow.getUpdateTime(); assertEquals(updated1, updated2); Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS); workflowExecutor.terminateWorkflow(wfid, "done"); workflow = workflowExecutor.getWorkflow(wfid, false); updated2 = workflow.getUpdateTime(); assertTrue("updated1[" + updated1 + "] >? updated2[" + updated2 + "]", updated2 > updated1); }
/** * Pauses the workflow given a worklfowId. * @param workflowId WorkflowId of the workflow. */ @Service public void pauseWorkflow(String workflowId) { workflowExecutor.pauseWorkflow(workflowId); }
@Override public void cancel(Workflow workflow, Task task, WorkflowExecutor provider) { String workflowId = (String) task.getOutputData().get(SUB_WORKFLOW_ID); if(workflowId == null) { workflowId = (String) task.getInputData().get(SUB_WORKFLOW_ID); //Backward compatibility } if(StringUtils.isEmpty(workflowId)) { return; } Workflow subWorkflow = provider.getWorkflow(workflowId, false); subWorkflow.setStatus(WorkflowStatus.TERMINATED); provider.terminateWorkflow(subWorkflow, "Parent workflow has been terminated with status " + workflow.getStatus(), null); }
task = executor.getTask(taskId); } else if (StringUtils.isNotEmpty(workflowId) && StringUtils.isNotEmpty(taskRefName)) { Workflow workflow = executor.getWorkflow(workflowId, true); if (workflow == null) { replaced.put("error", "No workflow found with ID: " + workflowId); executor.updateTask(new TaskResult(task)); } catch (RuntimeException e) { logger.error("Error updating task: {} in workflow: {} in action: {} for event: {} for message: {}", taskDetails.getTaskRefName(), taskDetails.getWorkflowId(), action.getAction(), event, messageId, e);
List<Task> failedTasks = getFailedTasksToRetry(workflow); failedTasks.forEach(failedTask -> rescheduledTasks.add(taskToBeRescheduled(failedTask))); executionDAOFacade.updateTask(task); } else { rescheduledTasks.add(taskToBeRescheduled(task)); scheduleTask(workflow, rescheduledTasks); dedupAndAddTasks(workflow, rescheduledTasks); executionDAOFacade.updateTasks(workflow.getTasks()); decide(workflowId);
/** * @throws ApplicationException */ public String startWorkflow(String name, Integer version, String correlationId, Map<String, Object> input, String externalInputPayloadStoragePath) { return startWorkflow(name, version, correlationId, input, externalInputPayloadStoragePath, null); }
/** * Starts the decision task for a workflow. * @param workflowId WorkflowId of the workflow. */ @Service public void decideWorkflow(String workflowId) { workflowExecutor.decide(workflowId); }
started.set(true); return id; }).when(workflowExecutor).startWorkflow(startWorkflowAction.getStart_workflow().getName(), startWorkflowAction.getStart_workflow().getVersion(), startWorkflowAction.getStart_workflow().getCorrelationId(), startWorkflowAction.getStart_workflow().getInput(), null, event, taskToDomain); completed.set(true); return null; }).when(workflowExecutor).updateTask(any()); Workflow workflow = new Workflow(); workflow.setTasks(Collections.singletonList(task)); when(workflowExecutor.getWorkflow(completeTaskAction.getComplete_task().getWorkflowId(), true)).thenReturn(workflow);
workflowExecutor.pauseWorkflow(wfid); workflowExecutor.decide(wfid); workflowExecutor.resumeWorkflow(wfid);
Map<String, String> taskToDomain ) { return startWorkflow( name, version, String event ) { return startWorkflow( name, version, WorkflowDef workflowDefinition = metadataMapperService.lookupForWorkflowDefinition(name, version); return startWorkflow( workflowDefinition, workflowInput, validateWorkflow(workflowDefinition, workflowInput, externalInputPayloadStoragePath); decide(workflowId); return workflowId;
/** * Retries the last failed task. * @param workflowId WorkflowId of the workflow. */ @Service public void retryWorkflow(String workflowId) { workflowExecutor.retry(workflowId); }
/** * Restarts a completed workflow. * * @param workflowId WorkflowId of the workflow. * @param useLatestDefinitions if true, use the latest workflow and task definitions upon restart */ @Service public void restartWorkflow(String workflowId, boolean useLatestDefinitions) { workflowExecutor.rewind(workflowId, useLatestDefinitions); }
@Test public void testCompleteTask() throws Exception { TaskDetails taskDetails = new TaskDetails(); taskDetails.setWorkflowId("${workflowId}"); taskDetails.setTaskRefName("testTask"); Action action = new Action(); action.setAction(Type.complete_task); action.setComplete_task(taskDetails); Object payload = new ObjectMapper().readValue("{\"workflowId\":\"workflow_1\"}", Object.class); Task task = new Task(); task.setReferenceTaskName("testTask"); Workflow workflow = new Workflow(); workflow.getTasks().add(task); when(workflowExecutor.getWorkflow(eq("workflow_1"), anyBoolean())).thenReturn(workflow); actionProcessor.execute(action, payload, "testEvent", "testMessage"); ArgumentCaptor<TaskResult> argumentCaptor = ArgumentCaptor.forClass(TaskResult.class); verify(workflowExecutor).updateTask(argumentCaptor.capture()); assertEquals(Status.COMPLETED, argumentCaptor.getValue().getStatus()); assertEquals("testMessage", argumentCaptor.getValue().getOutputData().get("conductor.event.messageId")); assertEquals("testEvent", argumentCaptor.getValue().getOutputData().get("conductor.event.name")); assertEquals("workflow_1", argumentCaptor.getValue().getOutputData().get("workflowId")); assertEquals("testTask", argumentCaptor.getValue().getOutputData().get("taskRefName")); }
@Override public boolean execute(Workflow workflow, Task task, WorkflowExecutor provider) { String workflowId = (String) task.getOutputData().get(SUB_WORKFLOW_ID); if (workflowId == null) { workflowId = (String) task.getInputData().get(SUB_WORKFLOW_ID); //Backward compatibility } if(StringUtils.isEmpty(workflowId)) { return false; } Workflow subWorkflow = provider.getWorkflow(workflowId, false); WorkflowStatus subWorkflowStatus = subWorkflow.getStatus(); if(!subWorkflowStatus.isTerminal()){ return false; } task.getOutputData().putAll(subWorkflow.getOutput()); if (subWorkflowStatus.isSuccessful()) { task.setStatus(Status.COMPLETED); } else { task.setReasonForIncompletion(subWorkflow.getReasonForIncompletion()); task.setStatus(Status.FAILED); } return true; }
decide(workflowId); return true; if (rerunWF(subWorkflowId, taskId, taskInput, null, null)) { rerunFromTask = task; break; rerunFromTask.setInputData(taskInput); addTaskToQueue(rerunFromTask); decide(workflowId); return true;
/** * Reruns the workflow from a specific task. * @param workflowId WorkflowId of the workflow you want to rerun. * @param request (@link RerunWorkflowRequest) for the workflow. * @return WorkflowId of the rerun workflow. */ @Service public String rerunWorkflow(String workflowId, RerunWorkflowRequest request) { request.setReRunFromWorkflowId(workflowId); return workflowExecutor.rerun(request); }
decide(parent.getWorkflowId()); ); String failureWFId = startWorkflow( latestFailureWorkflow, input,
/** * Resumes the workflow. * @param workflowId WorkflowId of the workflow. */ @Service public void resumeWorkflow(String workflowId) { workflowExecutor.resumeWorkflow(workflowId); }