Search in sources :

Example 1 with PlanningTask

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;
}
Also used : KieContainerStatus(org.kie.server.api.model.KieContainerStatus) Status(org.kie.api.task.model.Status) KieServicesException(org.kie.server.api.exception.KieServicesException) Arrays(java.util.Arrays) PlanningExecutionResult(org.kie.server.api.model.taskassigning.PlanningExecutionResult) CompositeCommand(org.jbpm.services.task.commands.CompositeCommand) QueryService(org.jbpm.services.api.query.QueryService) SavePlanningItemCommand(org.kie.server.services.taskassigning.runtime.command.SavePlanningItemCommand) LoggerFactory(org.slf4j.LoggerFactory) Reserved(org.kie.api.task.model.Status.Reserved) HashMap(java.util.HashMap) Function(java.util.function.Function) KieContainerInstanceImpl(org.kie.server.services.impl.KieContainerInstanceImpl) InProgress(org.kie.api.task.model.Status.InProgress) ArrayList(java.util.ArrayList) TaskData(org.kie.server.api.model.taskassigning.TaskData) StringUtils.isNotEmpty(org.apache.commons.lang3.StringUtils.isNotEmpty) DeletePlanningItemCommand(org.kie.server.services.taskassigning.runtime.command.DeletePlanningItemCommand) PlanningCommand(org.kie.server.services.taskassigning.runtime.command.PlanningCommand) Map(java.util.Map) PlanningItem(org.kie.server.api.model.taskassigning.PlanningItem) UserTaskService(org.jbpm.services.api.UserTaskService) KieContainerStatus(org.kie.server.api.model.KieContainerStatus) Suspended(org.kie.api.task.model.Status.Suspended) Ready(org.kie.api.task.model.Status.Ready) Logger(org.slf4j.Logger) PlanningItemList(org.kie.server.api.model.taskassigning.PlanningItemList) PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) StopWatch(org.apache.commons.lang3.time.StopWatch) StatusConverter.convertFromString(org.kie.server.api.model.taskassigning.util.StatusConverter.convertFromString) StatusConverter.convertToStringList(org.kie.server.api.model.taskassigning.util.StatusConverter.convertToStringList) Collectors(java.util.stream.Collectors) KieServerRegistry(org.kie.server.services.api.KieServerRegistry) List(java.util.List) DelegateAndSaveCommand(org.kie.server.services.taskassigning.runtime.command.DelegateAndSaveCommand) PlanningException(org.kie.server.services.taskassigning.runtime.command.PlanningException) Context(org.kie.api.runtime.Context) TaskCommand(org.jbpm.services.task.commands.TaskCommand) KieServerImpl(org.kie.server.services.impl.KieServerImpl) Status(org.kie.api.task.model.Status) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) StatusConverter.convertFromString(org.kie.server.api.model.taskassigning.util.StatusConverter.convertFromString) DelegateAndSaveCommand(org.kie.server.services.taskassigning.runtime.command.DelegateAndSaveCommand) TaskData(org.kie.server.api.model.taskassigning.TaskData) SavePlanningItemCommand(org.kie.server.services.taskassigning.runtime.command.SavePlanningItemCommand) PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) DeletePlanningItemCommand(org.kie.server.services.taskassigning.runtime.command.DeletePlanningItemCommand) PlanningException(org.kie.server.services.taskassigning.runtime.command.PlanningException) ArrayList(java.util.ArrayList) PlanningItemList(org.kie.server.api.model.taskassigning.PlanningItemList) StatusConverter.convertToStringList(org.kie.server.api.model.taskassigning.util.StatusConverter.convertToStringList) List(java.util.List) PlanningItem(org.kie.server.api.model.taskassigning.PlanningItem)

Example 2 with PlanningTask

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;
}
Also used : PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) TaskData(org.kie.server.api.model.taskassigning.TaskData)

Example 3 with PlanningTask

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;
}
Also used : PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) Task(org.kie.server.services.taskassigning.core.model.Task) ArrayList(java.util.ArrayList) PlanningItem(org.kie.server.api.model.taskassigning.PlanningItem)

Example 4 with PlanningTask

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);
}
Also used : Status(org.kie.api.task.model.Status) Task(org.kie.server.services.taskassigning.core.model.Task) PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) TaskOrUser(org.kie.server.services.taskassigning.core.model.TaskOrUser) User(org.kie.server.services.taskassigning.core.model.User) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TaskAssigningSolution(org.kie.server.services.taskassigning.core.model.TaskAssigningSolution) StatusConverter.convertFromString(org.kie.server.api.model.taskassigning.util.StatusConverter.convertFromString) PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) ArrayList(java.util.ArrayList) List(java.util.List)

Example 5 with PlanningTask

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);
}
Also used : PlanningTask(org.kie.server.api.model.taskassigning.PlanningTask) TaskData(org.kie.server.api.model.taskassigning.TaskData) Test(org.junit.Test)

Aggregations

PlanningTask (org.kie.server.api.model.taskassigning.PlanningTask)23 TaskData (org.kie.server.api.model.taskassigning.TaskData)20 Test (org.junit.Test)17 ArrayList (java.util.ArrayList)5 PlanningItem (org.kie.server.api.model.taskassigning.PlanningItem)4 Task (org.kie.server.services.taskassigning.core.model.Task)4 List (java.util.List)3 PlanningExecutionResult (org.kie.server.api.model.taskassigning.PlanningExecutionResult)3 PlanningItemList (org.kie.server.api.model.taskassigning.PlanningItemList)3 TaskAssigningSolution (org.kie.server.services.taskassigning.core.model.TaskAssigningSolution)3 User (org.kie.server.services.taskassigning.core.model.User)3 HashMap (java.util.HashMap)2 Status (org.kie.api.task.model.Status)2 StatusConverter.convertFromString (org.kie.server.api.model.taskassigning.util.StatusConverter.convertFromString)2 Arrays (java.util.Arrays)1 Map (java.util.Map)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 StringUtils.isNotEmpty (org.apache.commons.lang3.StringUtils.isNotEmpty)1 StopWatch (org.apache.commons.lang3.time.StopWatch)1