use of eu.bcvsolutions.idm.core.scheduler.api.domain.IdmCheckConcurrentExecution in project CzechIdMng by bcvsolutions.
the class DefaultLongRunningTaskManager method processCreated.
/**
* Executes long running task on this instance
*/
@Override
@Transactional
public synchronized List<LongRunningFutureTask<?>> processCreated() {
String instanceId = configurationService.getInstanceId();
LOG.debug("Processing created tasks from long running task queue on instance id [{}]", instanceId);
// Prevent to mess up logged identity authentication => tasks can be started manually => will be visible in audit
if (!securityService.isAuthenticated()) {
securityService.setSystemAuthentication();
}
//
Set<String> processedTaskTypes = Sets.newHashSet();
List<LongRunningFutureTask<?>> taskList = new ArrayList<LongRunningFutureTask<?>>();
for (IdmLongRunningTaskDto task : service.findAllByInstance(instanceId, OperationState.CREATED)) {
String taskType = task.getTaskType();
UUID taskId = task.getId();
//
if (processedTaskTypes.contains(taskType)) {
LOG.debug("Task type [{}] is already processed.", taskType);
continue;
}
// check concurrent tasks before task is executed
try {
Class<?> executorClass = Class.forName(taskType);
if (executorClass.isAnnotationPresent(IdmCheckConcurrentExecution.class)) {
IdmCheckConcurrentExecution disallowConcurrentExecution = executorClass.getAnnotation(IdmCheckConcurrentExecution.class);
Class<? extends LongRunningTaskExecutor<?>>[] disallowConcurrentTaskTypes = disallowConcurrentExecution.taskTypes();
if (disallowConcurrentTaskTypes.length > 0 && CollectionUtils.containsAny(processedTaskTypes, Arrays.asList(disallowConcurrentTaskTypes).stream().map(Class::getCanonicalName).collect(Collectors.toList()))) {
LOG.debug("Concurrent task for task type [{}] is already processed.", taskType);
processedTaskTypes.add(taskType);
continue;
}
}
} catch (ClassNotFoundException ex) {
LOG.warn("Class [{}] for long running task [{}] not found. Task execution will be skipped.", taskType, task.getId());
}
//
try {
LongRunningFutureTask<?> futureTask = processCreated(taskId);
if (futureTask != null) {
taskList.add(futureTask);
// prevent to persisted task starts twice
Class<?> executorClass = AutowireHelper.getTargetClass(futureTask.getExecutor());
if (executorClass.isAnnotationPresent(DisallowConcurrentExecution.class)) {
processedTaskTypes.add(taskType);
}
if (executorClass.isAnnotationPresent(IdmCheckConcurrentExecution.class)) {
IdmCheckConcurrentExecution disallowConcurrentExecution = executorClass.getAnnotation(IdmCheckConcurrentExecution.class);
Class<? extends LongRunningTaskExecutor<?>>[] disallowConcurrentTaskTypes = disallowConcurrentExecution.taskTypes();
if (disallowConcurrentTaskTypes.length == 0) {
processedTaskTypes.add(taskType);
}
}
// task is processed => remove from failed tasks to log exception again, when task fails in future
failedLoggedTask.remove(taskId);
}
} catch (ResultCodeException ex) {
// we want to process other task, if some task fails and log just once
processedTaskTypes.add(taskType);
if (!failedLoggedTask.contains(taskId)) {
// we want to know in log, some scheduled task is not complete before next execution attempt
ExceptionUtils.log(LOG, ex);
failedLoggedTask.add(taskId);
}
}
}
return taskList;
}
use of eu.bcvsolutions.idm.core.scheduler.api.domain.IdmCheckConcurrentExecution in project CzechIdMng by bcvsolutions.
the class AbstractLongRunningTaskExecutor method validate.
/**
* Validates task before start e.q. if task already running or to prevent run task concurrently.
*
* Look out: override this method additively
*
* @param task persisted task to validate
*/
@Override
public void validate(IdmLongRunningTaskDto task) {
Assert.notNull(task, "Long running task has to be prepared before task is started");
//
if (task.isRunning()) {
throw new ResultCodeException(CoreResultCode.LONG_RUNNING_TASK_IS_RUNNING, ImmutableMap.of("taskId", task.getId()));
}
if (!OperationState.isRunnable(task.getResultState())) {
throw new ResultCodeException(CoreResultCode.LONG_RUNNING_TASK_IS_PROCESSED, ImmutableMap.of("taskId", task.getId()));
}
//
// check concurrent task is not running (or waiting => operation state is used)
String taskType = task.getTaskType();
if (this.getClass().isAnnotationPresent(DisallowConcurrentExecution.class)) {
IdmLongRunningTaskFilter filter = new IdmLongRunningTaskFilter();
filter.setTaskType(taskType);
filter.setOperationState(OperationState.RUNNING);
// ignore waiting tasks
filter.setRunning(Boolean.TRUE);
List<UUID> runningTasks = longRunningTaskService.findIds(filter, null).getContent().stream().filter(t -> {
// not self
return !t.equals(task.getId());
}).collect(Collectors.toList());
if (!runningTasks.isEmpty()) {
throw new ConcurrentExecutionException(CoreResultCode.LONG_RUNNING_TASK_IS_RUNNING, ImmutableMap.of("taskId", getName()));
}
}
if (this.getClass().isAnnotationPresent(IdmCheckConcurrentExecution.class)) {
List<String> disallowConcurrentTaskTypes = new ArrayList<>();
IdmCheckConcurrentExecution disallowConcurrentExecution = this.getClass().getAnnotation(IdmCheckConcurrentExecution.class);
Class<? extends LongRunningTaskExecutor<?>>[] taskTypes = disallowConcurrentExecution.taskTypes();
if (taskTypes.length == 0) {
disallowConcurrentTaskTypes.add(taskType);
} else {
disallowConcurrentTaskTypes.addAll(// TODO: move to utils somewhere - DRY manager
Arrays.asList(taskTypes).stream().map(Class::getCanonicalName).collect(Collectors.toList()));
}
// TODO: filter.setTaskTypes(...)
disallowConcurrentTaskTypes.forEach(concurrentTaskType -> {
IdmLongRunningTaskFilter filter = new IdmLongRunningTaskFilter();
filter.setTaskType(concurrentTaskType);
filter.setOperationState(OperationState.RUNNING);
// ignore waiting tasks
filter.setRunning(Boolean.TRUE);
List<UUID> runningTasks = longRunningTaskService.findIds(filter, null).getContent().stream().filter(t -> {
// not self
return !t.equals(task.getId());
}).collect(Collectors.toList());
if (!runningTasks.isEmpty()) {
throw new AcceptedException(CoreResultCode.LONG_RUNNING_TASK_ACCEPTED, ImmutableMap.of("taskId", getName()));
}
});
}
}
Aggregations