/** * * @return Workflow Type / Definition */ @Deprecated public String getWorkflowType() { return getWorkflowName(); }
@Override public String toString() { return getWorkflowName() + "." + getWorkflowVersion() + "/" + workflowId + "." + status; }
public List<Workflow> getWorkflowInstances(String workflowName, String correlationId, boolean includeClosed, boolean includeTasks) { List<Workflow> workflows = executionDAOFacade.getWorkflowsByCorrelationId(correlationId, includeTasks); List<Workflow> result = new LinkedList<>(); for (Workflow wf : workflows) { if (wf.getWorkflowName().equals(workflowName) && (includeClosed || wf.getStatus().equals(Workflow.WorkflowStatus.RUNNING))) { result.add(wf); } } return result; }
@Override public Workflow getWorkflow(String workflowId, boolean includeTasks) { String json = dynoClient.get(nsKey(WORKFLOW, workflowId)); Workflow workflow = null; if(json != null) { workflow = readValue(json, Workflow.class); recordRedisDaoRequests("getWorkflow", "n/a", workflow.getWorkflowName()); recordRedisDaoPayloadSize("getWorkflow", json.length(),"n/a", workflow.getWorkflowName()); if (includeTasks) { List<Task> tasks = getTasksForWorkflow(workflowId); tasks.sort(Comparator.comparingLong(Task::getScheduledTime).thenComparingInt(Task::getSeq)); workflow.setTasks(tasks); } } return workflow; }
@Override public boolean removeWorkflow(String workflowId) { Workflow workflow = getWorkflow(workflowId, true); boolean removed = false; // TODO: calculate number of shards and iterate if (workflow != null) { try { recordCassandraDaoRequests("removeWorkflow", "n/a", workflow.getWorkflowName()); ResultSet resultSet = session.execute(deleteWorkflowStatement.bind(UUID.fromString(workflowId), DEFAULT_SHARD_ID)); if (resultSet.wasApplied()) { removed = true; } } catch (Exception e) { Monitors.error(CLASS_NAME, "removeWorkflow"); String errorMsg = String.format("Failed to remove workflow: %s", workflowId); LOGGER.error(errorMsg, e); throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, errorMsg); } workflow.getTasks().forEach(this::removeTaskLookup); } return removed; }
@Override public String createWorkflow(Workflow workflow) { try { workflow.setCreateTime(System.currentTimeMillis()); List<Task> tasks = workflow.getTasks(); workflow.setTasks(new LinkedList<>()); String payload = toJson(workflow); recordCassandraDaoRequests("createWorkflow", "n/a", workflow.getWorkflowName()); recordCassandraDaoPayloadSize("createWorkflow", payload.length(), "n/a", workflow.getWorkflowName()); session.execute(insertWorkflowStatement.bind(UUID.fromString(workflow.getWorkflowId()), 1, "", payload, 0, 1)); workflow.setTasks(tasks); return workflow.getWorkflowId(); } catch (Exception e) { Monitors.error(CLASS_NAME, "createWorkflow"); String errorMsg = String.format("Error creating workflow: %s", workflow.getWorkflowId()); LOGGER.error(errorMsg, e); throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, errorMsg, e); } }
@Override public String updateWorkflow(Workflow workflow) { try { workflow.setUpdateTime(System.currentTimeMillis()); if (workflow.getStatus().isTerminal()) { workflow.setEndTime(System.currentTimeMillis()); } List<Task> tasks = workflow.getTasks(); workflow.setTasks(new LinkedList<>()); String payload = toJson(workflow); recordCassandraDaoRequests("createWorkflow", "n/a", workflow.getWorkflowName()); recordCassandraDaoPayloadSize("createWorkflow", payload.length(), "n/a", workflow.getWorkflowName()); session.execute(updateWorkflowStatement.bind(payload, UUID.fromString(workflow.getWorkflowId()))); workflow.setTasks(tasks); return workflow.getWorkflowId(); } catch (Exception e) { Monitors.error(CLASS_NAME, "updateWorkflow"); String errorMsg = String.format("Failed to update workflow: %s", workflow.getWorkflowId()); LOGGER.error(errorMsg, e); throw new ApplicationException(ApplicationException.Code.BACKEND_ERROR, errorMsg); } }
/** * Populates the workflow output from external payload storage if the external storage path is specified. * * @param workflow the workflow for which the output is to be populated. */ private void populateWorkflowOutput(Workflow workflow) { if (StringUtils.isNotBlank(workflow.getExternalOutputPayloadStoragePath())) { WorkflowTaskMetrics.incrementExternalPayloadUsedCount(workflow.getWorkflowName(), ExternalPayloadStorage.Operation.READ.name(), ExternalPayloadStorage.PayloadType.WORKFLOW_OUTPUT.name()); workflow.setOutput(downloadFromExternalStorage(ExternalPayloadStorage.PayloadType.WORKFLOW_OUTPUT, workflow.getExternalOutputPayloadStoragePath())); } }
@Override public void start(Workflow workflow, Task task, WorkflowExecutor provider) { Map<String, Object> payload = new HashMap<>(task.getInputData()); payload.put("workflowInstanceId", workflow.getWorkflowId()); payload.put("workflowType", workflow.getWorkflowName()); payload.put("workflowVersion", workflow.getWorkflowVersion()); payload.put("correlationId", workflow.getCorrelationId()); String payloadJson; try { payloadJson = objectMapper.writeValueAsString(payload); } catch (JsonProcessingException e) { String msg = String.format("Error serializing JSON payload for task: %s, workflow: %s", task.getTaskId(), workflow.getWorkflowId()); throw new ApplicationException(INTERNAL_ERROR, msg); } Message message = new Message(task.getTaskId(), payloadJson, task.getTaskId()); ObservableQueue queue = getQueue(workflow, task); if(queue != null) { queue.publish(Collections.singletonList(message)); task.getOutputData().putAll(payload); task.setStatus(Status.COMPLETED); } else { task.setReasonForIncompletion("No queue found to publish."); task.setStatus(Status.FAILED); } }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Workflow workflow = (Workflow) o; return getEndTime() == workflow.getEndTime() && getWorkflowVersion() == workflow.getWorkflowVersion() && getSchemaVersion() == workflow.getSchemaVersion() && getStatus() == workflow.getStatus() && Objects.equals(getWorkflowId(), workflow.getWorkflowId()) && Objects.equals(getParentWorkflowId(), workflow.getParentWorkflowId()) && Objects.equals(getParentWorkflowTaskId(), workflow.getParentWorkflowTaskId()) && Objects.equals(getTasks(), workflow.getTasks()) && Objects.equals(getInput(), workflow.getInput()) && Objects.equals(getOutput(), workflow.getOutput()) && Objects.equals(getWorkflowName(), workflow.getWorkflowName()) && Objects.equals(getCorrelationId(), workflow.getCorrelationId()) && Objects.equals(getReRunFromWorkflowId(), workflow.getReRunFromWorkflowId()) && Objects.equals(getReasonForIncompletion(), workflow.getReasonForIncompletion()) && Objects.equals(getEvent(), workflow.getEvent()) && Objects.equals(getTaskToDomain(), workflow.getTaskToDomain()) && Objects.equals(getFailedReferenceTaskNames(), workflow.getFailedReferenceTaskNames()) && Objects.equals(getExternalInputPayloadStoragePath(), workflow.getExternalInputPayloadStoragePath()) && Objects.equals(getExternalOutputPayloadStoragePath(), workflow.getExternalOutputPayloadStoragePath()) && Objects.equals(getWorkflowDefinition(), workflow.getWorkflowDefinition()); }
public Workflow populateWorkflowWithDefinitions(Workflow workflow) { WorkflowDef workflowDefinition = Optional.ofNullable(workflow.getWorkflowDefinition()) .orElseGet(() -> { WorkflowDef wd = lookupForWorkflowDefinition(workflow.getWorkflowName(), workflow.getWorkflowVersion()); workflow.setWorkflowDefinition(wd); return wd; }); workflowDefinition.collectTasks().forEach( workflowTask -> { if (shouldPopulateDefinition(workflowTask)) { workflowTask.setTaskDefinition(metadataDAO.getTaskDef(workflowTask.getName())); } else if (workflowTask.getType().equals(TaskType.SUB_WORKFLOW.name())) { populateVersionForSubWorkflow(workflowTask); } } ); checkNotEmptyDefinitions(workflowDefinition); return workflow; }
private String insertOrUpdateWorkflow(Workflow workflow, boolean update) { Preconditions.checkNotNull(workflow, "workflow object cannot be null"); boolean terminal = workflow.getStatus().isTerminal(); if (terminal) { workflow.setEndTime(System.currentTimeMillis()); } List<Task> tasks = workflow.getTasks(); workflow.setTasks(Lists.newLinkedList()); withTransaction(tx -> { if (!update) { addWorkflow(tx, workflow); addWorkflowDefToWorkflowMapping(tx, workflow); } else { updateWorkflow(tx, workflow); } if (terminal) { removePendingWorkflow(tx, workflow.getWorkflowName(), workflow.getWorkflowId()); } else { addPendingWorkflow(tx, workflow.getWorkflowName(), workflow.getWorkflowId()); } }); workflow.setTasks(tasks); return workflow.getWorkflowId(); }
private void addWorkflowDefToWorkflowMapping(Connection connection, Workflow workflow) { String INSERT_WORKFLOW_DEF_TO_WORKFLOW = "INSERT INTO workflow_def_to_workflow (workflow_def, date_str, workflow_id) VALUES (?, ?, ?)"; execute(connection, INSERT_WORKFLOW_DEF_TO_WORKFLOW, q -> q.addParameter(workflow.getWorkflowName()).addParameter(dateStr(workflow.getCreateTime())) .addParameter(workflow.getWorkflowId()).executeUpdate()); }
private void removeWorkflowDefToWorkflowMapping(Connection connection, Workflow workflow) { String REMOVE_WORKFLOW_DEF_TO_WORKFLOW = "DELETE FROM workflow_def_to_workflow WHERE workflow_def = ? AND date_str = ? AND workflow_id = ?"; execute(connection, REMOVE_WORKFLOW_DEF_TO_WORKFLOW, q -> q.addParameter(workflow.getWorkflowName()).addParameter(dateStr(workflow.getCreateTime())) .addParameter(workflow.getWorkflowId()).executeUpdate()); }
eventTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); eventTask.setWorkflowInstanceId(workflowInstance.getWorkflowId()); eventTask.setWorkflowType(workflowInstance.getWorkflowName()); eventTask.setCorrelationId(workflowInstance.getCorrelationId()); eventTask.setScheduledTime(System.currentTimeMillis());
@Override public boolean removeWorkflow(String workflowId) { Workflow workflow = getWorkflow(workflowId, true); if (workflow != null) { recordRedisDaoRequests("removeWorkflow"); // Remove from lists String key = nsKey(WORKFLOW_DEF_TO_WORKFLOWS, workflow.getWorkflowName(), dateStr(workflow.getCreateTime())); dynoClient.srem(key, workflowId); dynoClient.srem(nsKey(CORR_ID_TO_WORKFLOWS, workflow.getCorrelationId()), workflowId); dynoClient.srem(nsKey(PENDING_WORKFLOWS, workflow.getWorkflowName()), workflowId); // Remove the object dynoClient.del(nsKey(WORKFLOW, workflowId)); for (Task task : workflow.getTasks()) { removeTask(task.getTaskId()); } return true; } return false; }
@Override public boolean removeWorkflow(String workflowId) { boolean removed = false; Workflow workflow = getWorkflow(workflowId, true); if (workflow != null) { withTransaction(connection -> { removeWorkflowDefToWorkflowMapping(connection, workflow); removeWorkflow(connection, workflowId); removePendingWorkflow(connection, workflow.getWorkflowName(), workflowId); }); removed = true; for (Task task : workflow.getTasks()) { if (!removeTask(task.getTaskId())) { removed = false; } } } return removed; }
/** * This method creates a JOIN task that is used in the {@link this#getMappedTasks(TaskMapperContext)} * at the end to add a join task to be scheduled after all the fork tasks * * @param workflowInstance: A instance of the {@link Workflow} which represents the workflow being executed. * @param joinWorkflowTask: A instance of {@link WorkflowTask} which is of type {@link TaskType#JOIN} * @param joinInput: The input which is set in the {@link Task#setInputData(Map)} * @return a new instance of {@link Task} representing a {@link SystemTaskType#JOIN} */ @VisibleForTesting Task createJoinTask(Workflow workflowInstance, WorkflowTask joinWorkflowTask, HashMap<String, Object> joinInput) { Task joinTask = new Task(); joinTask.setTaskType(SystemTaskType.JOIN.name()); joinTask.setTaskDefName(SystemTaskType.JOIN.name()); joinTask.setReferenceTaskName(joinWorkflowTask.getTaskReferenceName()); joinTask.setWorkflowInstanceId(workflowInstance.getWorkflowId()); joinTask.setWorkflowType(workflowInstance.getWorkflowName()); joinTask.setCorrelationId(workflowInstance.getCorrelationId()); joinTask.setScheduledTime(System.currentTimeMillis()); joinTask.setInputData(joinInput); joinTask.setTaskId(IDGenerator.generate()); joinTask.setStatus(Task.Status.IN_PROGRESS); joinTask.setWorkflowTask(joinWorkflowTask); return joinTask; }
@Override public List<Task> getMappedTasks(TaskMapperContext taskMapperContext) { logger.debug("TaskMapperContext {} in WaitTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); Map<String, Object> waitTaskInput = parametersUtils.getTaskInputV2(taskMapperContext.getTaskToSchedule().getInputParameters(), workflowInstance, taskId, null); Task waitTask = new Task(); waitTask.setTaskType(Wait.NAME); waitTask.setTaskDefName(taskMapperContext.getTaskToSchedule().getName()); waitTask.setReferenceTaskName(taskMapperContext.getTaskToSchedule().getTaskReferenceName()); waitTask.setWorkflowInstanceId(workflowInstance.getWorkflowId()); waitTask.setWorkflowType(workflowInstance.getWorkflowName()); waitTask.setCorrelationId(workflowInstance.getCorrelationId()); waitTask.setScheduledTime(System.currentTimeMillis()); waitTask.setInputData(waitTaskInput); waitTask.setTaskId(taskId); waitTask.setStatus(Task.Status.IN_PROGRESS); waitTask.setWorkflowTask(taskToSchedule); return Collections.singletonList(waitTask); } }
@Override public int hashCode() { return Objects.hash( getStatus(), getEndTime(), getWorkflowId(), getParentWorkflowId(), getParentWorkflowTaskId(), getTasks(), getInput(), getOutput(), getWorkflowName(), getWorkflowVersion(), getCorrelationId(), getReRunFromWorkflowId(), getReasonForIncompletion(), getSchemaVersion(), getEvent(), getTaskToDomain(), getFailedReferenceTaskNames(), getWorkflowDefinition(), getExternalInputPayloadStoragePath(), getExternalOutputPayloadStoragePath() ); } }