Closes #2366 - add TaskEndstatePreprocessor
This commit is contained in:
parent
24fb36a7df
commit
948fe21d1c
|
@ -6,18 +6,23 @@ import static pro.taskana.testapi.DefaultTestEntities.defaultTestClassification;
|
|||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestObjectReference;
|
||||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestWorkbasket;
|
||||
|
||||
import acceptance.task.complete.CompleteTaskWithSpiAccTest.SetCustomAttributeToEndstate;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.api.models.ClassificationSummary;
|
||||
import pro.taskana.common.internal.util.Triplet;
|
||||
import pro.taskana.spi.task.api.TaskEndstatePreprocessor;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.TaskState;
|
||||
import pro.taskana.task.api.exceptions.InvalidTaskStateException;
|
||||
|
@ -26,6 +31,7 @@ import pro.taskana.task.api.models.Task;
|
|||
import pro.taskana.testapi.DefaultTestEntities;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
import pro.taskana.testapi.builder.TaskBuilder;
|
||||
import pro.taskana.testapi.builder.WorkbasketAccessItemBuilder;
|
||||
import pro.taskana.testapi.security.WithAccessId;
|
||||
|
@ -182,4 +188,33 @@ class CancelTaskAccTest {
|
|||
};
|
||||
return DynamicTest.stream(list.iterator(), Triplet::getLeft, testCancelTask);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskEndstatePreprocessor.class,
|
||||
serviceProviders = SetCustomAttributeToEndstate.class)
|
||||
class ServiceProviderSetsCustomAttributeToCancelled {
|
||||
|
||||
@TaskanaInject TaskService taskService;
|
||||
|
||||
@WithAccessId(user = "user-1-2")
|
||||
@Test
|
||||
void should_SetCustomAttribute_When_UserCancelsTask() throws Exception {
|
||||
Task task =
|
||||
TaskBuilder.newTask()
|
||||
.classificationSummary(defaultClassificationSummary)
|
||||
.workbasketSummary(defaultWorkbasketSummary)
|
||||
.state(TaskState.CLAIMED)
|
||||
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
|
||||
.buildAndStore(taskService);
|
||||
Task processedTask = taskService.cancelTask(task.getId());
|
||||
assertThat(processedTask.getState()).isEqualTo(TaskState.CANCELLED);
|
||||
assertThat(processedTask.getCustomAttributeMap())
|
||||
.containsEntry(
|
||||
"camunda:attribute1",
|
||||
"{\"valueInfo\":{\"objectTypeName\":\"java.lang.String\"},"
|
||||
+ "\"type\":\"String\",\"value\":\"CANCELLED\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.stream.Stream;
|
|||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
@ -17,6 +18,7 @@ import org.junit.jupiter.api.function.ThrowingConsumer;
|
|||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.api.models.ClassificationSummary;
|
||||
import pro.taskana.spi.task.api.ReviewRequiredProvider;
|
||||
import pro.taskana.spi.task.api.TaskEndstatePreprocessor;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.TaskState;
|
||||
import pro.taskana.task.api.models.ObjectReference;
|
||||
|
@ -91,6 +93,21 @@ class CompleteTaskWithSpiAccTest {
|
|||
}
|
||||
}
|
||||
|
||||
static class SetCustomAttributeToEndstate implements TaskEndstatePreprocessor {
|
||||
@Override
|
||||
public Task processTaskBeforeEndstate(Task task) {
|
||||
String endstate = task.getState().toString();
|
||||
task.getCustomAttributeMap()
|
||||
.put(
|
||||
"camunda:attribute1",
|
||||
"{\"valueInfo\":{\"objectTypeName\":\"java.lang.String\"},"
|
||||
+ "\"type\":\"String\",\"value\":\""
|
||||
+ endstate
|
||||
+ "\"}");
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
@WithServiceProvider(
|
||||
|
@ -171,4 +188,27 @@ class CompleteTaskWithSpiAccTest {
|
|||
tasks.iterator(), t -> "Try to complete " + t.getState().name() + " Task", test);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskEndstatePreprocessor.class,
|
||||
serviceProviders = SetCustomAttributeToEndstate.class)
|
||||
class ServiceProviderSetsCustomAttributeToCompleted {
|
||||
|
||||
@TaskanaInject TaskService taskService;
|
||||
|
||||
@WithAccessId(user = "user-1-1")
|
||||
@Test
|
||||
void should_SetCustomAttribute_When_UserCompletesTask() throws Exception {
|
||||
Task task = createTaskClaimedByUser("user-1-1").buildAndStore(taskService);
|
||||
Task processedTask = taskService.completeTask(task.getId());
|
||||
assertThat(processedTask.getState()).isEqualTo(TaskState.COMPLETED);
|
||||
assertThat(processedTask.getCustomAttributeMap())
|
||||
.containsEntry(
|
||||
"camunda:attribute1",
|
||||
"{\"valueInfo\":{\"objectTypeName\":\"java.lang.String\"},"
|
||||
+ "\"type\":\"String\",\"value\":\"COMPLETED\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,17 @@ import static org.assertj.core.api.Assertions.catchThrowableOfType;
|
|||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestClassification;
|
||||
import static pro.taskana.testapi.DefaultTestEntities.defaultTestWorkbasket;
|
||||
|
||||
import acceptance.task.complete.CompleteTaskWithSpiAccTest.SetCustomAttributeToEndstate;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
import org.junit.jupiter.api.function.ThrowingConsumer;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
|
@ -19,6 +24,7 @@ import pro.taskana.common.api.TaskanaRole;
|
|||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.common.internal.util.Triplet;
|
||||
import pro.taskana.spi.task.api.TaskEndstatePreprocessor;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.api.TaskState;
|
||||
import pro.taskana.task.api.exceptions.InvalidTaskStateException;
|
||||
|
@ -26,6 +32,7 @@ import pro.taskana.task.api.models.Task;
|
|||
import pro.taskana.testapi.DefaultTestEntities;
|
||||
import pro.taskana.testapi.TaskanaInject;
|
||||
import pro.taskana.testapi.TaskanaIntegrationTest;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
import pro.taskana.testapi.builder.TaskBuilder;
|
||||
import pro.taskana.testapi.builder.WorkbasketAccessItemBuilder;
|
||||
import pro.taskana.testapi.security.WithAccessId;
|
||||
|
@ -157,4 +164,33 @@ class TerminateTaskAccTest {
|
|||
|
||||
return DynamicTest.stream(testValues.iterator(), Triplet::getLeft, test);
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
@WithServiceProvider(
|
||||
serviceProviderInterface = TaskEndstatePreprocessor.class,
|
||||
serviceProviders = SetCustomAttributeToEndstate.class)
|
||||
class ServiceProviderSetsCustomAttributeToTerminated {
|
||||
|
||||
@TaskanaInject TaskService taskService;
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_SetCustomAttribute_When_UserTerminatesTask() throws Exception {
|
||||
Task task =
|
||||
TaskBuilder.newTask()
|
||||
.classificationSummary(defaultClassificationSummary)
|
||||
.workbasketSummary(defaultWorkbasketSummary)
|
||||
.state(TaskState.READY)
|
||||
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build())
|
||||
.buildAndStore(taskService);
|
||||
Task processedTask = taskService.terminateTask(task.getId());
|
||||
assertThat(processedTask.getState()).isEqualTo(TaskState.TERMINATED);
|
||||
assertThat(processedTask.getCustomAttributeMap())
|
||||
.containsEntry(
|
||||
"camunda:attribute1",
|
||||
"{\"valueInfo\":{\"objectTypeName\":\"java.lang.String\"},"
|
||||
+ "\"type\":\"String\",\"value\":\"TERMINATED\"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import pro.taskana.spi.task.internal.BeforeRequestChangesManager;
|
|||
import pro.taskana.spi.task.internal.BeforeRequestReviewManager;
|
||||
import pro.taskana.spi.task.internal.CreateTaskPreprocessorManager;
|
||||
import pro.taskana.spi.task.internal.ReviewRequiredManager;
|
||||
import pro.taskana.spi.task.internal.TaskEndstatePreprocessorManager;
|
||||
|
||||
/**
|
||||
* FOR INTERNAL USE ONLY.
|
||||
|
@ -144,4 +145,11 @@ public interface InternalTaskanaEngine {
|
|||
* @return the {@linkplain AfterRequestChangesManager} instance
|
||||
*/
|
||||
AfterRequestChangesManager getAfterRequestChangesManager();
|
||||
|
||||
/**
|
||||
* Retrieves the {@linkplain pro.taskana.spi.task.internal.TaskEndstatePreprocessorManager}.
|
||||
*
|
||||
* @return the {@linkplain pro.taskana.spi.task.internal.TaskEndstatePreprocessorManager} instance
|
||||
*/
|
||||
TaskEndstatePreprocessorManager getTaskEndstatePreprocessorManager();
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import pro.taskana.spi.task.internal.BeforeRequestChangesManager;
|
|||
import pro.taskana.spi.task.internal.BeforeRequestReviewManager;
|
||||
import pro.taskana.spi.task.internal.CreateTaskPreprocessorManager;
|
||||
import pro.taskana.spi.task.internal.ReviewRequiredManager;
|
||||
import pro.taskana.spi.task.internal.TaskEndstatePreprocessorManager;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.task.internal.AttachmentMapper;
|
||||
import pro.taskana.task.internal.ObjectReferenceMapper;
|
||||
|
@ -98,6 +99,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
private final AfterRequestReviewManager afterRequestReviewManager;
|
||||
private final BeforeRequestChangesManager beforeRequestChangesManager;
|
||||
private final AfterRequestChangesManager afterRequestChangesManager;
|
||||
private final TaskEndstatePreprocessorManager taskEndstatePreprocessorManager;
|
||||
|
||||
private final InternalTaskanaEngineImpl internalTaskanaEngineImpl;
|
||||
private final WorkingTimeCalculator workingTimeCalculator;
|
||||
private final HistoryEventManager historyEventManager;
|
||||
|
@ -176,6 +179,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
afterRequestReviewManager = new AfterRequestReviewManager(this);
|
||||
beforeRequestChangesManager = new BeforeRequestChangesManager(this);
|
||||
afterRequestChangesManager = new AfterRequestChangesManager(this);
|
||||
taskEndstatePreprocessorManager = new TaskEndstatePreprocessorManager();
|
||||
|
||||
// don't remove, to reset possible explicit mode
|
||||
this.mode = connectionManagementMode;
|
||||
|
@ -624,5 +628,10 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
public AfterRequestChangesManager getAfterRequestChangesManager() {
|
||||
return afterRequestChangesManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskEndstatePreprocessorManager getTaskEndstatePreprocessorManager() {
|
||||
return taskEndstatePreprocessorManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package pro.taskana.spi.task.api;
|
||||
|
||||
import pro.taskana.task.api.models.Task;
|
||||
|
||||
/**
|
||||
* The TaskEndstatePreprocessor allows to implement customized behaviour before the given
|
||||
* {@linkplain Task} goes into an {@linkplain pro.taskana.task.api.TaskState#END_STATES end state}
|
||||
* (cancelled, terminated or completed).
|
||||
*/
|
||||
public interface TaskEndstatePreprocessor {
|
||||
|
||||
/**
|
||||
* Perform any action before a {@linkplain Task} goes into an {@linkplain
|
||||
* pro.taskana.task.api.TaskState#END_STATES end state}. A {@linkplain Task} goes into an end
|
||||
* state at the end of the following methods: {@linkplain
|
||||
* pro.taskana.task.api.TaskService#completeTask(String)}, {@linkplain
|
||||
* pro.taskana.task.api.TaskService#cancelTask(String)}, {@linkplain
|
||||
* pro.taskana.task.api.TaskService#terminateTask(String)}.
|
||||
*
|
||||
* <p>This SPI is executed within the same transaction staple as {@linkplain
|
||||
* pro.taskana.task.api.TaskService#completeTask(String)}, {@linkplain
|
||||
* pro.taskana.task.api.TaskService#cancelTask(String)}, {@linkplain
|
||||
* pro.taskana.task.api.TaskService#terminateTask(String)}.
|
||||
*
|
||||
* <p>This SPI is executed with the same {@linkplain
|
||||
* pro.taskana.common.api.security.UserPrincipal} and {@linkplain
|
||||
* pro.taskana.common.api.security.GroupPrincipal} as in the methods mentioned above.
|
||||
*
|
||||
* @param taskToProcess the {@linkplain Task} to preprocess
|
||||
* @return the modified {@linkplain Task}. <b>IMPORTANT:</b> persistent changes to the {@linkplain
|
||||
* Task} have to be managed by the service provider
|
||||
*/
|
||||
Task processTaskBeforeEndstate(Task taskToProcess);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package pro.taskana.spi.task.internal;
|
||||
|
||||
import static pro.taskana.common.internal.util.CheckedConsumer.wrap;
|
||||
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import pro.taskana.common.internal.util.SpiLoader;
|
||||
import pro.taskana.spi.task.api.TaskEndstatePreprocessor;
|
||||
import pro.taskana.task.api.models.Task;
|
||||
|
||||
public class TaskEndstatePreprocessorManager {
|
||||
|
||||
private static final Logger LOGGER =
|
||||
LoggerFactory.getLogger(TaskEndstatePreprocessorManager.class);
|
||||
private final List<TaskEndstatePreprocessor> taskEndstatePreprocessors;
|
||||
|
||||
public TaskEndstatePreprocessorManager() {
|
||||
taskEndstatePreprocessors = SpiLoader.load(TaskEndstatePreprocessor.class);
|
||||
for (TaskEndstatePreprocessor preprocessor : taskEndstatePreprocessors) {
|
||||
LOGGER.info(
|
||||
"Registered TaskEndstatePreprocessor provider: {}", preprocessor.getClass().getName());
|
||||
}
|
||||
if (taskEndstatePreprocessors.isEmpty()) {
|
||||
LOGGER.info("No TaskEndstatePreprocessor found. Running without TaskEndstatePreprocessor.");
|
||||
}
|
||||
}
|
||||
|
||||
public Task processTaskBeforeEndstate(Task taskToProcess) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Sending task to TaskEndstatePreprocessor providers: {}", taskToProcess);
|
||||
}
|
||||
taskEndstatePreprocessors.forEach(
|
||||
wrap(
|
||||
taskEndstatePreprocessor ->
|
||||
taskEndstatePreprocessor.processTaskBeforeEndstate(taskToProcess)));
|
||||
return taskToProcess;
|
||||
}
|
||||
}
|
|
@ -58,6 +58,7 @@ import pro.taskana.spi.task.internal.BeforeRequestChangesManager;
|
|||
import pro.taskana.spi.task.internal.BeforeRequestReviewManager;
|
||||
import pro.taskana.spi.task.internal.CreateTaskPreprocessorManager;
|
||||
import pro.taskana.spi.task.internal.ReviewRequiredManager;
|
||||
import pro.taskana.spi.task.internal.TaskEndstatePreprocessorManager;
|
||||
import pro.taskana.task.api.CallbackState;
|
||||
import pro.taskana.task.api.TaskCommentQuery;
|
||||
import pro.taskana.task.api.TaskCustomField;
|
||||
|
@ -123,6 +124,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
private final AfterRequestReviewManager afterRequestReviewManager;
|
||||
private final BeforeRequestChangesManager beforeRequestChangesManager;
|
||||
private final AfterRequestChangesManager afterRequestChangesManager;
|
||||
private final TaskEndstatePreprocessorManager taskEndstatePreprocessorManager;
|
||||
|
||||
public TaskServiceImpl(
|
||||
InternalTaskanaEngine taskanaEngine,
|
||||
|
@ -146,6 +148,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
this.afterRequestReviewManager = taskanaEngine.getAfterRequestReviewManager();
|
||||
this.beforeRequestChangesManager = taskanaEngine.getBeforeRequestChangesManager();
|
||||
this.afterRequestChangesManager = taskanaEngine.getAfterRequestChangesManager();
|
||||
this.taskEndstatePreprocessorManager = taskanaEngine.getTaskEndstatePreprocessorManager();
|
||||
this.taskTransferrer = new TaskTransferrer(taskanaEngine, taskMapper, this);
|
||||
this.taskCommentService =
|
||||
new TaskCommentServiceImpl(taskanaEngine, taskCommentMapper, userMapper, this);
|
||||
|
@ -874,12 +877,35 @@ public class TaskServiceImpl implements TaskService {
|
|||
public Task cancelTask(String taskId)
|
||||
throws TaskNotFoundException, NotAuthorizedOnWorkbasketException, InvalidTaskStateException {
|
||||
|
||||
Task cancelledTask;
|
||||
TaskImpl cancelledTask;
|
||||
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
cancelledTask = terminateCancelCommonActions(taskId, TaskState.CANCELLED);
|
||||
if (taskId == null || taskId.isEmpty()) {
|
||||
throw new TaskNotFoundException(taskId);
|
||||
}
|
||||
cancelledTask = (TaskImpl) getTask(taskId);
|
||||
TaskState state = cancelledTask.getState();
|
||||
if (state.isEndState()) {
|
||||
throw new InvalidTaskStateException(
|
||||
taskId,
|
||||
state,
|
||||
TaskState.READY,
|
||||
TaskState.CLAIMED,
|
||||
TaskState.READY_FOR_REVIEW,
|
||||
TaskState.IN_REVIEW);
|
||||
}
|
||||
|
||||
terminateCancelCommonActions(cancelledTask, TaskState.CANCELLED);
|
||||
cancelledTask =
|
||||
(TaskImpl) taskEndstatePreprocessorManager.processTaskBeforeEndstate(cancelledTask);
|
||||
taskMapper.update(cancelledTask);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Task '{}' cancelled by user '{}'.",
|
||||
taskId,
|
||||
taskanaEngine.getEngine().getCurrentUserContext().getUserid());
|
||||
}
|
||||
if (historyEventManager.isEnabled()) {
|
||||
historyEventManager.createEvent(
|
||||
new TaskCancelledEvent(
|
||||
|
@ -901,12 +927,35 @@ public class TaskServiceImpl implements TaskService {
|
|||
|
||||
taskanaEngine.getEngine().checkRoleMembership(TaskanaRole.ADMIN, TaskanaRole.TASK_ADMIN);
|
||||
|
||||
Task terminatedTask;
|
||||
TaskImpl terminatedTask;
|
||||
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
terminatedTask = terminateCancelCommonActions(taskId, TaskState.TERMINATED);
|
||||
if (taskId == null || taskId.isEmpty()) {
|
||||
throw new TaskNotFoundException(taskId);
|
||||
}
|
||||
terminatedTask = (TaskImpl) getTask(taskId);
|
||||
TaskState state = terminatedTask.getState();
|
||||
if (state.isEndState()) {
|
||||
throw new InvalidTaskStateException(
|
||||
taskId,
|
||||
state,
|
||||
TaskState.READY,
|
||||
TaskState.CLAIMED,
|
||||
TaskState.READY_FOR_REVIEW,
|
||||
TaskState.IN_REVIEW);
|
||||
}
|
||||
|
||||
terminateCancelCommonActions(terminatedTask, TaskState.TERMINATED);
|
||||
terminatedTask =
|
||||
(TaskImpl) taskEndstatePreprocessorManager.processTaskBeforeEndstate(terminatedTask);
|
||||
taskMapper.update(terminatedTask);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Task '{}' cancelled by user '{}'.",
|
||||
taskId,
|
||||
taskanaEngine.getEngine().getCurrentUserContext().getUserid());
|
||||
}
|
||||
if (historyEventManager.isEnabled()) {
|
||||
historyEventManager.createEvent(
|
||||
new TaskTerminatedEvent(
|
||||
|
@ -1208,35 +1257,11 @@ public class TaskServiceImpl implements TaskService {
|
|||
newTaskImpl.setModified(Instant.now());
|
||||
}
|
||||
|
||||
private TaskImpl terminateCancelCommonActions(String taskId, TaskState targetState)
|
||||
throws TaskNotFoundException, NotAuthorizedOnWorkbasketException, InvalidTaskStateException {
|
||||
if (taskId == null || taskId.isEmpty()) {
|
||||
throw new TaskNotFoundException(taskId);
|
||||
}
|
||||
TaskImpl task = (TaskImpl) getTask(taskId);
|
||||
TaskState state = task.getState();
|
||||
if (state.isEndState()) {
|
||||
throw new InvalidTaskStateException(
|
||||
taskId,
|
||||
state,
|
||||
TaskState.READY,
|
||||
TaskState.CLAIMED,
|
||||
TaskState.READY_FOR_REVIEW,
|
||||
TaskState.IN_REVIEW);
|
||||
}
|
||||
|
||||
private static void terminateCancelCommonActions(TaskImpl task, TaskState targetState) {
|
||||
Instant now = Instant.now();
|
||||
task.setModified(now);
|
||||
task.setCompleted(now);
|
||||
task.setState(targetState);
|
||||
taskMapper.update(task);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Task '{}' cancelled by user '{}'.",
|
||||
taskId,
|
||||
taskanaEngine.getEngine().getCurrentUserContext().getUserid());
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
private Task claim(String taskId, boolean forceClaim)
|
||||
|
@ -1552,6 +1577,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
|
||||
Instant now = Instant.now();
|
||||
completeActionsOnTask(task, userId, now);
|
||||
task = (TaskImpl) taskEndstatePreprocessorManager.processTaskBeforeEndstate(task);
|
||||
taskMapper.update(task);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Task '{}' completed by user '{}'.", taskId, userId);
|
||||
|
|
|
@ -20,6 +20,7 @@ import pro.taskana.spi.task.api.BeforeRequestChangesProvider;
|
|||
import pro.taskana.spi.task.api.BeforeRequestReviewProvider;
|
||||
import pro.taskana.spi.task.api.CreateTaskPreprocessor;
|
||||
import pro.taskana.spi.task.api.ReviewRequiredProvider;
|
||||
import pro.taskana.spi.task.api.TaskEndstatePreprocessor;
|
||||
import pro.taskana.testapi.WithServiceProvider;
|
||||
|
||||
public class ServiceProviderExtractor {
|
||||
|
@ -34,7 +35,8 @@ public class ServiceProviderExtractor {
|
|||
BeforeRequestReviewProvider.class,
|
||||
AfterRequestReviewProvider.class,
|
||||
BeforeRequestChangesProvider.class,
|
||||
AfterRequestChangesProvider.class);
|
||||
AfterRequestChangesProvider.class,
|
||||
TaskEndstatePreprocessor.class);
|
||||
|
||||
private ServiceProviderExtractor() {
|
||||
throw new IllegalStateException("utility class");
|
||||
|
|
Loading…
Reference in New Issue