diff --git a/history/taskana-simplehistory-provider/pom.xml b/history/taskana-simplehistory-provider/pom.xml
index 97d54044d..9029e084b 100644
--- a/history/taskana-simplehistory-provider/pom.xml
+++ b/history/taskana-simplehistory-provider/pom.xml
@@ -32,6 +32,12 @@
+
+ pro.taskana
+ taskana-data
+ ${project.version}
+ test
+
org.assertj
assertj-core
diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryEventImpl.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryEventImpl.java
index d1fe4e7f2..15e3b4de2 100644
--- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryEventImpl.java
+++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/HistoryEventImpl.java
@@ -7,7 +7,7 @@ public class HistoryEventImpl extends TaskanaHistoryEvent {
public HistoryEventImpl() {}
- public HistoryEventImpl(String userId, String details) {
- super(userId, details);
+ public HistoryEventImpl(String id, String userId, String details) {
+ super(id, userId, details);
}
}
diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImpl.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImpl.java
index 920d8ed81..73f7a5a95 100644
--- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImpl.java
+++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImpl.java
@@ -2,10 +2,14 @@ package pro.taskana.simplehistory.impl;
import java.sql.SQLException;
import java.time.Instant;
+import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
+import pro.taskana.common.api.TaskanaRole;
+import pro.taskana.common.api.exceptions.InvalidArgumentException;
+import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.simplehistory.impl.mappings.HistoryEventMapper;
import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
import pro.taskana.simplehistory.query.HistoryQuery;
@@ -54,6 +58,32 @@ public class SimpleHistoryServiceImpl implements TaskanaHistory {
}
}
+ @Override
+ public void deleteHistoryEventsByTaskIds(List taskIds)
+ throws InvalidArgumentException, NotAuthorizedException {
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("entry to deleteHistoryEventsByTaskIds(taskIds = {})", taskIds);
+ }
+
+ taskanaHistoryEngine.checkRoleMembership(TaskanaRole.ADMIN);
+
+ try {
+ taskanaHistoryEngine.openConnection();
+ if (taskIds == null) {
+ throw new InvalidArgumentException("List of taskIds must not be null.");
+ }
+
+ historyEventMapper.deleteMultipleByTaskIds(taskIds);
+
+ } catch (SQLException e) {
+ LOGGER.error("Caught exception while trying to delete history events", e);
+ } finally {
+ LOGGER.debug("exit from deleteHistoryEventsByTaskIds()");
+ taskanaHistoryEngine.returnConnection();
+ }
+ }
+
public TaskanaHistoryEvent getHistoryEvent(String historyEventId)
throws TaskanaHistoryEventNotFoundException {
LOGGER.debug("entry to getHistoryEvent (id = {})", historyEventId);
diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/TaskanaHistoryEngineImpl.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/TaskanaHistoryEngineImpl.java
index 74669eb1d..f4f3979d1 100644
--- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/TaskanaHistoryEngineImpl.java
+++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/TaskanaHistoryEngineImpl.java
@@ -2,7 +2,10 @@ package pro.taskana.simplehistory.impl;
import java.sql.SQLException;
import java.util.ArrayDeque;
+import java.util.Arrays;
import java.util.Deque;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
@@ -12,8 +15,13 @@ import org.apache.ibatis.session.SqlSessionManager;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
+import pro.taskana.common.api.TaskanaRole;
+import pro.taskana.common.api.exceptions.NotAuthorizedException;
+import pro.taskana.common.internal.security.CurrentUserContext;
import pro.taskana.simplehistory.TaskanaHistoryEngine;
import pro.taskana.simplehistory.impl.mappings.HistoryEventMapper;
import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
@@ -23,7 +31,7 @@ import pro.taskana.spi.history.api.TaskanaHistory;
public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {
protected static final ThreadLocal> SESSION_STACK = new ThreadLocal<>();
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaHistoryEngineImpl.class);
private static final String DEFAULT = "default";
protected SqlSessionManager sessionManager;
protected TransactionFactory transactionFactory;
@@ -52,6 +60,38 @@ public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {
return this.taskanaHistoryService;
}
+ public boolean isUserInRole(TaskanaRole... roles) {
+ if (!getConfiguration().isSecurityEnabled()) {
+ return true;
+ }
+
+ Set rolesMembers =
+ Arrays.stream(roles)
+ .map(role -> getConfiguration().getRoleMap().get(role))
+ .collect(HashSet::new, Set::addAll, Set::addAll);
+
+ return CurrentUserContext.getAccessIds().stream()
+ .anyMatch(rolesMembers::contains);
+ }
+
+ public void checkRoleMembership(TaskanaRole... roles) throws NotAuthorizedException {
+ if (!isUserInRole(roles)) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(
+ "Throwing NotAuthorizedException because accessIds {} are not member of roles {}",
+ CurrentUserContext.getAccessIds(),
+ Arrays.toString(roles));
+ }
+ throw new NotAuthorizedException(
+ "current user is not member of role(s) " + Arrays.toString(roles),
+ CurrentUserContext.getUserid());
+ }
+ }
+
+ public TaskanaEngineConfiguration getConfiguration() {
+ return this.taskanaEngineConfiguration;
+ }
+
protected SqlSessionManager createSqlSessionManager() {
Environment environment =
new Environment(
diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/mappings/HistoryEventMapper.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/mappings/HistoryEventMapper.java
index a63ba7b0a..e9c35b9a7 100644
--- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/mappings/HistoryEventMapper.java
+++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/mappings/HistoryEventMapper.java
@@ -1,5 +1,7 @@
package pro.taskana.simplehistory.impl.mappings;
+import java.util.List;
+import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
@@ -13,11 +15,11 @@ import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
public interface HistoryEventMapper {
@Insert(
- "")
+ void deleteMultipleByTaskIds(@Param("taskIds") List taskIds);
+
}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/AbstractAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/AbstractAccTest.java
index e000772cc..df080866e 100644
--- a/history/taskana-simplehistory-provider/src/test/java/acceptance/AbstractAccTest.java
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/AbstractAccTest.java
@@ -1,27 +1,39 @@
package acceptance;
-import configuration.DbWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.reflect.Field;
import java.util.Objects;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
+import org.apache.ibatis.session.SqlSessionManager;
import org.junit.jupiter.api.BeforeAll;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
+import pro.taskana.common.api.TaskanaEngine;
+import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
+import pro.taskana.common.internal.util.IdGenerator;
+import pro.taskana.sampledata.SampleDataGenerator;
import pro.taskana.simplehistory.impl.HistoryEventImpl;
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.TaskanaHistoryEngineImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
/** Set up database for tests. */
public abstract class AbstractAccTest {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAccTest.class);
+ private static final String ID_PREFIX_HISTORY_EVENT = "HEI";
+
+ protected static TaskanaEngineConfiguration taskanaEngineConfiguration;
+ protected static TaskanaHistoryEngineImpl taskanaHistoryEngine;
+ protected static TaskanaEngine taskanaEngine;
private static final String USER_HOME_DIRECTORY = System.getProperty("user.home");
private static final int POOL_TIME_TO_WAIT = 50;
@@ -72,17 +84,20 @@ public abstract class AbstractAccTest {
protected static void resetDb(String schemaName) throws Exception {
DataSource dataSource = getDataSource();
- TaskanaEngineConfiguration taskanaEngineConfiguration =
+ taskanaEngineConfiguration =
new TaskanaEngineConfiguration(
dataSource,
false,
schemaName != null && !schemaName.isEmpty() ? schemaName : getSchemaName());
+ taskanaHistoryEngine = TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngineConfiguration);
+ taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
+ taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
historyService = new SimpleHistoryServiceImpl();
historyService.initialize(taskanaEngineConfiguration);
- DbWriter writer = new DbWriter();
- writer.clearDB(dataSource);
- writer.generateTestData(dataSource);
+ SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, getSchemaName());
+ sampleDataGenerator.clearDb();
+ sampleDataGenerator.generateTestData();
}
protected static DataSource getDataSource() {
@@ -117,6 +132,12 @@ public abstract class AbstractAccTest {
protected static SimpleHistoryServiceImpl getHistoryService() {
return historyService;
+ * @param id the id of the event
+ String id,
+ HistoryEventImpl historyEvent =
+ new HistoryEventImpl(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT), userid, details);
+ historyEvent.setId(id);
}
@BeforeAll
@@ -236,4 +257,15 @@ public abstract class AbstractAccTest {
return schemaName;
}
+
+ protected HistoryQueryMapper getHistoryQueryMapper()
+ throws NoSuchFieldException, IllegalAccessException {
+
+ Field sessionManagerField = TaskanaHistoryEngineImpl.class.getDeclaredField("sessionManager");
+ sessionManagerField.setAccessible(true);
+ SqlSessionManager sqlSessionManager =
+ (SqlSessionManager) sessionManagerField.get(taskanaHistoryEngine);
+
+ return sqlSessionManager.getMapper(HistoryQueryMapper.class);
+ }
}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnCancelClaimAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnCancelClaimAccTest.java
new file mode 100644
index 000000000..499db154a
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnCancelClaimAccTest.java
@@ -0,0 +1,60 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+import pro.taskana.task.api.TaskState;
+import pro.taskana.task.api.models.Task;
+
+@ExtendWith(JaasExtension.class)
+class CreateHistoryEventOnCancelClaimAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ @WithAccessId(user = "admin")
+ @Test
+ void should_CreateCancelClaimedHistoryEvent_When_TaskIsCancelClaimed() throws Exception {
+
+ final String taskId = "TKI:000000000000000000000000000000000043";
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(0);
+
+ assertThat(taskService.getTask(taskId).getState()).isEqualTo(TaskState.CLAIMED);
+ Task task = taskService.forceCancelClaim(taskId);
+ assertThat(task.getState()).isEqualTo(TaskState.READY);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(1);
+ assertThat(historyService.getHistoryEvent(listEvents.get(0).getId()).getEventType())
+ .isEqualTo("TASK_CLAIM_CANCELLED");
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnClaimAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnClaimAccTest.java
new file mode 100644
index 000000000..bc3912a1c
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnClaimAccTest.java
@@ -0,0 +1,60 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+import pro.taskana.task.api.TaskState;
+import pro.taskana.task.api.models.Task;
+
+@ExtendWith(JaasExtension.class)
+class CreateHistoryEventOnClaimAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ @WithAccessId(user = "admin")
+ @Test
+ void should_CreateClaimedHistoryEvent_When_TaskIsClaimed() throws Exception {
+
+ final String taskId = "TKI:000000000000000000000000000000000047";
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(0);
+
+ assertThat(taskService.getTask(taskId).getState()).isEqualTo(TaskState.READY);
+ Task task = taskService.claim(taskId);
+ assertThat(task.getState()).isEqualTo(TaskState.CLAIMED);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(1);
+ assertThat(historyService.getHistoryEvent(listEvents.get(0).getId()).getEventType())
+ .isEqualTo("TASK_CLAIMED");
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnCompletionAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnCompletionAccTest.java
new file mode 100644
index 000000000..17e789c35
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnCompletionAccTest.java
@@ -0,0 +1,58 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+import pro.taskana.task.api.TaskState;
+
+@ExtendWith(JaasExtension.class)
+class CreateHistoryEventOnCompletionAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ @WithAccessId(user = "admin")
+ @Test
+ void should_CreateCompletedHistoryEvent_When_TaskIsCompleted() throws Exception {
+
+ final String taskId = "TKI:000000000000000000000000000000000001";
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(0);
+
+ assertThat(taskService.getTask(taskId).getState()).isEqualTo(TaskState.CLAIMED);
+ taskService.forceCompleteTask(taskId);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(1);
+ assertThat(historyService.getHistoryEvent(listEvents.get(0).getId()).getEventType())
+ .isEqualTo("TASK_COMPLETED");
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTaskCreationAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTaskCreationAccTest.java
new file mode 100644
index 000000000..8ff788960
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTaskCreationAccTest.java
@@ -0,0 +1,65 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+import pro.taskana.task.api.models.ObjectReference;
+import pro.taskana.task.internal.models.TaskImpl;
+
+@ExtendWith(JaasExtension.class)
+class CreateHistoryEventOnTaskCreationAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ protected ObjectReference createObjectRef(
+ String company, String system, String systemInstance, String type, String value) {
+ ObjectReference objectRef = new ObjectReference();
+ objectRef.setCompany(company);
+ objectRef.setSystem(system);
+ objectRef.setSystemInstance(systemInstance);
+ objectRef.setType(type);
+ objectRef.setValue(value);
+ return objectRef;
+ }
+
+ @Test
+ @WithAccessId(user = "admin")
+ void should_CreateCreatedHistoryEvent_When_TaskIsCreated() throws Exception {
+
+ TaskImpl newTask = (TaskImpl) taskService.newTask("WBI:100000000000000000000000000000000006");
+ newTask.setClassificationKey("T2100");
+ ObjectReference objectReference =
+ createObjectRef("COMPANY_A", "SYSTEM_A", "INSTANCE_A", "VNR", "1234567");
+ newTask.setPrimaryObjRef(objectReference);
+ taskService.createTask(newTask);
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(newTask.getId()));
+
+ assertThat(listEvents).hasSize(1);
+ assertThat(listEvents.get(0).getEventType()).isEqualTo("TASK_CREATED");
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTaskUpdateAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTaskUpdateAccTest.java
new file mode 100644
index 000000000..752d0cdf3
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTaskUpdateAccTest.java
@@ -0,0 +1,60 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+import pro.taskana.task.api.models.Task;
+
+@ExtendWith(JaasExtension.class)
+class CreateHistoryEventOnTaskUpdateAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ @Test
+ @WithAccessId(user = "admin")
+ void should_CreateUpdatedHistoryEvent_When_TaskIsCreated() throws Exception {
+
+ final String taskId = "TKI:000000000000000000000000000000000000";
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(2);
+
+ Task task = taskService.getTask(taskId);
+ task.setName("someUpdatedName");
+ taskService.updateTask(task);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(3);
+ assertThat(listEvents.get(2).getEventType()).isEqualTo("TASK_UPDATED");
+
+ assertThat(historyService.getHistoryEvent(listEvents.get(2).getId()).getDetails())
+ .contains("someUpdatedName");
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTransferAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTransferAccTest.java
new file mode 100644
index 000000000..2aa91065b
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/CreateHistoryEventOnTransferAccTest.java
@@ -0,0 +1,56 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.List;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+
+@ExtendWith(JaasExtension.class)
+class CreateHistoryEventOnTransferAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ @WithAccessId(user = "admin")
+ @Test
+ void should_CreateTransferredHistoryEvent_When_TaskIstransferred() throws Exception {
+
+ final String taskId = "TKI:000000000000000000000000000000000003";
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(0);
+
+ taskService.transfer(taskId, "WBI:100000000000000000000000000000000006");
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+
+ assertThat(listEvents).hasSize(1);
+ assertThat(historyService.getHistoryEvent(listEvents.get(0).getId()).getEventType())
+ .isEqualTo("TASK_TRANSFERRED");
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/DeleteHistoryEventsOnTaskDeletionAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/DeleteHistoryEventsOnTaskDeletionAccTest.java
new file mode 100644
index 000000000..a5a36a8b4
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/DeleteHistoryEventsOnTaskDeletionAccTest.java
@@ -0,0 +1,173 @@
+package acceptance.events;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import acceptance.AbstractAccTest;
+import acceptance.security.JaasExtension;
+import acceptance.security.WithAccessId;
+import java.util.Arrays;
+import java.util.List;
+import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import pro.taskana.simplehistory.impl.HistoryEventImpl;
+import pro.taskana.simplehistory.impl.HistoryQueryImpl;
+import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
+import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
+import pro.taskana.task.api.TaskService;
+import pro.taskana.task.api.exceptions.TaskNotFoundException;
+
+@ExtendWith(JaasExtension.class)
+class DeleteHistoryEventsOnTaskDeletionAccTest extends AbstractAccTest {
+
+ private TaskService taskService;
+ private SimpleHistoryServiceImpl historyService;
+
+ @BeforeEach
+ public void setUp() {
+
+ taskService = taskanaEngine.getTaskService();
+ historyService = getHistoryService();
+ }
+
+ @Test
+ @WithAccessId(user = "admin")
+ void should_deleteHistoryEvents_When_TaskIsDeleted_With_HistoryDeletionEnabled()
+ throws Exception {
+
+ final String taskid = "TKI:000000000000000000000000000000000036";
+ taskanaEngineConfiguration.setDeleteHistoryOnTaskDeletionEnabled(true);
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskid));
+ assertThat(listEvents).hasSize(2);
+
+ taskService.deleteTask(taskid);
+
+ // make sure the task got deleted
+ ThrowingCallable getDeletedTaskCall =
+ () -> {
+ taskService.getTask(taskid);
+ };
+
+ assertThatThrownBy(getDeletedTaskCall).isInstanceOf(TaskNotFoundException.class);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskid));
+ assertThat(listEvents).hasSize(0);
+ }
+
+ @Test
+ @WithAccessId(user = "admin")
+ void should_deleteHistoryEvents_When_TasksAreDeleted_With_HistoryDeletionEnabled()
+ throws Exception {
+
+ final String taskId_1 = "TKI:000000000000000000000000000000000037";
+ final String taskId_2 = "TKI:000000000000000000000000000000000038";
+
+ taskanaEngineConfiguration.setDeleteHistoryOnTaskDeletionEnabled(true);
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId_1, taskId_2));
+ assertThat(listEvents).hasSize(3);
+
+ taskService.deleteTasks(Arrays.asList(taskId_1, taskId_2));
+
+ // make sure the tasks got deleted
+ ThrowingCallable getDeletedTaskCall =
+ () -> {
+ taskService.getTask(taskId_1);
+ };
+ ThrowingCallable getDeletedTaskCall2 =
+ () -> {
+ taskService.getTask(taskId_2);
+ };
+
+ assertThatThrownBy(getDeletedTaskCall).isInstanceOf(TaskNotFoundException.class);
+ assertThatThrownBy(getDeletedTaskCall2).isInstanceOf(TaskNotFoundException.class);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId_1, taskId_2));
+ assertThat(listEvents).hasSize(0);
+ }
+
+ @Test
+ @WithAccessId(user = "admin")
+ void should_notDeleteHistoryEvents_When_TaskIsDeleted_With_HistoryDeletionDisabled()
+ throws Exception {
+
+ final String taskId = "TKI:000000000000000000000000000000000039";
+
+ taskanaEngineConfiguration.setDeleteHistoryOnTaskDeletionEnabled(false);
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+ assertThat(listEvents).hasSize(2);
+
+ taskService.deleteTask(taskId);
+
+ // make sure the task got deleted
+ ThrowingCallable getDeletedTaskCall =
+ () -> {
+ taskService.getTask(taskId);
+ };
+
+ assertThatThrownBy(getDeletedTaskCall).isInstanceOf(TaskNotFoundException.class);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId));
+ assertThat(listEvents).hasSize(2);
+ }
+
+ @Test
+ @WithAccessId(user = "admin")
+ void should_notDeleteHistoryEvents_When_TasksAreDeleted_With_HistoryDeletionDisabled()
+ throws Exception {
+ final String taskId_1 = "TKI:000000000000000000000000000000000040";
+ final String taskId_2 = "TKI:000000000000000000000000000000000068";
+
+ taskanaEngineConfiguration.setDeleteHistoryOnTaskDeletionEnabled(false);
+
+ HistoryQueryMapper historyQueryMapper = getHistoryQueryMapper();
+
+ List listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId_1, taskId_2));
+ assertThat(listEvents).hasSize(2);
+
+ taskService.deleteTasks(Arrays.asList(taskId_1, taskId_2));
+
+ // make sure the tasks got deleted
+ ThrowingCallable getDeletedTaskCall =
+ () -> {
+ taskService.getTask(taskId_1);
+ };
+ ThrowingCallable getDeletedTaskCall2 =
+ () -> {
+ taskService.getTask(taskId_2);
+ };
+
+ assertThatThrownBy(getDeletedTaskCall).isInstanceOf(TaskNotFoundException.class);
+ assertThatThrownBy(getDeletedTaskCall2).isInstanceOf(TaskNotFoundException.class);
+
+ listEvents =
+ historyQueryMapper.queryHistoryEvent(
+ (HistoryQueryImpl) historyService.createHistoryQuery().taskIdIn(taskId_1, taskId_2));
+ assertThat(listEvents).hasSize(2);
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/GetHistoryEventAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/GetHistoryEventAccTest.java
index 50bba6c5c..fbaa6fe8f 100644
--- a/history/taskana-simplehistory-provider/src/test/java/acceptance/events/GetHistoryEventAccTest.java
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/events/GetHistoryEventAccTest.java
@@ -7,10 +7,11 @@ import org.junit.jupiter.api.Test;
import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
+
class GetHistoryEventAccTest extends AbstractAccTest {
@Test
- void should_ReturnSpecificTaskHistoryEventWithDetails_For_HistoryEventId() throws Exception {
+ void should_ReturnSpecificTaskHistoryEventWithDetails_For_HistoryEventId()
String detailsJson =
"{\"changes\":[{"
@@ -21,7 +22,8 @@ class GetHistoryEventAccTest extends AbstractAccTest {
+ "\"fieldName\":\"owner\","
+ "\"oldValue\":\"owner1\"}]}";
- TaskanaHistoryEvent taskHistoryEvent = getHistoryService().getHistoryEvent("4");
+ TaskanaHistoryEvent taskHistoryEvent =
+ getHistoryService().getHistoryEvent("HEI:000000000000000000000000000000000000");
assertThat(taskHistoryEvent.getBusinessProcessId()).isEqualTo("BPI:01");
assertThat(taskHistoryEvent.getUserId()).isEqualTo("admin");
assertThat(taskHistoryEvent.getEventType()).isEqualTo("TASK_UPDATED");
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/query/QueryHistoryAccTest.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/query/QueryHistoryAccTest.java
index 2a359f95b..7d95b5dd5 100644
--- a/history/taskana-simplehistory-provider/src/test/java/acceptance/query/QueryHistoryAccTest.java
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/query/QueryHistoryAccTest.java
@@ -31,7 +31,7 @@ class QueryHistoryAccTest extends AbstractAccTest {
.createHistoryQuery()
.listValues(HistoryQueryColumnName.CREATED, SortDirection.ASCENDING);
- assertThat(ascendingList).hasSize(2);
+ assertThat(ascendingList).hasSize(13);
assertThat(ascendingList).isEqualTo(defaultList);
List descendingList =
@@ -55,12 +55,12 @@ class QueryHistoryAccTest extends AbstractAccTest {
List results = query.list();
assertThat(results)
.extracting(TaskanaHistoryEvent::getUserId)
- .containsExactly("admin", "peter");
+ .containsOnly("admin", "peter");
results = query.orderByUserId(SortDirection.DESCENDING).list();
assertThat(results)
.extracting(TaskanaHistoryEvent::getUserId)
- .containsExactly("admin", "peter");
- assertThat(query.domainLike().count()).isEqualTo(3);
+ .containsOnly("admin", "peter");
+ assertThat(query.domainLike().count()).isEqualTo(13);
}
@Test
@@ -76,7 +76,7 @@ class QueryHistoryAccTest extends AbstractAccTest {
@Test
void should_ReturnEmptyList_When_ProvidingWrongContraints() {
List result = getHistoryService().createHistoryQuery().list(1, 1000);
- assertThat(result).hasSize(2);
+ assertThat(result).hasSize(12);
result = getHistoryService().createHistoryQuery().list(100, 1000);
assertThat(result).isEmpty();
@@ -94,10 +94,10 @@ class QueryHistoryAccTest extends AbstractAccTest {
@Test
void should_ReturnCountOfEvents_When_UsingCountMethod() {
long count = getHistoryService().createHistoryQuery().userIdIn("peter").count();
- assertThat(count).isOne();
+ assertThat(count).isEqualTo(6);
count = getHistoryService().createHistoryQuery().count();
- assertThat(count).isEqualTo(3);
+ assertThat(count).isEqualTo(13);
count = getHistoryService().createHistoryQuery().userIdIn("klaus", "arnold", "benni").count();
assertThat(count).isZero();
@@ -107,11 +107,11 @@ class QueryHistoryAccTest extends AbstractAccTest {
void should_ReturnHistoryEvents_For_DifferentInAttributes() {
List returnValues =
getHistoryService().createHistoryQuery().businessProcessIdIn("BPI:01", "BPI:02").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues =
getHistoryService().createHistoryQuery().parentBusinessProcessIdIn("BPI:01").list();
- assertThat(returnValues).hasSize(1);
+ assertThat(returnValues).hasSize(6);
returnValues =
getHistoryService()
@@ -121,63 +121,63 @@ class QueryHistoryAccTest extends AbstractAccTest {
assertThat(returnValues).hasSize(2);
returnValues = getHistoryService().createHistoryQuery().eventTypeIn("TASK_CREATED").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(12);
TimeInterval timeInterval = new TimeInterval(Instant.now().minusSeconds(10), Instant.now());
returnValues = getHistoryService().createHistoryQuery().createdWithin(timeInterval).list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(0);
returnValues = getHistoryService().createHistoryQuery().userIdIn("admin").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues = getHistoryService().createHistoryQuery().domainIn("DOMAIN_A").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(12);
returnValues =
getHistoryService()
.createHistoryQuery()
.workbasketKeyIn("WBI:100000000000000000000000000000000001")
.list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues = getHistoryService().createHistoryQuery().porCompanyIn("00").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues = getHistoryService().createHistoryQuery().porSystemIn("PASystem").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues = getHistoryService().createHistoryQuery().porInstanceIn("22").list();
- assertThat(returnValues).hasSize(1);
+ assertThat(returnValues).hasSize(6);
returnValues = getHistoryService().createHistoryQuery().porTypeIn("VN").list();
assertThat(returnValues).isEmpty();
returnValues = getHistoryService().createHistoryQuery().porValueIn("11223344").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues =
getHistoryService().createHistoryQuery().taskClassificationKeyIn("L140101").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues =
getHistoryService().createHistoryQuery().taskClassificationCategoryIn("TASK").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues =
getHistoryService()
.createHistoryQuery()
.attachmentClassificationKeyIn("DOCTYPE_DEFAULT")
.list();
- assertThat(returnValues).hasSize(1);
+ assertThat(returnValues).hasSize(6);
returnValues = getHistoryService().createHistoryQuery().custom1In("custom1").list();
- assertThat(returnValues).hasSize(3);
+ assertThat(returnValues).hasSize(13);
returnValues = getHistoryService().createHistoryQuery().custom2In("custom2").list();
assertThat(returnValues).hasSize(1);
returnValues = getHistoryService().createHistoryQuery().custom3In("custom3").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
returnValues = getHistoryService().createHistoryQuery().custom4In("custom4").list();
assertThat(returnValues).hasSize(1);
@@ -192,35 +192,35 @@ class QueryHistoryAccTest extends AbstractAccTest {
assertThat(returnValues).hasSize(1);
returnValues = getHistoryService().createHistoryQuery().newValueLike("new_%").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
}
@Test
void should_ReturnHistoryEvents_For_DifferentLikeAttributes() {
List returnValues =
getHistoryService().createHistoryQuery().businessProcessIdLike("BPI:0%").list();
- assertThat(returnValues).hasSize(3);
+ assertThat(returnValues).hasSize(13);
returnValues =
getHistoryService().createHistoryQuery().parentBusinessProcessIdLike("BPI:01", " %").list();
- assertThat(returnValues).hasSize(1);
+ assertThat(returnValues).hasSize(6);
returnValues =
getHistoryService().createHistoryQuery().taskIdLike("TKI:000000000000000%").list();
- assertThat(returnValues).hasSize(3);
+ assertThat(returnValues).hasSize(13);
returnValues = getHistoryService().createHistoryQuery().oldValueLike("old%").list();
assertThat(returnValues).hasSize(1);
returnValues = getHistoryService().createHistoryQuery().newValueLike("new_%").list();
- assertThat(returnValues).hasSize(2);
+ assertThat(returnValues).hasSize(7);
}
@Test
void should_ReturnHistoryEvents_When_ProvidingListValues() {
List returnedList =
getHistoryService().createHistoryQuery().listValues(HistoryQueryColumnName.ID, null);
- assertThat(returnedList).hasSize(3);
+ assertThat(returnedList).hasSize(13);
returnedList =
getHistoryService()
@@ -236,7 +236,7 @@ class QueryHistoryAccTest extends AbstractAccTest {
returnedList =
getHistoryService().createHistoryQuery().listValues(HistoryQueryColumnName.TASK_ID, null);
- assertThat(returnedList).hasSize(2);
+ assertThat(returnedList).hasSize(7);
returnedList =
getHistoryService()
@@ -246,7 +246,7 @@ class QueryHistoryAccTest extends AbstractAccTest {
returnedList =
getHistoryService().createHistoryQuery().listValues(HistoryQueryColumnName.CREATED, null);
- assertThat(returnedList).hasSize(2);
+ assertThat(returnedList).hasSize(13);
returnedList =
getHistoryService().createHistoryQuery().listValues(HistoryQueryColumnName.USER_ID, null);
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/security/JaasExtension.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/security/JaasExtension.java
new file mode 100644
index 000000000..7a4ec81db
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/security/JaasExtension.java
@@ -0,0 +1,329 @@
+package acceptance.security;
+
+import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
+import static pro.taskana.common.internal.util.CheckedFunction.wrap;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import javax.security.auth.Subject;
+import org.junit.jupiter.api.DynamicContainer;
+import org.junit.jupiter.api.DynamicNode;
+import org.junit.jupiter.api.extension.Extension;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
+import org.junit.jupiter.api.extension.ExtensionContext.Store;
+import org.junit.jupiter.api.extension.InvocationInterceptor;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolver;
+import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContext;
+import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider;
+import org.junit.platform.commons.JUnitException;
+import org.junit.platform.commons.support.AnnotationSupport;
+
+import pro.taskana.common.api.exceptions.SystemException;
+import pro.taskana.common.internal.security.GroupPrincipal;
+import pro.taskana.common.internal.security.UserPrincipal;
+
+/** Runner for integration tests that enables JAAS subject. */
+public class JaasExtension implements InvocationInterceptor, TestTemplateInvocationContextProvider {
+
+ private static final String ACCESS_IDS_STORE_KEY = "accessIds";
+
+ // region InvocationInterceptor
+
+ @Override
+ public T interceptTestClassConstructor(
+ Invocation invocation,
+ ReflectiveInvocationContext> invocationContext,
+ ExtensionContext extensionContext) {
+ return extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ @Override
+ public void interceptBeforeAllMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ @Override
+ public void interceptBeforeEachMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ @Override
+ public void interceptTestMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ if (isAnnotated(invocationContext.getExecutable(), WithAccessIds.class)) {
+ throw new JUnitException("Please use @TestTemplate instead of @Test for multiple accessIds");
+ }
+ extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T interceptTestFactoryMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ WithAccessIds annotation = invocationContext.getExecutable().getAnnotation(
+ WithAccessIds.class);
+ if (annotation != null) {
+ // our goal is to run each test returned from the test factory X times. X is the amount of
+ // WithAccessId annotations. In order to achieve this we are wrapping the result from the
+ // factory (the returning tests) in a dynamicContainer for each accessId. Since we don't know
+ // what the factory will return we have to check for every possible return type. All possible
+ // return types can be found here:
+ // https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests
+ // After checking each return type we abuse the return type of T and hardly change it to
+ // Stream no matter what the factory returns. This return type is allowed
+ // per definition (See link above), but is not the type T. Hence we have an unchecked cast at
+ // the end to keep the compiler happy...
+
+ // we are using the first annotation to run the factory method with.
+ T factoryResult = performInvocationWithAccessId(invocation, annotation.value()[0]);
+
+ Iterable newChildrenForDynamicContainer;
+ // TestFactory must have one of the following return types. See link above for further details
+ if (factoryResult instanceof DynamicNode) {
+ newChildrenForDynamicContainer = Collections.singleton((DynamicNode) factoryResult);
+ } else if (factoryResult instanceof Stream) {
+ Stream nodes = (Stream) factoryResult;
+ newChildrenForDynamicContainer = nodes.collect(Collectors.toList());
+ } else if (factoryResult instanceof Iterable) {
+ newChildrenForDynamicContainer = (Iterable) factoryResult;
+ } else if (factoryResult instanceof Iterator) {
+ newChildrenForDynamicContainer = () -> (Iterator) factoryResult;
+ } else if (factoryResult instanceof DynamicNode[]) {
+ newChildrenForDynamicContainer = Arrays.asList((DynamicNode[]) factoryResult);
+ } else {
+ throw new SystemException(
+ String.format(
+ "Testfactory '%s' did not return a proper type",
+ invocationContext.getExecutable().getName()));
+ }
+
+ // Currently a DynamicContainer has children from this type: Stream
+ // Because of this the children can only be extracted once (Streams can only be operated
+ // once). This is obviously not ok since we want to execute each node X times. So we have to
+ // manually persist all children recursively to extract them X times...
+ Map> childrenMap = new HashMap<>();
+ persistDynamicContainerChildren(newChildrenForDynamicContainer, childrenMap);
+
+ Function wrapTestsInDynamicContainer =
+ accessId ->
+ DynamicContainer.dynamicContainer(
+ getDisplayNameForAccessId(accessId),
+ StreamSupport.stream(newChildrenForDynamicContainer.spliterator(), false)
+ .map(x -> duplicateDynamicNode(x, childrenMap)));
+
+ Store store = getStore(extensionContext);
+ return (T)
+ Stream.of(annotation.value())
+ .peek(a -> store.put(ACCESS_IDS_STORE_KEY, a))
+ .map(wrapTestsInDynamicContainer);
+ }
+
+ return extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ @Override
+ public void interceptTestTemplateMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ WithAccessId accessId =
+ getStore(extensionContext).get(ACCESS_IDS_STORE_KEY, WithAccessId.class);
+ performInvocationWithAccessId(invocation, accessId);
+ }
+
+ @Override
+ public void interceptDynamicTest(Invocation invocation, ExtensionContext extensionContext) {
+ ExtensionContext testContext = getParentMethodExtensionContent(extensionContext);
+ // Check if the test factory provided an access Id for this dynamic test.
+ WithAccessId o = getStore(testContext).get(ACCESS_IDS_STORE_KEY, WithAccessId.class);
+ if (o != null) {
+ performInvocationWithAccessId(invocation, o);
+ } else {
+ extractAccessIdAndPerformInvocation(invocation, testContext.getRequiredTestMethod());
+ }
+ }
+
+ @Override
+ public void interceptAfterEachMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ @Override
+ public void interceptAfterAllMethod(
+ Invocation invocation,
+ ReflectiveInvocationContext invocationContext,
+ ExtensionContext extensionContext) {
+ extractAccessIdAndPerformInvocation(invocation, invocationContext.getExecutable());
+ }
+
+ // endregion
+
+ // region TestTemplateInvocationContextProvider
+
+ @Override
+ public boolean supportsTestTemplate(ExtensionContext context) {
+ return isAnnotated(context.getElement(), WithAccessIds.class)
+ || isAnnotated(context.getElement(), WithAccessId.class);
+ }
+
+ @Override
+ public Stream provideTestTemplateInvocationContexts(
+ ExtensionContext context) {
+ List accessIds =
+ AnnotationSupport.findRepeatableAnnotations(context.getElement(), WithAccessId.class);
+ Store store = getStore(context);
+ return accessIds.stream()
+ .peek(a -> store.put(ACCESS_IDS_STORE_KEY, a))
+ .map(JaasExtensionInvocationContext::new);
+ }
+
+ // endregion
+
+ private static void persistDynamicContainerChildren(
+ Iterable nodes, Map> childrenMap) {
+ nodes.forEach(
+ node -> {
+ if (node instanceof DynamicContainer) {
+ DynamicContainer container = (DynamicContainer) node;
+ List children = container.getChildren().collect(Collectors.toList());
+ childrenMap.put(container.hashCode() + container.getDisplayName(), children);
+ persistDynamicContainerChildren(children, childrenMap);
+ }
+ });
+ }
+
+ private static DynamicNode duplicateDynamicNode(
+ DynamicNode node, Map> lookupMap) {
+ if (node instanceof DynamicContainer) {
+ DynamicContainer container = (DynamicContainer) node;
+ Stream children =
+ lookupMap.get(node.hashCode() + node.getDisplayName()).stream()
+ .map(x -> duplicateDynamicNode(x, lookupMap));
+ return DynamicContainer.dynamicContainer(container.getDisplayName(), children);
+ }
+ return node;
+ }
+
+ private static T extractAccessIdAndPerformInvocation(
+ Invocation invocation, AnnotatedElement executable) {
+ return performInvocationWithAccessId(invocation, executable.getAnnotation(
+ WithAccessId.class));
+ }
+
+ private static T performInvocationWithAccessId(
+ Invocation invocation, WithAccessId withAccessId) {
+ Subject subject = new Subject();
+ subject.getPrincipals().addAll(getPrincipals(withAccessId));
+
+ Function, T> proceedInvocation = wrap(Invocation::proceed);
+ PrivilegedAction performInvocation = () -> proceedInvocation.apply(invocation);
+ return Subject.doAs(subject, performInvocation);
+ }
+
+ private static List getPrincipals(
+ WithAccessId withAccessId) {
+ if (withAccessId != null) {
+ return Stream.concat(
+ Stream.of(withAccessId.user()).map(UserPrincipal::new),
+ Arrays.stream(withAccessId.groups()).map(GroupPrincipal::new))
+ .collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+
+ private ExtensionContext getParentMethodExtensionContent(ExtensionContext extensionContext) {
+ Optional parent = extensionContext.getParent();
+ // the class MethodExtensionContext is part of junit-jupiter-engine and has only a
+ // package-private visibility thus this workaround is needed.
+ while (!parent
+ .map(Object::getClass)
+ .map(Class::getName)
+ .filter(s -> s.endsWith("MethodExtensionContext"))
+ .isPresent()) {
+ parent = parent.flatMap(ExtensionContext::getParent);
+ }
+ return parent.orElseThrow(
+ () ->
+ new JUnitException(
+ String.format(
+ "Test '%s' does not have a parent method", extensionContext.getUniqueId())));
+ }
+
+ /**
+ * Gets the store with a method-level scope.
+ *
+ * @param context context for current extension
+ * @return The store
+ */
+ private Store getStore(ExtensionContext context) {
+ return context.getStore(Namespace.create(getClass(), context.getRequiredTestMethod()));
+ }
+
+ private static String getDisplayNameForAccessId(
+ WithAccessId withAccessId) {
+ return String.format("for user '%s'", withAccessId.user());
+ }
+
+ private static class JaasExtensionInvocationContext implements TestTemplateInvocationContext {
+ private final WithAccessId withAccessId;
+
+ private JaasExtensionInvocationContext(
+ WithAccessId withAccessId) {
+ this.withAccessId = withAccessId;
+ }
+
+ @Override
+ public String getDisplayName(int invocationIndex) {
+ return getDisplayNameForAccessId(withAccessId);
+ }
+
+ @Override
+ public List getAdditionalExtensions() {
+ return Collections.singletonList(new WithAccessIdParameterResolver());
+ }
+
+ private class WithAccessIdParameterResolver implements ParameterResolver {
+ @Override
+ public boolean supportsParameter(
+ ParameterContext parameterContext, ExtensionContext extensionContext) {
+ return parameterContext.getParameter().getType().equals(WithAccessId.class);
+ }
+
+ @Override
+ public Object resolveParameter(
+ ParameterContext parameterContext, ExtensionContext extensionContext) {
+ return withAccessId;
+ }
+ }
+ }
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/security/WithAccessId.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/security/WithAccessId.java
new file mode 100644
index 000000000..9370896f6
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/security/WithAccessId.java
@@ -0,0 +1,17 @@
+package acceptance.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+@Repeatable(WithAccessIds.class)
+public @interface WithAccessId {
+
+ String user();
+
+ String[] groups() default {};
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/acceptance/security/WithAccessIds.java b/history/taskana-simplehistory-provider/src/test/java/acceptance/security/WithAccessIds.java
new file mode 100644
index 000000000..65fd66bbf
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/java/acceptance/security/WithAccessIds.java
@@ -0,0 +1,12 @@
+package acceptance.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface WithAccessIds {
+ WithAccessId[] value();
+}
diff --git a/history/taskana-simplehistory-provider/src/test/java/configuration/DbWriter.java b/history/taskana-simplehistory-provider/src/test/java/configuration/DbWriter.java
deleted file mode 100644
index dbd8f35c7..000000000
--- a/history/taskana-simplehistory-provider/src/test/java/configuration/DbWriter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package configuration;
-
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
-import java.sql.Connection;
-import java.sql.SQLException;
-import javax.sql.DataSource;
-import org.apache.ibatis.jdbc.ScriptRunner;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Set up the database's writer and generates data for tests. */
-public class DbWriter {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DbWriter.class);
- private static final String INSERTVALUES = "/sql/history-events.sql";
- private StringWriter outWriter = new StringWriter();
- private PrintWriter logWriter;
- private StringWriter errorWriter;
- private PrintWriter errorLogWriter;
-
- public DbWriter() {
- this.logWriter = new PrintWriter(this.outWriter);
- this.errorWriter = new StringWriter();
- this.errorLogWriter = new PrintWriter(this.errorWriter);
- }
-
- public void generateTestData(DataSource dataSource) throws SQLException {
- ScriptRunner runner = null;
- try (Connection connection = dataSource.getConnection()) {
- runner = configScriptRunner(connection);
- runner.runScript(
- new InputStreamReader(
- DbWriter.class.getResourceAsStream(INSERTVALUES), StandardCharsets.UTF_8));
- } finally {
- LOGGER.debug(outWriter.toString());
- if (!errorWriter.toString().trim().isEmpty()) {
- LOGGER.error(errorWriter.toString());
- }
- }
- }
-
- public void clearDB(DataSource dataSource) throws SQLException {
- ScriptRunner runner = null;
- try (Connection connection = dataSource.getConnection()) {
- runner = configScriptRunner(connection);
- runner.runScript(new StringReader("DELETE FROM HISTORY_EVENTS;"));
- } finally {
- LOGGER.debug(outWriter.toString());
- if (!errorWriter.toString().trim().isEmpty()) {
- LOGGER.error(errorWriter.toString());
- }
- }
- }
-
- private ScriptRunner configScriptRunner(Connection connection) throws SQLException {
- LOGGER.debug(connection.getMetaData().toString());
- ScriptRunner runner = new ScriptRunner(connection);
- runner.setStopOnError(true);
- runner.setLogWriter(this.logWriter);
- runner.setErrorLogWriter(this.errorLogWriter);
- runner.setStopOnError(true);
- runner.setLogWriter(this.logWriter);
- runner.setErrorLogWriter(this.errorLogWriter);
- return runner;
- }
-}
diff --git a/history/taskana-simplehistory-provider/src/test/java/configuration/TaskanaEngineConfigurationTest.java b/history/taskana-simplehistory-provider/src/test/java/configuration/TaskanaEngineConfigurationTest.java
index 5cb834bb2..67274eea4 100644
--- a/history/taskana-simplehistory-provider/src/test/java/configuration/TaskanaEngineConfigurationTest.java
+++ b/history/taskana-simplehistory-provider/src/test/java/configuration/TaskanaEngineConfigurationTest.java
@@ -20,7 +20,7 @@ class TaskanaEngineConfigurationTest extends AbstractAccTest {
void testCreateTaskanaEngine() throws Exception {
DataSource ds = getDataSource();
TaskanaEngineConfiguration taskEngineConfiguration =
- new TaskanaEngineConfiguration(ds, false, getSchemaName());
+ new TaskanaEngineConfiguration(ds, false, false, getSchemaName());
TaskanaEngine te = taskEngineConfiguration.buildTaskanaEngine();
@@ -35,7 +35,13 @@ class TaskanaEngineConfigurationTest extends AbstractAccTest {
getHistoryService()
.create(
AbstractAccTest.createHistoryEvent(
- "wbKey1", "taskId1", "type1", "Some comment", "wbKey2", "someUserId"));
+ "HEI:000000000000000000000000000000000000",
+ "wbKey1",
+ "taskId1",
+ "type1",
+ "Some comment",
+ "wbKey2",
+ "someUserId"));
count = getHistoryService().createHistoryQuery().workbasketKeyIn("wbKey1").count();
assertThat(count).isOne();
}
diff --git a/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/HistoryQueryImplTest.java b/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/HistoryQueryImplTest.java
index c366002f1..2b1b466f1 100644
--- a/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/HistoryQueryImplTest.java
+++ b/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/HistoryQueryImplTest.java
@@ -15,6 +15,7 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import pro.taskana.common.api.TimeInterval;
+import pro.taskana.common.internal.util.IdGenerator;
import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
/**
@@ -25,6 +26,8 @@ import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
@ExtendWith(MockitoExtension.class)
class HistoryQueryImplTest {
+ private static final String ID_PREFIX_HISTORY_EVENT = "HEI";
+
private HistoryQueryImpl historyQueryImpl;
@Mock private TaskanaHistoryEngineImpl taskanaHistoryEngineMock;
@@ -66,7 +69,9 @@ class HistoryQueryImplTest {
String userId,
String details,
Instant created) {
- HistoryEventImpl he = new HistoryEventImpl(userId, details);
+ HistoryEventImpl he =
+ new HistoryEventImpl(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT), userId, details);
he.setTaskId(taskId);
he.setWorkbasketKey(workbasketKey);
he.setEventType(type);
diff --git a/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImplTest.java b/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImplTest.java
index bd4b43001..08178aa54 100644
--- a/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImplTest.java
+++ b/history/taskana-simplehistory-provider/src/test/java/pro/taskana/simplehistory/impl/SimpleHistoryServiceImplTest.java
@@ -56,7 +56,13 @@ class SimpleHistoryServiceImplTest {
void testCreateEvent() throws Exception {
HistoryEventImpl expectedWb =
AbstractAccTest.createHistoryEvent(
- "wbKey1", "taskId1", "type1", "wbKey2", "someUserId", "someDetails");
+ "HEI:000000000000000000000000000000000000",
+ "wbKey1",
+ "taskId1",
+ "type1",
+ "wbKey2",
+ "someUserId",
+ "someDetails");
cutSpy.create(expectedWb);
verify(taskanaHistoryEngineMock, times(1)).openConnection();
@@ -70,7 +76,13 @@ class SimpleHistoryServiceImplTest {
List returnList = new ArrayList<>();
returnList.add(
AbstractAccTest.createHistoryEvent(
- "wbKey1", "taskId1", "type1", "wbKey2", "someUserId", "someDetails"));
+ "HEI:000000000000000000000000000000000000",
+ "wbKey1",
+ "taskId1",
+ "type1",
+ "wbKey2",
+ "someUserId",
+ "someDetails"));
when(historyQueryMapperMock.queryHistoryEvent(any())).thenReturn(returnList);
final List result = cutSpy.createHistoryQuery().taskIdIn("taskId1").list();
diff --git a/history/taskana-simplehistory-provider/src/test/resources/sql/history-events.sql b/history/taskana-simplehistory-provider/src/test/resources/sql/history-events.sql
deleted file mode 100644
index 4201a2df2..000000000
--- a/history/taskana-simplehistory-provider/src/test/resources/sql/history-events.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-INSERT INTO HISTORY_EVENTS (BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, TASK_CLASSIFICATION_KEY,
- TASK_CLASSIFICATION_CATEGORY, ATTACHMENT_CLASSIFICATION_KEY, OLD_VALUE, NEW_VALUE, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, DETAILS) VALUES
--- BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY , POR_SYSTEM, POR_INSTANCE , POR_TYPE , POR_VALUE , TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY , ATTACHMENT_CLASSIFICATION_KEY , OLD_VALUE , NEW_VALUE , CUSTOM_1 , CUSTOM_2 , CUSTOM_3 , CUSTOM_4, details
-('BPI:01' ,'' ,'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', CURRENT_TIMESTAMP , 'admin', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344', 'L140101' , 'TASK' ,'' ,'old_val' ,'new_val' ,'custom1' ,'custom2' , 'custom3' ,'custom4', '{"changes":[{"newValue":"BPI:01","fieldName":"businessProcessId","oldValue":"BPI:02"},{"newValue":"admin","fieldName":"owner","oldValue":"owner1"}]}' ),
-('BPI:02' ,'' ,'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -2, CURRENT_TIMESTAMP),'peter', 'DOMAIN_A', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344', '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom2' ,'' ,'someDetails' ),
-('BPI:03' ,'BPI:01','TKI:000000000000000000000000000000000001','TASK_CREATED', CURRENT_TIMESTAMP , 'admin', 'DOMAIN_A', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'' ,'someDetails' )
-;
diff --git a/history/taskana-simplehistory-provider/src/test/resources/taskana.properties b/history/taskana-simplehistory-provider/src/test/resources/taskana.properties
new file mode 100644
index 000000000..413d7e278
--- /dev/null
+++ b/history/taskana-simplehistory-provider/src/test/resources/taskana.properties
@@ -0,0 +1,19 @@
+taskana.roles.user=group1 | group2|teamlead_1 | teamlead_2 |user_1_1| user_1_1| user_1_2| user_2_1| user_2_2| max|elena|simone
+taskana.roles.Admin=name=konrad,Organisation=novatec|admin
+taskana.roles.businessadmin=max|Moritz|businessadmin
+taskana.roles.monitor=john|teamlead_2 | monitor
+taskana.roles.taskadmin=peter | taskadmin
+taskana.domains=Domain_A , DOMAIN_B
+taskana.classification.types=TASK , document
+taskana.classification.categories.task=EXTERNAL, manual, autoMAtic, Process
+taskana.classification.categories.document=EXTERNAL
+taskana.jobs.maxRetries=3
+taskana.jobs.batchSize=50
+taskana.jobs.cleanup.runEvery=P1D
+taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
+taskana.jobs.cleanup.minimumAge=P14D
+taskana.german.holidays.enabled=true
+taskana.german.holidays.corpus-christi.enabled=false
+taskana.history.deletion.on.task.deletion.enabled=true
+
+
diff --git a/history/taskana-simplehistory-rest-spring/src/main/resources/sql.sample-data/history-event.sql b/history/taskana-simplehistory-rest-spring/src/main/resources/sql.sample-data/history-event.sql
index d57493d20..af73b57fe 100644
--- a/history/taskana-simplehistory-rest-spring/src/main/resources/sql.sample-data/history-event.sql
+++ b/history/taskana-simplehistory-rest-spring/src/main/resources/sql.sample-data/history-event.sql
@@ -1,47 +1,47 @@
-INSERT INTO HISTORY_EVENTS (BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY, ATTACHMENT_CLASSIFICATION_KEY, OLD_VALUE, NEW_VALUE, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, DETAILS) VALUES
+INSERT INTO HISTORY_EVENTS (ID, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, CREATED, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY, ATTACHMENT_CLASSIFICATION_KEY, OLD_VALUE, NEW_VALUE, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, DETAILS) VALUES
-- BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, TASK_ID, EVENT_TYPE, TASK_CREATEDD, USER_ID, DOMAIN, WORKBASKET_KEY, POR_COMPANY , POR_SYSTEM, POR_INSTANCE , POR_TYPE , POR_VALUE , TASK_CLASSIFICATION_KEY, TASK_CLASSIFICATION_CATEGORY , ATTACHMENT_CLASSIFICATION_KEY , OLD_VALUE , NEW_VALUE , CUSTOM_1 , CUSTOM_2 , CUSTOM_3 , CUSTOM_4
-('BPI:01' ,'', 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER-2-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' ,' L140101' , 'TASK' ,'' ,'old_val12' ,'new_val12' ,'custom1' ,'custom2' , 'custom3' ,'custom4', 'some Details'),
-('BPI:02' ,'', 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -2, CURRENT_TIMESTAMP ), 'USER-1-1', 'DOMAIN_A', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '65464564' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:06' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:04' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:06' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:06' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
-('BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER-1-2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
-('BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER-2-1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details');
\ No newline at end of file
+('HEI:000000000000000000000000000000000000','BPI:01' ,'', 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER_2_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' ,' L140101' , 'TASK' ,'' ,'old_val12' ,'new_val12' ,'custom1' ,'custom2' , 'custom3' ,'custom4', 'some Details'),
+('HEI:000000000000000000000000000000000001','BPI:02' ,'', 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -2, CURRENT_TIMESTAMP ), 'USER_1_1', 'DOMAIN_A', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '65464564' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000002','BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000003','BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000004','BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000005','BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000006','BPI:06' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000007','BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000008','BPI:04' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000009','BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000010','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000011','BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000012','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000013','BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000014','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000015','BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000016','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000017','BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000018','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000019','BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000020','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000021','BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000022','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000023','BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000024','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000025','BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000026','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000027','BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000028','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000029','BPI:03' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000030','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000031','BPI:05' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000032','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000033','BPI:06' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000034','BPI:02' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_CREATED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000035','BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000036','BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000037','BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000038','BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000039','BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000040','BPI:06' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000041','BPI:02' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_UPDATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000042','BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details'),
+('HEI:000000000000000000000000000000000043','BPI:04' ,'' , 'TKI:000000000000000000000000000000000000', 'TASK_CREATED', DATEADD('DAY', -1, CURRENT_TIMESTAMP ), 'USER_1_2', 'DOMAIN_B', 'WBI:100000000000000000000000000000000001', '00' , 'PASystem', '00' , 'VNR' , '11223344' , '' , '' ,'' ,'2old_val' ,'new_val2' ,'custom1' ,'' , 'custom3' ,'custom4','some Details'),
+('HEI:000000000000000000000000000000000044','BPI:03' ,'BPI:01', 'TKI:000000000000000000000000000000000001', 'TASK_DELETED', CURRENT_TIMESTAMP , 'USER_2_1', 'DOMAIN_B', 'WBI:100000000000000000000000000000000002', '11' , '' , '22' , '' , '' , 'L140101' , 'TASK' ,'DOCTYPE_DEFAULT' ,'' ,'' ,'custom1' ,'' , 'custom3' ,'','some Details');
\ No newline at end of file
diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java
index 748ae6ec2..35cea5377 100644
--- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java
+++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventControllerIntTest.java
@@ -104,7 +104,7 @@ class TaskHistoryEventControllerIntTest {
void should_ReturnSpecificTaskHistoryEventWithDetails_When_SingleEventIsQueried() {
ResponseEntity response =
template.exchange(
- server + port + "/api/v1/task-history-event/45",
+ server + port + "/api/v1/task-history-event/HEI:000000000000000000000000000000000000",
HttpMethod.GET,
request,
ParameterizedTypeReference.forType(TaskHistoryEventResource.class));
diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java
index be864a00f..8910004da 100644
--- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java
+++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/TaskHistoryEventResourceAssemblerTest.java
@@ -33,7 +33,8 @@ class TaskHistoryEventResourceAssemblerTest {
@Test
void taskHistoryEventModelToResource() {
- HistoryEventImpl historyEvent = new HistoryEventImpl("user1", "someDetails");
+ HistoryEventImpl historyEvent =
+ new HistoryEventImpl("HEI:000000000000000000000000000000000000", "user1", "someDetails");
historyEvent.setEventType("TASK_CREATED");
historyEvent.setBusinessProcessId("BPI:01");
diff --git a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java
index 92a7dba13..153d41db2 100644
--- a/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java
+++ b/history/taskana-simplehistory-rest-spring/src/test/java/pro/taskana/doc/api/TaskHistoryEventControllerRestDocumentation.java
@@ -173,7 +173,7 @@ public class TaskHistoryEventControllerRestDocumentation {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
- "http://127.0.0.1:" + port + "/api/v1/task-history-event/1")
+ "http://127.0.0.1:" + port + "/api/v1/task-history-event/HEI:000000000000000000000000000000000000")
.accept("application/hal+json")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
diff --git a/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java b/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java
index ea3f458c3..90e9d1e85 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/TaskanaEngineConfiguration.java
@@ -68,6 +68,8 @@ public class TaskanaEngineConfiguration {
"taskana.german.holidays.corpus-christi.enabled";
private static final String TASKANA_CUSTOM_HOLIDAY = "taskana.custom.holidays";
private static final String TASKANA_CUSTOM_HOLIDAY_DAY_MONTH_SEPARATOR = ".";
+ private static final String TASKANA_HISTORY_DELETION_ON_TASK_DELETION_ENABLED =
+ "taskana.history.deletion.on.task.deletion.enabled";
// TASKANA_SCHEMA_VERSION
private static final String DEFAULT_SCHEMA_NAME = "TASKANA";
@@ -92,6 +94,7 @@ public class TaskanaEngineConfiguration {
protected List classificationTypes = new ArrayList<>();
protected Map> classificationCategoriesByTypeMap = new HashMap<>();
// Properties for the monitor
+ private boolean deleteHistoryOnTaskDeletionEnabled;
private boolean germanPublicHolidaysEnabled;
private boolean corpusChristiEnabled;
// Properties for general job execution
@@ -171,8 +174,9 @@ public class TaskanaEngineConfiguration {
initDomains(props);
initClassificationTypes(props);
initClassificationCategories(props);
- initGermanHolidaysEnabled(props);
- initCorpusChristiEnabled(props);
+ initBooleanFlag(props, TASKANA_GERMAN_HOLIDAYS_ENABLED);
+ initBooleanFlag(props, TASKANA_GERMAN_HOLIDAYS_CORPUS_CHRISTI_ENABLED);
+ initBooleanFlag(props, TASKANA_HISTORY_DELETION_ON_TASK_DELETION_ENABLED);
initCustomHolidays(props);
}
@@ -268,6 +272,14 @@ public class TaskanaEngineConfiguration {
this.germanPublicHolidaysEnabled = germanPublicHolidaysEnabled;
}
+ public boolean isDeleteHistoryOnTaskDeletionEnabled() {
+ return deleteHistoryOnTaskDeletionEnabled;
+ }
+
+ public void setDeleteHistoryOnTaskDeletionEnabled(boolean deleteHistoryOnTaskDeletionEnabled) {
+ this.deleteHistoryOnTaskDeletionEnabled = deleteHistoryOnTaskDeletionEnabled;
+ }
+
public List getCustomHolidays() {
return customHolidays;
}
@@ -362,24 +374,21 @@ public class TaskanaEngineConfiguration {
return true;
}
- private void initGermanHolidaysEnabled(Properties props) {
- String enabled = props.getProperty(TASKANA_GERMAN_HOLIDAYS_ENABLED);
+ private void initBooleanFlag(Properties props, String propName) {
+ String enabled = props.getProperty(propName);
if (enabled != null && !enabled.isEmpty()) {
- germanPublicHolidaysEnabled = Boolean.parseBoolean(enabled);
- } else {
- germanPublicHolidaysEnabled = false;
+ boolean isEnabled = Boolean.parseBoolean(enabled);
+ if (propName.equals(TASKANA_GERMAN_HOLIDAYS_ENABLED)) {
+ germanPublicHolidaysEnabled = isEnabled;
+ } else if (propName.equals(TASKANA_GERMAN_HOLIDAYS_CORPUS_CHRISTI_ENABLED)) {
+ corpusChristiEnabled = isEnabled;
+ } else if (propName.equals(TASKANA_HISTORY_DELETION_ON_TASK_DELETION_ENABLED)) {
+ deleteHistoryOnTaskDeletionEnabled = isEnabled;
+ }
}
- LOGGER.debug("GermanPublicHolidaysEnabled = {}", germanPublicHolidaysEnabled);
- }
-
- private void initCorpusChristiEnabled(Properties props) {
- String enabled = props.getProperty(TASKANA_GERMAN_HOLIDAYS_CORPUS_CHRISTI_ENABLED);
- if (enabled != null && !enabled.isEmpty()) {
- corpusChristiEnabled = Boolean.parseBoolean(enabled);
- } else {
- corpusChristiEnabled = false;
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(String.format("%s = %b", propName, Boolean.parseBoolean(enabled)));
}
- LOGGER.debug("CorpusChristiEnabled = {}", corpusChristiEnabled);
}
private void initJobParameters(Properties props) {
diff --git a/lib/taskana-core/src/main/java/pro/taskana/common/internal/InternalTaskanaEngine.java b/lib/taskana-core/src/main/java/pro/taskana/common/internal/InternalTaskanaEngine.java
index 4c0c93cbc..d5f03f9c4 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/common/internal/InternalTaskanaEngine.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/common/internal/InternalTaskanaEngine.java
@@ -4,7 +4,7 @@ import java.util.function.Supplier;
import org.apache.ibatis.session.SqlSession;
import pro.taskana.common.api.TaskanaEngine;
-import pro.taskana.spi.history.internal.HistoryEventProducer;
+import pro.taskana.spi.history.internal.HistoryEventManager;
import pro.taskana.task.internal.TaskRoutingManager;
/**
@@ -67,7 +67,7 @@ public interface InternalTaskanaEngine {
*
* @return the HistoryEventProducer instance.
*/
- HistoryEventProducer getHistoryEventProducer();
+ HistoryEventManager getHistoryEventManager();
/**
* Retrieve TaskRoutingProducer.
diff --git a/lib/taskana-core/src/main/java/pro/taskana/common/internal/TaskanaEngineImpl.java b/lib/taskana-core/src/main/java/pro/taskana/common/internal/TaskanaEngineImpl.java
index 892c71b65..06d493dca 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/common/internal/TaskanaEngineImpl.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/common/internal/TaskanaEngineImpl.java
@@ -49,7 +49,7 @@ import pro.taskana.common.internal.security.GroupPrincipal;
import pro.taskana.monitor.api.MonitorService;
import pro.taskana.monitor.internal.MonitorMapper;
import pro.taskana.monitor.internal.MonitorServiceImpl;
-import pro.taskana.spi.history.internal.HistoryEventProducer;
+import pro.taskana.spi.history.internal.HistoryEventManager;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.internal.AttachmentMapper;
import pro.taskana.task.internal.ObjectReferenceMapper;
@@ -80,12 +80,13 @@ public class TaskanaEngineImpl implements TaskanaEngine {
protected SqlSessionManager sessionManager;
protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE;
protected Connection connection = null;
+ private HistoryEventManager historyEventManager;
protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration) {
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
this.sessionManager = createSqlSessionManager();
- historyEventProducer = HistoryEventProducer.getInstance(taskanaEngineConfiguration);
+ historyEventManager = HistoryEventManager.getInstance(taskanaEngineConfiguration);
taskRoutingManager = TaskRoutingManager.getInstance(this);
this.internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
workingDaysToDaysConverter =
@@ -154,7 +155,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
@Override
public boolean isHistoryEnabled() {
- return HistoryEventProducer.isHistoryEnabled();
+ return HistoryEventManager.isHistoryEnabled();
}
@Override
@@ -410,8 +411,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
@Override
- public HistoryEventProducer getHistoryEventProducer() {
- return historyEventProducer;
+ public HistoryEventManager getHistoryEventManager() {
+ return historyEventManager;
}
@Override
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/TaskanaHistory.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/TaskanaHistory.java
index 0443e148f..1f2c6fd58 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/TaskanaHistory.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/TaskanaHistory.java
@@ -1,6 +1,10 @@
package pro.taskana.spi.history.api;
+import java.util.List;
+
import pro.taskana.TaskanaEngineConfiguration;
+import pro.taskana.common.api.exceptions.InvalidArgumentException;
+import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
/** Interface for TASKANA History Service Provider. */
@@ -20,4 +24,14 @@ public interface TaskanaHistory {
* @param event {@link TaskanaHistoryEvent} The event to be created.
*/
void create(TaskanaHistoryEvent event);
+
+ /**
+ * Delete history events by taskIds.
+ *
+ * @param taskIds the task ids for which all history events must be deleted
+ * @throws InvalidArgumentException If the list of taskIds is null
+ * @throws NotAuthorizedException If the user has no permission to delete events
+ */
+ void deleteHistoryEventsByTaskIds(List taskIds)
+ throws InvalidArgumentException, NotAuthorizedException;
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/TaskanaHistoryEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/TaskanaHistoryEvent.java
index a6baf4cba..d544d397e 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/TaskanaHistoryEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/TaskanaHistoryEvent.java
@@ -5,7 +5,7 @@ import java.time.Instant;
/** Super class for all specific events from the TASKANA engine. */
public class TaskanaHistoryEvent {
- protected long id;
+ protected String id;
protected String businessProcessId;
protected String parentBusinessProcessId;
protected String taskId;
@@ -32,15 +32,20 @@ public class TaskanaHistoryEvent {
public TaskanaHistoryEvent() {}
- public TaskanaHistoryEvent(String userId, String details) {
+ public TaskanaHistoryEvent(String id, String userId, String details) {
+ this.id = id;
this.userId = userId;
this.details = details;
}
- public long getId() {
+ public String getId() {
return id;
}
+ public void setId(String id) {
+ this.id = id;
+ }
+
public String getBusinessProcessId() {
return businessProcessId;
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimCancelledEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimCancelledEvent.java
index 5e58339c9..13635fdba 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimCancelledEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimCancelledEvent.java
@@ -5,8 +5,8 @@ import pro.taskana.task.api.models.Task;
/** Event fired if a task is cancelled to be claimed. */
public class ClaimCancelledEvent extends TaskEvent {
- public ClaimCancelledEvent(Task task, String userId) {
- super(task, userId, null);
+ public ClaimCancelledEvent(String id, Task task, String userId) {
+ super(id, task, userId, null);
eventType = "TASK_CLAIM_CANCELLED";
created = task.getModified();
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimedEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimedEvent.java
index 130490a59..8ceaf3267 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimedEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/ClaimedEvent.java
@@ -5,8 +5,8 @@ import pro.taskana.task.api.models.Task;
/** Event fired if a task is claimed. */
public class ClaimedEvent extends TaskEvent {
- public ClaimedEvent(Task task, String userId) {
- super(task, userId, null);
+ public ClaimedEvent(String id, Task task, String userId) {
+ super(id, task, userId, null);
setEventType("TASK_CLAIMED");
created = task.getClaimed();
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CompletedEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CompletedEvent.java
index 0f521b387..bd065014b 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CompletedEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CompletedEvent.java
@@ -6,14 +6,14 @@ import pro.taskana.task.api.models.TaskSummary;
/** Event fired if a task is completed. */
public class CompletedEvent extends TaskEvent {
- public CompletedEvent(Task completedTask, String userId) {
- super(completedTask, userId, null);
+ public CompletedEvent(String id, Task completedTask, String userId) {
+ super(id, completedTask, userId, null);
eventType = "TASK_COMPLETED";
created = completedTask.getCompleted();
}
- public CompletedEvent(TaskSummary completedTask, String userId) {
- super(completedTask, userId, null);
+ public CompletedEvent(String id, TaskSummary completedTask, String userId) {
+ super(id, completedTask, userId, null);
eventType = "TASK_COMPLETED";
created = completedTask.getCompleted();
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CreatedEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CreatedEvent.java
index 42208db5b..a98e22f49 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CreatedEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/CreatedEvent.java
@@ -5,8 +5,8 @@ import pro.taskana.task.api.models.Task;
/** Event fired if a task is created. */
public class CreatedEvent extends TaskEvent {
- public CreatedEvent(Task task, String userId, String details) {
- super(task, userId, details);
+ public CreatedEvent(String id, Task task, String userId, String details) {
+ super(id, task, userId, details);
eventType = "TASK_CREATED";
created = task.getCreated();
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TaskEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TaskEvent.java
index 405df55f9..b89555fa0 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TaskEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TaskEvent.java
@@ -7,8 +7,8 @@ import pro.taskana.task.api.models.TaskSummary;
/** Super class for all task related events. */
public class TaskEvent extends TaskanaHistoryEvent {
- public TaskEvent(Task task, String userId, String details) {
- super(userId, details);
+ public TaskEvent(String id, Task task, String userId, String details) {
+ super(id, userId, details);
taskId = task.getId();
businessProcessId = task.getBusinessProcessId();
parentBusinessProcessId = task.getParentBusinessProcessId();
@@ -31,8 +31,8 @@ public class TaskEvent extends TaskanaHistoryEvent {
}
}
- public TaskEvent(TaskSummary task, String userId, String details) {
- super(userId, details);
+ public TaskEvent(String id, TaskSummary task, String userId, String details) {
+ super(id, userId, details);
taskId = task.getId();
businessProcessId = task.getBusinessProcessId();
parentBusinessProcessId = task.getParentBusinessProcessId();
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TransferredEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TransferredEvent.java
index 8009705f7..bacd0fe38 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TransferredEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TransferredEvent.java
@@ -12,8 +12,12 @@ public class TransferredEvent extends TaskEvent {
private static final Logger LOGGER = LoggerFactory.getLogger(TransferredEvent.class);
public TransferredEvent(
- Task task, WorkbasketSummary oldWorkbasket, WorkbasketSummary newWorkbasket, String userId) {
- super(task, userId, null);
+ String id,
+ Task task,
+ WorkbasketSummary oldWorkbasket,
+ WorkbasketSummary newWorkbasket,
+ String userId) {
+ super(id, task, userId, null);
eventType = "TASK_TRANSFERRED";
created = task.getModified();
this.oldValue = oldWorkbasket.getId();
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/UpdatedEvent.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/UpdatedEvent.java
index fc52ae995..5553bebe2 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/UpdatedEvent.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/UpdatedEvent.java
@@ -4,8 +4,8 @@ import pro.taskana.task.api.models.Task;
public class UpdatedEvent extends TaskEvent {
- public UpdatedEvent(Task updatedTask, String userId, String details) {
- super(updatedTask, userId, details);
+ public UpdatedEvent(String id, Task updatedTask, String userId, String details) {
+ super(id, updatedTask, userId, details);
eventType = "TASK_UPDATED";
created = updatedTask.getModified();
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/spi/history/internal/HistoryEventProducer.java b/lib/taskana-core/src/main/java/pro/taskana/spi/history/internal/HistoryEventManager.java
similarity index 56%
rename from lib/taskana-core/src/main/java/pro/taskana/spi/history/internal/HistoryEventProducer.java
rename to lib/taskana-core/src/main/java/pro/taskana/spi/history/internal/HistoryEventManager.java
index 45eb74924..b4912b8f6 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/spi/history/internal/HistoryEventProducer.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/spi/history/internal/HistoryEventManager.java
@@ -1,23 +1,28 @@
package pro.taskana.spi.history.internal;
+import java.util.List;
import java.util.Objects;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
+import pro.taskana.common.api.exceptions.InvalidArgumentException;
+import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.spi.history.api.TaskanaHistory;
import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
-/** Creates events and emits them to the registered history service providers. */
-public final class HistoryEventProducer {
+/**
+ * Creates and deletes events and emits them to the registered history service providers.
+ */
+public final class HistoryEventManager {
- private static final Logger LOGGER = LoggerFactory.getLogger(HistoryEventProducer.class);
- private static HistoryEventProducer singleton;
+ private static final Logger LOGGER = LoggerFactory.getLogger(HistoryEventManager.class);
+ private static HistoryEventManager singleton;
private boolean enabled = false;
private ServiceLoader serviceLoader;
- private HistoryEventProducer(TaskanaEngineConfiguration taskanaEngineConfiguration) {
+ private HistoryEventManager(TaskanaEngineConfiguration taskanaEngineConfiguration) {
serviceLoader = ServiceLoader.load(TaskanaHistory.class);
for (TaskanaHistory history : serviceLoader) {
history.initialize(taskanaEngineConfiguration);
@@ -29,10 +34,10 @@ public final class HistoryEventProducer {
}
}
- public static synchronized HistoryEventProducer getInstance(
+ public static synchronized HistoryEventManager getInstance(
TaskanaEngineConfiguration taskanaEngineConfiguration) {
if (singleton == null) {
- singleton = new HistoryEventProducer(taskanaEngineConfiguration);
+ singleton = new HistoryEventManager(taskanaEngineConfiguration);
}
return singleton;
}
@@ -45,4 +50,15 @@ public final class HistoryEventProducer {
LOGGER.debug("Sending event to history service providers: {}", event);
serviceLoader.forEach(historyProvider -> historyProvider.create(event));
}
+
+ public void deleteEvents(List taskIds) {
+ LOGGER.debug("Sending taskIds to history service providers: {}", taskIds);
+ serviceLoader.forEach(historyProvider -> {
+ try {
+ historyProvider.deleteHistoryEventsByTaskIds(taskIds);
+ } catch (InvalidArgumentException | NotAuthorizedException e) {
+ LOGGER.warn("Caught an exception while trying to delete HistoryEvents", e);
+ }
+ });
+ }
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java
index 5b4e29fab..c7f04ee62 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentHandler.java
@@ -177,7 +177,7 @@ public class AttachmentHandler {
oldAttachments.forEach(
a -> {
if (!newAttIds.contains(a.getId())) {
- attachmentMapper.deleteAttachment(a.getId());
+ attachmentMapper.delete(a.getId());
LOGGER.debug(
"TaskService.updateTask() for TaskId={} DELETED an Attachment={}.",
newTaskImpl.getId(),
diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java
index f9887dcf7..8978f3d8d 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/AttachmentMapper.java
@@ -91,7 +91,11 @@ public interface AttachmentMapper {
@Param("taskIds") List taskIds);
@Delete("DELETE FROM ATTACHMENT WHERE ID=#{attachmentId}")
- void deleteAttachment(@Param("attachmentId") String attachmentId);
+ void delete(@Param("attachmentId") String attachmentId);
+
+ @Delete(
+ "")
+ void deleteMultipleByTaskIds(@Param("taskIds") List taskIds);
@Update(
"UPDATE ATTACHMENT SET TASK_ID = #{taskId}, CREATED = #{created}, MODIFIED = #{modified},"
diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java
index 442074ec6..f6299c27e 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java
@@ -46,7 +46,7 @@ import pro.taskana.spi.history.api.events.task.ClaimedEvent;
import pro.taskana.spi.history.api.events.task.CompletedEvent;
import pro.taskana.spi.history.api.events.task.CreatedEvent;
import pro.taskana.spi.history.api.events.task.UpdatedEvent;
-import pro.taskana.spi.history.internal.HistoryEventProducer;
+import pro.taskana.spi.history.internal.HistoryEventManager;
import pro.taskana.task.api.CallbackState;
import pro.taskana.task.api.TaskQuery;
import pro.taskana.task.api.TaskService;
@@ -101,18 +101,19 @@ public class TaskServiceImpl implements TaskService {
private static final String ID_PREFIX_BUSINESS_PROCESS = "BPI";
private static final Set ALLOWED_CUSTOM_KEYS =
IntStream.rangeClosed(1, 16).mapToObj(String::valueOf).collect(Collectors.toSet());
+ private static final String ID_PREFIX_HISTORY_EVENT = "HEI";
private static final String TASK_WITH_ID_IS_ALREADY_IN_END_STATE =
"Task with Id %s is already in an end state.";
private final InternalTaskanaEngine taskanaEngine;
private final WorkbasketService workbasketService;
private final ClassificationService classificationService;
private final TaskMapper taskMapper;
- private final AttachmentMapper attachmentMapper;
- private final HistoryEventProducer historyEventProducer;
private final TaskTransferrer taskTransferrer;
private final TaskCommentServiceImpl taskCommentService;
private final ServiceLevelHandler serviceLevelHandler;
private final AttachmentHandler attachmentHandler;
+ private AttachmentMapper attachmentMapper;
+ private HistoryEventManager historyEventManager;
public TaskServiceImpl(
InternalTaskanaEngine taskanaEngine,
@@ -124,7 +125,7 @@ public class TaskServiceImpl implements TaskService {
this.workbasketService = taskanaEngine.getEngine().getWorkbasketService();
this.attachmentMapper = attachmentMapper;
this.classificationService = taskanaEngine.getEngine().getClassificationService();
- this.historyEventProducer = taskanaEngine.getHistoryEventProducer();
+ this.historyEventManager = taskanaEngine.getHistoryEventManager();
this.taskTransferrer = new TaskTransferrer(taskanaEngine, taskMapper, this);
this.taskCommentService = new TaskCommentServiceImpl(taskanaEngine, taskCommentMapper, this);
this.serviceLevelHandler = new ServiceLevelHandler(taskanaEngine, taskMapper, attachmentMapper);
@@ -231,11 +232,15 @@ public class TaskServiceImpl implements TaskService {
try {
this.taskMapper.insert(task);
LOGGER.debug("Method createTask() created Task '{}'.", task.getId());
- if (HistoryEventProducer.isHistoryEnabled()) {
+ if (HistoryEventManager.isHistoryEnabled()) {
String details = determineChangesInTaskAttributes(newTask(), task);
- historyEventProducer.createEvent(
- new CreatedEvent(task, CurrentUserContext.getUserid(), details));
+ historyEventManager.createEvent(
+ new CreatedEvent(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ CurrentUserContext.getUserid(),
+ details));
}
} catch (PersistenceException e) {
// Error messages:
@@ -434,13 +439,17 @@ public class TaskServiceImpl implements TaskService {
LOGGER.debug("Method updateTask() updated task '{}' for user '{}'.", task.getId(), userId);
- if (HistoryEventProducer.isHistoryEnabled()) {
+ if (HistoryEventManager.isHistoryEnabled()) {
String changeDetails = determineChangesInTaskAttributes(oldTaskImpl, newTaskImpl);
LOGGER.warn(changeDetails);
- historyEventProducer.createEvent(
- new UpdatedEvent(task, CurrentUserContext.getUserid(), changeDetails));
+ historyEventManager.createEvent(
+ new UpdatedEvent(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ CurrentUserContext.getUserid(),
+ changeDetails));
}
} finally {
@@ -537,8 +546,18 @@ public class TaskServiceImpl implements TaskService {
while (taskIdIterator.hasNext()) {
removeSingleTaskForTaskDeletionById(bulkLog, taskSummaries, taskIdIterator);
}
+
if (!taskIds.isEmpty()) {
+ attachmentMapper.deleteMultipleByTaskIds(taskIds);
taskMapper.deleteMultiple(taskIds);
+
+ if (taskanaEngine.getEngine().isHistoryEnabled()
+ && taskanaEngine
+ .getEngine()
+ .getConfiguration()
+ .isDeleteHistoryOnTaskDeletionEnabled()) {
+ historyEventManager.deleteEvents(taskIds);
+ }
}
return bulkLog;
} finally {
@@ -1198,8 +1217,12 @@ public class TaskServiceImpl implements TaskService {
claimActionsOnTask(task, userId, now);
taskMapper.update(task);
LOGGER.debug("Task '{}' claimed by user '{}'.", taskId, userId);
- if (HistoryEventProducer.isHistoryEnabled()) {
- historyEventProducer.createEvent(new ClaimedEvent(task, CurrentUserContext.getUserid()));
+ if (HistoryEventManager.isHistoryEnabled()) {
+ historyEventManager.createEvent(
+ new ClaimedEvent(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ CurrentUserContext.getUserid()));
}
} finally {
taskanaEngine.returnConnection();
@@ -1294,9 +1317,12 @@ public class TaskServiceImpl implements TaskService {
task.setState(TaskState.READY);
taskMapper.update(task);
LOGGER.debug("Task '{}' unclaimed by user '{}'.", taskId, userId);
- if (HistoryEventProducer.isHistoryEnabled()) {
- historyEventProducer.createEvent(
- new ClaimCancelledEvent(task, CurrentUserContext.getUserid()));
+ if (HistoryEventManager.isHistoryEnabled()) {
+ historyEventManager.createEvent(
+ new ClaimCancelledEvent(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ CurrentUserContext.getUserid()));
}
} finally {
taskanaEngine.returnConnection();
@@ -1332,8 +1358,12 @@ public class TaskServiceImpl implements TaskService {
completeActionsOnTask(task, userId, now);
taskMapper.update(task);
LOGGER.debug("Task '{}' completed by user '{}'.", taskId, userId);
- if (HistoryEventProducer.isHistoryEnabled()) {
- historyEventProducer.createEvent(new CompletedEvent(task, CurrentUserContext.getUserid()));
+ if (HistoryEventManager.isHistoryEnabled()) {
+ historyEventManager.createEvent(
+ new CompletedEvent(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ CurrentUserContext.getUserid()));
}
} finally {
taskanaEngine.returnConnection();
@@ -1360,7 +1390,14 @@ public class TaskServiceImpl implements TaskService {
throw new InvalidStateException(String.format(TASK_WITH_ID_CALLBACK_NOT_PROCESSED, taskId));
}
+ attachmentMapper.deleteMultipleByTaskIds(Arrays.asList(taskId));
taskMapper.delete(taskId);
+
+ if (taskanaEngine.getEngine().isHistoryEnabled()
+ && taskanaEngine.getEngine().getConfiguration().isDeleteHistoryOnTaskDeletionEnabled()) {
+ historyEventManager.deleteEvents(Arrays.asList(taskId));
+ }
+
LOGGER.debug("Task {} deleted.", taskId);
} finally {
taskanaEngine.returnConnection();
@@ -1560,7 +1597,7 @@ public class TaskServiceImpl implements TaskService {
if (!updateClaimedTaskIds.isEmpty()) {
taskMapper.updateClaimed(updateClaimedTaskIds, claimedReference);
}
- if (HistoryEventProducer.isHistoryEnabled()) {
+ if (HistoryEventManager.isHistoryEnabled()) {
createTasksCompletedEvents(taskSummaryList);
}
}
@@ -1906,7 +1943,10 @@ public class TaskServiceImpl implements TaskService {
private void createTasksCompletedEvents(List extends TaskSummary> taskSummaries) {
taskSummaries.forEach(
task ->
- historyEventProducer.createEvent(
- new CompletedEvent(task, CurrentUserContext.getUserid())));
+ historyEventManager.createEvent(
+ new CompletedEvent(
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ CurrentUserContext.getUserid())));
}
}
diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java
index e10a53043..716595379 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskTransferrer.java
@@ -16,8 +16,9 @@ import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.InternalTaskanaEngine;
import pro.taskana.common.internal.security.CurrentUserContext;
+import pro.taskana.common.internal.util.IdGenerator;
import pro.taskana.spi.history.api.events.task.TransferredEvent;
-import pro.taskana.spi.history.internal.HistoryEventProducer;
+import pro.taskana.spi.history.internal.HistoryEventManager;
import pro.taskana.task.api.TaskState;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
@@ -41,12 +42,13 @@ public class TaskTransferrer {
private static final String TASK_WITH_ID = "Task with id ";
private static final String WAS_MARKED_FOR_DELETION = " was marked for deletion";
private static final String THE_WORKBASKET = "The workbasket ";
+ private static final String ID_PREFIX_HISTORY_EVENT = "HEI";
private static final Logger LOGGER = LoggerFactory.getLogger(TaskTransferrer.class);
private InternalTaskanaEngine taskanaEngine;
private WorkbasketService workbasketService;
private TaskServiceImpl taskService;
private TaskMapper taskMapper;
- private HistoryEventProducer historyEventProducer;
+ private HistoryEventManager historyEventManager;
TaskTransferrer(
InternalTaskanaEngine taskanaEngine, TaskMapper taskMapper, TaskServiceImpl taskService) {
@@ -55,7 +57,7 @@ public class TaskTransferrer {
this.taskService = taskService;
this.taskMapper = taskMapper;
this.workbasketService = taskanaEngine.getEngine().getWorkbasketService();
- this.historyEventProducer = taskanaEngine.getHistoryEventProducer();
+ this.historyEventManager = taskanaEngine.getHistoryEventManager();
}
Task transfer(String taskId, String destinationWorkbasketKey, String domain)
@@ -110,7 +112,7 @@ public class TaskTransferrer {
"Method transfer() transferred Task '{}' to destination workbasket {}",
taskId,
destinationWorkbasket.getId());
- if (HistoryEventProducer.isHistoryEnabled()) {
+ if (HistoryEventManager.isHistoryEnabled()) {
createTaskTransferredEvent(task, oldWorkbasketSummary, destinationWorkbasket.asSummary());
}
return task;
@@ -167,7 +169,7 @@ public class TaskTransferrer {
"Method transfer() transferred Task '{}' to destination workbasket {}",
taskId,
destinationWorkbasketId);
- if (HistoryEventProducer.isHistoryEnabled()) {
+ if (HistoryEventManager.isHistoryEnabled()) {
createTaskTransferredEvent(task, oldWorkbasketSummary, destinationWorkbasket.asSummary());
}
return task;
@@ -364,9 +366,13 @@ public class TaskTransferrer {
private void createTaskTransferredEvent(
Task task, WorkbasketSummary oldWorkbasketSummary, WorkbasketSummary newWorkbasketSummary) {
- historyEventProducer.createEvent(
+ historyEventManager.createEvent(
new TransferredEvent(
- task, oldWorkbasketSummary, newWorkbasketSummary, CurrentUserContext.getUserid()));
+ IdGenerator.generateWithPrefix(ID_PREFIX_HISTORY_EVENT),
+ task,
+ oldWorkbasketSummary,
+ newWorkbasketSummary,
+ CurrentUserContext.getUserid()));
}
private void updateTasksToBeTransferred(
@@ -397,7 +403,7 @@ public class TaskTransferrer {
updateObject.setState(TaskState.READY);
updateObject.setOwner(null);
taskMapper.updateTransfered(taskIds, updateObject);
- if (HistoryEventProducer.isHistoryEnabled()) {
+ if (HistoryEventManager.isHistoryEnabled()) {
createTasksTransferredEvents(taskSummaries, updateObject);
}
}
diff --git a/lib/taskana-core/src/main/resources/sql/db2/taskana-schema-db2.sql b/lib/taskana-core/src/main/resources/sql/db2/taskana-schema-db2.sql
index 76980dc93..aed05ee0f 100644
--- a/lib/taskana-core/src/main/resources/sql/db2/taskana-schema-db2.sql
+++ b/lib/taskana-core/src/main/resources/sql/db2/taskana-schema-db2.sql
@@ -208,7 +208,7 @@ CREATE TABLE SCHEDULED_JOB(
CREATE TABLE HISTORY_EVENTS
(
- ID INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
+ ID VARCHAR(40) NOT NULL,
BUSINESS_PROCESS_ID VARCHAR(128) NULL,
PARENT_BUSINESS_PROCESS_ID VARCHAR(128) NULL,
TASK_ID VARCHAR(40) NULL,
diff --git a/lib/taskana-core/src/main/resources/sql/h2/taskana-schema-h2.sql b/lib/taskana-core/src/main/resources/sql/h2/taskana-schema-h2.sql
index bfffb2f7c..1affd3da4 100644
--- a/lib/taskana-core/src/main/resources/sql/h2/taskana-schema-h2.sql
+++ b/lib/taskana-core/src/main/resources/sql/h2/taskana-schema-h2.sql
@@ -211,7 +211,7 @@ CREATE TABLE SCHEDULED_JOB(
CREATE TABLE HISTORY_EVENTS
(
- ID INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
+ ID VARCHAR(40) NOT NULL,
BUSINESS_PROCESS_ID VARCHAR(128) NULL,
PARENT_BUSINESS_PROCESS_ID VARCHAR(128) NULL,
TASK_ID VARCHAR(40) NULL,
diff --git a/lib/taskana-core/src/main/resources/sql/postgres/taskana-schema-postgres.sql b/lib/taskana-core/src/main/resources/sql/postgres/taskana-schema-postgres.sql
index e4d38c93b..b3e0782f8 100644
--- a/lib/taskana-core/src/main/resources/sql/postgres/taskana-schema-postgres.sql
+++ b/lib/taskana-core/src/main/resources/sql/postgres/taskana-schema-postgres.sql
@@ -206,7 +206,7 @@ CREATE TABLE SCHEDULED_JOB(
CREATE TABLE HISTORY_EVENTS
(
- ID INT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
+ ID VARCHAR(40) NOT NULL,
BUSINESS_PROCESS_ID VARCHAR(128) NULL,
PARENT_BUSINESS_PROCESS_ID VARCHAR(128) NULL,
TASK_ID VARCHAR(40) NULL,
diff --git a/lib/taskana-core/src/test/java/acceptance/history/TaskEventProducerTest.java b/lib/taskana-core/src/test/java/acceptance/history/HistoryEventManagerTest.java
similarity index 59%
rename from lib/taskana-core/src/test/java/acceptance/history/TaskEventProducerTest.java
rename to lib/taskana-core/src/test/java/acceptance/history/HistoryEventManagerTest.java
index f3c7f8ac5..0c9277626 100644
--- a/lib/taskana-core/src/test/java/acceptance/history/TaskEventProducerTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/history/HistoryEventManagerTest.java
@@ -5,11 +5,11 @@ import static org.assertj.core.api.Assertions.assertThat;
import acceptance.AbstractAccTest;
import org.junit.jupiter.api.Test;
-/** Acceptance test for historyEventProducer class. */
-class TaskEventProducerTest extends AbstractAccTest {
+/** Acceptance test for HistoryEventManager class. */
+class HistoryEventManagerTest extends AbstractAccTest {
@Test
- void testHistoryEventProducerIsNotEnabled() {
+ void testHistoryEventManagerIsNotEnabled() {
assertThat(taskanaEngine.isHistoryEnabled()).isFalse();
}
}
diff --git a/lib/taskana-core/src/test/java/acceptance/jobs/TaskCleanupJobAccTest.java b/lib/taskana-core/src/test/java/acceptance/jobs/TaskCleanupJobAccTest.java
index b7a3f724a..9be3aa28d 100644
--- a/lib/taskana-core/src/test/java/acceptance/jobs/TaskCleanupJobAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/jobs/TaskCleanupJobAccTest.java
@@ -36,7 +36,7 @@ class TaskCleanupJobAccTest extends AbstractAccTest {
createAndCompleteTask();
long totalTasksCount = taskService.createTaskQuery().count();
- assertThat(totalTasksCount).isEqualTo(85);
+ assertThat(totalTasksCount).isEqualTo(88);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(false);
@@ -51,7 +51,7 @@ class TaskCleanupJobAccTest extends AbstractAccTest {
@Test
void shouldCleanCompletedTasksUntilDateWithSameParentBussiness() throws Exception {
long totalTasksCount = taskService.createTaskQuery().count();
- assertThat(totalTasksCount).isEqualTo(84);
+ assertThat(totalTasksCount).isEqualTo(87);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(true);
diff --git a/lib/taskana-core/src/test/java/acceptance/security/TaskQueryAccTest.java b/lib/taskana-core/src/test/java/acceptance/security/TaskQueryAccTest.java
index 5194acb44..378b3ccb5 100644
--- a/lib/taskana-core/src/test/java/acceptance/security/TaskQueryAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/security/TaskQueryAccTest.java
@@ -36,7 +36,7 @@ class TaskQueryAccTest extends AbstractAccTest {
List results = taskService.createTaskQuery().ownerLike("%a%", "%u%").list();
- assertThat(results).hasSize(4);
+ assertThat(results).hasSize(7);
}
@WithAccessId(user = "user-1-1", groups = "businessadmin")
@@ -46,7 +46,7 @@ class TaskQueryAccTest extends AbstractAccTest {
List results = taskService.createTaskQuery().ownerLike("%a%", "%u%").list();
- assertThat(results).hasSize(4);
+ assertThat(results).hasSize(7);
}
@WithAccessId(user = "user-1-1", groups = "admin")
@@ -56,6 +56,6 @@ class TaskQueryAccTest extends AbstractAccTest {
List results = taskService.createTaskQuery().ownerLike("%a%", "%u%").list();
- assertThat(results).hasSize(36);
+ assertThat(results).hasSize(39);
}
}
diff --git a/lib/taskana-core/src/test/java/acceptance/task/CancelTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/CancelTaskAccTest.java
index f2290a179..a1a60fe83 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/CancelTaskAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/CancelTaskAccTest.java
@@ -89,7 +89,7 @@ class CancelTaskAccTest extends AbstractAccTest {
void testCancelCompletedTask() {
List taskSummaries =
taskService.createTaskQuery().stateIn(TaskState.COMPLETED).list();
- assertThat(taskSummaries).hasSize(7);
+ assertThat(taskSummaries).hasSize(10);
ThrowingCallable taskanaCall = () -> taskService.cancelTask(taskSummaries.get(0).getId());
diff --git a/lib/taskana-core/src/test/java/acceptance/task/DeleteTaskAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/DeleteTaskAccTest.java
index faf8722d1..0f56c3980 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/DeleteTaskAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/DeleteTaskAccTest.java
@@ -15,14 +15,18 @@ import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.common.api.BulkOperationResults;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.common.api.exceptions.TaskanaException;
+import pro.taskana.common.internal.TaskanaEngineProxyForTest;
import pro.taskana.common.internal.security.JaasExtension;
import pro.taskana.common.internal.security.WithAccessId;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.exceptions.InvalidStateException;
import pro.taskana.task.api.exceptions.TaskNotFoundException;
import pro.taskana.task.api.models.Task;
+import pro.taskana.task.internal.AttachmentMapper;
-/** Acceptance test for all "delete task" scenarios. */
+/**
+ * Acceptance test for all "delete task" scenarios.
+ */
@ExtendWith(JaasExtension.class)
class DeleteTaskAccTest extends AbstractAccTest {
@@ -42,6 +46,54 @@ class DeleteTaskAccTest extends AbstractAccTest {
assertThatThrownBy(call).isInstanceOf(NotAuthorizedException.class);
}
+ @WithAccessId(user = "admin")
+ @Test
+ void should_deleteAttachments_When_MultipleTasksAreDeleted()
+ throws NotAuthorizedException, InvalidArgumentException, NoSuchFieldException,
+ IllegalAccessException {
+
+ TaskService taskService = taskanaEngine.getTaskService();
+
+ TaskanaEngineProxyForTest engineProxy = new TaskanaEngineProxyForTest(taskanaEngine);
+ AttachmentMapper attachmentMapper =
+ engineProxy.getEngine().getSqlSession().getMapper(AttachmentMapper.class);
+
+ assertThat(attachmentMapper.findAttachmentSummariesByTaskIds(Arrays.asList(
+ "TKI:000000000000000000000000000000000067", "TKI:000000000000000000000000000000000068")))
+ .hasSize(4);
+
+ taskService.deleteTasks(Arrays.asList("TKI:000000000000000000000000000000000067",
+ "TKI:000000000000000000000000000000000068"));
+
+ assertThat(attachmentMapper.findAttachmentSummariesByTaskIds(Arrays.asList(
+ "TKI:000000000000000000000000000000000067", "TKI:000000000000000000000000000000000068")))
+ .hasSize(0);
+
+ }
+
+ @WithAccessId(user = "admin")
+ @Test
+ void should_deleteAttachments_When_SingleTaskIsDeleted()
+ throws NotAuthorizedException, NoSuchFieldException,
+ IllegalAccessException, InvalidStateException, TaskNotFoundException {
+
+ TaskService taskService = taskanaEngine.getTaskService();
+
+ TaskanaEngineProxyForTest engineProxy = new TaskanaEngineProxyForTest(taskanaEngine);
+ AttachmentMapper attachmentMapper =
+ engineProxy.getSqlSession().getMapper(AttachmentMapper.class);
+
+ assertThat(attachmentMapper.findAttachmentsByTaskId("TKI:000000000000000000000000000000000069"))
+ .hasSize(1);
+
+ taskService.deleteTask(
+ "TKI:000000000000000000000000000000000069");
+
+ assertThat(attachmentMapper.findAttachmentsByTaskId("TKI:000000000000000000000000000000000069"))
+ .hasSize(0);
+
+ }
+
@WithAccessId(user = "businessadmin")
@WithAccessId(user = "taskadmin")
@WithAccessId(user = "user-1-1")
diff --git a/lib/taskana-core/src/test/java/acceptance/task/QueryTaskByClassificationNameAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/QueryTaskByClassificationNameAccTest.java
index 2f71bd5d9..4f8178d75 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/QueryTaskByClassificationNameAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/QueryTaskByClassificationNameAccTest.java
@@ -107,14 +107,14 @@ class QueryTaskByClassificationNameAccTest extends AbstractAccTest {
.attachmentClassificationNameLike("Widerruf", "Beratungsprotokoll", "Dynamik%")
.orderByAttachmentClassificationName(SortDirection.ASCENDING)
.list();
- assertThat(tasks).hasSize(7);
+ assertThat(tasks).hasSize(10);
// make sure that unordered query returns the same number of objects
tasks =
taskService
.createTaskQuery()
.attachmentClassificationNameLike("Widerruf", "Beratungsprotokoll", "Dynamik%")
.list();
- assertThat(tasks).hasSize(7);
+ assertThat(tasks).hasSize(10);
}
@WithAccessId(user = "user-1-1")
@@ -128,14 +128,14 @@ class QueryTaskByClassificationNameAccTest extends AbstractAccTest {
.attachmentClassificationNameIn("Widerruf", "Beratungsprotokoll", "Dynamikänderung")
.orderByAttachmentClassificationName(SortDirection.ASCENDING)
.list();
- assertThat(tasks).hasSize(4);
+ assertThat(tasks).hasSize(7);
// make sure that unordered query returns the same number of objects
tasks =
taskService
.createTaskQuery()
.attachmentClassificationNameIn("Widerruf", "Beratungsprotokoll", "Dynamikänderung")
.list();
- assertThat(tasks).hasSize(4);
+ assertThat(tasks).hasSize(7);
}
@WithAccessId(user = "user-1-1")
@@ -162,12 +162,12 @@ class QueryTaskByClassificationNameAccTest extends AbstractAccTest {
// we expect 4 result objects in this case, because task
// TKI:000000000000000000000000000000000001 has 2 attachments with different Classifications
// therefore task TKI:000000000000000000000000000000000001 occurs twice in the result set
- assertThat(tasks).hasSize(4);
+ assertThat(tasks).hasSize(7);
long numberOfTasks =
taskQuery
.attachmentClassificationNameIn("Widerruf", "Beratungsprotokoll", "Dynamikänderung")
.count();
- assertThat(numberOfTasks).isEqualTo(3);
+ assertThat(numberOfTasks).isEqualTo(6);
// the count returns only the number of tasks that have an attachment with the specified
// classification name.
// therefore, task 001 is counted only once.
diff --git a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java
index dc9c78210..417ba8a23 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksAccTest.java
@@ -145,7 +145,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List results =
taskService.createTaskQuery().ownerLike("%a%", "%u%").orderByCreated(ASCENDING).list();
- assertThat(results).hasSize(36);
+ assertThat(results).hasSize(39);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
if (previousSummary != null) {
@@ -206,7 +206,7 @@ class QueryTasksAccTest extends AbstractAccTest {
List result4 =
taskService.createTaskQuery().classificationKeyNotIn("L1050", "L1060", "T2100").list();
- assertThat(result4).hasSize(7);
+ assertThat(result4).hasSize(10);
}
@WithAccessId(user = "admin")
@@ -256,7 +256,7 @@ class QueryTasksAccTest extends AbstractAccTest {
.createTaskQuery()
.externalIdLike("ETI:000000000000000000000000000000%")
.listValues(TaskQueryColumnName.EXTERNAL_ID, DESCENDING);
- assertThat(resultValues).hasSize(71);
+ assertThat(resultValues).hasSize(74);
long countAllExternalIds = taskService.createTaskQuery().externalIdLike("ETI:%").count();
long countAllIds = taskService.createTaskQuery().count();
@@ -475,7 +475,7 @@ class QueryTasksAccTest extends AbstractAccTest {
@Test
void testQueryForReadEquals() {
List results = taskService.createTaskQuery().readEquals(true).list();
- assertThat(results).hasSize(36);
+ assertThat(results).hasSize(39);
}
@WithAccessId(user = "admin")
@@ -497,7 +497,7 @@ class QueryTasksAccTest extends AbstractAccTest {
@Test
void testQueryForBusinessProcessIdLike() {
List results = taskService.createTaskQuery().businessProcessIdLike("pI_%").list();
- assertThat(results).hasSize(77);
+ assertThat(results).hasSize(80);
}
@WithAccessId(user = "admin")
diff --git a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByTimeIntervalsAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByTimeIntervalsAccTest.java
index 8380f46b0..2705d05a0 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByTimeIntervalsAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByTimeIntervalsAccTest.java
@@ -42,7 +42,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
.orderByCreated(asc)
.list();
- assertThat(results).hasSize(50);
+ assertThat(results).hasSize(53);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getCreated();
@@ -88,7 +88,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List results =
taskService.createTaskQuery().createdWithin(interval1).orderByCreated(asc).list();
- assertThat(results).hasSize(48);
+ assertThat(results).hasSize(51);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getCreated();
@@ -118,7 +118,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
.orderByCreated(asc)
.list();
- assertThat(results).hasSize(35);
+ assertThat(results).hasSize(38);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getClaimed();
@@ -141,7 +141,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List results =
taskService.createTaskQuery().completedWithin(interval).orderByCompleted(asc).list();
- assertThat(results).hasSize(15);
+ assertThat(results).hasSize(18);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getCompleted();
@@ -187,7 +187,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List results =
taskService.createTaskQuery().plannedWithin(interval).orderByPlanned(asc).list();
- assertThat(results).hasSize(82);
+ assertThat(results).hasSize(85);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getPlanned();
@@ -210,7 +210,7 @@ class QueryTasksByTimeIntervalsAccTest extends AbstractAccTest {
List results =
taskService.createTaskQuery().dueWithin(interval).orderByPlanned(asc).list();
- assertThat(results).hasSize(82);
+ assertThat(results).hasSize(85);
TaskSummary previousSummary = null;
for (TaskSummary taskSummary : results) {
Instant cr = taskSummary.getDue();
diff --git a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByWorkbasketAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByWorkbasketAccTest.java
index aa3e68e8e..f2f1fb150 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByWorkbasketAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/QueryTasksByWorkbasketAccTest.java
@@ -39,7 +39,7 @@ class QueryTasksByWorkbasketAccTest extends AbstractAccTest {
.createTaskQuery()
.workbasketKeyDomainIn(workbasketIdentifiers.toArray(new KeyDomain[0]))
.list();
- assertThat(results).hasSize(30);
+ assertThat(results).hasSize(55);
String[] ids =
results.stream()
@@ -48,7 +48,7 @@ class QueryTasksByWorkbasketAccTest extends AbstractAccTest {
.toArray(new String[0]);
List result2 = taskService.createTaskQuery().workbasketIdIn(ids).list();
- assertThat(result2).hasSize(30);
+ assertThat(result2).hasSize(59);
}
@WithAccessId(user = "user-1-1")
diff --git a/lib/taskana-core/src/test/java/acceptance/task/SetOwnerAccTest.java b/lib/taskana-core/src/test/java/acceptance/task/SetOwnerAccTest.java
index 9f19fc0d4..87c91ad06 100644
--- a/lib/taskana-core/src/test/java/acceptance/task/SetOwnerAccTest.java
+++ b/lib/taskana-core/src/test/java/acceptance/task/SetOwnerAccTest.java
@@ -164,7 +164,7 @@ class SetOwnerAccTest extends AbstractAccTest {
allTaskSummaries.stream().map(TaskSummary::getId).collect(Collectors.toList());
BulkOperationResults results =
taskanaEngine.getTaskService().setOwnerOfTasks("theWorkaholic", allTaskIds);
- assertThat(allTaskSummaries).hasSize(84);
+ assertThat(allTaskSummaries).hasSize(87);
assertThat(results.containsErrors()).isTrue();
Condition