use of org.kie.server.api.model.taskassigning.PlanningTask in project droolsjbpm-integration by kiegroup.
the class TaskAssigningRuntimeServiceBase method calculatePlanningCommands.
private Map<String, List<PlanningCommand>> calculatePlanningCommands(PlanningItemList planningItemList, String userId) {
final Map<String, List<PlanningCommand>> commandsByContainer = new HashMap<>();
final Map<Long, TaskData> taskDataById = prepareTaskDataForExecutePlanning();
for (PlanningItem planningItem : planningItemList.getItems()) {
final TaskData taskData = taskDataById.remove(planningItem.getTaskId());
if (taskData == null) {
// and a new plan will arrive soon.
throw new PlanningException(String.format(TASK_MODIFIED_ERROR_MSG_3, planningItem.getPlanningTask().getTaskId(), Arrays.toString(new Status[] { Ready, Reserved, InProgress, Suspended })), planningItem.getContainerId(), PlanningExecutionResult.ErrorCode.TASK_MODIFIED_SINCE_PLAN_CALCULATION_ERROR);
}
final String actualOwner = taskData.getActualOwner();
final PlanningTask actualPlanningTask = taskData.getPlanningTask();
final Status taskStatus = convertFromString(taskData.getStatus());
if (isNotEmpty(actualOwner) && actualPlanningTask != null && actualOwner.equals(actualPlanningTask.getAssignedUser()) && actualPlanningTask.equals(planningItem.getPlanningTask())) {
continue;
}
switch(taskStatus) {
case Ready:
addCommand(commandsByContainer, planningItem.getContainerId(), new DelegateAndSaveCommand(planningItem, userId));
break;
case Reserved:
if (actualPlanningTask != null && !actualOwner.equals(actualPlanningTask.getAssignedUser()) && !actualOwner.equals(planningItem.getPlanningTask().getAssignedUser())) {
// and a new plan will arrive soon.
throw new PlanningException(String.format(TASK_MODIFIED_ERROR_MSG_1, planningItem.getPlanningTask().getTaskId(), actualOwner, actualPlanningTask.getAssignedUser()), planningItem.getContainerId(), PlanningExecutionResult.ErrorCode.TASK_MODIFIED_SINCE_PLAN_CALCULATION_ERROR);
} else {
addCommand(commandsByContainer, planningItem.getContainerId(), new DelegateAndSaveCommand(planningItem, userId));
}
break;
case InProgress:
case Suspended:
if (actualOwner == null || !actualOwner.equals(planningItem.getPlanningTask().getAssignedUser())) {
// and a new plan will arrive soon.
throw new PlanningException(String.format(TASK_MODIFIED_ERROR_MSG_2, planningItem.getPlanningTask().getTaskId(), actualOwner, planningItem.getPlanningTask().getAssignedUser()), planningItem.getContainerId(), PlanningExecutionResult.ErrorCode.TASK_MODIFIED_SINCE_PLAN_CALCULATION_ERROR);
} else {
// task might have been created, assigned and started/suspended completely out of the task
// or the planning data might have changed. Just update the planning data.
addCommand(commandsByContainer, planningItem.getContainerId(), new SavePlanningItemCommand(planningItem));
}
break;
default:
// sonar required, no more cases are expected for this switch by construction.
throw new IndexOutOfBoundsException("Value: " + taskData.getStatus() + " is out of range in current switch");
}
}
for (TaskData taskData : taskDataById.values()) {
final Status status = convertFromString(taskData.getStatus());
if ((status == Ready || status == Reserved || status == Suspended) && taskData.getPlanningTask() != null) {
commandsByContainer.computeIfAbsent(taskData.getContainerId(), k -> new ArrayList<>()).add(new DeletePlanningItemCommand(taskData.getTaskId()));
}
}
return commandsByContainer;
}
use of org.kie.server.api.model.taskassigning.PlanningTask in project droolsjbpm-integration by kiegroup.
the class TaskAssigningRuntimeServiceQueryHelperTest method mockTaskData.
private TaskData mockTaskData(Long taskId, Status status, boolean hasPlanningTask, String containerId) {
TaskData taskData = TaskData.builder().taskId(taskId).status(status.name()).containerId(containerId).build();
if (hasPlanningTask) {
PlanningTask planningTask = PlanningTask.builder().taskId(taskId).build();
taskData.setPlanningTask(planningTask);
}
return taskData;
}
use of org.kie.server.api.model.taskassigning.PlanningTask in project droolsjbpm-integration by kiegroup.
the class PlanningBuilder method buildPlanningItems.
private List<PlanningItem> buildPlanningItems(User user) {
int index = 0;
int publishedCount = 0;
PlanningItem planningItem;
// dummy tasks has nothing to with the jBPM runtime, don't process them
final List<Task> userTasks = extractTasks(user, IS_NOT_DUMMY);
final List<PlanningItem> userPlanningItems = new ArrayList<>();
for (Task task : userTasks) {
planningItem = PlanningItem.builder().containerId(task.getContainerId()).taskId(task.getId()).processInstanceId(task.getProcessInstanceId()).planningTask(PlanningTask.builder().taskId(task.getId()).published(task.isPinned()).assignedUser(user.getUser().getEntityId()).index(index++).build()).build();
userPlanningItems.add(planningItem);
publishedCount += planningItem.getPlanningTask().isPublished() ? 1 : 0;
}
Iterator<PlanningItem> userPlanningItemsIt = userPlanningItems.iterator();
while (userPlanningItemsIt.hasNext() && (publishedCount < publishWindowSize || IS_PLANNING_USER.test(user.getEntityId()))) {
planningItem = userPlanningItemsIt.next();
if (!planningItem.getPlanningTask().isPublished()) {
planningItem.getPlanningTask().setPublished(true);
publishedCount++;
}
}
return userPlanningItems;
}
use of org.kie.server.api.model.taskassigning.PlanningTask in project droolsjbpm-integration by kiegroup.
the class SolutionBuilder method build.
public TaskAssigningSolution build() {
final List<Task> tasks = new ArrayList<>();
final Map<String, List<IndexedElement<Task>>> assignedTasksByUserId = new HashMap<>();
final Map<String, User> usersById = filterDuplicates(externalUsers).filter(externalUser -> !IS_PLANNING_USER.test(externalUser.getId())).map(UserUtil::fromExternalUser).collect(Collectors.toMap(User::getEntityId, Function.identity()));
usersById.put(PLANNING_USER.getEntityId(), PLANNING_USER);
taskDataList.forEach(taskData -> {
context.setTaskChangeTime(taskData.getTaskId(), taskData.getLastModificationDate());
final Task task = fromTaskData(taskData);
final Status status = convertFromString(task.getStatus());
switch(status) {
case Ready:
tasks.add(task);
break;
case Reserved:
case InProgress:
case Suspended:
if (isNoneEmpty(taskData.getActualOwner())) {
// If actualOwner is empty the only chance is that the task was in Ready status and changed to
// Suspended, since Reserved and InProgress tasks has always an owner in jBPM.
// Finally tasks with no actualOwner (Suspended) are skipped, since they'll be properly added to
// the solution when they change to Ready status and the proper jBPM event is raised.
tasks.add(task);
final PlanningTask planningTask = taskData.getPlanningTask();
if (planningTask != null && taskData.getActualOwner().equals(planningTask.getAssignedUser())) {
boolean pinned = InProgress == status || Suspended == status || planningTask.getPublished() || !usersById.containsKey(taskData.getActualOwner());
addTaskToUser(assignedTasksByUserId, task, planningTask.getAssignedUser(), planningTask.getIndex(), pinned);
} else {
boolean pinned = (Reserved == status && !IS_PLANNING_USER.test(taskData.getActualOwner())) || InProgress == status || Suspended == status;
addTaskToUser(assignedTasksByUserId, task, taskData.getActualOwner(), -1, pinned);
}
}
break;
default:
// no other cases exists, sonar required.
throw new IndexOutOfBoundsException("Value: " + taskData.getStatus() + " is out of range in current switch");
}
});
assignedTasksByUserId.forEach((key, assignedTasks) -> {
User user = usersById.get(key);
if (user == null) {
// create the user by convention.
user = new User(key.hashCode(), key);
usersById.put(key, user);
}
final List<Task> userTasks = assignedTasks.stream().map(IndexedElement::getElement).collect(Collectors.toList());
addTasksToUser(user, userTasks);
});
// Add the DUMMY_TASK to avoid running into scenarios where the solution remains with no tasks.
tasks.add(DUMMY_TASK);
final List<User> users = new ArrayList<>(usersById.values());
return new TaskAssigningSolution(-1, users, tasks);
}
use of org.kie.server.api.model.taskassigning.PlanningTask in project droolsjbpm-integration by kiegroup.
the class SolutionBuilderTest method buildAndCheckInProgressTaskWithModifiedPlanningTaskNotPublishedWasProcessedCorrect.
@Test
public void buildAndCheckInProgressTaskWithModifiedPlanningTaskNotPublishedWasProcessedCorrect() {
PlanningTask planningTask = PlanningTask.builder().taskId(1L).assignedUser(USER1).published(false).index(1).build();
TaskData taskData = mockTaskData(1L, InProgress, USER2);
buildAndCheckTaskWithPlanningTaskWasProcessedCorrect(taskData, planningTask, taskData.getActualOwner(), true);
}
Aggregations