use of com.netflix.conductor.core.execution.TerminateWorkflowException in project conductor by Netflix.
the class UserDefinedTaskMapper method getMappedTasks.
/**
* This method maps a {@link WorkflowTask} of type {@link TaskType#USER_DEFINED}
* to a {@link Task} in a {@link Task.Status#SCHEDULED} state
*
* @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link WorkflowDef}, {@link Workflow} and a string representation of the TaskId
* @return a List with just one User defined task
* @throws TerminateWorkflowException In case if the task definition does not exist
*/
@Override
public List<Task> getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException {
logger.debug("TaskMapperContext {} in UserDefinedTaskMapper", taskMapperContext);
WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule();
Workflow workflowInstance = taskMapperContext.getWorkflowInstance();
String taskId = taskMapperContext.getTaskId();
int retryCount = taskMapperContext.getRetryCount();
TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()).orElseGet(() -> Optional.ofNullable(metadataDAO.getTaskDef(taskToSchedule.getName())).orElseThrow(() -> {
String reason = String.format("Invalid task specified. Cannot find task by name %s in the task definitions", taskToSchedule.getName());
return new TerminateWorkflowException(reason);
}));
Map<String, Object> input = parametersUtils.getTaskInputV2(taskToSchedule.getInputParameters(), workflowInstance, taskId, taskDefinition);
Task userDefinedTask = new Task();
userDefinedTask.setTaskType(taskToSchedule.getType());
userDefinedTask.setTaskDefName(taskToSchedule.getName());
userDefinedTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName());
userDefinedTask.setWorkflowInstanceId(workflowInstance.getWorkflowId());
userDefinedTask.setWorkflowType(workflowInstance.getWorkflowName());
userDefinedTask.setCorrelationId(workflowInstance.getCorrelationId());
userDefinedTask.setScheduledTime(System.currentTimeMillis());
userDefinedTask.setTaskId(taskId);
userDefinedTask.setInputData(input);
userDefinedTask.setStatus(Task.Status.SCHEDULED);
userDefinedTask.setRetryCount(retryCount);
userDefinedTask.setCallbackAfterSeconds(taskToSchedule.getStartDelay());
userDefinedTask.setWorkflowTask(taskToSchedule);
userDefinedTask.setWorkflowPriority(workflowInstance.getPriority());
userDefinedTask.setRateLimitPerFrequency(taskDefinition.getRateLimitPerFrequency());
userDefinedTask.setRateLimitFrequencyInSeconds(taskDefinition.getRateLimitFrequencyInSeconds());
return Collections.singletonList(userDefinedTask);
}
use of com.netflix.conductor.core.execution.TerminateWorkflowException in project conductor by Netflix.
the class ForkJoinDynamicTaskMapper method getDynamicForkJoinTasksAndInput.
/**
* This method is used to get the List of dynamic workflow tasks and their input based on the {@link WorkflowTask#getDynamicForkJoinTasksParam()}
* <p><b>NOTE:</b> This method is kept for legacy reasons, new workflows should use the {@link #getDynamicForkTasksAndInput}</p>
*
* @param taskToSchedule: The Task of type FORK_JOIN_DYNAMIC that needs to scheduled, which has the input parameters
* @param workflowInstance: The instance of the {@link Workflow} which represents the workflow being executed.
* @return {@link Pair} representing the list of dynamic fork tasks in {@link Pair#getLeft()} and the input for the dynamic fork tasks in {@link Pair#getRight()}
* @throws TerminateWorkflowException : In case of the {@link WorkflowTask#getInputParameters()} does not have a payload that contains the list of the dynamic tasks
*/
@VisibleForTesting
Pair<List<WorkflowTask>, Map<String, Map<String, Object>>> getDynamicForkJoinTasksAndInput(WorkflowTask taskToSchedule, Workflow workflowInstance) throws TerminateWorkflowException {
String dynamicForkJoinTaskParam = taskToSchedule.getDynamicForkJoinTasksParam();
Map<String, Object> input = parametersUtils.getTaskInput(taskToSchedule.getInputParameters(), workflowInstance, null, null);
Object paramValue = input.get(dynamicForkJoinTaskParam);
DynamicForkJoinTaskList dynamicForkJoinTaskList = objectMapper.convertValue(paramValue, DynamicForkJoinTaskList.class);
if (dynamicForkJoinTaskList == null) {
String reason = String.format("Dynamic tasks could not be created. The value of %s from task's input %s has no dynamic tasks to be scheduled", dynamicForkJoinTaskParam, input);
logger.error(reason);
throw new TerminateWorkflowException(reason);
}
Map<String, Map<String, Object>> dynamicForkJoinTasksInput = new HashMap<>();
List<WorkflowTask> dynamicForkJoinWorkflowTasks = dynamicForkJoinTaskList.getDynamicTasks().stream().peek(// TODO create a custom pair collector
dynamicForkJoinTask -> dynamicForkJoinTasksInput.put(dynamicForkJoinTask.getReferenceName(), dynamicForkJoinTask.getInput())).map(dynamicForkJoinTask -> {
WorkflowTask dynamicForkJoinWorkflowTask = new WorkflowTask();
dynamicForkJoinWorkflowTask.setTaskReferenceName(dynamicForkJoinTask.getReferenceName());
dynamicForkJoinWorkflowTask.setName(dynamicForkJoinTask.getTaskName());
dynamicForkJoinWorkflowTask.setType(dynamicForkJoinTask.getType());
if (dynamicForkJoinWorkflowTask.getTaskDefinition() == null && StringUtils.isNotBlank(dynamicForkJoinWorkflowTask.getName())) {
dynamicForkJoinWorkflowTask.setTaskDefinition(metadataDAO.getTaskDef(dynamicForkJoinTask.getTaskName()));
}
return dynamicForkJoinWorkflowTask;
}).collect(Collectors.toCollection(LinkedList::new));
return new ImmutablePair<>(dynamicForkJoinWorkflowTasks, dynamicForkJoinTasksInput);
}
use of com.netflix.conductor.core.execution.TerminateWorkflowException in project conductor by Netflix.
the class ForkJoinTaskMapper method getMappedTasks.
/**
* This method gets the list of tasks that need to scheduled when the task to scheduled is of type {@link TaskType#FORK_JOIN}.
*
* @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link WorkflowDef}, {@link Workflow} and a string representation of the TaskId
* @return List of tasks in the following order:
* * <ul>
* <li>
* {@link SystemTaskType#FORK} with {@link Task.Status#COMPLETED}
* </li>
* <li>
* Might be any kind of task, but in most cases is a UserDefinedTask with {@link Task.Status#SCHEDULED}
* </li>
* </ul>
* @throws TerminateWorkflowException When the task after {@link TaskType#FORK_JOIN} is not a {@link TaskType#JOIN}
*/
@Override
public List<Task> getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException {
logger.debug("TaskMapperContext {} in ForkJoinTaskMapper", taskMapperContext);
WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule();
Map<String, Object> taskInput = taskMapperContext.getTaskInput();
Workflow workflowInstance = taskMapperContext.getWorkflowInstance();
int retryCount = taskMapperContext.getRetryCount();
String taskId = taskMapperContext.getTaskId();
List<Task> tasksToBeScheduled = new LinkedList<>();
Task forkTask = new Task();
forkTask.setTaskType(SystemTaskType.FORK.name());
forkTask.setTaskDefName(SystemTaskType.FORK.name());
forkTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName());
forkTask.setWorkflowInstanceId(workflowInstance.getWorkflowId());
forkTask.setWorkflowType(workflowInstance.getWorkflowName());
forkTask.setCorrelationId(workflowInstance.getCorrelationId());
forkTask.setScheduledTime(System.currentTimeMillis());
forkTask.setStartTime(System.currentTimeMillis());
forkTask.setInputData(taskInput);
forkTask.setTaskId(taskId);
forkTask.setStatus(Task.Status.COMPLETED);
forkTask.setWorkflowPriority(workflowInstance.getPriority());
forkTask.setWorkflowTask(taskToSchedule);
tasksToBeScheduled.add(forkTask);
List<List<WorkflowTask>> forkTasks = taskToSchedule.getForkTasks();
for (List<WorkflowTask> wfts : forkTasks) {
WorkflowTask wft = wfts.get(0);
List<Task> tasks2 = taskMapperContext.getDeciderService().getTasksToBeScheduled(workflowInstance, wft, retryCount);
tasksToBeScheduled.addAll(tasks2);
}
WorkflowTask joinWorkflowTask = workflowInstance.getWorkflowDefinition().getNextTask(taskToSchedule.getTaskReferenceName());
if (joinWorkflowTask == null || !joinWorkflowTask.getType().equals(TaskType.JOIN.name())) {
throw new TerminateWorkflowException("Fork task definition is not followed by a join task. Check the blueprint");
}
return tasksToBeScheduled;
}
use of com.netflix.conductor.core.execution.TerminateWorkflowException in project conductor by Netflix.
the class DecisionTaskMapper method getEvaluatedCaseValue.
/**
* This method evaluates the case expression of a decision task and returns a string representation of the evaluated result.
*
* @param taskToSchedule: The decision task that has the case expression to be evaluated.
* @param taskInput: the input which has the values that will be used in evaluating the case expression.
* @return A String representation of the evaluated result
*/
@VisibleForTesting
String getEvaluatedCaseValue(WorkflowTask taskToSchedule, Map<String, Object> taskInput) {
String expression = taskToSchedule.getCaseExpression();
String caseValue;
if (StringUtils.isNotBlank(expression)) {
logger.debug("Case being evaluated using decision expression: {}", expression);
try {
// Evaluate the expression by using the Nashhorn based script evaluator
Object returnValue = ScriptEvaluator.eval(expression, taskInput);
caseValue = (returnValue == null) ? "null" : returnValue.toString();
} catch (ScriptException e) {
String errorMsg = String.format("Error while evaluating script: %s", expression);
logger.error(errorMsg, e);
throw new TerminateWorkflowException(errorMsg);
}
} else {
// In case of no case expression, get the caseValueParam and treat it as a string representation of caseValue
logger.debug("No Expression available on the decision task, case value being assigned as param name");
String paramName = taskToSchedule.getCaseValueParam();
caseValue = "" + taskInput.get(paramName);
}
return caseValue;
}
Aggregations