Skip to content

Commit 6ad7274

Browse files
committed
Closes #2378 - Add DeleteHistoryEvent for Task
1 parent 6cb97d2 commit 6ad7274

File tree

7 files changed

+178
-7
lines changed

7 files changed

+178
-7
lines changed

common/taskana-common/src/main/java/pro/taskana/common/internal/util/ObjectAttributeChangeDetector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ public static <T> String determineChangesInAttributes(T oldObject, T newObject)
4040

4141
// this has to be checked after we deal with List data types, because
4242
// we want to allow different implementations of the List interface to work as well.
43-
if (!oldObject.getClass().equals(newObject.getClass())) {
43+
if (!oldObject.getClass().equals(newObject.getClass())
44+
&& !oldObject.getClass().isAssignableFrom(newObject.getClass())) {
4445
throw new SystemException(
4546
String.format(
4647
"The classes differ between the oldObject(%s) and newObject(%s). "

history/taskana-simplehistory-provider/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@
9191
<version>${version.oracle}</version>
9292
<scope>test</scope>
9393
</dependency>
94-
94+
<dependency>
95+
<groupId>pro.taskana</groupId>
96+
<artifactId>taskana-test-api</artifactId>
97+
<version>${project.version}</version>
98+
<scope>test</scope>
99+
</dependency>
95100
</dependencies>
96101

97102
</project>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package acceptance.events.task;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.List;
6+
import org.junit.jupiter.api.BeforeAll;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.ExtendWith;
9+
import pro.taskana.classification.api.ClassificationService;
10+
import pro.taskana.classification.api.models.ClassificationSummary;
11+
import pro.taskana.common.api.TaskanaEngine;
12+
import pro.taskana.common.test.security.JaasExtension;
13+
import pro.taskana.common.test.security.WithAccessId;
14+
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
15+
import pro.taskana.spi.history.api.TaskanaHistory;
16+
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
17+
import pro.taskana.spi.history.api.events.task.TaskHistoryEventType;
18+
import pro.taskana.task.api.TaskService;
19+
import pro.taskana.task.api.TaskState;
20+
import pro.taskana.task.api.models.Task;
21+
import pro.taskana.testapi.DefaultTestEntities;
22+
import pro.taskana.testapi.TaskanaInject;
23+
import pro.taskana.testapi.TaskanaIntegrationTest;
24+
import pro.taskana.testapi.WithServiceProvider;
25+
import pro.taskana.testapi.builder.TaskBuilder;
26+
import pro.taskana.workbasket.api.WorkbasketService;
27+
import pro.taskana.workbasket.api.models.WorkbasketSummary;
28+
29+
@WithServiceProvider(
30+
serviceProviderInterface = TaskanaHistory.class,
31+
serviceProviders = SimpleHistoryServiceImpl.class)
32+
@TaskanaIntegrationTest
33+
@ExtendWith(JaasExtension.class)
34+
class CreateHistoryEventOnTaskDeletionAccTest {
35+
@TaskanaInject TaskanaEngine taskanaEngine;
36+
@TaskanaInject TaskService taskService;
37+
@TaskanaInject WorkbasketService workbasketService;
38+
@TaskanaInject ClassificationService classificationService;
39+
ClassificationSummary defaultClassificationSummary;
40+
WorkbasketSummary defaultWorkbasketSummary;
41+
Task task1;
42+
Task task2;
43+
Task task3;
44+
Task task4;
45+
private SimpleHistoryServiceImpl historyService = new SimpleHistoryServiceImpl();
46+
47+
@WithAccessId(user = "admin")
48+
@BeforeAll
49+
void setUp() throws Exception {
50+
historyService.initialize(taskanaEngine);
51+
52+
defaultClassificationSummary =
53+
DefaultTestEntities.defaultTestClassification()
54+
.buildAndStoreAsSummary(classificationService);
55+
defaultWorkbasketSummary =
56+
DefaultTestEntities.defaultTestWorkbasket().buildAndStoreAsSummary(workbasketService);
57+
58+
task1 = createTask().buildAndStore(taskService);
59+
task2 = createTask().state(TaskState.COMPLETED).buildAndStore(taskService);
60+
task3 = createTask().state(TaskState.COMPLETED).buildAndStore(taskService);
61+
task4 = createTask().state(TaskState.COMPLETED).buildAndStore(taskService);
62+
}
63+
64+
@WithAccessId(user = "admin")
65+
@Test
66+
void should_CreateDeleteHistoryEvent_When_TaskIsDeleted() throws Exception {
67+
historyService.deleteHistoryEventsByTaskIds(List.of(task4.getId()));
68+
69+
taskService.deleteTask(task4.getId());
70+
71+
List<TaskHistoryEvent> events =
72+
historyService.createTaskHistoryQuery().taskIdIn(task4.getId()).list();
73+
assertThat(events).hasSize(1);
74+
assertDeleteHistoryEvent(
75+
events.get(0).getId(), "admin");
76+
}
77+
78+
@WithAccessId(user = "admin")
79+
@Test
80+
void should_CreateDeleteHistoryEvent_When_TaskIsForceDeleted() throws Exception {
81+
historyService.deleteHistoryEventsByTaskIds(List.of(task1.getId()));
82+
83+
taskService.forceDeleteTask(task1.getId());
84+
85+
List<TaskHistoryEvent> events =
86+
historyService.createTaskHistoryQuery().taskIdIn(task1.getId()).list();
87+
assertThat(events).hasSize(1);
88+
assertDeleteHistoryEvent(events.get(0).getId(), "admin");
89+
}
90+
91+
@WithAccessId(user = "admin")
92+
@Test
93+
void should_CreateDeleteHistoryEvents_When_MultipleTasksAreDeleted() throws Exception {
94+
List<String> taskIds = List.of(task2.getId(), task3.getId());
95+
historyService.deleteHistoryEventsByTaskIds(taskIds);
96+
97+
taskService.deleteTasks(taskIds);
98+
99+
List<TaskHistoryEvent> events =
100+
historyService.createTaskHistoryQuery().taskIdIn(taskIds.toArray(new String[0])).list();
101+
assertThat(events)
102+
.extracting(TaskHistoryEvent::getTaskId)
103+
.containsExactlyInAnyOrderElementsOf(taskIds);
104+
for (TaskHistoryEvent event : events) {
105+
assertDeleteHistoryEvent(event.getId(), "admin");
106+
}
107+
}
108+
109+
private void assertDeleteHistoryEvent(
110+
String eventId, String expectedUser)
111+
throws Exception {
112+
TaskHistoryEvent event = historyService.getTaskHistoryEvent(eventId);
113+
assertThat(event.getUserId()).isEqualTo(expectedUser);
114+
assertThat(event.getEventType()).isEqualTo(TaskHistoryEventType.DELETED.getName());
115+
}
116+
117+
private TaskBuilder createTask() {
118+
return TaskBuilder.newTask()
119+
.classificationSummary(defaultClassificationSummary)
120+
.workbasketSummary(defaultWorkbasketSummary)
121+
.primaryObjRef(DefaultTestEntities.defaultTestObjectReference().build());
122+
}
123+
}

history/taskana-simplehistory-provider/src/test/java/acceptance/events/task/DeleteHistoryEventsOnTaskDeletionAccTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import pro.taskana.simplehistory.impl.TaskHistoryQueryImpl;
1616
import pro.taskana.simplehistory.impl.task.TaskHistoryQueryMapper;
1717
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
18+
import pro.taskana.spi.history.api.events.task.TaskHistoryEventType;
1819
import pro.taskana.task.api.exceptions.TaskNotFoundException;
1920

2021
@ExtendWith(JaasExtension.class)
@@ -47,7 +48,8 @@ void should_DeleteHistoryEvents_When_TaskIsDeletedWithHistoryDeletionEnabled() t
4748
listEvents =
4849
taskHistoryQueryMapper.queryHistoryEvents(
4950
(TaskHistoryQueryImpl) historyService.createTaskHistoryQuery().taskIdIn(taskid));
50-
assertThat(listEvents).isEmpty();
51+
assertThat(listEvents).hasSize(1);
52+
assertThat(listEvents.get(0).getEventType()).isEqualTo(TaskHistoryEventType.DELETED.getName());
5153
}
5254

5355
@Test
@@ -87,7 +89,9 @@ void should_DeleteHistoryEvents_When_TasksAreDeletedWithHistoryDeletionEnabled()
8789
taskHistoryQueryMapper.queryHistoryEvents(
8890
(TaskHistoryQueryImpl)
8991
historyService.createTaskHistoryQuery().taskIdIn(taskId_1, taskId_2));
90-
assertThat(listEvents).isEmpty();
92+
assertThat(listEvents).hasSize(2);
93+
assertThat(listEvents.get(0).getEventType()).isEqualTo(TaskHistoryEventType.DELETED.getName());
94+
assertThat(listEvents.get(1).getEventType()).isEqualTo(TaskHistoryEventType.DELETED.getName());
9195
}
9296

9397
@Test
@@ -119,7 +123,7 @@ void should_NotDeleteHistoryEvents_When_TaskIsDeletedWithHistoryDeletionDisabled
119123
listEvents =
120124
taskHistoryQueryMapper.queryHistoryEvents(
121125
(TaskHistoryQueryImpl) historyService.createTaskHistoryQuery().taskIdIn(taskId));
122-
assertThat(listEvents).hasSize(2);
126+
assertThat(listEvents).hasSize(3);
123127
}
124128

125129
@Test
@@ -152,7 +156,7 @@ void should_NotDeleteHistoryEvents_When_TasksAreDeletedWithHistoryDeletionDisabl
152156
taskHistoryQueryMapper.queryHistoryEvents(
153157
(TaskHistoryQueryImpl)
154158
historyService.createTaskHistoryQuery().taskIdIn(taskId_1, taskId_2));
155-
assertThat(listEvents).hasSize(2);
159+
assertThat(listEvents).hasSize(4);
156160
}
157161

