Closes #2377 - add configuration for lock expiration period

This commit is contained in:
Jörg Heffner 2023-09-19 16:01:52 +02:00
parent 67502025a5
commit cf5268894b
12 changed files with 332 additions and 52 deletions

View File

@ -14,6 +14,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TimeInterval; import pro.taskana.common.api.TimeInterval;
@ -52,6 +53,10 @@ public class HistoryCleanupJob extends AbstractTaskanaJob {
super(taskanaEngine, txProvider, scheduledJob, true); super(taskanaEngine, txProvider, scheduledJob, true);
} }
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
return taskanaConfiguration.getSimpleHistoryCleanupJobLockExpirationPeriod();
}
@Override @Override
public void execute() { public void execute() {
Instant createdBefore = Instant.now().minus(minimumAge); Instant createdBefore = Instant.now().minus(minimumAge);

View File

@ -270,21 +270,27 @@ class TaskanaConfigurationTest {
int expectedJobBatchSize = 50; int expectedJobBatchSize = 50;
Instant expectedJobFirstJun = Instant.MIN; Instant expectedJobFirstJun = Instant.MIN;
Duration expectedJobRunEvery = Duration.ofDays(2); Duration expectedJobRunEvery = Duration.ofDays(2);
Duration expectedJobLockExpirationPeriod = Duration.ofDays(2);
boolean expectedTaskCleanupJobEnabled = false; boolean expectedTaskCleanupJobEnabled = false;
Duration expectedTaskCleanupJobMinimumAge = Duration.ofDays(1); Duration expectedTaskCleanupJobMinimumAge = Duration.ofDays(1);
boolean expectedTaskCleanupJobAllCompletedSameParentBusiness = false; boolean expectedTaskCleanupJobAllCompletedSameParentBusiness = false;
Duration expectedTaskCleanupJobLockExpirationPeriod = Duration.ofDays(2);
boolean expectedWorkbasketCleanupJobEnabled = false; boolean expectedWorkbasketCleanupJobEnabled = false;
Duration expectedWorkbasketCleanupJobLockExpirationPeriod = Duration.ofDays(2);
boolean expectedSimpleHistoryCleanupJobEnabled = true; boolean expectedSimpleHistoryCleanupJobEnabled = true;
int expectedSimpleHistoryCleanupJobBatchSize = 16; int expectedSimpleHistoryCleanupJobBatchSize = 16;
Duration expectedSimpleHistoryCleanupJobMinimumAge = Duration.ofHours(3); Duration expectedSimpleHistoryCleanupJobMinimumAge = Duration.ofHours(3);
boolean expectedSimpleHistoryCleanupJobAllCompletedSameParentBusiness = false; boolean expectedSimpleHistoryCleanupJobAllCompletedSameParentBusiness = false;
Duration expectedSimpleHistoryCleanupJobLockExpirationPeriod = Duration.ofDays(2);
boolean expectedTaskUpdatePriorityJobEnabled = true; boolean expectedTaskUpdatePriorityJobEnabled = true;
int expectedPriorityJobBatchSize = 49; int expectedPriorityJobBatchSize = 49;
Instant expectedPriorityJobFirstRun = Instant.MIN.plus(1, ChronoUnit.DAYS); Instant expectedPriorityJobFirstRun = Instant.MIN.plus(1, ChronoUnit.DAYS);
Duration expectedTaskUpdatePriorityJobRunEvery = Duration.ofMinutes(17); Duration expectedTaskUpdatePriorityJobRunEvery = Duration.ofMinutes(17);
Duration expectedTaskUpdatePriorityJobLockExpirationPeriod = Duration.ofDays(2);
boolean expectedUserInfoRefreshJobEnabled = true; boolean expectedUserInfoRefreshJobEnabled = true;
Instant expectedUserRefreshJobFirstRun = Instant.MIN.plus(2, ChronoUnit.DAYS); Instant expectedUserRefreshJobFirstRun = Instant.MIN.plus(2, ChronoUnit.DAYS);
Duration expectedUserRefreshJobRunEvery = Duration.ofDays(5); Duration expectedUserRefreshJobRunEvery = Duration.ofDays(5);
Duration expectedUserRefreshJobLockExpirationPeriod = Duration.ofDays(2);
Set<String> expectedJobSchedulerCustomJobs = Set.of("Job_A", "Job_B"); Set<String> expectedJobSchedulerCustomJobs = Set.of("Job_A", "Job_B");
// user configuration // user configuration
boolean expectedAddAdditionalUserInfo = true; boolean expectedAddAdditionalUserInfo = true;
@ -329,23 +335,32 @@ class TaskanaConfigurationTest {
.jobBatchSize(expectedJobBatchSize) .jobBatchSize(expectedJobBatchSize)
.jobFirstRun(expectedJobFirstJun) .jobFirstRun(expectedJobFirstJun)
.jobRunEvery(expectedJobRunEvery) .jobRunEvery(expectedJobRunEvery)
.jobLockExpirationPeriod(expectedJobLockExpirationPeriod)
.taskCleanupJobEnabled(expectedTaskCleanupJobEnabled) .taskCleanupJobEnabled(expectedTaskCleanupJobEnabled)
.taskCleanupJobMinimumAge(expectedTaskCleanupJobMinimumAge) .taskCleanupJobMinimumAge(expectedTaskCleanupJobMinimumAge)
.taskCleanupJobAllCompletedSameParentBusiness( .taskCleanupJobAllCompletedSameParentBusiness(
expectedTaskCleanupJobAllCompletedSameParentBusiness) expectedTaskCleanupJobAllCompletedSameParentBusiness)
.taskCleanupJobLockExpirationPeriod(expectedTaskCleanupJobLockExpirationPeriod)
.workbasketCleanupJobEnabled(expectedWorkbasketCleanupJobEnabled) .workbasketCleanupJobEnabled(expectedWorkbasketCleanupJobEnabled)
.workbasketCleanupJobLockExpirationPeriod(
expectedWorkbasketCleanupJobLockExpirationPeriod)
.simpleHistoryCleanupJobEnabled(expectedSimpleHistoryCleanupJobEnabled) .simpleHistoryCleanupJobEnabled(expectedSimpleHistoryCleanupJobEnabled)
.simpleHistoryCleanupJobBatchSize(expectedSimpleHistoryCleanupJobBatchSize) .simpleHistoryCleanupJobBatchSize(expectedSimpleHistoryCleanupJobBatchSize)
.simpleHistoryCleanupJobMinimumAge(expectedSimpleHistoryCleanupJobMinimumAge) .simpleHistoryCleanupJobMinimumAge(expectedSimpleHistoryCleanupJobMinimumAge)
.simpleHistoryCleanupJobAllCompletedSameParentBusiness( .simpleHistoryCleanupJobAllCompletedSameParentBusiness(
expectedSimpleHistoryCleanupJobAllCompletedSameParentBusiness) expectedSimpleHistoryCleanupJobAllCompletedSameParentBusiness)
.simpleHistoryCleanupJobLockExpirationPeriod(
expectedSimpleHistoryCleanupJobLockExpirationPeriod)
.taskUpdatePriorityJobEnabled(expectedTaskUpdatePriorityJobEnabled) .taskUpdatePriorityJobEnabled(expectedTaskUpdatePriorityJobEnabled)
.taskUpdatePriorityJobBatchSize(expectedPriorityJobBatchSize) .taskUpdatePriorityJobBatchSize(expectedPriorityJobBatchSize)
.taskUpdatePriorityJobFirstRun(expectedPriorityJobFirstRun) .taskUpdatePriorityJobFirstRun(expectedPriorityJobFirstRun)
.taskUpdatePriorityJobRunEvery(expectedTaskUpdatePriorityJobRunEvery) .taskUpdatePriorityJobRunEvery(expectedTaskUpdatePriorityJobRunEvery)
.taskUpdatePriorityJobLockExpirationPeriod(
expectedTaskUpdatePriorityJobLockExpirationPeriod)
.userInfoRefreshJobEnabled(expectedUserInfoRefreshJobEnabled) .userInfoRefreshJobEnabled(expectedUserInfoRefreshJobEnabled)
.userRefreshJobFirstRun(expectedUserRefreshJobFirstRun) .userRefreshJobFirstRun(expectedUserRefreshJobFirstRun)
.userRefreshJobRunEvery(expectedUserRefreshJobRunEvery) .userRefreshJobRunEvery(expectedUserRefreshJobRunEvery)
.userRefreshJobLockExpirationPeriod(expectedUserRefreshJobLockExpirationPeriod)
.customJobs(expectedJobSchedulerCustomJobs) .customJobs(expectedJobSchedulerCustomJobs)
// user configuration // user configuration
.addAdditionalUserInfo(expectedAddAdditionalUserInfo) .addAdditionalUserInfo(expectedAddAdditionalUserInfo)
@ -467,21 +482,27 @@ class TaskanaConfigurationTest {
.jobBatchSize(50) .jobBatchSize(50)
.jobFirstRun(Instant.MIN) .jobFirstRun(Instant.MIN)
.jobRunEvery(Duration.ofDays(2)) .jobRunEvery(Duration.ofDays(2))
.jobLockExpirationPeriod(Duration.ofDays(2))
.taskCleanupJobEnabled(false) .taskCleanupJobEnabled(false)
.taskCleanupJobMinimumAge(Duration.ofDays(1)) .taskCleanupJobMinimumAge(Duration.ofDays(1))
.taskCleanupJobAllCompletedSameParentBusiness(false) .taskCleanupJobAllCompletedSameParentBusiness(false)
.taskCleanupJobLockExpirationPeriod(Duration.ofDays(6))
.workbasketCleanupJobEnabled(false) .workbasketCleanupJobEnabled(false)
.workbasketCleanupJobLockExpirationPeriod(Duration.ofDays(7))
.simpleHistoryCleanupJobEnabled(true) .simpleHistoryCleanupJobEnabled(true)
.simpleHistoryCleanupJobBatchSize(16) .simpleHistoryCleanupJobBatchSize(16)
.simpleHistoryCleanupJobMinimumAge(Duration.ofHours(3)) .simpleHistoryCleanupJobMinimumAge(Duration.ofHours(3))
.simpleHistoryCleanupJobAllCompletedSameParentBusiness(false) .simpleHistoryCleanupJobAllCompletedSameParentBusiness(false)
.simpleHistoryCleanupJobLockExpirationPeriod(Duration.ofDays(9))
.taskUpdatePriorityJobEnabled(true) .taskUpdatePriorityJobEnabled(true)
.taskUpdatePriorityJobBatchSize(49) .taskUpdatePriorityJobBatchSize(49)
.taskUpdatePriorityJobFirstRun(Instant.MIN.plus(1, ChronoUnit.DAYS)) .taskUpdatePriorityJobFirstRun(Instant.MIN.plus(1, ChronoUnit.DAYS))
.taskUpdatePriorityJobRunEvery(Duration.ofMinutes(17)) .taskUpdatePriorityJobRunEvery(Duration.ofMinutes(17))
.taskUpdatePriorityJobLockExpirationPeriod(Duration.ofDays(10))
.userInfoRefreshJobEnabled(true) .userInfoRefreshJobEnabled(true)
.userRefreshJobFirstRun(Instant.MIN.plus(2, ChronoUnit.DAYS)) .userRefreshJobFirstRun(Instant.MIN.plus(2, ChronoUnit.DAYS))
.userRefreshJobRunEvery(Duration.ofDays(5)) .userRefreshJobRunEvery(Duration.ofDays(5))
.userRefreshJobLockExpirationPeriod(Duration.ofDays(8))
.customJobs(Set.of("Job_A", "Job_B")) .customJobs(Set.of("Job_A", "Job_B"))
// user configuration // user configuration
.addAdditionalUserInfo(true) .addAdditionalUserInfo(true)

View File

@ -35,21 +35,27 @@ taskana.jobs.maxRetries=4
taskana.jobs.batchSize=50 taskana.jobs.batchSize=50
taskana.jobs.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.runEvery=P2D taskana.jobs.runEvery=P2D
taskana.jobs.lockExpirationPeriod=PT7M
taskana.jobs.cleanup.task.enable=false taskana.jobs.cleanup.task.enable=false
taskana.jobs.cleanup.task.minimumAge=P15D taskana.jobs.cleanup.task.minimumAge=P15D
taskana.jobs.cleanup.task.allCompletedSameParentBusiness=false taskana.jobs.cleanup.task.allCompletedSameParentBusiness=false
taskana.jobs.cleanup.task.lockExpirationPeriod=PT4M
taskana.jobs.cleanup.workbasket.enable=false taskana.jobs.cleanup.workbasket.enable=false
taskana.jobs.cleanup.workbasket.lockExpirationPeriod=PT3M
taskana.jobs.cleanup.history.simple.enable=true taskana.jobs.cleanup.history.simple.enable=true
taskana.jobs.cleanup.history.simple.batchSize=50 taskana.jobs.cleanup.history.simple.batchSize=50
taskana.jobs.cleanup.history.simple.minimumAge=P17D taskana.jobs.cleanup.history.simple.minimumAge=P17D
taskana.jobs.cleanup.history.simple.allCompletedSameParentBusiness=false taskana.jobs.cleanup.history.simple.allCompletedSameParentBusiness=false
taskana.jobs.cleanup.history.simple.lockExpirationPeriod=PT2M
taskana.jobs.priority.task.enable=true taskana.jobs.priority.task.enable=true
taskana.jobs.priority.task.batchSize=50 taskana.jobs.priority.task.batchSize=50
taskana.jobs.priority.task.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.priority.task.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.priority.task.runEvery=P3D taskana.jobs.priority.task.runEvery=P3D
taskana.jobs.priority.task.lockExpirationPeriod=PT8M
taskana.jobs.refresh.user.enable=true taskana.jobs.refresh.user.enable=true
taskana.jobs.refresh.user.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.refresh.user.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.refresh.user.runEvery=P4D taskana.jobs.refresh.user.runEvery=P4D
taskana.jobs.refresh.user.lockExpirationPeriod=PT5M
taskana.jobs.customJobs=A | B | C taskana.jobs.customJobs=A | B | C
# user configuration # user configuration
taskana.user.addAdditionalUserInfo=true taskana.user.addAdditionalUserInfo=true

View File

@ -95,26 +95,30 @@ public class TaskanaConfiguration {
private final int jobBatchSize; private final int jobBatchSize;
private final Instant jobFirstRun; private final Instant jobFirstRun;
private final Duration jobRunEvery; private final Duration jobRunEvery;
private final Duration jobLockExpirationPeriod;
private final boolean taskCleanupJobEnabled; private final boolean taskCleanupJobEnabled;
private final Duration taskCleanupJobMinimumAge; private final Duration taskCleanupJobMinimumAge;
private final boolean taskCleanupJobAllCompletedSameParentBusiness; private final boolean taskCleanupJobAllCompletedSameParentBusiness;
private final Duration taskCleanupJobLockExpirationPeriod;
private final boolean workbasketCleanupJobEnabled; private final boolean workbasketCleanupJobEnabled;
private final Duration workbasketCleanupJobLockExpirationPeriod;
private final boolean simpleHistoryCleanupJobEnabled; private final boolean simpleHistoryCleanupJobEnabled;
private final int simpleHistoryCleanupJobBatchSize; private final int simpleHistoryCleanupJobBatchSize;
private final Duration simpleHistoryCleanupJobMinimumAge; private final Duration simpleHistoryCleanupJobMinimumAge;
private final boolean simpleHistoryCleanupJobAllCompletedSameParentBusiness; private final boolean simpleHistoryCleanupJobAllCompletedSameParentBusiness;
private final Duration simpleHistoryCleanupJobLockExpirationPeriod;
private final boolean taskUpdatePriorityJobEnabled; private final boolean taskUpdatePriorityJobEnabled;
private final int taskUpdatePriorityJobBatchSize; private final int taskUpdatePriorityJobBatchSize;
private final Instant taskUpdatePriorityJobFirstRun; private final Instant taskUpdatePriorityJobFirstRun;
private final Duration taskUpdatePriorityJobRunEvery; private final Duration taskUpdatePriorityJobRunEvery;
private final Duration taskUpdatePriorityJobLockExpirationPeriod;
private final boolean userInfoRefreshJobEnabled; private final boolean userInfoRefreshJobEnabled;
private final Instant userRefreshJobFirstRun; private final Instant userRefreshJobFirstRun;
private final Duration userRefreshJobRunEvery; private final Duration userRefreshJobRunEvery;
private final Duration userRefreshJobLockExpirationPeriod;
private final Set<String> customJobs; private final Set<String> customJobs;
// endregion // endregion
@ -178,23 +182,32 @@ public class TaskanaConfiguration {
this.jobBatchSize = builder.jobBatchSize; this.jobBatchSize = builder.jobBatchSize;
this.jobFirstRun = builder.jobFirstRun; this.jobFirstRun = builder.jobFirstRun;
this.jobRunEvery = builder.jobRunEvery; this.jobRunEvery = builder.jobRunEvery;
this.jobLockExpirationPeriod = builder.jobLockExpirationPeriod;
this.taskCleanupJobEnabled = builder.taskCleanupJobEnabled; this.taskCleanupJobEnabled = builder.taskCleanupJobEnabled;
this.taskCleanupJobMinimumAge = builder.taskCleanupJobMinimumAge; this.taskCleanupJobMinimumAge = builder.taskCleanupJobMinimumAge;
this.taskCleanupJobAllCompletedSameParentBusiness = this.taskCleanupJobAllCompletedSameParentBusiness =
builder.taskCleanupJobAllCompletedSameParentBusiness; builder.taskCleanupJobAllCompletedSameParentBusiness;
this.taskCleanupJobLockExpirationPeriod = builder.taskCleanupJobLockExpirationPeriod;
this.workbasketCleanupJobEnabled = builder.workbasketCleanupJobEnabled; this.workbasketCleanupJobEnabled = builder.workbasketCleanupJobEnabled;
this.workbasketCleanupJobLockExpirationPeriod =
builder.workbasketCleanupJobLockExpirationPeriod;
this.simpleHistoryCleanupJobEnabled = builder.simpleHistoryCleanupJobEnabled; this.simpleHistoryCleanupJobEnabled = builder.simpleHistoryCleanupJobEnabled;
this.simpleHistoryCleanupJobBatchSize = builder.simpleHistoryCleanupJobBatchSize; this.simpleHistoryCleanupJobBatchSize = builder.simpleHistoryCleanupJobBatchSize;
this.simpleHistoryCleanupJobMinimumAge = builder.simpleHistoryCleanupJobMinimumAge; this.simpleHistoryCleanupJobMinimumAge = builder.simpleHistoryCleanupJobMinimumAge;
this.simpleHistoryCleanupJobAllCompletedSameParentBusiness = this.simpleHistoryCleanupJobAllCompletedSameParentBusiness =
builder.simpleHistoryCleanupJobAllCompletedSameParentBusiness; builder.simpleHistoryCleanupJobAllCompletedSameParentBusiness;
this.simpleHistoryCleanupJobLockExpirationPeriod =
builder.simpleHistoryCleanupJobLockExpirationPeriod;
this.taskUpdatePriorityJobEnabled = builder.taskUpdatePriorityJobEnabled; this.taskUpdatePriorityJobEnabled = builder.taskUpdatePriorityJobEnabled;
this.taskUpdatePriorityJobBatchSize = builder.taskUpdatePriorityJobBatchSize; this.taskUpdatePriorityJobBatchSize = builder.taskUpdatePriorityJobBatchSize;
this.taskUpdatePriorityJobFirstRun = builder.taskUpdatePriorityJobFirstRun; this.taskUpdatePriorityJobFirstRun = builder.taskUpdatePriorityJobFirstRun;
this.taskUpdatePriorityJobRunEvery = builder.taskUpdatePriorityJobRunEvery; this.taskUpdatePriorityJobRunEvery = builder.taskUpdatePriorityJobRunEvery;
this.taskUpdatePriorityJobLockExpirationPeriod =
builder.taskUpdatePriorityJobLockExpirationPeriod;
this.userInfoRefreshJobEnabled = builder.userInfoRefreshJobEnabled; this.userInfoRefreshJobEnabled = builder.userInfoRefreshJobEnabled;
this.userRefreshJobFirstRun = builder.userRefreshJobFirstRun; this.userRefreshJobFirstRun = builder.userRefreshJobFirstRun;
this.userRefreshJobRunEvery = builder.userRefreshJobRunEvery; this.userRefreshJobRunEvery = builder.userRefreshJobRunEvery;
this.userRefreshJobLockExpirationPeriod = builder.userRefreshJobLockExpirationPeriod;
this.customJobs = Collections.unmodifiableSet(builder.customJobs); this.customJobs = Collections.unmodifiableSet(builder.customJobs);
// user configuration // user configuration
this.addAdditionalUserInfo = builder.addAdditionalUserInfo; this.addAdditionalUserInfo = builder.addAdditionalUserInfo;
@ -328,6 +341,10 @@ public class TaskanaConfiguration {
return jobRunEvery; return jobRunEvery;
} }
public Duration getJobLockExpirationPeriod() {
return jobLockExpirationPeriod;
}
public boolean isTaskCleanupJobEnabled() { public boolean isTaskCleanupJobEnabled() {
return taskCleanupJobEnabled; return taskCleanupJobEnabled;
} }
@ -340,10 +357,18 @@ public class TaskanaConfiguration {
return taskCleanupJobAllCompletedSameParentBusiness; return taskCleanupJobAllCompletedSameParentBusiness;
} }
public Duration getTaskCleanupJobLockExpirationPeriod() {
return taskCleanupJobLockExpirationPeriod;
}
public boolean isWorkbasketCleanupJobEnabled() { public boolean isWorkbasketCleanupJobEnabled() {
return workbasketCleanupJobEnabled; return workbasketCleanupJobEnabled;
} }
public Duration getWorkbasketCleanupJobLockExpirationPeriod() {
return workbasketCleanupJobLockExpirationPeriod;
}
public boolean isSimpleHistoryCleanupJobEnabled() { public boolean isSimpleHistoryCleanupJobEnabled() {
return simpleHistoryCleanupJobEnabled; return simpleHistoryCleanupJobEnabled;
} }
@ -360,6 +385,10 @@ public class TaskanaConfiguration {
return simpleHistoryCleanupJobAllCompletedSameParentBusiness; return simpleHistoryCleanupJobAllCompletedSameParentBusiness;
} }
public Duration getSimpleHistoryCleanupJobLockExpirationPeriod() {
return simpleHistoryCleanupJobLockExpirationPeriod;
}
public boolean isTaskUpdatePriorityJobEnabled() { public boolean isTaskUpdatePriorityJobEnabled() {
return taskUpdatePriorityJobEnabled; return taskUpdatePriorityJobEnabled;
} }
@ -376,6 +405,10 @@ public class TaskanaConfiguration {
return taskUpdatePriorityJobRunEvery; return taskUpdatePriorityJobRunEvery;
} }
public Duration getTaskUpdatePriorityJobLockExpirationPeriod() {
return taskUpdatePriorityJobLockExpirationPeriod;
}
public boolean isUserInfoRefreshJobEnabled() { public boolean isUserInfoRefreshJobEnabled() {
return userInfoRefreshJobEnabled; return userInfoRefreshJobEnabled;
} }
@ -388,6 +421,10 @@ public class TaskanaConfiguration {
return userRefreshJobRunEvery; return userRefreshJobRunEvery;
} }
public Duration getUserRefreshJobLockExpirationPeriod() {
return userRefreshJobLockExpirationPeriod;
}
public Set<String> getCustomJobs() { public Set<String> getCustomJobs() {
return customJobs; return customJobs;
} }
@ -418,6 +455,7 @@ public class TaskanaConfiguration {
// endregion // endregion
// region hashCode, equals + toString // region hashCode, equals + toString
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash( return Objects.hash(
@ -446,21 +484,27 @@ public class TaskanaConfiguration {
jobBatchSize, jobBatchSize,
jobFirstRun, jobFirstRun,
jobRunEvery, jobRunEvery,
jobLockExpirationPeriod,
taskCleanupJobEnabled, taskCleanupJobEnabled,
taskCleanupJobMinimumAge, taskCleanupJobMinimumAge,
taskCleanupJobAllCompletedSameParentBusiness, taskCleanupJobAllCompletedSameParentBusiness,
taskCleanupJobLockExpirationPeriod,
workbasketCleanupJobEnabled, workbasketCleanupJobEnabled,
workbasketCleanupJobLockExpirationPeriod,
simpleHistoryCleanupJobEnabled, simpleHistoryCleanupJobEnabled,
simpleHistoryCleanupJobBatchSize, simpleHistoryCleanupJobBatchSize,
simpleHistoryCleanupJobMinimumAge, simpleHistoryCleanupJobMinimumAge,
simpleHistoryCleanupJobAllCompletedSameParentBusiness, simpleHistoryCleanupJobAllCompletedSameParentBusiness,
simpleHistoryCleanupJobLockExpirationPeriod,
taskUpdatePriorityJobEnabled, taskUpdatePriorityJobEnabled,
taskUpdatePriorityJobBatchSize, taskUpdatePriorityJobBatchSize,
taskUpdatePriorityJobFirstRun, taskUpdatePriorityJobFirstRun,
taskUpdatePriorityJobRunEvery, taskUpdatePriorityJobRunEvery,
taskUpdatePriorityJobLockExpirationPeriod,
userInfoRefreshJobEnabled, userInfoRefreshJobEnabled,
userRefreshJobFirstRun, userRefreshJobFirstRun,
userRefreshJobRunEvery, userRefreshJobRunEvery,
userRefreshJobLockExpirationPeriod,
customJobs, customJobs,
addAdditionalUserInfo, addAdditionalUserInfo,
minimalPermissionsToAssignDomains, minimalPermissionsToAssignDomains,
@ -500,10 +544,10 @@ public class TaskanaConfiguration {
&& simpleHistoryCleanupJobAllCompletedSameParentBusiness && simpleHistoryCleanupJobAllCompletedSameParentBusiness
== other.simpleHistoryCleanupJobAllCompletedSameParentBusiness == other.simpleHistoryCleanupJobAllCompletedSameParentBusiness
&& taskUpdatePriorityJobEnabled == other.taskUpdatePriorityJobEnabled && taskUpdatePriorityJobEnabled == other.taskUpdatePriorityJobEnabled
&& useSpecificDb2Taskquery == other.useSpecificDb2Taskquery
&& taskUpdatePriorityJobBatchSize == other.taskUpdatePriorityJobBatchSize && taskUpdatePriorityJobBatchSize == other.taskUpdatePriorityJobBatchSize
&& userInfoRefreshJobEnabled == other.userInfoRefreshJobEnabled && userInfoRefreshJobEnabled == other.userInfoRefreshJobEnabled
&& addAdditionalUserInfo == other.addAdditionalUserInfo && addAdditionalUserInfo == other.addAdditionalUserInfo
&& useSpecificDb2Taskquery == other.useSpecificDb2Taskquery
&& Objects.equals(dataSource, other.dataSource) && Objects.equals(dataSource, other.dataSource)
&& Objects.equals(schemaName, other.schemaName) && Objects.equals(schemaName, other.schemaName)
&& Objects.equals(domains, other.domains) && Objects.equals(domains, other.domains)
@ -517,13 +561,27 @@ public class TaskanaConfiguration {
&& jobSchedulerPeriodTimeUnit == other.jobSchedulerPeriodTimeUnit && jobSchedulerPeriodTimeUnit == other.jobSchedulerPeriodTimeUnit
&& Objects.equals(jobFirstRun, other.jobFirstRun) && Objects.equals(jobFirstRun, other.jobFirstRun)
&& Objects.equals(jobRunEvery, other.jobRunEvery) && Objects.equals(jobRunEvery, other.jobRunEvery)
&& Objects.equals(jobLockExpirationPeriod, other.jobLockExpirationPeriod)
&& Objects.equals(taskCleanupJobMinimumAge, other.taskCleanupJobMinimumAge) && Objects.equals(taskCleanupJobMinimumAge, other.taskCleanupJobMinimumAge)
&& Objects.equals(
taskCleanupJobLockExpirationPeriod, other.taskCleanupJobLockExpirationPeriod)
&& Objects.equals(
workbasketCleanupJobLockExpirationPeriod,
other.workbasketCleanupJobLockExpirationPeriod)
&& Objects.equals( && Objects.equals(
simpleHistoryCleanupJobMinimumAge, other.simpleHistoryCleanupJobMinimumAge) simpleHistoryCleanupJobMinimumAge, other.simpleHistoryCleanupJobMinimumAge)
&& Objects.equals(
simpleHistoryCleanupJobLockExpirationPeriod,
other.simpleHistoryCleanupJobLockExpirationPeriod)
&& Objects.equals(taskUpdatePriorityJobFirstRun, other.taskUpdatePriorityJobFirstRun) && Objects.equals(taskUpdatePriorityJobFirstRun, other.taskUpdatePriorityJobFirstRun)
&& Objects.equals(taskUpdatePriorityJobRunEvery, other.taskUpdatePriorityJobRunEvery) && Objects.equals(taskUpdatePriorityJobRunEvery, other.taskUpdatePriorityJobRunEvery)
&& Objects.equals(
taskUpdatePriorityJobLockExpirationPeriod,
other.taskUpdatePriorityJobLockExpirationPeriod)
&& Objects.equals(userRefreshJobFirstRun, other.userRefreshJobFirstRun) && Objects.equals(userRefreshJobFirstRun, other.userRefreshJobFirstRun)
&& Objects.equals(userRefreshJobRunEvery, other.userRefreshJobRunEvery) && Objects.equals(userRefreshJobRunEvery, other.userRefreshJobRunEvery)
&& Objects.equals(
userRefreshJobLockExpirationPeriod, other.userRefreshJobLockExpirationPeriod)
&& Objects.equals(customJobs, other.customJobs) && Objects.equals(customJobs, other.customJobs)
&& Objects.equals( && Objects.equals(
minimalPermissionsToAssignDomains, other.minimalPermissionsToAssignDomains) minimalPermissionsToAssignDomains, other.minimalPermissionsToAssignDomains)
@ -532,12 +590,14 @@ public class TaskanaConfiguration {
@Override @Override
public String toString() { public String toString() {
return "TaskanaConfiguration [dataSource=" return "TaskanaConfiguration{"
+ "dataSource="
+ dataSource + dataSource
+ ", useManagedTransactions=" + ", useManagedTransactions="
+ useManagedTransactions + useManagedTransactions
+ ", schemaName=" + ", schemaName='"
+ schemaName + schemaName
+ '\''
+ ", securityEnabled=" + ", securityEnabled="
+ securityEnabled + securityEnabled
+ ", domains=" + ", domains="
@ -564,8 +624,9 @@ public class TaskanaConfiguration {
+ germanPublicHolidaysCorpusChristiEnabled + germanPublicHolidaysCorpusChristiEnabled
+ ", deleteHistoryEventsOnTaskDeletionEnabled=" + ", deleteHistoryEventsOnTaskDeletionEnabled="
+ deleteHistoryEventsOnTaskDeletionEnabled + deleteHistoryEventsOnTaskDeletionEnabled
+ ", logHistoryLoggerName=" + ", logHistoryLoggerName='"
+ logHistoryLoggerName + logHistoryLoggerName
+ '\''
+ ", jobSchedulerEnabled=" + ", jobSchedulerEnabled="
+ jobSchedulerEnabled + jobSchedulerEnabled
+ ", jobSchedulerInitialStartDelay=" + ", jobSchedulerInitialStartDelay="
@ -582,14 +643,20 @@ public class TaskanaConfiguration {
+ jobFirstRun + jobFirstRun
+ ", jobRunEvery=" + ", jobRunEvery="
+ jobRunEvery + jobRunEvery
+ ", jobLockExpirationPeriod="
+ jobLockExpirationPeriod
+ ", taskCleanupJobEnabled=" + ", taskCleanupJobEnabled="
+ taskCleanupJobEnabled + taskCleanupJobEnabled
+ ", taskCleanupJobMinimumAge=" + ", taskCleanupJobMinimumAge="
+ taskCleanupJobMinimumAge + taskCleanupJobMinimumAge
+ ", taskCleanupJobAllCompletedSameParentBusiness=" + ", taskCleanupJobAllCompletedSameParentBusiness="
+ taskCleanupJobAllCompletedSameParentBusiness + taskCleanupJobAllCompletedSameParentBusiness
+ ", taskCleanupJobLockExpirationPeriod="
+ taskCleanupJobLockExpirationPeriod
+ ", workbasketCleanupJobEnabled=" + ", workbasketCleanupJobEnabled="
+ workbasketCleanupJobEnabled + workbasketCleanupJobEnabled
+ ", workbasketCleanupJobLockExpirationPeriod="
+ workbasketCleanupJobLockExpirationPeriod
+ ", simpleHistoryCleanupJobEnabled=" + ", simpleHistoryCleanupJobEnabled="
+ simpleHistoryCleanupJobEnabled + simpleHistoryCleanupJobEnabled
+ ", simpleHistoryCleanupJobBatchSize=" + ", simpleHistoryCleanupJobBatchSize="
@ -598,6 +665,8 @@ public class TaskanaConfiguration {
+ simpleHistoryCleanupJobMinimumAge + simpleHistoryCleanupJobMinimumAge
+ ", simpleHistoryCleanupJobAllCompletedSameParentBusiness=" + ", simpleHistoryCleanupJobAllCompletedSameParentBusiness="
+ simpleHistoryCleanupJobAllCompletedSameParentBusiness + simpleHistoryCleanupJobAllCompletedSameParentBusiness
+ ", simpleHistoryCleanupJobLockExpirationPeriod="
+ simpleHistoryCleanupJobLockExpirationPeriod
+ ", taskUpdatePriorityJobEnabled=" + ", taskUpdatePriorityJobEnabled="
+ taskUpdatePriorityJobEnabled + taskUpdatePriorityJobEnabled
+ ", taskUpdatePriorityJobBatchSize=" + ", taskUpdatePriorityJobBatchSize="
@ -606,12 +675,16 @@ public class TaskanaConfiguration {
+ taskUpdatePriorityJobFirstRun + taskUpdatePriorityJobFirstRun
+ ", taskUpdatePriorityJobRunEvery=" + ", taskUpdatePriorityJobRunEvery="
+ taskUpdatePriorityJobRunEvery + taskUpdatePriorityJobRunEvery
+ ", taskUpdatePriorityJobLockExpirationPeriod="
+ taskUpdatePriorityJobLockExpirationPeriod
+ ", userInfoRefreshJobEnabled=" + ", userInfoRefreshJobEnabled="
+ userInfoRefreshJobEnabled + userInfoRefreshJobEnabled
+ ", userRefreshJobFirstRun=" + ", userRefreshJobFirstRun="
+ userRefreshJobFirstRun + userRefreshJobFirstRun
+ ", userRefreshJobRunEvery=" + ", userRefreshJobRunEvery="
+ userRefreshJobRunEvery + userRefreshJobRunEvery
+ ", userRefreshJobLockExpirationPeriod="
+ userRefreshJobLockExpirationPeriod
+ ", customJobs=" + ", customJobs="
+ customJobs + customJobs
+ ", addAdditionalUserInfo=" + ", addAdditionalUserInfo="
@ -622,7 +695,7 @@ public class TaskanaConfiguration {
+ useSpecificDb2Taskquery + useSpecificDb2Taskquery
+ ", properties=" + ", properties="
+ properties + properties
+ "]"; + '}';
} }
// endregion // endregion
@ -714,6 +787,9 @@ public class TaskanaConfiguration {
@TaskanaProperty("taskana.jobs.runEvery") @TaskanaProperty("taskana.jobs.runEvery")
private Duration jobRunEvery = Duration.ofDays(1); private Duration jobRunEvery = Duration.ofDays(1);
@TaskanaProperty("taskana.jobs.lockExpirationPeriod")
private Duration jobLockExpirationPeriod = Duration.ofMinutes(30);
@TaskanaProperty("taskana.jobs.cleanup.task.enable") @TaskanaProperty("taskana.jobs.cleanup.task.enable")
private boolean taskCleanupJobEnabled = true; private boolean taskCleanupJobEnabled = true;
@ -723,9 +799,15 @@ public class TaskanaConfiguration {
@TaskanaProperty("taskana.jobs.cleanup.task.allCompletedSameParentBusiness") @TaskanaProperty("taskana.jobs.cleanup.task.allCompletedSameParentBusiness")
private boolean taskCleanupJobAllCompletedSameParentBusiness = true; private boolean taskCleanupJobAllCompletedSameParentBusiness = true;
@TaskanaProperty("taskana.jobs.cleanup.task.lockExpirationPeriod")
private Duration taskCleanupJobLockExpirationPeriod = Duration.ofMinutes(30);
@TaskanaProperty("taskana.jobs.cleanup.workbasket.enable") @TaskanaProperty("taskana.jobs.cleanup.workbasket.enable")
private boolean workbasketCleanupJobEnabled = true; private boolean workbasketCleanupJobEnabled = true;
@TaskanaProperty("taskana.jobs.cleanup.workbasket.lockExpirationPeriod")
private Duration workbasketCleanupJobLockExpirationPeriod = Duration.ofMinutes(30);
@TaskanaProperty("taskana.jobs.cleanup.history.simple.enable") @TaskanaProperty("taskana.jobs.cleanup.history.simple.enable")
private boolean simpleHistoryCleanupJobEnabled = false; private boolean simpleHistoryCleanupJobEnabled = false;
@ -738,6 +820,9 @@ public class TaskanaConfiguration {
@TaskanaProperty("taskana.jobs.cleanup.history.simple.allCompletedSameParentBusiness") @TaskanaProperty("taskana.jobs.cleanup.history.simple.allCompletedSameParentBusiness")
private boolean simpleHistoryCleanupJobAllCompletedSameParentBusiness = true; private boolean simpleHistoryCleanupJobAllCompletedSameParentBusiness = true;
@TaskanaProperty("taskana.jobs.cleanup.history.simple.lockExpirationPeriod")
private Duration simpleHistoryCleanupJobLockExpirationPeriod = Duration.ofMinutes(30);
@TaskanaProperty("taskana.jobs.priority.task.enable") @TaskanaProperty("taskana.jobs.priority.task.enable")
private boolean taskUpdatePriorityJobEnabled = false; private boolean taskUpdatePriorityJobEnabled = false;
@ -750,6 +835,9 @@ public class TaskanaConfiguration {
@TaskanaProperty("taskana.jobs.priority.task.runEvery") @TaskanaProperty("taskana.jobs.priority.task.runEvery")
private Duration taskUpdatePriorityJobRunEvery = Duration.ofDays(1); private Duration taskUpdatePriorityJobRunEvery = Duration.ofDays(1);
@TaskanaProperty("taskana.jobs.priority.task.lockExpirationPeriod")
private Duration taskUpdatePriorityJobLockExpirationPeriod = Duration.ofMinutes(30);
@TaskanaProperty("taskana.jobs.refresh.user.enable") @TaskanaProperty("taskana.jobs.refresh.user.enable")
private boolean userInfoRefreshJobEnabled = false; private boolean userInfoRefreshJobEnabled = false;
@ -759,6 +847,9 @@ public class TaskanaConfiguration {
@TaskanaProperty("taskana.jobs.refresh.user.runEvery") @TaskanaProperty("taskana.jobs.refresh.user.runEvery")
private Duration userRefreshJobRunEvery = Duration.ofDays(1); private Duration userRefreshJobRunEvery = Duration.ofDays(1);
@TaskanaProperty("taskana.jobs.refresh.user.lockExpirationPeriod")
private Duration userRefreshJobLockExpirationPeriod = Duration.ofMinutes(30);
@TaskanaProperty("taskana.jobs.customJobs") @TaskanaProperty("taskana.jobs.customJobs")
private Set<String> customJobs = new HashSet<>(); private Set<String> customJobs = new HashSet<>();
// endregion // endregion
@ -858,23 +949,31 @@ public class TaskanaConfiguration {
this.jobBatchSize = conf.jobBatchSize; this.jobBatchSize = conf.jobBatchSize;
this.jobFirstRun = conf.jobFirstRun; this.jobFirstRun = conf.jobFirstRun;
this.jobRunEvery = conf.jobRunEvery; this.jobRunEvery = conf.jobRunEvery;
this.jobLockExpirationPeriod = conf.jobLockExpirationPeriod;
this.taskCleanupJobEnabled = conf.taskCleanupJobEnabled; this.taskCleanupJobEnabled = conf.taskCleanupJobEnabled;
this.taskCleanupJobMinimumAge = conf.taskCleanupJobMinimumAge; this.taskCleanupJobMinimumAge = conf.taskCleanupJobMinimumAge;
this.taskCleanupJobAllCompletedSameParentBusiness = this.taskCleanupJobAllCompletedSameParentBusiness =
conf.taskCleanupJobAllCompletedSameParentBusiness; conf.taskCleanupJobAllCompletedSameParentBusiness;
this.taskCleanupJobLockExpirationPeriod = conf.taskCleanupJobLockExpirationPeriod;
this.workbasketCleanupJobEnabled = conf.workbasketCleanupJobEnabled; this.workbasketCleanupJobEnabled = conf.workbasketCleanupJobEnabled;
this.workbasketCleanupJobLockExpirationPeriod = conf.workbasketCleanupJobLockExpirationPeriod;
this.simpleHistoryCleanupJobEnabled = conf.simpleHistoryCleanupJobEnabled; this.simpleHistoryCleanupJobEnabled = conf.simpleHistoryCleanupJobEnabled;
this.simpleHistoryCleanupJobBatchSize = conf.simpleHistoryCleanupJobBatchSize; this.simpleHistoryCleanupJobBatchSize = conf.simpleHistoryCleanupJobBatchSize;
this.simpleHistoryCleanupJobMinimumAge = conf.simpleHistoryCleanupJobMinimumAge; this.simpleHistoryCleanupJobMinimumAge = conf.simpleHistoryCleanupJobMinimumAge;
this.simpleHistoryCleanupJobAllCompletedSameParentBusiness = this.simpleHistoryCleanupJobAllCompletedSameParentBusiness =
conf.simpleHistoryCleanupJobAllCompletedSameParentBusiness; conf.simpleHistoryCleanupJobAllCompletedSameParentBusiness;
this.simpleHistoryCleanupJobLockExpirationPeriod =
conf.simpleHistoryCleanupJobLockExpirationPeriod;
this.taskUpdatePriorityJobEnabled = conf.taskUpdatePriorityJobEnabled; this.taskUpdatePriorityJobEnabled = conf.taskUpdatePriorityJobEnabled;
this.taskUpdatePriorityJobBatchSize = conf.taskUpdatePriorityJobBatchSize; this.taskUpdatePriorityJobBatchSize = conf.taskUpdatePriorityJobBatchSize;
this.taskUpdatePriorityJobFirstRun = conf.taskUpdatePriorityJobFirstRun; this.taskUpdatePriorityJobFirstRun = conf.taskUpdatePriorityJobFirstRun;
this.taskUpdatePriorityJobRunEvery = conf.taskUpdatePriorityJobRunEvery; this.taskUpdatePriorityJobRunEvery = conf.taskUpdatePriorityJobRunEvery;
this.taskUpdatePriorityJobLockExpirationPeriod =
conf.taskUpdatePriorityJobLockExpirationPeriod;
this.userInfoRefreshJobEnabled = conf.userInfoRefreshJobEnabled; this.userInfoRefreshJobEnabled = conf.userInfoRefreshJobEnabled;
this.userRefreshJobFirstRun = conf.userRefreshJobFirstRun; this.userRefreshJobFirstRun = conf.userRefreshJobFirstRun;
this.userRefreshJobRunEvery = conf.userRefreshJobRunEvery; this.userRefreshJobRunEvery = conf.userRefreshJobRunEvery;
this.userRefreshJobLockExpirationPeriod = conf.userRefreshJobLockExpirationPeriod;
this.customJobs = conf.customJobs; this.customJobs = conf.customJobs;
// user configuration // user configuration
this.addAdditionalUserInfo = conf.addAdditionalUserInfo; this.addAdditionalUserInfo = conf.addAdditionalUserInfo;
@ -1074,6 +1173,11 @@ public class TaskanaConfiguration {
return this; return this;
} }
public Builder jobLockExpirationPeriod(Duration jobLockExpirationPeriod) {
this.jobLockExpirationPeriod = jobLockExpirationPeriod;
return this;
}
public Builder taskCleanupJobMinimumAge(Duration taskCleanupJobMinimumAge) { public Builder taskCleanupJobMinimumAge(Duration taskCleanupJobMinimumAge) {
this.taskCleanupJobMinimumAge = taskCleanupJobMinimumAge; this.taskCleanupJobMinimumAge = taskCleanupJobMinimumAge;
return this; return this;
@ -1086,11 +1190,22 @@ public class TaskanaConfiguration {
return this; return this;
} }
public Builder taskCleanupJobLockExpirationPeriod(Duration taskCleanupJobLockExpirationPeriod) {
this.taskCleanupJobLockExpirationPeriod = taskCleanupJobLockExpirationPeriod;
return this;
}
public Builder workbasketCleanupJobEnabled(boolean workbasketCleanupJobEnabled) { public Builder workbasketCleanupJobEnabled(boolean workbasketCleanupJobEnabled) {
this.workbasketCleanupJobEnabled = workbasketCleanupJobEnabled; this.workbasketCleanupJobEnabled = workbasketCleanupJobEnabled;
return this; return this;
} }
public Builder workbasketCleanupJobLockExpirationPeriod(
Duration workbasketCleanupJobLockExpirationPeriod) {
this.workbasketCleanupJobLockExpirationPeriod = workbasketCleanupJobLockExpirationPeriod;
return this;
}
public Builder simpleHistoryCleanupJobEnabled(boolean simpleHistoryCleanupJobEnabled) { public Builder simpleHistoryCleanupJobEnabled(boolean simpleHistoryCleanupJobEnabled) {
this.simpleHistoryCleanupJobEnabled = simpleHistoryCleanupJobEnabled; this.simpleHistoryCleanupJobEnabled = simpleHistoryCleanupJobEnabled;
return this; return this;
@ -1113,6 +1228,13 @@ public class TaskanaConfiguration {
return this; return this;
} }
public Builder simpleHistoryCleanupJobLockExpirationPeriod(
Duration simpleHistoryCleanupJobLockExpirationPeriod) {
this.simpleHistoryCleanupJobLockExpirationPeriod =
simpleHistoryCleanupJobLockExpirationPeriod;
return this;
}
public Builder taskUpdatePriorityJobEnabled(boolean taskUpdatePriorityJobEnabled) { public Builder taskUpdatePriorityJobEnabled(boolean taskUpdatePriorityJobEnabled) {
this.taskUpdatePriorityJobEnabled = taskUpdatePriorityJobEnabled; this.taskUpdatePriorityJobEnabled = taskUpdatePriorityJobEnabled;
return this; return this;
@ -1133,6 +1255,12 @@ public class TaskanaConfiguration {
return this; return this;
} }
public Builder taskUpdatePriorityJobLockExpirationPeriod(
Duration taskUpdatePriorityJobLockExpirationPeriod) {
this.taskUpdatePriorityJobLockExpirationPeriod = taskUpdatePriorityJobLockExpirationPeriod;
return this;
}
public Builder userInfoRefreshJobEnabled(boolean userInfoRefreshJobEnabled) { public Builder userInfoRefreshJobEnabled(boolean userInfoRefreshJobEnabled) {
this.userInfoRefreshJobEnabled = userInfoRefreshJobEnabled; this.userInfoRefreshJobEnabled = userInfoRefreshJobEnabled;
return this; return this;
@ -1148,6 +1276,11 @@ public class TaskanaConfiguration {
return this; return this;
} }
public Builder userRefreshJobLockExpirationPeriod(Duration userRefreshJobLockExpirationPeriod) {
this.userRefreshJobLockExpirationPeriod = userRefreshJobLockExpirationPeriod;
return this;
}
public Builder customJobs(Set<String> customJobs) { public Builder customJobs(Set<String> customJobs) {
this.customJobs = customJobs; this.customJobs = customJobs;
return this; return this;

View File

@ -1,18 +1,20 @@
package pro.taskana.common.internal; package pro.taskana.common.internal;
import java.lang.reflect.InvocationTargetException;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.JobService; import pro.taskana.common.api.JobService;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.exceptions.SystemException;
/** Controls all job activities. */ /** Controls all job activities. */
public class JobServiceImpl implements JobService { public class JobServiceImpl implements JobService {
public static final int JOB_DEFAULT_PRIORITY = 50; public static final int JOB_DEFAULT_PRIORITY = 50;
private static final Duration JOB_DEFAULT_LOCK_EXPIRATION_PERIOD = Duration.ofSeconds(60);
private static final Logger LOGGER = LoggerFactory.getLogger(JobServiceImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(JobServiceImpl.class);
private final JobMapper jobMapper; private final JobMapper jobMapper;
@ -43,7 +45,27 @@ public class JobServiceImpl implements JobService {
public ScheduledJob lockJob(ScheduledJob job, String owner) { public ScheduledJob lockJob(ScheduledJob job, String owner) {
job.setLockedBy(owner); job.setLockedBy(owner);
job.setLockExpires(Instant.now().plus(JOB_DEFAULT_LOCK_EXPIRATION_PERIOD)); Class<?> jobClass = null;
try {
jobClass = Thread.currentThread().getContextClassLoader().loadClass(job.getType());
job.setLockExpires(
Instant.now()
.plus(
(Duration)
jobClass
.getMethod("getLockExpirationPeriod", TaskanaConfiguration.class)
.invoke(null, taskanaEngineImpl.getEngine().getConfiguration())));
} catch (ClassNotFoundException | NoSuchMethodException e) {
throw new SystemException(
String.format(
"Job '%s' does not have a method matching ('getLockExpirationPeriod', %s",
jobClass, TaskanaConfiguration.class));
} catch (InvocationTargetException | IllegalAccessException e) {
throw new SystemException(
String.format(
"Caught Exception while invoking method 'getLockExpirationPeriod' by reflection"));
}
job.setRetryCount(job.getRetryCount() - 1); job.setRetryCount(job.getRetryCount() - 1);
taskanaEngineImpl.executeInDatabaseConnection(() -> jobMapper.update(job)); taskanaEngineImpl.executeInDatabaseConnection(() -> jobMapper.update(job));
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {

View File

@ -4,6 +4,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.common.api.exceptions.SystemException;
@ -42,8 +43,7 @@ public abstract class AbstractTaskanaJob implements TaskanaJob {
try { try {
jobClass = Thread.currentThread().getContextClassLoader().loadClass(job.getType()); jobClass = Thread.currentThread().getContextClassLoader().loadClass(job.getType());
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new SystemException( throw new SystemException(String.format("Can't load class '%s'", job.getType()));
String.format("Can't load class '%s'", job.getType()));
} }
return initTaskanaJob(engine, jobClass, txProvider, job); return initTaskanaJob(engine, jobClass, txProvider, job);
@ -76,6 +76,46 @@ public abstract class AbstractTaskanaJob implements TaskanaJob {
job.scheduleNextJob(); job.scheduleNextJob();
} }
public boolean isAsync() {
return async;
}
public Instant getFirstRun() {
return firstRun;
}
public Duration getRunEvery() {
return runEvery;
}
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
return taskanaConfiguration.getJobLockExpirationPeriod();
}
protected abstract String getType();
protected abstract void execute() throws TaskanaException;
protected Instant getNextDueForJob() {
Instant nextRun = firstRun;
if (scheduledJob != null && scheduledJob.getDue() != null) {
nextRun = scheduledJob.getDue();
}
while (nextRun.isBefore(Instant.now())) {
nextRun = nextRun.plus(runEvery);
}
return nextRun;
}
protected void scheduleNextJob() {
ScheduledJob job = new ScheduledJob();
job.setType(getType());
job.setDue(getNextDueForJob());
taskanaEngineImpl.getJobService().createJob(job);
}
private static AbstractTaskanaJob initTaskanaJob( private static AbstractTaskanaJob initTaskanaJob(
TaskanaEngine taskanaEngine, TaskanaEngine taskanaEngine,
Class<?> jobClass, Class<?> jobClass,
@ -120,40 +160,4 @@ public abstract class AbstractTaskanaJob implements TaskanaJob {
} }
return job; return job;
} }
public boolean isAsync() {
return async;
}
public Instant getFirstRun() {
return firstRun;
}
public Duration getRunEvery() {
return runEvery;
}
protected abstract String getType();
protected abstract void execute() throws TaskanaException;
protected Instant getNextDueForJob() {
Instant nextRun = firstRun;
if (scheduledJob != null && scheduledJob.getDue() != null) {
nextRun = scheduledJob.getDue();
}
while (nextRun.isBefore(Instant.now())) {
nextRun = nextRun.plus(runEvery);
}
return nextRun;
}
protected void scheduleNextJob() {
ScheduledJob job = new ScheduledJob();
job.setType(getType());
job.setDue(getNextDueForJob());
taskanaEngineImpl.getJobService().createJob(job);
}
} }

View File

@ -11,6 +11,7 @@ import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.BaseQuery.SortDirection; import pro.taskana.common.api.BaseQuery.SortDirection;
import pro.taskana.common.api.BulkOperationResults; import pro.taskana.common.api.BulkOperationResults;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
@ -64,6 +65,10 @@ public class TaskCleanupJob extends AbstractTaskanaJob {
} }
} }
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
return taskanaConfiguration.getTaskCleanupJobLockExpirationPeriod();
}
@Override @Override
protected String getType() { protected String getType() {
return TaskCleanupJob.class.getName(); return TaskCleanupJob.class.getName();

View File

@ -2,8 +2,10 @@ package pro.taskana.task.internal.jobs;
import static pro.taskana.common.internal.util.CollectionUtil.partitionBasedOnSize; import static pro.taskana.common.internal.util.CollectionUtil.partitionBasedOnSize;
import java.time.Duration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.common.api.exceptions.SystemException;
@ -45,6 +47,10 @@ public class TaskUpdatePriorityJob extends AbstractTaskanaJob {
} }
} }
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
return taskanaConfiguration.getTaskUpdatePriorityJobLockExpirationPeriod();
}
public int getBatchSize() { public int getBatchSize() {
return batchSize; return batchSize;
} }

View File

@ -1,8 +1,10 @@
package pro.taskana.workbasket.internal.jobs; package pro.taskana.workbasket.internal.jobs;
import java.time.Duration;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.BaseQuery; import pro.taskana.common.api.BaseQuery;
import pro.taskana.common.api.BulkOperationResults; import pro.taskana.common.api.BulkOperationResults;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
@ -48,6 +50,10 @@ public class WorkbasketCleanupJob extends AbstractTaskanaJob {
} }
} }
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
return taskanaConfiguration.getWorkbasketCleanupJobLockExpirationPeriod();
}
@Override @Override
protected String getType() { protected String getType() {
return WorkbasketCleanupJob.class.getName(); return WorkbasketCleanupJob.class.getName();

View File

@ -4,12 +4,18 @@ import static org.assertj.core.api.Assertions.assertThat;
import acceptance.AbstractAccTest; import acceptance.AbstractAccTest;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.List; import java.util.List;
import java.util.stream.Stream;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.function.ThrowingConsumer;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.internal.stubbing.answers.CallsRealMethods; import org.mockito.internal.stubbing.answers.CallsRealMethods;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@ -20,13 +26,20 @@ import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.common.internal.JobServiceImpl; import pro.taskana.common.internal.JobServiceImpl;
import pro.taskana.common.internal.jobs.JobRunner; import pro.taskana.common.internal.jobs.JobRunner;
import pro.taskana.common.internal.jobs.PlainJavaTransactionProvider; import pro.taskana.common.internal.jobs.PlainJavaTransactionProvider;
import pro.taskana.common.internal.util.Pair;
import pro.taskana.common.test.config.DataSourceGenerator; import pro.taskana.common.test.config.DataSourceGenerator;
import pro.taskana.common.test.util.ParallelThreadHelper; import pro.taskana.common.test.util.ParallelThreadHelper;
import pro.taskana.task.internal.jobs.TaskCleanupJob; import pro.taskana.task.internal.jobs.TaskCleanupJob;
import pro.taskana.task.internal.jobs.TaskUpdatePriorityJob;
import pro.taskana.workbasket.internal.jobs.WorkbasketCleanupJob;
@Disabled @Disabled
class JobRunnerAccTest extends AbstractAccTest { class JobRunnerAccTest extends AbstractAccTest {
private static final Duration TASK_CLEANUP_JOB_LOCK_EXPIRATION_PERIOD = Duration.ofMinutes(4);
private static final Duration WORKBASKET_CLEANUP_JOB_LOCK_EXPIRATION_PERIOD =
Duration.ofMinutes(3);
private static final Duration TASK_UPDATE_PRIORITY_LOCK_EXPIRATION_PERIOD = Duration.ofMinutes(1);
private final JobServiceImpl jobService = (JobServiceImpl) taskanaEngine.getJobService(); private final JobServiceImpl jobService = (JobServiceImpl) taskanaEngine.getJobService();
@Test @Test
@ -34,7 +47,8 @@ class JobRunnerAccTest extends AbstractAccTest {
resetDb(true); // for some reason clearing the job table is not enough.. resetDb(true); // for some reason clearing the job table is not enough..
assertThat(jobService.findJobsToRun()).isEmpty(); assertThat(jobService.findJobsToRun()).isEmpty();
ScheduledJob job = createJob(Instant.now().minus(5, ChronoUnit.MINUTES)); ScheduledJob job =
createJob(Instant.now().minus(5, ChronoUnit.MINUTES), TaskCleanupJob.class.getName());
assertThat(jobService.findJobsToRun()).containsExactly(job); assertThat(jobService.findJobsToRun()).containsExactly(job);
ParallelThreadHelper.runInThread( ParallelThreadHelper.runInThread(
@ -70,9 +84,55 @@ class JobRunnerAccTest extends AbstractAccTest {
assertThat(jobsToRun).hasSize(1).doesNotContain(job); assertThat(jobsToRun).hasSize(1).doesNotContain(job);
} }
private ScheduledJob createJob(Instant firstDue) { @TestFactory
Stream<DynamicTest> should_setTheLockExpirationDateCorrectly_When_CreatingJobs() {
List<Pair<String, Duration>> list =
List.of(
Pair.of(TaskCleanupJob.class.getName(), TASK_CLEANUP_JOB_LOCK_EXPIRATION_PERIOD),
Pair.of(
TaskUpdatePriorityJob.class.getName(), TASK_UPDATE_PRIORITY_LOCK_EXPIRATION_PERIOD),
Pair.of(
WorkbasketCleanupJob.class.getName(),
WORKBASKET_CLEANUP_JOB_LOCK_EXPIRATION_PERIOD));
ThrowingConsumer<Pair<String, Duration>> testSettingLockExpirationDate =
p -> {
resetDb(true);
assertThat(jobService.findJobsToRun()).isEmpty();
createJob(Instant.now().minus(5, ChronoUnit.MINUTES), p.getLeft());
ParallelThreadHelper.runInThread(
() -> {
TaskanaEngine taskanaEngine;
try {
taskanaEngine =
TaskanaEngine.buildTaskanaEngine(
taskanaConfiguration, ConnectionManagementMode.AUTOCOMMIT);
} catch (SQLException e) {
throw new RuntimeException("Could not build the TaskanaEngine");
}
DataSource dataSource = DataSourceGenerator.getDataSource();
PlainJavaTransactionProvider transactionProvider =
new PlainJavaTransactionProvider(taskanaEngine, dataSource);
JobRunner runner = new JobRunner(taskanaEngine);
runner.registerTransactionProvider(transactionProvider);
runner.runJobs();
},
1);
List<ScheduledJob> resultJobs =
getJobMapper(taskanaEngine).findJobsToRun(Instant.now().plus(2, ChronoUnit.DAYS));
assertThat(resultJobs).hasSize(1);
assertThat(resultJobs.get(0).getType()).isEqualTo(p.getLeft());
assertThat(resultJobs.get(0).getLockExpires())
.isBetween(
resultJobs.get(0).getCreated().plus(p.getRight()),
resultJobs.get(0).getCreated().plus(p.getRight()).plusSeconds(1));
};
return DynamicTest.stream(list.iterator(), Pair::getLeft, testSettingLockExpirationDate);
}
private ScheduledJob createJob(Instant firstDue, String type) {
ScheduledJob job = new ScheduledJob(); ScheduledJob job = new ScheduledJob();
job.setType(TaskCleanupJob.class.getName()); job.setType(type);
job.setDue(firstDue); job.setDue(firstDue);
jobService.createJob(job); jobService.createJob(job);
return job; return job;

View File

@ -13,6 +13,12 @@ taskana.jobs.maxRetries=3
taskana.jobs.batchSize=50 taskana.jobs.batchSize=50
taskana.jobs.runEvery=P1D taskana.jobs.runEvery=P1D
taskana.jobs.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.lockExpirationPeriod=PT1M
taskana.jobs.cleanup.task.lockExpirationPeriod=PT4M
taskana.jobs.cleanup.workbasket.lockExpirationPeriod=PT3M
taskana.jobs.priority.task.lockExpirationPeriod=PT1M
taskana.jobs.refresh.user.lockExpirationPeriod=PT5M
taskana.jobs.cleanup.history.lockExpirationPeriod=PT2M
taskana.jobs.cleanup.task.minimumAge=P14D taskana.jobs.cleanup.task.minimumAge=P14D
taskana.workingTime.holidays.german.enabled=true taskana.workingTime.holidays.german.enabled=true
taskana.workingTime.holidays.german.corpus-christi.enabled=false taskana.workingTime.holidays.german.corpus-christi.enabled=false
@ -29,12 +35,12 @@ taskana.workingTime.timezone=UTC
# set it to false and no jobs are running # set it to false and no jobs are running
taskana.jobs.scheduler.enabled=true taskana.jobs.scheduler.enabled=true
# wait time before the first job run # wait time before the first job run
taskana.jobs.scheduler.initialStartDelay=100000 taskana.jobs.scheduler.initialStartDelay=0
# sleeping time befor the next job runs # sleeping time befor the next job runs
taskana.jobs.scheduler.period=12 taskana.jobs.scheduler.period=12
# timeunit for the initial start delay and the sleeping period # timeunit for the initial start delay and the sleeping period
# Possible values: MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS # Possible values: MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS
taskana.jobs.scheduler.periodTimeUnit=HOURS taskana.jobs.scheduler.periodTimeUnit=SECONDS
taskana.jobs.cleanup.task.enable=false taskana.jobs.cleanup.task.enable=false
taskana.jobs.priority.task.enable=false taskana.jobs.priority.task.enable=false
taskana.jobs.cleanup.workbasket.enable=false taskana.jobs.cleanup.workbasket.enable=false

View File

@ -1,10 +1,12 @@
package pro.taskana.user.jobs; package pro.taskana.user.jobs;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.time.Duration;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaConfiguration;
import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.ScheduledJob;
import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.InvalidArgumentException; import pro.taskana.common.api.exceptions.InvalidArgumentException;
@ -42,6 +44,10 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob {
refreshUserPostprocessorManager = new RefreshUserPostprocessorManager(); refreshUserPostprocessorManager = new RefreshUserPostprocessorManager();
} }
public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) {
return taskanaConfiguration.getUserRefreshJobLockExpirationPeriod();
}
@Override @Override
protected String getType() { protected String getType() {
return UserInfoRefreshJob.class.getName(); return UserInfoRefreshJob.class.getName();