diff --git a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/jobs/HistoryCleanupJob.java b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/jobs/HistoryCleanupJob.java index 77889d8aa..4c58490f1 100644 --- a/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/jobs/HistoryCleanupJob.java +++ b/history/taskana-simplehistory-provider/src/main/java/pro/taskana/simplehistory/impl/jobs/HistoryCleanupJob.java @@ -14,6 +14,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.TimeInterval; @@ -52,6 +53,10 @@ public class HistoryCleanupJob extends AbstractTaskanaJob { super(taskanaEngine, txProvider, scheduledJob, true); } + public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) { + return taskanaConfiguration.getSimpleHistoryCleanupJobLockExpirationPeriod(); + } + @Override public void execute() { Instant createdBefore = Instant.now().minus(minimumAge); diff --git a/lib/taskana-core-test/src/test/java/acceptance/TaskanaConfigurationTest.java b/lib/taskana-core-test/src/test/java/acceptance/TaskanaConfigurationTest.java index 76c0abb3b..21efb159b 100644 --- a/lib/taskana-core-test/src/test/java/acceptance/TaskanaConfigurationTest.java +++ b/lib/taskana-core-test/src/test/java/acceptance/TaskanaConfigurationTest.java @@ -270,21 +270,27 @@ class TaskanaConfigurationTest { int expectedJobBatchSize = 50; Instant expectedJobFirstJun = Instant.MIN; Duration expectedJobRunEvery = Duration.ofDays(2); + Duration expectedJobLockExpirationPeriod = Duration.ofDays(2); boolean expectedTaskCleanupJobEnabled = false; Duration expectedTaskCleanupJobMinimumAge = Duration.ofDays(1); boolean expectedTaskCleanupJobAllCompletedSameParentBusiness = false; + Duration expectedTaskCleanupJobLockExpirationPeriod = Duration.ofDays(2); boolean expectedWorkbasketCleanupJobEnabled = false; + Duration expectedWorkbasketCleanupJobLockExpirationPeriod = Duration.ofDays(2); boolean expectedSimpleHistoryCleanupJobEnabled = true; int expectedSimpleHistoryCleanupJobBatchSize = 16; Duration expectedSimpleHistoryCleanupJobMinimumAge = Duration.ofHours(3); boolean expectedSimpleHistoryCleanupJobAllCompletedSameParentBusiness = false; + Duration expectedSimpleHistoryCleanupJobLockExpirationPeriod = Duration.ofDays(2); boolean expectedTaskUpdatePriorityJobEnabled = true; int expectedPriorityJobBatchSize = 49; Instant expectedPriorityJobFirstRun = Instant.MIN.plus(1, ChronoUnit.DAYS); Duration expectedTaskUpdatePriorityJobRunEvery = Duration.ofMinutes(17); + Duration expectedTaskUpdatePriorityJobLockExpirationPeriod = Duration.ofDays(2); boolean expectedUserInfoRefreshJobEnabled = true; Instant expectedUserRefreshJobFirstRun = Instant.MIN.plus(2, ChronoUnit.DAYS); Duration expectedUserRefreshJobRunEvery = Duration.ofDays(5); + Duration expectedUserRefreshJobLockExpirationPeriod = Duration.ofDays(2); Set expectedJobSchedulerCustomJobs = Set.of("Job_A", "Job_B"); // user configuration boolean expectedAddAdditionalUserInfo = true; @@ -329,23 +335,32 @@ class TaskanaConfigurationTest { .jobBatchSize(expectedJobBatchSize) .jobFirstRun(expectedJobFirstJun) .jobRunEvery(expectedJobRunEvery) + .jobLockExpirationPeriod(expectedJobLockExpirationPeriod) .taskCleanupJobEnabled(expectedTaskCleanupJobEnabled) .taskCleanupJobMinimumAge(expectedTaskCleanupJobMinimumAge) .taskCleanupJobAllCompletedSameParentBusiness( expectedTaskCleanupJobAllCompletedSameParentBusiness) + .taskCleanupJobLockExpirationPeriod(expectedTaskCleanupJobLockExpirationPeriod) .workbasketCleanupJobEnabled(expectedWorkbasketCleanupJobEnabled) + .workbasketCleanupJobLockExpirationPeriod( + expectedWorkbasketCleanupJobLockExpirationPeriod) .simpleHistoryCleanupJobEnabled(expectedSimpleHistoryCleanupJobEnabled) .simpleHistoryCleanupJobBatchSize(expectedSimpleHistoryCleanupJobBatchSize) .simpleHistoryCleanupJobMinimumAge(expectedSimpleHistoryCleanupJobMinimumAge) .simpleHistoryCleanupJobAllCompletedSameParentBusiness( expectedSimpleHistoryCleanupJobAllCompletedSameParentBusiness) + .simpleHistoryCleanupJobLockExpirationPeriod( + expectedSimpleHistoryCleanupJobLockExpirationPeriod) .taskUpdatePriorityJobEnabled(expectedTaskUpdatePriorityJobEnabled) .taskUpdatePriorityJobBatchSize(expectedPriorityJobBatchSize) .taskUpdatePriorityJobFirstRun(expectedPriorityJobFirstRun) .taskUpdatePriorityJobRunEvery(expectedTaskUpdatePriorityJobRunEvery) + .taskUpdatePriorityJobLockExpirationPeriod( + expectedTaskUpdatePriorityJobLockExpirationPeriod) .userInfoRefreshJobEnabled(expectedUserInfoRefreshJobEnabled) .userRefreshJobFirstRun(expectedUserRefreshJobFirstRun) .userRefreshJobRunEvery(expectedUserRefreshJobRunEvery) + .userRefreshJobLockExpirationPeriod(expectedUserRefreshJobLockExpirationPeriod) .customJobs(expectedJobSchedulerCustomJobs) // user configuration .addAdditionalUserInfo(expectedAddAdditionalUserInfo) @@ -467,21 +482,27 @@ class TaskanaConfigurationTest { .jobBatchSize(50) .jobFirstRun(Instant.MIN) .jobRunEvery(Duration.ofDays(2)) + .jobLockExpirationPeriod(Duration.ofDays(2)) .taskCleanupJobEnabled(false) .taskCleanupJobMinimumAge(Duration.ofDays(1)) .taskCleanupJobAllCompletedSameParentBusiness(false) + .taskCleanupJobLockExpirationPeriod(Duration.ofDays(6)) .workbasketCleanupJobEnabled(false) + .workbasketCleanupJobLockExpirationPeriod(Duration.ofDays(7)) .simpleHistoryCleanupJobEnabled(true) .simpleHistoryCleanupJobBatchSize(16) .simpleHistoryCleanupJobMinimumAge(Duration.ofHours(3)) .simpleHistoryCleanupJobAllCompletedSameParentBusiness(false) + .simpleHistoryCleanupJobLockExpirationPeriod(Duration.ofDays(9)) .taskUpdatePriorityJobEnabled(true) .taskUpdatePriorityJobBatchSize(49) .taskUpdatePriorityJobFirstRun(Instant.MIN.plus(1, ChronoUnit.DAYS)) .taskUpdatePriorityJobRunEvery(Duration.ofMinutes(17)) + .taskUpdatePriorityJobLockExpirationPeriod(Duration.ofDays(10)) .userInfoRefreshJobEnabled(true) .userRefreshJobFirstRun(Instant.MIN.plus(2, ChronoUnit.DAYS)) .userRefreshJobRunEvery(Duration.ofDays(5)) + .userRefreshJobLockExpirationPeriod(Duration.ofDays(8)) .customJobs(Set.of("Job_A", "Job_B")) // user configuration .addAdditionalUserInfo(true) diff --git a/lib/taskana-core-test/src/test/resources/fullTaskana.properties b/lib/taskana-core-test/src/test/resources/fullTaskana.properties index 83332a871..6bedd867a 100644 --- a/lib/taskana-core-test/src/test/resources/fullTaskana.properties +++ b/lib/taskana-core-test/src/test/resources/fullTaskana.properties @@ -35,21 +35,27 @@ taskana.jobs.maxRetries=4 taskana.jobs.batchSize=50 taskana.jobs.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.runEvery=P2D +taskana.jobs.lockExpirationPeriod=PT7M taskana.jobs.cleanup.task.enable=false taskana.jobs.cleanup.task.minimumAge=P15D taskana.jobs.cleanup.task.allCompletedSameParentBusiness=false +taskana.jobs.cleanup.task.lockExpirationPeriod=PT4M taskana.jobs.cleanup.workbasket.enable=false +taskana.jobs.cleanup.workbasket.lockExpirationPeriod=PT3M taskana.jobs.cleanup.history.simple.enable=true taskana.jobs.cleanup.history.simple.batchSize=50 taskana.jobs.cleanup.history.simple.minimumAge=P17D taskana.jobs.cleanup.history.simple.allCompletedSameParentBusiness=false +taskana.jobs.cleanup.history.simple.lockExpirationPeriod=PT2M taskana.jobs.priority.task.enable=true taskana.jobs.priority.task.batchSize=50 taskana.jobs.priority.task.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.priority.task.runEvery=P3D +taskana.jobs.priority.task.lockExpirationPeriod=PT8M taskana.jobs.refresh.user.enable=true taskana.jobs.refresh.user.firstRunAt=2018-07-25T08:00:00Z taskana.jobs.refresh.user.runEvery=P4D +taskana.jobs.refresh.user.lockExpirationPeriod=PT5M taskana.jobs.customJobs=A | B | C # user configuration taskana.user.addAdditionalUserInfo=true diff --git a/lib/taskana-core/src/main/java/pro/taskana/TaskanaConfiguration.java b/lib/taskana-core/src/main/java/pro/taskana/TaskanaConfiguration.java index 7bc1b65c6..3759ba81a 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/TaskanaConfiguration.java +++ b/lib/taskana-core/src/main/java/pro/taskana/TaskanaConfiguration.java @@ -95,26 +95,30 @@ public class TaskanaConfiguration { private final int jobBatchSize; private final Instant jobFirstRun; private final Duration jobRunEvery; - + private final Duration jobLockExpirationPeriod; private final boolean taskCleanupJobEnabled; private final Duration taskCleanupJobMinimumAge; private final boolean taskCleanupJobAllCompletedSameParentBusiness; + private final Duration taskCleanupJobLockExpirationPeriod; private final boolean workbasketCleanupJobEnabled; + private final Duration workbasketCleanupJobLockExpirationPeriod; private final boolean simpleHistoryCleanupJobEnabled; private final int simpleHistoryCleanupJobBatchSize; private final Duration simpleHistoryCleanupJobMinimumAge; private final boolean simpleHistoryCleanupJobAllCompletedSameParentBusiness; - + private final Duration simpleHistoryCleanupJobLockExpirationPeriod; private final boolean taskUpdatePriorityJobEnabled; private final int taskUpdatePriorityJobBatchSize; private final Instant taskUpdatePriorityJobFirstRun; private final Duration taskUpdatePriorityJobRunEvery; + private final Duration taskUpdatePriorityJobLockExpirationPeriod; private final boolean userInfoRefreshJobEnabled; private final Instant userRefreshJobFirstRun; private final Duration userRefreshJobRunEvery; + private final Duration userRefreshJobLockExpirationPeriod; private final Set customJobs; // endregion @@ -178,23 +182,32 @@ public class TaskanaConfiguration { this.jobBatchSize = builder.jobBatchSize; this.jobFirstRun = builder.jobFirstRun; this.jobRunEvery = builder.jobRunEvery; + this.jobLockExpirationPeriod = builder.jobLockExpirationPeriod; this.taskCleanupJobEnabled = builder.taskCleanupJobEnabled; this.taskCleanupJobMinimumAge = builder.taskCleanupJobMinimumAge; this.taskCleanupJobAllCompletedSameParentBusiness = builder.taskCleanupJobAllCompletedSameParentBusiness; + this.taskCleanupJobLockExpirationPeriod = builder.taskCleanupJobLockExpirationPeriod; this.workbasketCleanupJobEnabled = builder.workbasketCleanupJobEnabled; + this.workbasketCleanupJobLockExpirationPeriod = + builder.workbasketCleanupJobLockExpirationPeriod; this.simpleHistoryCleanupJobEnabled = builder.simpleHistoryCleanupJobEnabled; this.simpleHistoryCleanupJobBatchSize = builder.simpleHistoryCleanupJobBatchSize; this.simpleHistoryCleanupJobMinimumAge = builder.simpleHistoryCleanupJobMinimumAge; this.simpleHistoryCleanupJobAllCompletedSameParentBusiness = builder.simpleHistoryCleanupJobAllCompletedSameParentBusiness; + this.simpleHistoryCleanupJobLockExpirationPeriod = + builder.simpleHistoryCleanupJobLockExpirationPeriod; this.taskUpdatePriorityJobEnabled = builder.taskUpdatePriorityJobEnabled; this.taskUpdatePriorityJobBatchSize = builder.taskUpdatePriorityJobBatchSize; this.taskUpdatePriorityJobFirstRun = builder.taskUpdatePriorityJobFirstRun; this.taskUpdatePriorityJobRunEvery = builder.taskUpdatePriorityJobRunEvery; + this.taskUpdatePriorityJobLockExpirationPeriod = + builder.taskUpdatePriorityJobLockExpirationPeriod; this.userInfoRefreshJobEnabled = builder.userInfoRefreshJobEnabled; this.userRefreshJobFirstRun = builder.userRefreshJobFirstRun; this.userRefreshJobRunEvery = builder.userRefreshJobRunEvery; + this.userRefreshJobLockExpirationPeriod = builder.userRefreshJobLockExpirationPeriod; this.customJobs = Collections.unmodifiableSet(builder.customJobs); // user configuration this.addAdditionalUserInfo = builder.addAdditionalUserInfo; @@ -328,6 +341,10 @@ public class TaskanaConfiguration { return jobRunEvery; } + public Duration getJobLockExpirationPeriod() { + return jobLockExpirationPeriod; + } + public boolean isTaskCleanupJobEnabled() { return taskCleanupJobEnabled; } @@ -340,10 +357,18 @@ public class TaskanaConfiguration { return taskCleanupJobAllCompletedSameParentBusiness; } + public Duration getTaskCleanupJobLockExpirationPeriod() { + return taskCleanupJobLockExpirationPeriod; + } + public boolean isWorkbasketCleanupJobEnabled() { return workbasketCleanupJobEnabled; } + public Duration getWorkbasketCleanupJobLockExpirationPeriod() { + return workbasketCleanupJobLockExpirationPeriod; + } + public boolean isSimpleHistoryCleanupJobEnabled() { return simpleHistoryCleanupJobEnabled; } @@ -360,6 +385,10 @@ public class TaskanaConfiguration { return simpleHistoryCleanupJobAllCompletedSameParentBusiness; } + public Duration getSimpleHistoryCleanupJobLockExpirationPeriod() { + return simpleHistoryCleanupJobLockExpirationPeriod; + } + public boolean isTaskUpdatePriorityJobEnabled() { return taskUpdatePriorityJobEnabled; } @@ -376,6 +405,10 @@ public class TaskanaConfiguration { return taskUpdatePriorityJobRunEvery; } + public Duration getTaskUpdatePriorityJobLockExpirationPeriod() { + return taskUpdatePriorityJobLockExpirationPeriod; + } + public boolean isUserInfoRefreshJobEnabled() { return userInfoRefreshJobEnabled; } @@ -388,6 +421,10 @@ public class TaskanaConfiguration { return userRefreshJobRunEvery; } + public Duration getUserRefreshJobLockExpirationPeriod() { + return userRefreshJobLockExpirationPeriod; + } + public Set getCustomJobs() { return customJobs; } @@ -418,6 +455,7 @@ public class TaskanaConfiguration { // endregion // region hashCode, equals + toString + @Override public int hashCode() { return Objects.hash( @@ -446,21 +484,27 @@ public class TaskanaConfiguration { jobBatchSize, jobFirstRun, jobRunEvery, + jobLockExpirationPeriod, taskCleanupJobEnabled, taskCleanupJobMinimumAge, taskCleanupJobAllCompletedSameParentBusiness, + taskCleanupJobLockExpirationPeriod, workbasketCleanupJobEnabled, + workbasketCleanupJobLockExpirationPeriod, simpleHistoryCleanupJobEnabled, simpleHistoryCleanupJobBatchSize, simpleHistoryCleanupJobMinimumAge, simpleHistoryCleanupJobAllCompletedSameParentBusiness, + simpleHistoryCleanupJobLockExpirationPeriod, taskUpdatePriorityJobEnabled, taskUpdatePriorityJobBatchSize, taskUpdatePriorityJobFirstRun, taskUpdatePriorityJobRunEvery, + taskUpdatePriorityJobLockExpirationPeriod, userInfoRefreshJobEnabled, userRefreshJobFirstRun, userRefreshJobRunEvery, + userRefreshJobLockExpirationPeriod, customJobs, addAdditionalUserInfo, minimalPermissionsToAssignDomains, @@ -500,10 +544,10 @@ public class TaskanaConfiguration { && simpleHistoryCleanupJobAllCompletedSameParentBusiness == other.simpleHistoryCleanupJobAllCompletedSameParentBusiness && taskUpdatePriorityJobEnabled == other.taskUpdatePriorityJobEnabled - && useSpecificDb2Taskquery == other.useSpecificDb2Taskquery && taskUpdatePriorityJobBatchSize == other.taskUpdatePriorityJobBatchSize && userInfoRefreshJobEnabled == other.userInfoRefreshJobEnabled && addAdditionalUserInfo == other.addAdditionalUserInfo + && useSpecificDb2Taskquery == other.useSpecificDb2Taskquery && Objects.equals(dataSource, other.dataSource) && Objects.equals(schemaName, other.schemaName) && Objects.equals(domains, other.domains) @@ -517,13 +561,27 @@ public class TaskanaConfiguration { && jobSchedulerPeriodTimeUnit == other.jobSchedulerPeriodTimeUnit && Objects.equals(jobFirstRun, other.jobFirstRun) && Objects.equals(jobRunEvery, other.jobRunEvery) + && Objects.equals(jobLockExpirationPeriod, other.jobLockExpirationPeriod) && Objects.equals(taskCleanupJobMinimumAge, other.taskCleanupJobMinimumAge) + && Objects.equals( + taskCleanupJobLockExpirationPeriod, other.taskCleanupJobLockExpirationPeriod) + && Objects.equals( + workbasketCleanupJobLockExpirationPeriod, + other.workbasketCleanupJobLockExpirationPeriod) && Objects.equals( simpleHistoryCleanupJobMinimumAge, other.simpleHistoryCleanupJobMinimumAge) + && Objects.equals( + simpleHistoryCleanupJobLockExpirationPeriod, + other.simpleHistoryCleanupJobLockExpirationPeriod) && Objects.equals(taskUpdatePriorityJobFirstRun, other.taskUpdatePriorityJobFirstRun) && Objects.equals(taskUpdatePriorityJobRunEvery, other.taskUpdatePriorityJobRunEvery) + && Objects.equals( + taskUpdatePriorityJobLockExpirationPeriod, + other.taskUpdatePriorityJobLockExpirationPeriod) && Objects.equals(userRefreshJobFirstRun, other.userRefreshJobFirstRun) && Objects.equals(userRefreshJobRunEvery, other.userRefreshJobRunEvery) + && Objects.equals( + userRefreshJobLockExpirationPeriod, other.userRefreshJobLockExpirationPeriod) && Objects.equals(customJobs, other.customJobs) && Objects.equals( minimalPermissionsToAssignDomains, other.minimalPermissionsToAssignDomains) @@ -532,12 +590,14 @@ public class TaskanaConfiguration { @Override public String toString() { - return "TaskanaConfiguration [dataSource=" + return "TaskanaConfiguration{" + + "dataSource=" + dataSource + ", useManagedTransactions=" + useManagedTransactions - + ", schemaName=" + + ", schemaName='" + schemaName + + '\'' + ", securityEnabled=" + securityEnabled + ", domains=" @@ -564,8 +624,9 @@ public class TaskanaConfiguration { + germanPublicHolidaysCorpusChristiEnabled + ", deleteHistoryEventsOnTaskDeletionEnabled=" + deleteHistoryEventsOnTaskDeletionEnabled - + ", logHistoryLoggerName=" + + ", logHistoryLoggerName='" + logHistoryLoggerName + + '\'' + ", jobSchedulerEnabled=" + jobSchedulerEnabled + ", jobSchedulerInitialStartDelay=" @@ -582,14 +643,20 @@ public class TaskanaConfiguration { + jobFirstRun + ", jobRunEvery=" + jobRunEvery + + ", jobLockExpirationPeriod=" + + jobLockExpirationPeriod + ", taskCleanupJobEnabled=" + taskCleanupJobEnabled + ", taskCleanupJobMinimumAge=" + taskCleanupJobMinimumAge + ", taskCleanupJobAllCompletedSameParentBusiness=" + taskCleanupJobAllCompletedSameParentBusiness + + ", taskCleanupJobLockExpirationPeriod=" + + taskCleanupJobLockExpirationPeriod + ", workbasketCleanupJobEnabled=" + workbasketCleanupJobEnabled + + ", workbasketCleanupJobLockExpirationPeriod=" + + workbasketCleanupJobLockExpirationPeriod + ", simpleHistoryCleanupJobEnabled=" + simpleHistoryCleanupJobEnabled + ", simpleHistoryCleanupJobBatchSize=" @@ -598,6 +665,8 @@ public class TaskanaConfiguration { + simpleHistoryCleanupJobMinimumAge + ", simpleHistoryCleanupJobAllCompletedSameParentBusiness=" + simpleHistoryCleanupJobAllCompletedSameParentBusiness + + ", simpleHistoryCleanupJobLockExpirationPeriod=" + + simpleHistoryCleanupJobLockExpirationPeriod + ", taskUpdatePriorityJobEnabled=" + taskUpdatePriorityJobEnabled + ", taskUpdatePriorityJobBatchSize=" @@ -606,12 +675,16 @@ public class TaskanaConfiguration { + taskUpdatePriorityJobFirstRun + ", taskUpdatePriorityJobRunEvery=" + taskUpdatePriorityJobRunEvery + + ", taskUpdatePriorityJobLockExpirationPeriod=" + + taskUpdatePriorityJobLockExpirationPeriod + ", userInfoRefreshJobEnabled=" + userInfoRefreshJobEnabled + ", userRefreshJobFirstRun=" + userRefreshJobFirstRun + ", userRefreshJobRunEvery=" + userRefreshJobRunEvery + + ", userRefreshJobLockExpirationPeriod=" + + userRefreshJobLockExpirationPeriod + ", customJobs=" + customJobs + ", addAdditionalUserInfo=" @@ -622,7 +695,7 @@ public class TaskanaConfiguration { + useSpecificDb2Taskquery + ", properties=" + properties - + "]"; + + '}'; } // endregion @@ -714,6 +787,9 @@ public class TaskanaConfiguration { @TaskanaProperty("taskana.jobs.runEvery") private Duration jobRunEvery = Duration.ofDays(1); + @TaskanaProperty("taskana.jobs.lockExpirationPeriod") + private Duration jobLockExpirationPeriod = Duration.ofMinutes(30); + @TaskanaProperty("taskana.jobs.cleanup.task.enable") private boolean taskCleanupJobEnabled = true; @@ -723,9 +799,15 @@ public class TaskanaConfiguration { @TaskanaProperty("taskana.jobs.cleanup.task.allCompletedSameParentBusiness") private boolean taskCleanupJobAllCompletedSameParentBusiness = true; + @TaskanaProperty("taskana.jobs.cleanup.task.lockExpirationPeriod") + private Duration taskCleanupJobLockExpirationPeriod = Duration.ofMinutes(30); + @TaskanaProperty("taskana.jobs.cleanup.workbasket.enable") private boolean workbasketCleanupJobEnabled = true; + @TaskanaProperty("taskana.jobs.cleanup.workbasket.lockExpirationPeriod") + private Duration workbasketCleanupJobLockExpirationPeriod = Duration.ofMinutes(30); + @TaskanaProperty("taskana.jobs.cleanup.history.simple.enable") private boolean simpleHistoryCleanupJobEnabled = false; @@ -738,6 +820,9 @@ public class TaskanaConfiguration { @TaskanaProperty("taskana.jobs.cleanup.history.simple.allCompletedSameParentBusiness") private boolean simpleHistoryCleanupJobAllCompletedSameParentBusiness = true; + @TaskanaProperty("taskana.jobs.cleanup.history.simple.lockExpirationPeriod") + private Duration simpleHistoryCleanupJobLockExpirationPeriod = Duration.ofMinutes(30); + @TaskanaProperty("taskana.jobs.priority.task.enable") private boolean taskUpdatePriorityJobEnabled = false; @@ -750,6 +835,9 @@ public class TaskanaConfiguration { @TaskanaProperty("taskana.jobs.priority.task.runEvery") private Duration taskUpdatePriorityJobRunEvery = Duration.ofDays(1); + @TaskanaProperty("taskana.jobs.priority.task.lockExpirationPeriod") + private Duration taskUpdatePriorityJobLockExpirationPeriod = Duration.ofMinutes(30); + @TaskanaProperty("taskana.jobs.refresh.user.enable") private boolean userInfoRefreshJobEnabled = false; @@ -759,6 +847,9 @@ public class TaskanaConfiguration { @TaskanaProperty("taskana.jobs.refresh.user.runEvery") private Duration userRefreshJobRunEvery = Duration.ofDays(1); + @TaskanaProperty("taskana.jobs.refresh.user.lockExpirationPeriod") + private Duration userRefreshJobLockExpirationPeriod = Duration.ofMinutes(30); + @TaskanaProperty("taskana.jobs.customJobs") private Set customJobs = new HashSet<>(); // endregion @@ -858,23 +949,31 @@ public class TaskanaConfiguration { this.jobBatchSize = conf.jobBatchSize; this.jobFirstRun = conf.jobFirstRun; this.jobRunEvery = conf.jobRunEvery; + this.jobLockExpirationPeriod = conf.jobLockExpirationPeriod; this.taskCleanupJobEnabled = conf.taskCleanupJobEnabled; this.taskCleanupJobMinimumAge = conf.taskCleanupJobMinimumAge; this.taskCleanupJobAllCompletedSameParentBusiness = conf.taskCleanupJobAllCompletedSameParentBusiness; + this.taskCleanupJobLockExpirationPeriod = conf.taskCleanupJobLockExpirationPeriod; this.workbasketCleanupJobEnabled = conf.workbasketCleanupJobEnabled; + this.workbasketCleanupJobLockExpirationPeriod = conf.workbasketCleanupJobLockExpirationPeriod; this.simpleHistoryCleanupJobEnabled = conf.simpleHistoryCleanupJobEnabled; this.simpleHistoryCleanupJobBatchSize = conf.simpleHistoryCleanupJobBatchSize; this.simpleHistoryCleanupJobMinimumAge = conf.simpleHistoryCleanupJobMinimumAge; this.simpleHistoryCleanupJobAllCompletedSameParentBusiness = conf.simpleHistoryCleanupJobAllCompletedSameParentBusiness; + this.simpleHistoryCleanupJobLockExpirationPeriod = + conf.simpleHistoryCleanupJobLockExpirationPeriod; this.taskUpdatePriorityJobEnabled = conf.taskUpdatePriorityJobEnabled; this.taskUpdatePriorityJobBatchSize = conf.taskUpdatePriorityJobBatchSize; this.taskUpdatePriorityJobFirstRun = conf.taskUpdatePriorityJobFirstRun; this.taskUpdatePriorityJobRunEvery = conf.taskUpdatePriorityJobRunEvery; + this.taskUpdatePriorityJobLockExpirationPeriod = + conf.taskUpdatePriorityJobLockExpirationPeriod; this.userInfoRefreshJobEnabled = conf.userInfoRefreshJobEnabled; this.userRefreshJobFirstRun = conf.userRefreshJobFirstRun; this.userRefreshJobRunEvery = conf.userRefreshJobRunEvery; + this.userRefreshJobLockExpirationPeriod = conf.userRefreshJobLockExpirationPeriod; this.customJobs = conf.customJobs; // user configuration this.addAdditionalUserInfo = conf.addAdditionalUserInfo; @@ -1074,6 +1173,11 @@ public class TaskanaConfiguration { return this; } + public Builder jobLockExpirationPeriod(Duration jobLockExpirationPeriod) { + this.jobLockExpirationPeriod = jobLockExpirationPeriod; + return this; + } + public Builder taskCleanupJobMinimumAge(Duration taskCleanupJobMinimumAge) { this.taskCleanupJobMinimumAge = taskCleanupJobMinimumAge; return this; @@ -1086,11 +1190,22 @@ public class TaskanaConfiguration { return this; } + public Builder taskCleanupJobLockExpirationPeriod(Duration taskCleanupJobLockExpirationPeriod) { + this.taskCleanupJobLockExpirationPeriod = taskCleanupJobLockExpirationPeriod; + return this; + } + public Builder workbasketCleanupJobEnabled(boolean workbasketCleanupJobEnabled) { this.workbasketCleanupJobEnabled = workbasketCleanupJobEnabled; return this; } + public Builder workbasketCleanupJobLockExpirationPeriod( + Duration workbasketCleanupJobLockExpirationPeriod) { + this.workbasketCleanupJobLockExpirationPeriod = workbasketCleanupJobLockExpirationPeriod; + return this; + } + public Builder simpleHistoryCleanupJobEnabled(boolean simpleHistoryCleanupJobEnabled) { this.simpleHistoryCleanupJobEnabled = simpleHistoryCleanupJobEnabled; return this; @@ -1113,6 +1228,13 @@ public class TaskanaConfiguration { return this; } + public Builder simpleHistoryCleanupJobLockExpirationPeriod( + Duration simpleHistoryCleanupJobLockExpirationPeriod) { + this.simpleHistoryCleanupJobLockExpirationPeriod = + simpleHistoryCleanupJobLockExpirationPeriod; + return this; + } + public Builder taskUpdatePriorityJobEnabled(boolean taskUpdatePriorityJobEnabled) { this.taskUpdatePriorityJobEnabled = taskUpdatePriorityJobEnabled; return this; @@ -1133,6 +1255,12 @@ public class TaskanaConfiguration { return this; } + public Builder taskUpdatePriorityJobLockExpirationPeriod( + Duration taskUpdatePriorityJobLockExpirationPeriod) { + this.taskUpdatePriorityJobLockExpirationPeriod = taskUpdatePriorityJobLockExpirationPeriod; + return this; + } + public Builder userInfoRefreshJobEnabled(boolean userInfoRefreshJobEnabled) { this.userInfoRefreshJobEnabled = userInfoRefreshJobEnabled; return this; @@ -1148,6 +1276,11 @@ public class TaskanaConfiguration { return this; } + public Builder userRefreshJobLockExpirationPeriod(Duration userRefreshJobLockExpirationPeriod) { + this.userRefreshJobLockExpirationPeriod = userRefreshJobLockExpirationPeriod; + return this; + } + public Builder customJobs(Set customJobs) { this.customJobs = customJobs; return this; diff --git a/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobServiceImpl.java index 206941adf..49ec0a4f3 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobServiceImpl.java @@ -1,18 +1,20 @@ package pro.taskana.common.internal; +import java.lang.reflect.InvocationTargetException; import java.time.Duration; import java.time.Instant; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.JobService; import pro.taskana.common.api.ScheduledJob; +import pro.taskana.common.api.exceptions.SystemException; /** Controls all job activities. */ public class JobServiceImpl implements JobService { 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 final JobMapper jobMapper; @@ -43,7 +45,27 @@ public class JobServiceImpl implements JobService { public ScheduledJob lockJob(ScheduledJob job, String 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); taskanaEngineImpl.executeInDatabaseConnection(() -> jobMapper.update(job)); if (LOGGER.isDebugEnabled()) { diff --git a/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/AbstractTaskanaJob.java b/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/AbstractTaskanaJob.java index 1805c87ac..eae36bad2 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/AbstractTaskanaJob.java +++ b/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/AbstractTaskanaJob.java @@ -4,6 +4,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.time.Duration; import java.time.Instant; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.exceptions.SystemException; @@ -42,8 +43,7 @@ public abstract class AbstractTaskanaJob implements TaskanaJob { try { jobClass = Thread.currentThread().getContextClassLoader().loadClass(job.getType()); } catch (ClassNotFoundException e) { - throw new SystemException( - String.format("Can't load class '%s'", job.getType())); + throw new SystemException(String.format("Can't load class '%s'", job.getType())); } return initTaskanaJob(engine, jobClass, txProvider, job); @@ -76,6 +76,46 @@ public abstract class AbstractTaskanaJob implements TaskanaJob { 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( TaskanaEngine taskanaEngine, Class jobClass, @@ -120,40 +160,4 @@ public abstract class AbstractTaskanaJob implements TaskanaJob { } 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); - } } diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskCleanupJob.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskCleanupJob.java index ea6ea3d4a..a49def538 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskCleanupJob.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskCleanupJob.java @@ -11,6 +11,7 @@ import java.util.Map; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.BaseQuery.SortDirection; import pro.taskana.common.api.BulkOperationResults; 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 protected String getType() { return TaskCleanupJob.class.getName(); diff --git a/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskUpdatePriorityJob.java b/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskUpdatePriorityJob.java index 468cad90f..76b2c735b 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskUpdatePriorityJob.java +++ b/lib/taskana-core/src/main/java/pro/taskana/task/internal/jobs/TaskUpdatePriorityJob.java @@ -2,8 +2,10 @@ package pro.taskana.task.internal.jobs; import static pro.taskana.common.internal.util.CollectionUtil.partitionBasedOnSize; +import java.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.TaskanaEngine; 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() { return batchSize; } diff --git a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/jobs/WorkbasketCleanupJob.java b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/jobs/WorkbasketCleanupJob.java index c418bdf5c..dd2914c0f 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/jobs/WorkbasketCleanupJob.java +++ b/lib/taskana-core/src/main/java/pro/taskana/workbasket/internal/jobs/WorkbasketCleanupJob.java @@ -1,8 +1,10 @@ package pro.taskana.workbasket.internal.jobs; +import java.time.Duration; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.BaseQuery; import pro.taskana.common.api.BulkOperationResults; 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 protected String getType() { return WorkbasketCleanupJob.class.getName(); diff --git a/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java b/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java index f39db8081..0976c3f25 100644 --- a/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java +++ b/lib/taskana-core/src/test/java/acceptance/jobs/JobRunnerAccTest.java @@ -4,12 +4,18 @@ import static org.assertj.core.api.Assertions.assertThat; import acceptance.AbstractAccTest; import java.sql.Connection; +import java.sql.SQLException; +import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.List; +import java.util.stream.Stream; import javax.sql.DataSource; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DynamicTest; 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.internal.stubbing.answers.CallsRealMethods; 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.jobs.JobRunner; 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.util.ParallelThreadHelper; import pro.taskana.task.internal.jobs.TaskCleanupJob; +import pro.taskana.task.internal.jobs.TaskUpdatePriorityJob; +import pro.taskana.workbasket.internal.jobs.WorkbasketCleanupJob; @Disabled 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(); @Test @@ -34,7 +47,8 @@ class JobRunnerAccTest extends AbstractAccTest { resetDb(true); // for some reason clearing the job table is not enough.. 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); ParallelThreadHelper.runInThread( @@ -70,9 +84,55 @@ class JobRunnerAccTest extends AbstractAccTest { assertThat(jobsToRun).hasSize(1).doesNotContain(job); } - private ScheduledJob createJob(Instant firstDue) { + @TestFactory + Stream should_setTheLockExpirationDateCorrectly_When_CreatingJobs() { + List> 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> 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 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(); - job.setType(TaskCleanupJob.class.getName()); + job.setType(type); job.setDue(firstDue); jobService.createJob(job); return job; diff --git a/lib/taskana-core/src/test/resources/taskana.properties b/lib/taskana-core/src/test/resources/taskana.properties index 13a36ca45..ba199488c 100644 --- a/lib/taskana-core/src/test/resources/taskana.properties +++ b/lib/taskana-core/src/test/resources/taskana.properties @@ -13,6 +13,12 @@ taskana.jobs.maxRetries=3 taskana.jobs.batchSize=50 taskana.jobs.runEvery=P1D 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.workingTime.holidays.german.enabled=true 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 taskana.jobs.scheduler.enabled=true # wait time before the first job run -taskana.jobs.scheduler.initialStartDelay=100000 +taskana.jobs.scheduler.initialStartDelay=0 # sleeping time befor the next job runs taskana.jobs.scheduler.period=12 # timeunit for the initial start delay and the sleeping period # 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.priority.task.enable=false taskana.jobs.cleanup.workbasket.enable=false diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/user/jobs/UserInfoRefreshJob.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/user/jobs/UserInfoRefreshJob.java index d8d9be1d7..f26b9e3ec 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/user/jobs/UserInfoRefreshJob.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/user/jobs/UserInfoRefreshJob.java @@ -1,10 +1,12 @@ package pro.taskana.user.jobs; import java.sql.PreparedStatement; +import java.time.Duration; import java.util.List; import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pro.taskana.TaskanaConfiguration; import pro.taskana.common.api.ScheduledJob; import pro.taskana.common.api.TaskanaEngine; import pro.taskana.common.api.exceptions.InvalidArgumentException; @@ -42,6 +44,10 @@ public class UserInfoRefreshJob extends AbstractTaskanaJob { refreshUserPostprocessorManager = new RefreshUserPostprocessorManager(); } + public static Duration getLockExpirationPeriod(TaskanaConfiguration taskanaConfiguration) { + return taskanaConfiguration.getUserRefreshJobLockExpirationPeriod(); + } + @Override protected String getType() { return UserInfoRefreshJob.class.getName();