158162
private void createTaskanaEngineWithNewConfig(boolean deleteHistoryOnTaskDeletionEnabled)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package pro.taskana.spi.history.api.events.task;
2+
3+
import java.time.Instant;
4+
import pro.taskana.task.api.models.TaskSummary;
5+
6+
public class TaskDeletedEvent extends TaskHistoryEvent {
7+
8+
public TaskDeletedEvent(
9+
String id,
10+
TaskSummary taskSummary,
11+
String userId) {
12+
super(id, taskSummary, userId, null);
13+
eventType = TaskHistoryEventType.DELETED.getName();
14+
created = Instant.now();
15+
}
16+
}

lib/taskana-core/src/main/java/pro/taskana/spi/history/api/events/task/TaskHistoryEventType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ public enum TaskHistoryEventType {
1010
COMPLETED("COMPLETED"),
1111
CANCELLED("CANCELLED"),
1212
TERMINATED("TERMINATED"),
13-
TRANSFERRED("TRANSFERRED");
13+
TRANSFERRED("TRANSFERRED"),
14+
DELETED("DELETED");
1415

1516
private String name;
1617

lib/taskana-core/src/main/java/pro/taskana/task/internal/TaskServiceImpl.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import pro.taskana.spi.history.api.events.task.TaskClaimedEvent;
4747
import pro.taskana.spi.history.api.events.task.TaskCompletedEvent;
4848
import pro.taskana.spi.history.api.events.task.TaskCreatedEvent;
49+
import pro.taskana.spi.history.api.events.task.TaskDeletedEvent;
4950
import pro.taskana.spi.history.api.events.task.TaskRequestChangesEvent;
5051
import pro.taskana.spi.history.api.events.task.TaskRequestReviewEvent;
5152
import pro.taskana.spi.history.api.events.task.TaskTerminatedEvent;
@@ -693,6 +694,11 @@ public BulkOperationResults<String, TaskanaException> deleteTasks(List<String> t
693694
}
694695

695696
if (!taskIds.isEmpty()) {
697+
List<TaskSummary> tasksToDelete = null;
698+
if (historyEventManager.isEnabled()) {
699+
tasksToDelete =
700+
createTaskQuery().idIn(taskIds.toArray(new String[0])).list();
701+
}
696702
attachmentMapper.deleteMultipleByTaskIds(taskIds);
697703
objectReferenceMapper.deleteMultipleByTaskIds(taskIds);
698704
taskMapper.deleteMultiple(taskIds);
@@ -704,6 +710,9 @@ public BulkOperationResults<String, TaskanaException> deleteTasks(List<String> t
704710
.isDeleteHistoryEventsOnTaskDeletionEnabled()) {
705711
historyEventManager.deleteEvents(taskIds);
706712
}
713+
if (historyEventManager.isEnabled()) {
714+
tasksToDelete.forEach(this::createTaskDeletedEvent);
715+
}
707716
}
708717
return bulkLog;
709718
} finally {
@@ -1709,6 +1718,10 @@ private void deleteTask(String taskId, boolean forceDelete)
17091718
historyEventManager.deleteEvents(Collections.singletonList(taskId));
17101719
}
17111720

1721+
if (historyEventManager.isEnabled()) {
1722+
createTaskDeletedEvent(task.asSummary());
1723+
}
1724+
17121725
if (LOGGER.isDebugEnabled()) {
17131726
LOGGER.debug("Task {} deleted.", taskId);
17141727
}
@@ -2241,6 +2254,14 @@ private void createTasksCompletedEvents(List<? extends TaskSummary> taskSummarie
22412254
taskanaEngine.getEngine().getCurrentUserContext().getUserid())));
22422255
}
22432256

2257+
private void createTaskDeletedEvent(TaskSummary taskSummary) {
2258+
historyEventManager.createEvent(
2259+
new TaskDeletedEvent(
2260+
IdGenerator.generateWithPrefix(IdGenerator.ID_PREFIX_TASK_HISTORY_EVENT),
2261+
taskSummary,
2262+
taskanaEngine.getEngine().getCurrentUserContext().getUserid()));
2263+
}
2264+
22442265
private TaskImpl duplicateTaskExactly(TaskImpl task) {
22452266
TaskImpl oldTask = task.copy();
22462267
oldTask.setId(task.getId());

0 commit comments

Comments
 (0)