
com.talanlabs.taskmanager.engine.TaskManagerEngine Maven / Gradle / Ivy
The newest version!
package com.talanlabs.taskmanager.engine;
import com.talanlabs.taskmanager.engine.configuration.ITaskManagerConfiguration;
import com.talanlabs.taskmanager.engine.configuration.transform.ITaskChainCriteriaTransform;
import com.talanlabs.taskmanager.engine.graph.IStatusGraph;
import com.talanlabs.taskmanager.engine.listener.ITaskCycleListener;
import com.talanlabs.taskmanager.engine.manager.ITaskObjectManager;
import com.talanlabs.taskmanager.engine.task.ICommonTask;
import com.talanlabs.taskmanager.engine.task.IStatusTask;
import com.talanlabs.taskmanager.engine.task.ISubTask;
import com.talanlabs.taskmanager.engine.taskdefinition.ITaskDefinition;
import com.talanlabs.taskmanager.engine.taskservice.ITaskService;
import com.talanlabs.taskmanager.model.ITaskCluster;
import com.talanlabs.taskmanager.model.ITaskObject;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.swing.event.EventListenerList;
import java.util.*;
import java.util.Map.Entry;
public class TaskManagerEngine {
private static final Log LOG = LogFactory.getLog(TaskManagerEngine.class);
private static final ExecuteTaskListener TODO_EXECUTE_TASK_LISTENER = ITaskCycleListener::onTodo;
private static final ExecuteTaskListener CURRENT_EXECUTE_TASK_LISTENER = ITaskCycleListener::onCurrent;
private static final ExecuteTaskListener DONE_EXECUTE_TASK_LISTENER = ITaskCycleListener::onDone;
private static final ExecuteTaskListener NOTHING_EXECUTE_TASK_LISTENER = ITaskCycleListener::onNothing;
private static final ExecuteTaskListener DELETE_EXECUTE_TASK_LISTENER = ITaskCycleListener::onDelete;
private ITaskManagerConfiguration taskManagerConfiguration;
private EventListenerList eventListenerList;
// Start engine
public TaskManagerEngine(ITaskManagerConfiguration taskManagerConfiguration) {
super();
this.taskManagerConfiguration = taskManagerConfiguration;
this.eventListenerList = new EventListenerList();
}
public ITaskManagerConfiguration getTaskManagerConfiguration() {
return taskManagerConfiguration;
}
public void addTaskManagerListener(ITaskCycleListener taskManagerListener) {
eventListenerList.add(ITaskCycleListener.class, taskManagerListener);
}
public void removeTaskManagerListener(ITaskCycleListener taskManagerListener) {
eventListenerList.remove(ITaskCycleListener.class, taskManagerListener);
}
public ITaskCycleListener[] getTaskCycleListeners() {
return eventListenerList.getListeners(ITaskCycleListener.class);
}
/**
* @param taskObjects
* @return
*/
public ITaskCluster startEngine(ITaskObject... taskObjects) {
if (taskObjects == null || taskObjects.length == 0) {
return null;
}
Set taskClusters = new HashSet<>();
Set createClusters = new HashSet<>();
for (ITaskObject taskObject : taskObjects) {
if (taskObject != null) {
// If cluster not existe, create
ITaskCluster taskCluster = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (taskCluster == null) {
createClusters.add(taskObject);
} else {
taskClusters.add(taskCluster);
}
}
}
ITaskCluster res = null;
if (!createClusters.isEmpty()) {
res = createTaskCluster(createClusters.toArray(new ITaskObject[createClusters.size()]));
taskClusters.add(res);
} else if (taskClusters.size() == 1) {
res = taskClusters.iterator().next();
}
startEngine(taskClusters.toArray(new ITaskCluster[taskClusters.size()]));
return res;
}
// Private Methods
/**
* Start engin for taskCluster
*
* @param taskClusters
* @return
*/
public void startEngine(ITaskCluster... taskClusters) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - StartEngine");
}
if (taskClusters == null || taskClusters.length == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, cluster is null or empty");
}
return;
}
LinkedList restartClusters = new LinkedList<>();
for (ITaskCluster taskCluster : taskClusters) {
if (taskCluster != null && !taskCluster.isCheckArchived() && !restartClusters.contains(taskCluster)) {
restartClusters.add(taskCluster);
}
}
while (!restartClusters.isEmpty()) {
ITaskCluster taskCluster = restartClusters.removeFirst();
boolean restart = false;
// Find all current task for cluster
List extends ICommonTask> tasks = getTaskManagerConfiguration().getTaskManagerReader().findCurrentTasksByTaskCluster(taskCluster);
if (tasks == null || tasks.isEmpty()) {
if (taskCluster != null && !taskCluster.isCheckGraphCreated()) {
createTaskGraphsForTaskCluster(taskCluster);
restartClusters.add(taskCluster);
} else {
getTaskManagerConfiguration().getTaskManagerWriter().archiveTaskCluster(taskCluster);
}
} else {
LinkedList tasksQueue = new LinkedList<>(tasks);
List recycleList = new ArrayList<>();
while (!tasksQueue.isEmpty()) {
ICommonTask task = tasksQueue.removeFirst();
restart = startEngineExecuteTask(taskCluster, task, tasksQueue, recycleList, restartClusters);
if (restart) {
break;
}
}
if (!restart && recycleList.isEmpty()) {
getTaskManagerConfiguration().getTaskManagerWriter().archiveTaskCluster(taskCluster);
}
}
}
}
private boolean startEngineExecuteTask(ITaskCluster taskCluster, ICommonTask task, LinkedList tasksQueue, List recycleList, LinkedList restartClusters) {
boolean restart = false;
boolean done = true;
Exception errorMessage = null;
Object taskServiceResult = null;
boolean noChanges = false;
if (task.getCodeTaskDefinition() != null) {
ITaskDefinition taskDefinition = getTaskManagerConfiguration().getTaskDefinitionRegistry().getTaskDefinition(task.getCodeTaskDefinition());
if (taskDefinition == null || taskDefinition.getTaskService() == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - TaskService does not exist code=" + task.getCodeTaskDefinition());
}
done = false;
errorMessage = new NotFoundTaskDefinitionException();
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Execute taskService code=" + task.getCodeTaskDefinition());
}
ITaskService taskService = taskDefinition.getTaskService();
try {
MyEngineContext context = new MyEngineContext(taskCluster, taskDefinition);
ITaskService.IExecutionResult executionResult = taskService.execute(context, task);
if (executionResult == null) {
throw new NullTaskExecutionException();
} else {
done = executionResult.isFinished();
taskServiceResult = executionResult.getResult();
noChanges = executionResult.isNoChanges();
if (executionResult.mustStopAndRestartTaskManager()) {
restart = true;
restartClusters.add(taskCluster);
}
if (done) {
executeContext(context, restartClusters);
restart = restartClusters.contains(taskCluster);
}
}
} catch (Exception t) {
LOG.error("TM - Error taskService code=" + task.getCodeTaskDefinition(), t);
errorMessage = t;
done = false;
}
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Finish code=" + task.getCodeTaskDefinition() + (done ? " - Success" : " - Failure"));
}
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - TaskService is null");
}
}
startEngineDone(taskCluster, task, done, taskServiceResult, noChanges, errorMessage, tasksQueue, recycleList);
return restart;
}
private void startEngineDone(ITaskCluster taskCluster, ICommonTask task, boolean done, Object taskServiceResult, boolean noChanges, Exception errorMessage, LinkedList tasksQueue,
List recycleList) {
if (done) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Task is done");
}
try {
TasksLists tasksLists = setTaskDone(taskCluster, task, taskServiceResult);
// Add new tasks to top of deque
if (tasksLists.newCurrentTasks != null && !tasksLists.newCurrentTasks.isEmpty()) {
tasksLists.newCurrentTasks.forEach(tasksQueue::addFirst);
}
if (tasksLists.tasksToRemoves != null && !tasksLists.tasksToRemoves.isEmpty()) {
for (ICommonTask idTask : tasksLists.tasksToRemoves) {
for (Iterator iterator = recycleList.iterator(); iterator.hasNext(); ) {
ICommonTask iTask = iterator.next();
if (idTask.equals(iTask)) {
iterator.remove();
break;
}
}
for (Iterator iterator = tasksQueue.iterator(); iterator.hasNext(); ) {
ICommonTask iTask = iterator.next();
if (idTask.equals(iTask)) {
iterator.remove();
break;
}
}
}
}
if (!noChanges) {
// Add previously failed tasks to end of deque. Not done when service nature is not DATA_CHECK because DATA_CHECK does not update objects.
recycleList.forEach(tasksQueue::addLast);
recycleList.clear();
}
} catch (Exception t) {
LOG.error("TM - Error setTaskDone " + task.getCodeTaskDefinition(), t);
setTaskNothing(taskCluster, task, taskServiceResult, t);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Task did nothing");
}
setTaskNothing(taskCluster, task, taskServiceResult, errorMessage);
recycleList.add(task);
}
}
/**
* Add task objects in task cluster and startEngine
*
* @param taskCluster
* @param taskObjects
*/
public void addTaskObjectsToTaskCluster(ITaskCluster taskCluster, ITaskObject... taskObjects) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - addTaskObjectsToTaskCluster");
}
if (taskCluster == null || taskCluster.isCheckArchived()) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, cluster is null or archived");
}
return;
}
if (taskObjects == null || taskObjects.length == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, taskObject is null");
}
return;
}
List adds = new ArrayList<>();
for (ITaskObject taskObject : taskObjects) {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, taskObject is other or same in cluster");
}
} else {
adds.add(taskObject);
}
}
}
createTaskGraphForTaskCluster(taskCluster, adds.toArray(new ITaskObject[adds.size()]));
startEngine(taskCluster);
}
/**
* Remove task objects in task cluster and startEngine
*
* @param taskObjects
*/
public void removeTaskObjectsFromTaskCluster(ITaskObject... taskObjects) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - removeTaskObjectsFromTaskCluster");
}
if (taskObjects == null || taskObjects.length == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, taskObject is null");
}
return;
}
Map> modifyClusterMap = new HashMap<>();
for (ITaskObject taskObject : taskObjects) {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null) {
List tos = modifyClusterMap.get(tc);
if (tos == null) {
tos = new ArrayList<>();
modifyClusterMap.put(tc, tos);
}
if (!tos.contains(taskObject)) {
tos.add(taskObject);
}
}
}
}
for (Entry> entry : modifyClusterMap.entrySet()) {
getTaskManagerConfiguration().getTaskManagerWriter().saveRemoveTaskObjectsFromTaskCluster(entry.getKey(), entry.getValue());
}
startEngine(modifyClusterMap.keySet().toArray(new ITaskCluster[modifyClusterMap.size()]));
}
/**
* Move task objects (with other cluster) to new task cluster, start engin on all cluster
*
* @param taskObjects
* @return
*/
public ITaskCluster moveTaskObjectsToNewTaskCluster(ITaskObject... taskObjects) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - moveTaskObjectsToNewTaskCluster");
}
if (taskObjects == null || taskObjects.length == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, taskObject is null");
}
return null;
}
Map> modifyClusterMap = new HashMap<>();
for (ITaskObject taskObject : taskObjects) {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null) {
List tos = modifyClusterMap.get(tc);
if (tos == null) {
tos = new ArrayList<>();
modifyClusterMap.put(tc, tos);
}
if (!tos.contains(taskObject)) {
tos.add(taskObject);
}
}
}
}
ITaskCluster taskCluster = null;
if (!modifyClusterMap.isEmpty()) {
taskCluster = getTaskManagerConfiguration().getTaskFactory().newTaskCluster();
taskCluster = getTaskManagerConfiguration().getTaskManagerWriter().saveNewTaskCluster(taskCluster);
taskCluster = getTaskManagerConfiguration().getTaskManagerWriter().saveMoveTaskObjectsToTaskCluster(taskCluster, modifyClusterMap);
List cs = new ArrayList<>(modifyClusterMap.keySet());
cs.add(taskCluster);
startEngine(cs.toArray(new ITaskCluster[cs.size()]));
}
return taskCluster;
}
/**
* Move task objects (with other cluster) to task cluster, start engin on all cluster
*
* @param dstTaskCluster
* @param taskObjects
*/
public void moveTaskObjectsToTaskCluster(ITaskCluster dstTaskCluster, ITaskObject... taskObjects) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - addTaskObjectsToTaskCluster");
}
if (dstTaskCluster == null || dstTaskCluster.isCheckArchived()) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, cluster is null or archived");
}
return;
}
if (taskObjects == null || taskObjects.length == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, taskObject is null");
}
return;
}
Map> modifyClusterMap = new HashMap<>();
for (ITaskObject taskObject : taskObjects) {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null && !tc.equals(dstTaskCluster)) {
List tos = modifyClusterMap.get(tc);
if (tos == null) {
tos = new ArrayList<>();
modifyClusterMap.put(tc, tos);
}
if (!tos.contains(taskObject)) {
tos.add(taskObject);
}
}
}
}
if (!modifyClusterMap.isEmpty()) {
getTaskManagerConfiguration().getTaskManagerWriter().saveMoveTaskObjectsToTaskCluster(dstTaskCluster, modifyClusterMap);
List cs = new ArrayList<>(modifyClusterMap.keySet());
cs.add(dstTaskCluster);
startEngine(cs.toArray(new ITaskCluster[cs.size()]));
}
}
private void executeContext(MyEngineContext context, LinkedList restartClusters) {
context.lock = true;
executeContextStartEngine(context, restartClusters);
executeContextAddRemove(context, restartClusters);
executeContextMove(context, restartClusters);
}
private void executeContextStartEngine(MyEngineContext context, LinkedList restartClusters) {
// Start engine from task objects
context.startEngineTaskObjects.forEach(pair -> {
Set taskClusters = new HashSet<>();
Set createClusters = new HashSet<>();
pair.getLeft().stream().filter(taskObject -> taskObject != null).forEach(taskObject -> {
// If cluster not existe, create
ITaskCluster taskCluster = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (taskCluster == null) {
createClusters.add(taskObject);
} else {
taskClusters.add(taskCluster);
}
});
ITaskCluster res = null;
if (!createClusters.isEmpty()) {
res = createTaskCluster(createClusters.toArray(new ITaskObject[createClusters.size()]));
taskClusters.add(res);
} else if (taskClusters.size() == 1) {
res = taskClusters.iterator().next();
}
restartClusters.addAll(taskClusters);
if (pair.getRight() != null) {
pair.getRight().setTaskCluster(res);
}
});
// Start engine from cluster
restartClusters.addAll(context.startEngineTaskClusters);
}
private void executeContextAddRemove(MyEngineContext context, LinkedList restartClusters) {
// Add
context.addToTaskClusters.forEach(pair -> {
List adds = new ArrayList<>();
pair.getRight().stream().filter(taskObject -> taskObject != null).forEach(taskObject -> {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("TM - Nothing, taskObject is other or same in cluster");
}
} else {
adds.add(taskObject);
}
});
createTaskGraphForTaskCluster(pair.getLeft(), adds.toArray(new ITaskObject[adds.size()]));
restartClusters.add(pair.getLeft());
});
// Remove
Map> modifyClusterMap = new HashMap<>();
context.removeFromTaskClusters.stream().filter(taskObject -> taskObject != null).forEach(taskObject -> {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null) {
List tos = modifyClusterMap.get(tc);
if (tos == null) {
tos = new ArrayList<>();
modifyClusterMap.put(tc, tos);
}
if (!tos.contains(taskObject)) {
tos.add(taskObject);
}
}
}
});
for (Entry> entry : modifyClusterMap.entrySet()) {
getTaskManagerConfiguration().getTaskManagerWriter().saveRemoveTaskObjectsFromTaskCluster(entry.getKey(), entry.getValue());
}
restartClusters.addAll(modifyClusterMap.keySet());
}
// Task creation
private void executeContextMove(MyEngineContext context, LinkedList restartClusters) {
// Move to new cluster
context.moveToNewTaskClusters.forEach(pair -> {
Map> modifyClusterMap = new HashMap<>();
for (ITaskObject taskObject : pair.getLeft()) {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null) {
List tos = modifyClusterMap.get(tc);
if (tos == null) {
tos = new ArrayList<>();
modifyClusterMap.put(tc, tos);
}
if (!tos.contains(taskObject)) {
tos.add(taskObject);
}
}
}
}
ITaskCluster taskCluster = null;
if (!modifyClusterMap.isEmpty()) {
taskCluster = getTaskManagerConfiguration().getTaskFactory().newTaskCluster();
taskCluster = getTaskManagerConfiguration().getTaskManagerWriter().saveNewTaskCluster(taskCluster);
taskCluster = getTaskManagerConfiguration().getTaskManagerWriter().saveMoveTaskObjectsToTaskCluster(taskCluster, modifyClusterMap);
List cs = new ArrayList<>(modifyClusterMap.keySet());
cs.add(taskCluster);
restartClusters.addAll(cs);
}
if (pair.getRight() != null) {
pair.getRight().setTaskCluster(taskCluster);
}
});
// Move
context.moveToTaskClusters.forEach(pair -> {
Map> modifyClusterMap = new HashMap<>();
ITaskCluster dstTaskCluster = pair.getLeft();
for (ITaskObject taskObject : pair.getRight()) {
if (taskObject != null) {
ITaskCluster tc = getTaskManagerConfiguration().getTaskManagerReader().findTaskClusterByTaskObject(taskObject);
if (tc != null && !tc.equals(pair.getLeft())) {
List tos = modifyClusterMap.get(tc);
if (tos == null) {
tos = new ArrayList<>();
modifyClusterMap.put(tc, tos);
}
if (!tos.contains(taskObject)) {
tos.add(taskObject);
}
}
}
}
if (!modifyClusterMap.isEmpty()) {
getTaskManagerConfiguration().getTaskManagerWriter().saveMoveTaskObjectsToTaskCluster(dstTaskCluster, modifyClusterMap);
List cs = new ArrayList<>(modifyClusterMap.keySet());
cs.add(dstTaskCluster);
restartClusters.addAll(cs);
}
});
}
/*
* Set task as nothing
*/
private void setTaskNothing(ITaskCluster taskCluster, ICommonTask task, Object taskServiceResult, Throwable throwable) {
getTaskManagerConfiguration().getTaskManagerWriter().saveNothingTask(taskCluster, task, taskServiceResult, throwable);
onNothingTasks(taskCluster, Collections.singletonList(task));
}
/*
* Set task Done and move others tasks
*/
private TasksLists setTaskDone(ITaskCluster taskCluster, ICommonTask task, Object taskServiceResult) {
return nextTasks(taskCluster, task, taskServiceResult);
}
@SuppressWarnings("unchecked")
private TasksLists nextTasks(ITaskCluster taskCluster, ICommonTask toDoneTask, Object taskServiceResult) {
TasksLists tasksLists = new TasksLists();
List nextTodoTasks = new ArrayList<>();
List nextCurrentTasks = new ArrayList<>();
List toDeleteTasks = new ArrayList<>();
if (getTaskManagerConfiguration().getTaskFactory().isStatusTask(toDoneTask)) {
nextTasksForStatusTask(taskCluster, toDoneTask, taskServiceResult, nextTodoTasks, nextCurrentTasks, toDeleteTasks);
} else if (getTaskManagerConfiguration().getTaskFactory().isSubTask(toDoneTask)) {
nextTasksForSubTask(taskCluster, toDoneTask, taskServiceResult, nextCurrentTasks);
}
onDoneTasks(taskCluster, Collections.singletonList(toDoneTask));
onTodoTasks(taskCluster, nextTodoTasks);
onCurrentTasks(taskCluster, nextCurrentTasks);
onDeleteTasks(taskCluster, toDeleteTasks);
tasksLists.newCurrentTasks = nextCurrentTasks;
tasksLists.tasksToRemoves = toDeleteTasks;
return tasksLists;
}
private void nextTasksForStatusTask(ITaskCluster taskCluster, ICommonTask toDoneTask, Object taskServiceResult, List nextTodoTasks, List nextCurrentTasks,
List toDeleteTasks) {
IStatusTask statusTask = (IStatusTask) toDoneTask;
Class extends ITaskObject> taskObjectClass = statusTask.getTaskObjectClass();
List extends ICommonTask> oldOtherPreviousNextTasks = getTaskManagerConfiguration().getTaskManagerReader().findOtherBranchFirstTasksByStatusTask(statusTask);
if (oldOtherPreviousNextTasks != null && !oldOtherPreviousNextTasks.isEmpty()) {
toDeleteTasks.addAll(extractAllTasks(oldOtherPreviousNextTasks));
}
ITaskObjectManager
© 2015 - 2025 Weber Informatics LLC | Privacy Policy