TSK-1332: Reworked logic after review

This commit is contained in:
Joerg Heffner 2020-08-21 16:00:45 +02:00 committed by gitgoodjhe
parent 851b3536db
commit 32a1db98bd
10 changed files with 409 additions and 168 deletions

View File

@ -14,6 +14,10 @@ taskana.jobs.batchSize=50
taskana.jobs.cleanup.runEvery=P1D
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=P14D
taskana.jobs.history.batchSize=50
taskana.jobs.history.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.history.cleanup.minimumAge=P14D
taskana.jobs.history.cleanup.runEvery=P1D
taskana.german.holidays.enabled=true
taskana.german.holidays.corpus-christi.enabled=true

View File

@ -1,4 +1,8 @@
package pro.taskana.simplehistory.impl;
package pro.taskana.simplehistory.impl.jobs;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import java.io.File;
import java.io.FileInputStream;
@ -8,12 +12,10 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -28,6 +30,10 @@ import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.jobs.AbstractTaskanaJob;
import pro.taskana.common.internal.transaction.TaskanaTransactionProvider;
import pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl;
import pro.taskana.simplehistory.impl.TaskanaHistoryEngineImpl;
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
import pro.taskana.spi.history.api.events.task.TaskHistoryEventType;
public class HistoryCleanupJob extends AbstractTaskanaJob {
@ -36,21 +42,25 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
private static final String TASKANA_PROPERTIES = "/taskana.properties";
private static final String TASKANA_JOB_HISTORY_BATCH_SIZE = "taskana.jobs.history.batchSize";
private static final String TASKANA_JOB_HISTORY_CLEANUP_RUN_EVERY =
"taskana.jobs.history.cleanup.runEvery";
private static final String TASKANA_JOB_HISTORY_CLEANUP_FIRST_RUN =
"taskana.jobs.history.cleanup.firstRunAt";
private static final String TASKANA_JOB_HISTORY_CLEANUP_MINIMUM_AGE =
"taskana.jobs.history.cleanup.minimumAge";
private final boolean allCompletedSameParentBusiness;
TaskanaHistoryEngineImpl taskanaHistoryEngine =
TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngineImpl.getConfiguration());
private Instant firstRun;
private Duration runEvery;
private Duration minimumAge;
private int batchSize;
private boolean allCompletedSameParentBusiness;
private Instant firstRun = Instant.parse("2018-01-01T00:00:00Z");
private Duration runEvery = Duration.parse("P1D");
private Duration minimumAge = Duration.parse("P14D");
private int batchSize = 100;
public HistoryCleanupJob(
TaskanaEngine taskanaEngine,
@ -75,28 +85,52 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
SimpleHistoryServiceImpl simpleHistoryService =
(SimpleHistoryServiceImpl) taskanaHistoryEngine.getTaskanaHistoryService();
List<HistoryEventImpl> historyEventsToClean =
List<TaskHistoryEvent> historyEventCandidatesToClean =
simpleHistoryService
.createHistoryQuery()
.createTaskHistoryQuery()
.createdWithin(new TimeInterval(null, createdBefore))
.eventTypeIn("TASK_COMPLETED")
.eventTypeIn(
TaskHistoryEventType.COMPLETED.getName(),
TaskHistoryEventType.CANCELLED.getName(),
TaskHistoryEventType.TERMINATED.getName())
.list();
List<String> taskIdsToDeleteHistoryEventsFor;
if (allCompletedSameParentBusiness) {
historyEventsToClean =
filterSameParentBusinessHistoryEventsQualifiedToClean(
simpleHistoryService, historyEventsToClean);
String[] parentBusinessProcessIds =
historyEventCandidatesToClean.stream()
.map(TaskHistoryEvent::getParentBusinessProcessId)
.distinct()
.toArray(String[]::new);
historyEventCandidatesToClean.addAll(
simpleHistoryService
.createTaskHistoryQuery()
.parentBusinessProcessIdIn(parentBusinessProcessIds)
.eventTypeIn(TaskHistoryEventType.CREATED.getName())
.list());
taskIdsToDeleteHistoryEventsFor =
filterSameParentBusinessHistoryEventsQualifiedToClean(historyEventCandidatesToClean);
} else {
taskIdsToDeleteHistoryEventsFor =
historyEventCandidatesToClean.stream()
.map(TaskHistoryEvent::getTaskId)
.collect(toList());
}
int totalNumberOfHistoryEventsDeleted = 0;
while (!historyEventsToClean.isEmpty()) {
while (!taskIdsToDeleteHistoryEventsFor.isEmpty()) {
int upperLimit = batchSize;
if (upperLimit > historyEventsToClean.size()) {
upperLimit = historyEventsToClean.size();
if (upperLimit > taskIdsToDeleteHistoryEventsFor.size()) {
upperLimit = taskIdsToDeleteHistoryEventsFor.size();
}
totalNumberOfHistoryEventsDeleted +=
deleteHistoryEventsTransactionally(historyEventsToClean.subList(0, upperLimit));
historyEventsToClean.subList(0, upperLimit).clear();
deleteHistoryEventsTransactionally(
taskIdsToDeleteHistoryEventsFor.subList(0, upperLimit));
taskIdsToDeleteHistoryEventsFor.subList(0, upperLimit).clear();
}
LOGGER.info(
"Job ended successfully. {} history events deleted.", totalNumberOfHistoryEventsDeleted);
@ -118,46 +152,50 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
job.scheduleNextCleanupJob();
}
private List<HistoryEventImpl> filterSameParentBusinessHistoryEventsQualifiedToClean(
SimpleHistoryServiceImpl simpleHistoryService, List<HistoryEventImpl> historyEventsToClean) {
private List<String> filterSameParentBusinessHistoryEventsQualifiedToClean(
List<TaskHistoryEvent> historyEventCandidatesToClean) {
Map<String, Long> eventsToCleanForParentBusinessCount = new HashMap<>();
Map<String, Map<String, List<String>>> historyEventsGroupedByParentBusinessProcessIdAndType =
historyEventCandidatesToClean.stream()
.collect(
groupingBy(
TaskHistoryEvent::getParentBusinessProcessId,
groupingBy(
TaskHistoryEvent::getEventType,
mapping(TaskHistoryEvent::getTaskId, toList()))));
historyEventsToClean.forEach(
event ->
eventsToCleanForParentBusinessCount.merge(
event.getParentBusinessProcessId(), 1L, Long::sum));
List<String> taskIdsToDeleteHistoryEventsFor = new ArrayList<>();
Predicate<HistoryEventImpl> noCompletedEventsUnderMinimumAgeExistInSameParentBusiness =
event ->
simpleHistoryService
.createHistoryQuery()
.parentBusinessProcessIdIn(event.getParentBusinessProcessId())
.eventTypeIn("TASK_COMPLETED")
.count()
== eventsToCleanForParentBusinessCount.get(event.getParentBusinessProcessId());
historyEventsGroupedByParentBusinessProcessIdAndType
.entrySet()
.forEach(
idsOfTasksInSameParentBusinessProcessGroupedByType -> {
if (idsOfTasksInSameParentBusinessProcessGroupedByType
.getValue()
.get(TaskHistoryEventType.CREATED.getName())
.size()
== idsOfTasksInSameParentBusinessProcessGroupedByType.getValue().entrySet()
.stream()
.filter(
entry -> !entry.getKey().equals(TaskHistoryEventType.CREATED.getName()))
.mapToInt(stringListEntry -> stringListEntry.getValue().size())
.sum()) {
Predicate<HistoryEventImpl> allTasksCleanedSameParentBusiness =
e ->
taskanaEngineImpl
.getTaskService()
.createTaskQuery()
.parentBusinessProcessIdIn(e.getParentBusinessProcessId())
.count()
== 0;
taskIdsToDeleteHistoryEventsFor.addAll(
idsOfTasksInSameParentBusinessProcessGroupedByType
.getValue()
.get(TaskHistoryEventType.CREATED.getName()));
}
});
return historyEventsToClean.stream()
.filter(
noCompletedEventsUnderMinimumAgeExistInSameParentBusiness.and(
allTasksCleanedSameParentBusiness))
.collect(Collectors.toList());
return taskIdsToDeleteHistoryEventsFor;
}
private int deleteHistoryEventsTransactionally(List<HistoryEventImpl> historyEventsToBeDeleted) {
private int deleteHistoryEventsTransactionally(List<String> taskIdsToDeleteHistoryEventsFor) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"entry to deleteHistoryEventsTransactionally(historyEventsToBeDeleted = {})",
historyEventsToBeDeleted);
"entry to deleteHistoryEventsTransactionally(taskIdsToDeleteHistoryEventsFor = {})",
taskIdsToDeleteHistoryEventsFor);
}
int deletedEventsCount = 0;
@ -167,7 +205,7 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
txProvider.executeInTransaction(
() -> {
try {
return deleteEvents(historyEventsToBeDeleted);
return deleteEvents(taskIdsToDeleteHistoryEventsFor);
} catch (Exception e) {
LOGGER.warn("Could not delete history events.", e);
return 0;
@ -177,7 +215,7 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
return count;
} else {
try {
deletedEventsCount = deleteEvents(historyEventsToBeDeleted);
deletedEventsCount = deleteEvents(taskIdsToDeleteHistoryEventsFor);
} catch (Exception e) {
LOGGER.warn("Could not delete history events.", e);
}
@ -187,34 +225,30 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
return deletedEventsCount;
}
private int deleteEvents(List<HistoryEventImpl> historyEventsToBeDeleted)
private int deleteEvents(List<String> taskIdsToDeleteHistoryEventsFor)
throws InvalidArgumentException, NotAuthorizedException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"entry to deleteEvents(historyEventsToBeDeleted = {})", historyEventsToBeDeleted);
"entry to deleteEvents(taskIdsToDeleteHistoryEventsFor = {})",
taskIdsToDeleteHistoryEventsFor);
}
List<String> taskIdsOfEventsToBeDeleted =
historyEventsToBeDeleted.stream()
.map(HistoryEventImpl::getTaskId)
.collect(Collectors.toList());
SimpleHistoryServiceImpl simpleHistoryService =
(SimpleHistoryServiceImpl) taskanaHistoryEngine.getTaskanaHistoryService();
String[] taskIdsArray = new String[taskIdsOfEventsToBeDeleted.size()];
String[] taskIdsArray = new String[taskIdsToDeleteHistoryEventsFor.size()];
int deletedTasksCount =
(int)
simpleHistoryService
.createHistoryQuery()
.taskIdIn(taskIdsOfEventsToBeDeleted.toArray(taskIdsArray))
.createTaskHistoryQuery()
.taskIdIn(taskIdsToDeleteHistoryEventsFor.toArray(taskIdsArray))
.count();
simpleHistoryService.deleteHistoryEventsByTaskIds(taskIdsOfEventsToBeDeleted);
simpleHistoryService.deleteHistoryEventsByTaskIds(taskIdsToDeleteHistoryEventsFor);
LOGGER.debug("{} events deleted.", deletedTasksCount);
LOGGER.debug("exit from deleteEvents(), returning {}", taskIdsOfEventsToBeDeleted.size());
LOGGER.debug("exit from deleteEvents(), returning {}", taskIdsToDeleteHistoryEventsFor.size());
return deletedTasksCount;
}
@ -315,8 +349,10 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
"taskana properties were loaded from file {} from classpath.", propertiesFile);
}
} else {
props.load(new FileInputStream(propertiesFile));
LOGGER.debug("taskana properties were loaded from file {}.", propertiesFile);
try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) {
props.load(fileInputStream);
LOGGER.debug("taskana properties were loaded from file {}.", propertiesFile);
}
}
} catch (IOException e) {
LOGGER.error("caught IOException when processing properties file {}.", propertiesFile);

View File

@ -11,8 +11,9 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.simplehistory.impl.HistoryCleanupJob;
import pro.taskana.simplehistory.impl.HistoryEventImpl;
import pro.taskana.simplehistory.impl.jobs.HistoryCleanupJob;
import pro.taskana.spi.history.api.events.task.TaskHistoryEvent;
import pro.taskana.spi.history.api.events.task.TaskHistoryEventType;
@ExtendWith(JaasExtension.class)
class HistoryCleanupJobAccTest extends AbstractAccTest {
@ -27,128 +28,336 @@ class HistoryCleanupJobAccTest extends AbstractAccTest {
void should_CleanHistoryEventsUntilDate_When_SameParentBusinessTrueAndEventsQualified()
throws Exception {
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(13);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(13);
HistoryEventImpl eventToBeCleaned =
createHistoryEvent(
"wbKey1", "taskId1", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
TaskHistoryEvent eventToBeCleaned =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
HistoryEventImpl eventToBeCleaned2 =
createHistoryEvent(
"wbKey1", "taskId2", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
TaskHistoryEvent eventToBeCleaned2 =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.COMPLETED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned2.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned3 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned3.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned3.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned4 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CANCELLED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned4.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned4.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned5 =
createTaskHistoryEvent(
"wbKey1",
"taskId3",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned5.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned5.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned6 =
createTaskHistoryEvent(
"wbKey1",
"taskId3",
TaskHistoryEventType.TERMINATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned6.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned6.setParentBusinessProcessId("sameParentId");
getHistoryService().create(eventToBeCleaned);
getHistoryService().create(eventToBeCleaned2);
getHistoryService().create(eventToBeCleaned3);
getHistoryService().create(eventToBeCleaned4);
getHistoryService().create(eventToBeCleaned5);
getHistoryService().create(eventToBeCleaned6);
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(15);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(19);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(true);
HistoryCleanupJob job = new HistoryCleanupJob(taskanaEngine, null, null);
job.run();
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(13);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(13);
}
@Test
@WithAccessId(user = "admin")
void should_NotCleanHistoryEventsUntilDate_When_SameParentBusinessTrueAndEventsNotQualified()
throws Exception {
void should_NotCleanHistoryEventsUntilDate_When_MinimumAgeNotReached() throws Exception {
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(13);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(13);
HistoryEventImpl eventToBeCleaned =
createHistoryEvent(
"wbKey1", "taskId1", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
eventToBeCleaned.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
HistoryEventImpl eventToBeCleaned2 =
createHistoryEvent(
"wbKey1", "taskId2", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(1, ChronoUnit.DAYS));
eventToBeCleaned2.setParentBusinessProcessId("sameParentId");
HistoryEventImpl eventToBeCleaned3 =
createHistoryEvent(
TaskHistoryEvent eventToBeCleaned =
createTaskHistoryEvent(
"wbKey1",
"TKI:000000000000000000000000000000000001",
"TASK_COMPLETED",
"taskId1",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned3.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned3.setParentBusinessProcessId("PBPI21");
eventToBeCleaned.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned2 =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.COMPLETED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(5, ChronoUnit.DAYS));
eventToBeCleaned2.setParentBusinessProcessId("sameParentId");
getHistoryService().create(eventToBeCleaned);
getHistoryService().create(eventToBeCleaned2);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(15);
HistoryCleanupJob job = new HistoryCleanupJob(taskanaEngine, null, null);
job.run();
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(15);
}
@Test
@WithAccessId(user = "admin")
void should_NotCleanHistoryEvents_When_SameParentBusinessTrueAndActiveTaskInParentBusiness()
throws Exception {
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(13);
TaskHistoryEvent eventToBeCleaned =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned2 =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.COMPLETED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned2.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned3 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned3.setCreated(Instant.now().minus(1, ChronoUnit.DAYS));
eventToBeCleaned3.setParentBusinessProcessId("sameParentId");
getHistoryService().create(eventToBeCleaned);
getHistoryService().create(eventToBeCleaned2);
getHistoryService().create(eventToBeCleaned3);
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(16);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(16);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(true);
HistoryCleanupJob job = new HistoryCleanupJob(taskanaEngine, null, null);
job.run();
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(16);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(16);
}
@Test
@WithAccessId(user = "admin")
void should_NotCleanHistoryEvents_When_MinimumAgeOfOtherEndtstateEventInParentBusinessNotReached()
throws Exception {
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(13);
TaskHistoryEvent eventToBeCleaned =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned2 =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.COMPLETED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned2.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned3 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned3.setCreated(Instant.now().minus(3, ChronoUnit.DAYS));
eventToBeCleaned3.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned4 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CANCELLED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned4.setCreated(Instant.now().minus(5, ChronoUnit.DAYS));
eventToBeCleaned4.setParentBusinessProcessId("sameParentId");
getHistoryService().create(eventToBeCleaned);
getHistoryService().create(eventToBeCleaned2);
getHistoryService().create(eventToBeCleaned3);
getHistoryService().create(eventToBeCleaned4);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(17);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(true);
HistoryCleanupJob job = new HistoryCleanupJob(taskanaEngine, null, null);
job.run();
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(17);
}
@Test
@WithAccessId(user = "admin")
void should_CleanHistoryEventsUntilDate_When_SameParentBusinessFalse() throws Exception {
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(13);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(13);
HistoryEventImpl eventToBeCleaned =
createHistoryEvent(
"wbKey1", "taskId1", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
TaskHistoryEvent eventToBeCleaned =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
HistoryEventImpl eventToBeCleaned2 =
createHistoryEvent(
"wbKey1", "taskId2", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(1, ChronoUnit.DAYS));
TaskHistoryEvent eventToBeCleaned2 =
createTaskHistoryEvent(
"wbKey1",
"taskId1",
TaskHistoryEventType.COMPLETED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned2.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned2.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned3 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned3.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned3.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned4 =
createTaskHistoryEvent(
"wbKey1",
"taskId2",
TaskHistoryEventType.CANCELLED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned4.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned4.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned5 =
createTaskHistoryEvent(
"wbKey1",
"taskId3",
TaskHistoryEventType.CREATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned5.setCreated(Instant.now().minus(20, ChronoUnit.DAYS));
eventToBeCleaned5.setParentBusinessProcessId("sameParentId");
TaskHistoryEvent eventToBeCleaned6 =
createTaskHistoryEvent(
"wbKey1",
"taskId3",
TaskHistoryEventType.TERMINATED.getName(),
"wbKey2",
"someUserId",
"someDetails");
eventToBeCleaned6.setCreated(Instant.now().minus(5, ChronoUnit.DAYS));
eventToBeCleaned6.setParentBusinessProcessId("sameParentId");
getHistoryService().create(eventToBeCleaned);
getHistoryService().create(eventToBeCleaned2);
getHistoryService().create(eventToBeCleaned3);
getHistoryService().create(eventToBeCleaned4);
getHistoryService().create(eventToBeCleaned5);
getHistoryService().create(eventToBeCleaned6);
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(15);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(19);
taskanaEngine.getConfiguration().setTaskCleanupJobAllCompletedSameParentBusiness(false);
HistoryCleanupJob job = new HistoryCleanupJob(taskanaEngine, null, null);
job.run();
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(14);
assertThat(getHistoryService().getHistoryEvent(eventToBeCleaned2.getId())).isNotNull();
}
@Test
@WithAccessId(user = "admin")
void should_NotCleanHistoryEvents_When_MinimumAgeNotReached() throws Exception {
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(13);
HistoryEventImpl eventToBeCleaned =
createHistoryEvent(
"wbKey1", "taskId1", "TASK_COMPLETED", "wbKey2", "someUserId", "someDetails");
eventToBeCleaned.setCreated(Instant.now().minus(1, ChronoUnit.DAYS));
eventToBeCleaned.setParentBusinessProcessId("sameParentId");
getHistoryService().create(eventToBeCleaned);
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(14);
HistoryCleanupJob job = new HistoryCleanupJob(taskanaEngine, null, null);
job.run();
assertThat(getHistoryService().createHistoryQuery().count()).isEqualTo(14);
assertThat(getHistoryService().createTaskHistoryQuery().count()).isEqualTo(15);
}
}

View File

@ -181,7 +181,7 @@ public class ScheduledJob {
UPDATETASKSJOB(TaskRefreshJob.class.getName()),
TASKCLEANUPJOB(TaskCleanupJob.class.getName()),
WORKBASKETCLEANUPJOB(WorkbasketCleanupJob.class.getName()),
HISTORYCLEANUPJOB("pro.taskana.simplehistory.impl.HistoryCleanupJob");
HISTORYCLEANUPJOB("pro.taskana.simplehistory.impl.jobs.HistoryCleanupJob");
private String clazz;

View File

@ -5,15 +5,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import pro.taskana.classification.internal.jobs.ClassificationChangedJob;
import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.internal.TaskanaEngineImpl;
import pro.taskana.common.internal.transaction.TaskanaTransactionProvider;
import pro.taskana.task.internal.jobs.TaskCleanupJob;
import pro.taskana.task.internal.jobs.TaskRefreshJob;
import pro.taskana.workbasket.internal.jobs.WorkbasketCleanupJob;
/** Abstract base for all background jobs of TASKANA. */
public abstract class AbstractTaskanaJob implements TaskanaJob {
@ -33,34 +28,15 @@ public abstract class AbstractTaskanaJob implements TaskanaJob {
public static TaskanaJob createFromScheduledJob(
TaskanaEngine engine, TaskanaTransactionProvider<Object> txProvider, ScheduledJob job)
throws TaskanaException, ClassNotFoundException, IllegalAccessException,
InstantiationException, InvocationTargetException {
throws ClassNotFoundException, IllegalAccessException, InstantiationException,
InvocationTargetException {
switch (job.getType()) {
case CLASSIFICATIONCHANGEDJOB:
return new ClassificationChangedJob(engine, txProvider, job);
case UPDATETASKSJOB:
return new TaskRefreshJob(engine, txProvider, job);
case TASKCLEANUPJOB:
return new TaskCleanupJob(engine, txProvider, job);
case WORKBASKETCLEANUPJOB:
return new WorkbasketCleanupJob(engine, txProvider, job);
case HISTORYCLEANUPJOB:
return (TaskanaJob)
Thread.currentThread()
.getContextClassLoader()
.loadClass(job.getType().getClazz())
.getConstructors()[0]
.newInstance(engine, txProvider, job);
default:
throw new TaskanaException(
"No matching job found for "
+ job.getType()
+ " of ScheduledJob "
+ job.getJobId()
+ ".");
}
return (TaskanaJob)
Thread.currentThread()
.getContextClassLoader()
.loadClass(job.getType().getClazz())
.getConstructors()[0]
.newInstance(engine, txProvider, job);
}
protected <T> List<List<T>> partition(Collection<T> members, int maxSize) {

View File

@ -13,3 +13,7 @@ taskana.jobs.cleanup.runEvery=P1D
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=PT0S
taskana.jobs.cleanup.allCompletedSameParentBusiness=false
taskana.jobs.history.batchSize=50
taskana.jobs.history.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.history.cleanup.minimumAge=P14D
taskana.jobs.history.cleanup.runEvery=P1D

View File

@ -14,6 +14,10 @@ taskana.jobs.batchSize=50
taskana.jobs.cleanup.runEvery=P1D
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=P14D
taskana.jobs.history.batchSize=50
taskana.jobs.history.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.history.cleanup.minimumAge=P14D
taskana.jobs.history.cleanup.runEvery=P1D
taskana.german.holidays.enabled=true
taskana.german.holidays.corpus-christi.enabled=true
taskana.historylogger.name=AUDIT

View File

@ -14,4 +14,8 @@ taskana.jobs.batchSize=50
taskana.jobs.cleanup.runEvery=P1D
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=P14D
taskana.jobs.history.batchSize=50
taskana.jobs.history.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.history.cleanup.minimumAge=P14D
taskana.jobs.history.cleanup.runEvery=P1D
taskana.german.holidays.enabled=true

View File

@ -28,7 +28,7 @@ import pro.taskana.workbasket.rest.models.WorkbasketSummaryRepresentationModel;
public class AbstractAccTest {
protected static final String DEPENDENCY_VERSION = "4.0.1-SNAPSHOT";
protected static final String DEPENDENCY_VERSION = "4.0.2-SNAPSHOT";
private static final String AUTHORIZATION_TEAMLEAD_1 = "Basic dGVhbWxlYWQtMTp0ZWFtbGVhZC0x";
/**

View File

@ -14,5 +14,9 @@ taskana.jobs.batchSize=50
taskana.jobs.cleanup.runEvery=P1D
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=P14D
taskana.jobs.history.batchSize=50
taskana.jobs.history.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.history.cleanup.minimumAge=P14D
taskana.jobs.history.cleanup.runEvery=P1D
taskana.german.holidays.enabled=true
taskana.historylogger.name=AUDIT