private Map<String, Object> completeTask(
            Action action,
            Object payload,
            TaskDetails taskDetails,
            TaskModel.Status status,
            String event,
            String messageId) {

        Map<String, Object> input = new HashMap<>();
        input.put("workflowId", taskDetails.getWorkflowId());
        input.put("taskId", taskDetails.getTaskId());
        input.put("taskRefName", taskDetails.getTaskRefName());
        input.putAll(taskDetails.getOutput());

        Map<String, Object> replaced = parametersUtils.replace(input, payload);
        String workflowId = (String) replaced.get("workflowId");
        String taskId = (String) replaced.get("taskId");
        String taskRefName = (String) replaced.get("taskRefName");

        TaskModel taskModel = null;
        if (StringUtils.isNotEmpty(taskId)) {
            taskModel = workflowExecutor.getTask(taskId);
        } else if (StringUtils.isNotEmpty(workflowId) && StringUtils.isNotEmpty(taskRefName)) {
            WorkflowModel workflow = workflowExecutor.getWorkflow(workflowId, true);
            if (workflow == null) {
                replaced.put("error", "No workflow found with ID: " + workflowId);
                return replaced;
            }
            taskModel = workflow.getTaskByRefName(taskRefName);
            // Task can be loopover task.In such case find corresponding task and update
            List<TaskModel> loopOverTaskList =
                    workflow.getTasks().stream()
                            .filter(
                                    t ->
                                            TaskUtils.removeIterationFromTaskRefName(
                                                            t.getReferenceTaskName())
                                                    .equals(taskRefName))
                            .collect(Collectors.toList());
            if (!loopOverTaskList.isEmpty()) {
                // Find loopover task with the highest iteration value
                taskModel =
                        loopOverTaskList.stream()
                                .sorted(Comparator.comparingInt(TaskModel::getIteration).reversed())
                                .findFirst()
                                .get();
            }
        }

        if (taskModel == null) {
            replaced.put(
                    "error",
                    "No task found with taskId: "
                            + taskId
                            + ", reference name: "
                            + taskRefName
                            + ", workflowId: "
                            + workflowId);
            return replaced;
        }

        taskModel.setStatus(status);
        taskModel.setOutputData(replaced);
        taskModel.setOutputMessage(taskDetails.getOutputMessage());
        taskModel.addOutput("conductor.event.messageId", messageId);
        taskModel.addOutput("conductor.event.name", event);

        try {
            workflowExecutor.updateTask(new TaskResult(taskModel.toTask()));
            LOGGER.debug(
                    "Updated task: {} in workflow:{} with status: {} for event: {} for message:{}",
                    taskId,
                    workflowId,
                    status,
                    event,
                    messageId);
        } catch (RuntimeException e) {
            Monitors.recordEventActionError(
                    action.getAction().name(), taskModel.getTaskType(), event);
            LOGGER.error(
                    "Error updating task: {} in workflow: {} in action: {} for event: {} for message: {}",
                    taskDetails.getTaskRefName(),
                    taskDetails.getWorkflowId(),
                    action.getAction(),
                    event,
                    messageId,
                    e);
            replaced.put("error", e.getMessage());
            throw e;
        }
        return replaced;
    }
Action Processor subscribes to the Event Actions queue and processes the actions (e.g. start
workflow etc)
core/src/main/java/com/netflix/conductor/core/events/SimpleActionProcessor.java