From dc64548c53aaba8f27b84d72611bd7c00367c775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= Date: Tue, 5 Mar 2024 15:35:29 +0100 Subject: [PATCH] [SYNCOPE-1801] Replacing Quartz by Spring scheduling features (#639) --- .../client/console/SyncopeConsoleSession.java | 9 +- .../implementations/MyPullActions.groovy | 2 +- .../implementations/MyPushActions.groovy | 2 +- .../MyReportJobDelegate.groovy | 11 +- .../MySchedTaskJobDelegate.groovy | 11 +- common/idrepo/lib/pom.xml | 2 +- .../src/main/resources/defaultContent.jpa.xml | 2 + .../main/resources/defaultContent.neo4j.xml | 2 + .../core/logic/ReconciliationLogic.java | 2 +- core/idrepo/logic/pom.xml | 6 +- .../core/logic/AbstractExecutableLogic.java | 4 +- .../syncope/core/logic/AbstractJobLogic.java | 111 +++---- .../apache/syncope/core/logic/GroupLogic.java | 45 +-- .../core/logic/IdRepoLogicContext.java | 10 +- .../syncope/core/logic/NotificationLogic.java | 9 +- .../syncope/core/logic/ReportLogic.java | 59 ++-- .../apache/syncope/core/logic/TaskLogic.java | 63 ++-- .../core/logic/job/MacroRunJobDelegate.java | 4 +- .../syncope/core/logic/ReportLogicTest.java | 10 +- .../core/rest/cxf/MDCInInterceptor.java | 4 +- .../rest/cxf/SyncopeOpenApiCustomizer.java | 11 + .../persistence/api/dao/JobStatusDAO.java | 6 + .../jpa/MyJPAJSONPersistenceContext.java | 4 +- .../jpa/OJPAJSONPersistenceContext.java | 4 +- .../jpa/PGJPAJSONPersistenceContext.java | 4 +- .../src/main/resources/core-myjson.properties | 3 - .../src/main/resources/core-ojson.properties | 3 - .../main/resources/core-pgjsonb.properties | 3 - .../domains/jpa-json/MasterContent.xml | 2 + .../jpa/JPAJSONTestContextCustomizer.java | 21 -- .../test/resources/domains/MasterContent.xml | 2 + .../persistence/jpa/JPADomainRegistry.java | 2 +- .../persistence/jpa/PersistenceContext.java | 14 +- .../persistence/jpa/dao/JPAJobStatusDAO.java | 34 +- .../main/resources/domains/MasterContent.xml | 2 + .../jpa/inner/ImplementationTest.java | 4 +- .../src/test/resources/core-test.properties | 3 - .../test/resources/domains/MasterContent.xml | 2 + .../src/test/resources/domains/TwoContent.xml | 2 + .../core/persistence/neo4j/MasterDomain.java | 16 - .../neo4j/Neo4jDomainRegistry.java | 29 -- .../persistence/neo4j/PersistenceContext.java | 35 +-- .../neo4j/dao/Neo4jJobStatusDAO.java | 29 ++ .../neo4j/spring/DomainRoutingDriver.java | 126 ++++++++ .../spring/DomainRoutingNeo4jClient.java | 75 ----- .../DomainRoutingNeo4jTransactionManager.java | 62 ---- .../main/resources/domains/MasterContent.xml | 2 + .../neo4j/PersistenceTestContext.java | 22 +- .../neo4j/inner/ImplementationTest.java | 4 +- .../test/resources/domains/MasterContent.xml | 2 + .../src/test/resources/domains/TwoContent.xml | 2 + core/provisioning-api/pom.xml | 10 +- .../api/event/JobStatusEvent.java | 12 +- .../api/job/JobExecutionContext.java | 62 ++++ ...legate.java => JobExecutionException.java} | 19 +- .../core/provisioning/api/job/JobManager.java | 24 +- .../core/provisioning/api/job/JobNamer.java | 14 +- .../api/job/SchedTaskJobDelegate.java | 8 +- .../api/job/report/ReportJobDelegate.java | 11 +- .../notification/NotificationJobDelegate.java | 5 +- .../api/pushpull/ProvisioningActions.java | 2 +- .../api/pushpull/PullActions.java | 2 +- .../api/pushpull/PushActions.java | 2 +- .../api/pushpull/SyncopePullExecutor.java | 4 - .../api/pushpull/SyncopePushExecutor.java | 3 - .../pushpull/SyncopeSinglePullExecutor.java | 2 +- .../pushpull/SyncopeSinglePushExecutor.java | 2 +- .../stream/SyncopeStreamPullExecutor.java | 2 +- .../stream/SyncopeStreamPushExecutor.java | 2 +- .../provisioning/api/job/JobNamerTest.java | 16 +- core/provisioning-java/pom.xml | 17 +- .../java/ProvisioningContext.java | 90 +----- .../java/ProvisioningProperties.java | 75 +---- .../java/data/ReportDataBinderImpl.java | 32 +- .../java/data/TaskDataBinderImpl.java | 29 +- .../java/job/AbstractInterruptableJob.java | 49 --- .../job/AbstractSchedTaskJobDelegate.java | 39 +-- .../java/job/AfterHandlingJob.java | 68 ++-- .../java/job/DefaultJobManager.java | 237 ++++++-------- .../java/job/ExpiredAccessTokenCleanup.java | 4 +- .../java/job/ExpiredBatchCleanup.java | 4 +- .../GroupMemberProvisionTaskJobDelegate.java | 36 +-- .../core/provisioning/java/job/Job.java | 74 +++++ .../java/job/JobStatusUpdater.java | 14 +- .../java/job/SchedulerDBInit.java | 74 ----- .../java/job/SyncopeSpringBeanJobFactory.java | 48 --- .../java/job/SyncopeTaskScheduler.java | 108 +++++++ .../java/job/SystemLoadReporterJob.java | 8 +- .../core/provisioning/java/job/TaskJob.java | 33 +- .../AbstractNotificationJobDelegate.java | 40 +-- .../job/notification/NotificationJob.java | 20 +- .../job/report/AbstractReportJobDelegate.java | 39 +-- .../java/job/report/ReportJob.java | 35 +-- .../AbstractProvisioningJobDelegate.java | 144 ++++----- .../pushpull/AbstractPullResultHandler.java | 2 +- .../pushpull/AbstractPushResultHandler.java | 143 +++++---- .../java/pushpull/DBPasswordPullActions.java | 2 +- .../DefaultRealmPullResultHandler.java | 2 +- .../DefaultRealmPushResultHandler.java | 6 +- .../DefaultUserPullResultHandler.java | 2 +- .../DefaultUserPushResultHandler.java | 2 +- .../pushpull/LDAPMembershipPullActions.java | 2 +- .../pushpull/LDAPPasswordPullActions.java | 2 +- .../java/pushpull/PullJobDelegate.java | 14 +- .../pushpull/PullResultHandlerDispatcher.java | 6 - .../java/pushpull/PushJobDelegate.java | 14 +- .../pushpull/PushResultHandlerDispatcher.java | 6 - .../java/pushpull/SinglePullJobDelegate.java | 4 +- .../java/pushpull/SinglePushJobDelegate.java | 6 +- .../stream/StreamPullJobDelegate.java | 4 +- .../stream/StreamPushJobDelegate.java | 4 +- .../src/main/resources/quartz/tables_h2.sql | 265 ---------------- .../main/resources/quartz/tables_mariadb.sql | 206 ------------ .../main/resources/quartz/tables_mysql.sql | 206 ------------ .../resources/quartz/tables_mysql_innodb.sql | 221 ------------- .../main/resources/quartz/tables_oracle.sql | 208 ------------ .../main/resources/quartz/tables_postgres.sql | 204 ------------ .../resources/quartz/tables_sqlServer.sql | 296 ------------------ .../java/job/JobStatusUpdaterTest.java | 11 +- .../java/job/SyncopeTaskSchedulerTest.java | 81 +++++ .../pushpull/DBPasswordPullActionsTest.java | 2 +- .../LDAPMembershipPullActionsTest.java | 2 +- .../pushpull/LDAPPasswordPullActionsTest.java | 2 +- .../stream/StreamPullJobDelegateTest.java | 2 +- .../src/test/resources/core-debug.properties | 4 - .../src/test/resources/log4j2.xml | 3 - .../core/starter/SyncopeCoreApplication.java | 4 +- .../src/main/resources/core.properties | 4 - docker/core/LICENSE | 5 - docker/core/NOTICE | 5 - .../main/resources/core-mariadb.properties | 3 - .../src/main/resources/core-myjson.properties | 3 - .../src/main/resources/core-mysql.properties | 3 - .../src/main/resources/core-ojson.properties | 3 - .../src/main/resources/core-oracle.properties | 3 - .../main/resources/core-pgjsonb.properties | 3 - .../main/resources/core-postgresql.properties | 3 - .../main/resources/core-sqlserver.properties | 3 - docker/core/src/main/resources/log4j2.xml | 3 - docker/wa/LICENSE | 5 - docker/wa/NOTICE | 5 - .../java/job/ElasticsearchReindex.java | 4 +- .../java/job/OpenSearchReindex.java | 4 +- fit/build-tools/pom.xml | 2 +- fit/core-reference/pom.xml | 2 +- .../reference/SampleReportJobDelegate.java | 4 +- .../fit/core/reference/TestPullActions.java | 2 +- .../core/reference/TestSampleJobDelegate.java | 17 +- .../main/resources/core-embedded.properties | 4 - .../main/resources/core-mariadb.properties | 3 - .../src/main/resources/core-myjson.properties | 3 - .../src/main/resources/core-mysql.properties | 3 - .../src/main/resources/core-ojson.properties | 3 - .../src/main/resources/core-oracle.properties | 3 - .../main/resources/core-pgjsonb.properties | 3 - .../main/resources/core-postgres.properties | 3 - .../main/resources/core-sqlserver.properties | 3 - .../main/resources/core-wildfly.properties | 2 +- .../src/main/resources/log4j2.xml | 3 - .../syncope/fit/core/AbstractTaskITCase.java | 10 +- .../syncope/fit/core/PullTaskITCase.java | 23 +- .../syncope/fit/core/SchedTaskITCase.java | 25 +- pom.xml | 92 ++---- .../reference-guide/concepts/reports.adoc | 2 +- .../reference-guide/concepts/tasks.adoc | 8 +- .../configurationparameters.adoc | 2 +- .../reference-guide/configuration/dbms.adoc | 24 -- .../configuration/highavailability.adoc | 23 -- .../wa/starter/SyncopeWAApplication.java | 48 ++- .../starter/config/WARefreshContextJob.java | 41 +-- 170 files changed, 1333 insertions(+), 3439 deletions(-) create mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingDriver.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jClient.java delete mode 100644 core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jTransactionManager.java create mode 100644 core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionContext.java rename core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/{JobDelegate.java => JobExecutionException.java} (67%) delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java create mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/Job.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SchedulerDBInit.java delete mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeSpringBeanJobFactory.java create mode 100644 core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskScheduler.java delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_h2.sql delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_mysql.sql delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_oracle.sql delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_postgres.sql delete mode 100644 core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql create mode 100644 core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java diff --git a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java index ff77c418aa..153a4d4118 100644 --- a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java +++ b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/SyncopeConsoleSession.java @@ -33,8 +33,6 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.stream.Collectors; import org.apache.commons.lang3.ArrayUtils; @@ -64,6 +62,7 @@ import org.apache.wicket.request.Request; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.TaskRejectedException; import org.springframework.util.CollectionUtils; @@ -104,7 +103,7 @@ public static SyncopeConsoleSession get() { protected final Map, Object> services = Collections.synchronizedMap(new HashMap<>()); - protected final ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); + protected final SimpleAsyncTaskExecutor executor; protected String domain; @@ -132,6 +131,9 @@ public SyncopeConsoleSession(final Request request) { super(request); clientFactory = SyncopeWebApplication.get().newClientFactory(); + + executor = new SimpleAsyncTaskExecutor(); + executor.setVirtualThreads(true); } protected String message(final SyncopeClientException sce) { @@ -273,7 +275,6 @@ public void invalidate() { } cleanup(); } - executor.shutdown(); super.invalidate(); } diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy index c8ee0be506..3d7de66769 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPullActions.groovy @@ -27,12 +27,12 @@ import org.apache.syncope.common.lib.to.OrgUnit import org.apache.syncope.common.lib.to.Provision import org.apache.syncope.common.lib.to.ProvisioningReport import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask +import org.apache.syncope.core.provisioning.api.job.JobExecutionException import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningActions import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile import org.apache.syncope.core.provisioning.api.pushpull.PullActions import org.identityconnectors.framework.common.objects.SyncDelta -import org.quartz.JobExecutionException @CompileStatic class MyPullActions implements PullActions { diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushActions.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushActions.groovy index 5eebcdbea3..9d4cbeb0ea 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushActions.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyPushActions.groovy @@ -21,9 +21,9 @@ import groovy.transform.CompileStatic import java.util.Set import org.apache.syncope.common.lib.to.ProvisioningReport import org.apache.syncope.core.persistence.api.entity.Entity +import org.apache.syncope.core.provisioning.api.job.JobExecutionException import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile import org.apache.syncope.core.provisioning.api.pushpull.PushActions -import org.quartz.JobExecutionException @CompileStatic class MyPushActions implements PushActions { diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportJobDelegate.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportJobDelegate.groovy index 51f0621a3a..1d9a9b7f29 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportJobDelegate.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MyReportJobDelegate.groovy @@ -18,19 +18,12 @@ */ import groovy.transform.CompileStatic import org.apache.syncope.common.lib.report.ReportConf +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext +import org.apache.syncope.core.provisioning.api.job.JobExecutionException import org.apache.syncope.core.provisioning.api.job.report.ReportJobDelegate -import org.quartz.JobExecutionContext -import org.quartz.JobExecutionException @CompileStatic class MyReportJobDelegate implements ReportJobDelegate { - - void interrupt() { - } - - boolean isInterrupted() { - return false - } void setConf(ReportConf conf) { diff --git a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy index c49983ad39..7012accddb 100644 --- a/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy +++ b/client/idrepo/console/src/main/resources/org/apache/syncope/client/console/implementations/MySchedTaskJobDelegate.groovy @@ -18,20 +18,13 @@ */ import groovy.transform.CompileStatic import org.apache.syncope.common.lib.types.TaskType +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext +import org.apache.syncope.core.provisioning.api.job.JobExecutionException import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate -import org.quartz.JobExecutionContext -import org.quartz.JobExecutionException @CompileStatic class MySchedTaskJobDelegate implements SchedTaskJobDelegate { - void interrupt() { - } - - boolean isInterrupted() { - return false - } - @Override void execute(TaskType taskType, String taskKey, boolean dryRun, JobExecutionContext context) throws JobExecutionException { diff --git a/common/idrepo/lib/pom.xml b/common/idrepo/lib/pom.xml index b767fece2f..e02675d4cf 100644 --- a/common/idrepo/lib/pom.xml +++ b/common/idrepo/lib/pom.xml @@ -49,7 +49,7 @@ under the License. io.swagger.core.v3 - swagger-annotations + swagger-annotations-jakarta diff --git a/common/keymaster/client-api/src/main/resources/defaultContent.jpa.xml b/common/keymaster/client-api/src/main/resources/defaultContent.jpa.xml index babe8adb59..a9dd041d14 100644 --- a/common/keymaster/client-api/src/main/resources/defaultContent.jpa.xml +++ b/common/keymaster/client-api/src/main/resources/defaultContent.jpa.xml @@ -43,6 +43,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + diff --git a/common/keymaster/client-api/src/main/resources/defaultContent.neo4j.xml b/common/keymaster/client-api/src/main/resources/defaultContent.neo4j.xml index da0ba9913b..71507b556d 100644 --- a/common/keymaster/client-api/src/main/resources/defaultContent.neo4j.xml +++ b/common/keymaster/client-api/src/main/resources/defaultContent.neo4j.xml @@ -42,6 +42,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + diff --git a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java index c1ee8a30d6..48f7f8529f 100644 --- a/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java +++ b/core/idm/logic/src/main/java/org/apache/syncope/core/logic/ReconciliationLogic.java @@ -75,6 +75,7 @@ import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.VirAttrHandler; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ConstantReconFilterBuilder; import org.apache.syncope.core.provisioning.api.pushpull.KeyValueReconFilterBuilder; import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder; @@ -104,7 +105,6 @@ import org.identityconnectors.framework.common.objects.Uid; import org.identityconnectors.framework.common.objects.filter.Filter; import org.identityconnectors.framework.spi.SearchResultsHandler; -import org.quartz.JobExecutionException; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.security.access.prepost.PreAuthorize; diff --git a/core/idrepo/logic/pom.xml b/core/idrepo/logic/pom.xml index dd1bbcbbdf..bf4860f8f2 100644 --- a/core/idrepo/logic/pom.xml +++ b/core/idrepo/logic/pom.xml @@ -46,7 +46,11 @@ under the License. org.springframework spring-context-support - + + org.springframework + spring-jdbc + + org.aspectj aspectjweaver diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java index 8258fc4e21..5ca851a1d8 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractExecutableLogic.java @@ -27,15 +27,15 @@ import org.apache.syncope.common.rest.api.batch.BatchResponseItem; import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; public abstract class AbstractExecutableLogic extends AbstractJobLogic { public AbstractExecutableLogic( final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO) { super(jobManager, scheduler, jobStatusDAO); diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java index 231383e168..0b2b756ed6 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/AbstractJobLogic.java @@ -18,8 +18,10 @@ */ package org.apache.syncope.core.logic; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.apache.commons.lang3.tuple.Triple; import org.apache.syncope.common.lib.to.EntityTO; import org.apache.syncope.common.lib.to.JobTO; @@ -27,32 +29,25 @@ import org.apache.syncope.common.lib.types.JobType; import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; import org.apache.syncope.core.persistence.api.entity.JobStatus; -import org.apache.syncope.core.persistence.api.utils.FormatUtils; import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.job.SystemLoadReporterJob; import org.apache.syncope.core.provisioning.java.job.TaskJob; import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob; import org.apache.syncope.core.provisioning.java.job.report.ReportJob; -import org.quartz.JobDetail; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.impl.matchers.GroupMatcher; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; +import org.apache.syncope.core.spring.security.AuthContextUtils; abstract class AbstractJobLogic extends AbstractTransactionalLogic { protected final JobManager jobManager; - protected final SchedulerFactoryBean scheduler; + protected final SyncopeTaskScheduler scheduler; protected final JobStatusDAO jobStatusDAO; protected AbstractJobLogic( final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO) { this.jobManager = jobManager; @@ -60,100 +55,76 @@ protected AbstractJobLogic( this.jobStatusDAO = jobStatusDAO; } - protected abstract Triple getReference(JobKey jobKey); + protected abstract Triple getReference(String jobName); - protected JobTO getJobTO(final JobKey jobKey, final boolean includeCustom) throws SchedulerException { + protected Optional getJobTO(final String jobName, final boolean includeCustom) { JobTO jobTO = null; - if (scheduler.getScheduler().checkExists(jobKey)) { - Triple reference = getReference(jobKey); + if (scheduler.contains(AuthContextUtils.getDomain(), jobName)) { + Triple reference = getReference(jobName); if (reference != null) { jobTO = new JobTO(); jobTO.setType(reference.getLeft()); jobTO.setRefKey(reference.getMiddle()); jobTO.setRefDesc(reference.getRight()); } else if (includeCustom) { - JobDetail jobDetail = scheduler.getScheduler().getJobDetail(jobKey); - if (!TaskJob.class.isAssignableFrom(jobDetail.getJobClass()) - && !ReportJob.class.isAssignableFrom(jobDetail.getJobClass()) - && !SystemLoadReporterJob.class.isAssignableFrom(jobDetail.getJobClass()) - && !NotificationJob.class.isAssignableFrom(jobDetail.getJobClass())) { - + Optional> jobClass = scheduler.getJobClass(AuthContextUtils.getDomain(), jobName). + filter(jc -> !TaskJob.class.isAssignableFrom(jc) + && !ReportJob.class.isAssignableFrom(jc) + && !SystemLoadReporterJob.class.isAssignableFrom(jc) + && !NotificationJob.class.isAssignableFrom(jc)); + if (jobClass.isPresent()) { jobTO = new JobTO(); jobTO.setType(JobType.CUSTOM); - jobTO.setRefKey(jobKey.getName()); - jobTO.setRefDesc(jobDetail.getJobClass().getName()); + jobTO.setRefKey(jobName); + jobTO.setRefDesc(jobClass.get().getName()); } } if (jobTO != null) { - List jobTriggers = scheduler.getScheduler().getTriggersOfJob(jobKey); - if (jobTriggers.isEmpty()) { - jobTO.setScheduled(false); - } else { + Optional nextTrigger = scheduler.getNextTrigger(AuthContextUtils.getDomain(), jobName); + if (nextTrigger.isPresent()) { jobTO.setScheduled(true); - jobTO.setStart(jobTriggers.get(0).getStartTime().toInstant().atOffset(FormatUtils.DEFAULT_OFFSET)); + jobTO.setStart(nextTrigger.get()); + } else { + jobTO.setScheduled(false); } - jobTO.setRunning(jobManager.isRunning(jobKey)); - - jobTO.setStatus("UNKNOWN"); - if (jobTO.isRunning()) { - try { - jobTO.setStatus(jobStatusDAO.findById(jobTO.getRefDesc()). - map(JobStatus::getStatus). - orElse(jobTO.getStatus())); - } catch (NoSuchBeanDefinitionException e) { - LOG.warn("Could not find job {} implementation", jobKey, e); - } - } + jobTO.setRunning(jobManager.isRunning(jobName)); + + jobTO.setStatus(jobStatusDAO.findById(jobName).map(JobStatus::getStatus).orElse("UNKNOWN")); } } - return jobTO; + return Optional.ofNullable(jobTO); } protected List doListJobs(final boolean includeCustom) { List jobTOs = new ArrayList<>(); - try { - for (JobKey jobKey : scheduler.getScheduler(). - getJobKeys(GroupMatcher.jobGroupEquals(Scheduler.DEFAULT_GROUP))) { - - JobTO jobTO = getJobTO(jobKey, includeCustom); - if (jobTO != null) { - jobTOs.add(jobTO); - } - } - } catch (SchedulerException e) { - LOG.debug("Problems while retrieving scheduled jobs", e); + for (String jobName : scheduler.getJobNames(AuthContextUtils.getDomain())) { + getJobTO(jobName, includeCustom).ifPresent(jobTOs::add); } return jobTOs; } - protected void doActionJob(final JobKey jobKey, final JobAction action) { - try { - if (scheduler.getScheduler().checkExists(jobKey)) { - switch (action) { - case START: - scheduler.getScheduler().triggerJob(jobKey); - break; + protected void doActionJob(final String jobName, final JobAction action) { + if (scheduler.contains(AuthContextUtils.getDomain(), jobName)) { + switch (action) { + case START -> + scheduler.start(AuthContextUtils.getDomain(), jobName); - case STOP: - scheduler.getScheduler().interrupt(jobKey); - break; + case STOP -> + scheduler.cancel(AuthContextUtils.getDomain(), jobName); - case DELETE: - scheduler.getScheduler().deleteJob(jobKey); - break; + case DELETE -> + scheduler.delete(AuthContextUtils.getDomain(), jobName); - default: + default -> { } - } else { - LOG.warn("Could not find job {}", jobKey); } - } catch (SchedulerException e) { - LOG.debug("Problems during {} operation on job {}", action.toString(), jobKey, e); + } else { + LOG.warn("Could not find job {}", jobName); } } } diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java index edbc18263b..676847158e 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/GroupLogic.java @@ -37,8 +37,6 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.IdRepoEntitlement; -import org.apache.syncope.common.lib.types.IdRepoImplementationType; -import org.apache.syncope.common.lib.types.ImplementationEngine; import org.apache.syncope.common.lib.types.JobType; import org.apache.syncope.common.lib.types.PatchOperation; import org.apache.syncope.common.lib.types.ProvisionAction; @@ -48,6 +46,7 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.GroupDAO; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; +import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.persistence.api.dao.RealmSearchDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; @@ -64,15 +63,13 @@ import org.apache.syncope.core.provisioning.api.data.GroupDataBinder; import org.apache.syncope.core.provisioning.api.data.TaskDataBinder; import org.apache.syncope.core.provisioning.api.job.JobManager; -import org.apache.syncope.core.provisioning.api.job.JobNamer; import org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.utils.TemplateUtils; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecurityProperties; -import org.quartz.JobDataMap; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; @@ -102,7 +99,7 @@ public class GroupLogic extends AbstractAnyLogic { protected final JobManager jobManager; - protected final SchedulerFactoryBean scheduler; + protected final SyncopeTaskScheduler scheduler; protected final EntityFactory entityFactory; @@ -120,7 +117,7 @@ public GroupLogic( final GroupProvisioningManager provisioningManager, final TaskDataBinder taskDataBinder, final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final EntityFactory entityFactory) { super(realmSearchDAO, anyTypeDAO, templateUtils); @@ -403,17 +400,10 @@ public ProvisioningResult provision( public ExecTO provisionMembers(final String key, final ProvisionAction action) { Group group = groupDAO.findById(key).orElseThrow(() -> new NotFoundException("Group " + key)); - Implementation jobDelegate = implementationDAO.findByType(IdRepoImplementationType.TASKJOB_DELEGATE).stream(). - filter(impl -> GroupMemberProvisionTaskJobDelegate.class.getName().equals(impl.getBody())). - findFirst().orElseGet(() -> { - Implementation groupMemberProvision = entityFactory.newEntity(Implementation.class); - groupMemberProvision.setKey(GroupMemberProvisionTaskJobDelegate.class.getSimpleName()); - groupMemberProvision.setEngine(ImplementationEngine.JAVA); - groupMemberProvision.setType(IdRepoImplementationType.TASKJOB_DELEGATE); - groupMemberProvision.setBody(GroupMemberProvisionTaskJobDelegate.class.getName()); - groupMemberProvision = implementationDAO.save(groupMemberProvision); - return groupMemberProvision; - }); + Implementation jobDelegate = implementationDAO.findById( + GroupMemberProvisionTaskJobDelegate.class.getSimpleName()). + orElseThrow(() -> new NotFoundException( + "Implementation " + GroupMemberProvisionTaskJobDelegate.class.getSimpleName())); String name = (action == ProvisionAction.DEPROVISION ? "de" : "") + "provision members of group " + group.getName(); @@ -428,18 +418,13 @@ public ExecTO provisionMembers(final String key, final ProvisionAction action) { task = taskDAO.save(task); try { - Map jobDataMap = jobManager.register( + jobManager.register( task, - null, - AuthContextUtils.getUsername()); - - jobDataMap.put(JobManager.DRY_RUN_JOBDETAIL_KEY, false); - jobDataMap.put(GroupMemberProvisionTaskJobDelegate.GROUP_KEY_JOBDETAIL_KEY, key); - jobDataMap.put(GroupMemberProvisionTaskJobDelegate.ACTION_JOBDETAIL_KEY, action); - - scheduler.getScheduler().triggerJob( - JobNamer.getJobKey(task), - new JobDataMap(jobDataMap)); + OffsetDateTime.now(), + AuthContextUtils.getUsername(), + false, + Map.of(GroupMemberProvisionTaskJobDelegate.GROUP_KEY_JOBDETAIL_KEY, key, + GroupMemberProvisionTaskJobDelegate.ACTION_JOBDETAIL_KEY, action)); } catch (Exception e) { LOG.error("While executing task {}", task, e); @@ -453,7 +438,7 @@ public ExecTO provisionMembers(final String key, final ProvisionAction action) { result.setRefKey(task.getKey()); result.setRefDesc(taskDataBinder.buildRefDesc(task)); result.setStart(OffsetDateTime.now()); - result.setStatus("JOB_FIRED"); + result.setStatus(JobStatusDAO.JOB_FIRED_STATUS); result.setMessage("Job fired; waiting for results..."); return result; diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java index f726e813bc..203f13c678 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/IdRepoLogicContext.java @@ -107,6 +107,7 @@ import org.apache.syncope.core.provisioning.api.propagation.PropagationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; import org.apache.syncope.core.provisioning.api.rules.RuleEnforcer; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.utils.TemplateUtils; import org.apache.syncope.core.spring.security.SecurityProperties; import org.slf4j.Logger; @@ -116,7 +117,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; @EnableAspectJAutoProxy(proxyTargetClass = false) @Configuration(proxyBeanMethods = false) @@ -330,7 +330,7 @@ public GroupLogic groupLogic( final GroupProvisioningManager provisioningManager, final TaskDataBinder taskDataBinder, final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final EntityFactory entityFactory) { return new GroupLogic( @@ -392,7 +392,7 @@ public NotificationLogic notificationLogic( final NotificationDataBinder binder, final JobManager jobManager, final JobStatusDAO jobStatusDAO, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final NotificationDAO notificationDAO) { return new NotificationLogic(jobManager, scheduler, jobStatusDAO, notificationDAO, binder); @@ -449,7 +449,7 @@ public RelationshipTypeLogic relationshipTypeLogic( public ReportLogic reportLogic( final JobManager jobManager, final ReportDataBinder binder, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO, final ReportDAO reportDAO, final EntityFactory entityFactory, @@ -524,7 +524,7 @@ public TaskLogic taskLogic( final PropagationTaskExecutor taskExecutor, final TaskExecDAO taskExecDAO, final TaskDAO taskDAO, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO, final ExternalResourceDAO externalResourceDAO, final NotificationJobDelegate notificationJobDelegate, diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java index 2679748a3e..05ea5c618b 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/NotificationLogic.java @@ -33,9 +33,8 @@ import org.apache.syncope.core.persistence.api.entity.Notification; import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder; import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob; -import org.quartz.JobKey; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; @@ -47,7 +46,7 @@ public class NotificationLogic extends AbstractJobLogic { public NotificationLogic( final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO, final NotificationDAO notificationDAO, final NotificationDataBinder binder) { @@ -100,8 +99,8 @@ public NotificationTO delete(final String key) { } @Override - protected Triple getReference(final JobKey jobKey) { - return JobManager.NOTIFICATION_JOB.equals(jobKey) + protected Triple getReference(final String jobName) { + return JobManager.NOTIFICATION_JOB.equals(jobName) ? Triple.of(JobType.NOTIFICATION, null, NotificationJob.class.getSimpleName()) : null; } diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java index 8f34d58af0..edd18370f2 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/ReportLogic.java @@ -25,7 +25,7 @@ import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Optional; import java.util.zip.ZipInputStream; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; @@ -52,13 +52,11 @@ import org.apache.syncope.core.provisioning.api.data.ReportDataBinder; import org.apache.syncope.core.provisioning.api.job.JobManager; import org.apache.syncope.core.provisioning.api.job.JobNamer; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.job.report.ReportJob; import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.quartz.JobKey; -import org.quartz.SchedulerException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; @@ -74,7 +72,7 @@ public class ReportLogic extends AbstractExecutableLogic { public ReportLogic( final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO, final ReportDAO reportDAO, final ReportExecDAO reportExecDAO, @@ -98,9 +96,10 @@ public ReportTO create(final ReportTO reportTO) { jobManager.register( report, null, - AuthContextUtils.getUsername()); + AuthContextUtils.getUsername(), + false); } catch (Exception e) { - LOG.error("While registering quartz job for report " + report.getKey(), e); + LOG.error("While registering job for report " + report.getKey(), e); SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); sce.getElements().add(e.getMessage()); @@ -121,9 +120,10 @@ public ReportTO update(final ReportTO reportTO) { jobManager.register( report, null, - AuthContextUtils.getUsername()); + AuthContextUtils.getUsername(), + false); } catch (Exception e) { - LOG.error("While registering quartz job for report " + report.getKey(), e); + LOG.error("While registering job for report " + report.getKey(), e); SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); sce.getElements().add(e.getMessage()); @@ -160,15 +160,11 @@ public ExecTO execute(final String key, final OffsetDateTime startAt, final bool } try { - Map jobDataMap = jobManager.register( + jobManager.register( report, - startAt, - AuthContextUtils.getUsername()); - jobDataMap.put(JobManager.DRY_RUN_JOBDETAIL_KEY, dryRun); - - if (startAt == null) { - scheduler.getScheduler().triggerJob(JobNamer.getJobKey(report)); - } + Optional.ofNullable(startAt).orElseGet(() -> OffsetDateTime.now()), + AuthContextUtils.getUsername(), + dryRun); } catch (Exception e) { LOG.error("While executing report {}", report, e); @@ -182,7 +178,7 @@ public ExecTO execute(final String key, final OffsetDateTime startAt, final bool result.setRefKey(report.getKey()); result.setRefDesc(binder.buildRefDesc(report)); result.setStart(OffsetDateTime.now()); - result.setStatus("JOB_FIRED"); + result.setStatus(JobStatusDAO.JOB_FIRED_STATUS); result.setMessage("Job fired; waiting for results..."); result.setExecutor(AuthContextUtils.getUsername()); return result; @@ -308,11 +304,11 @@ public List deleteExecutions( } @Override - protected Triple getReference(final JobKey jobKey) { - String key = JobNamer.getReportKeyFromJobName(jobKey.getName()); + protected Triple getReference(final String jobName) { + String key = JobNamer.getReportKeyFromJobName(jobName); return reportDAO.findById(key). - map(f -> Triple.of(JobType.REPORT, key, binder.buildRefDesc(f))).orElse(null); + map(r -> Triple.of(JobType.REPORT, key, binder.buildRefDesc(r))).orElse(null); } @PreAuthorize("hasRole('" + IdRepoEntitlement.REPORT_LIST + "')") @@ -324,23 +320,10 @@ public List listJobs() { @PreAuthorize("hasRole('" + IdRepoEntitlement.REPORT_READ + "')") @Override public JobTO getJob(final String key) { - Report report = reportDAO.findById(key). - orElseThrow(() -> new NotFoundException("Report " + key)); - - JobTO jobTO = null; - try { - jobTO = getJobTO(JobNamer.getJobKey(report), false); - } catch (SchedulerException e) { - LOG.error("Problems while retrieving scheduled job {}", JobNamer.getJobKey(report), e); + Report report = reportDAO.findById(key).orElseThrow(() -> new NotFoundException("Report " + key)); - SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); - sce.getElements().add(e.getMessage()); - throw sce; - } - if (jobTO == null) { - throw new NotFoundException("Job for report " + key); - } - return jobTO; + return getJobTO(JobNamer.getJobName(report), false). + orElseThrow(() -> new NotFoundException("Job for report " + key)); } @PreAuthorize("hasRole('" + IdRepoEntitlement.REPORT_EXECUTE + "')") @@ -349,7 +332,7 @@ public void actionJob(final String key, final JobAction action) { Report report = reportDAO.findById(key). orElseThrow(() -> new NotFoundException("Report " + key)); - doActionJob(JobNamer.getJobKey(report), action); + doActionJob(JobNamer.getJobName(report), action); } @Override diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java index e4b42233fe..e2a5c89b45 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/TaskLogic.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Triple; @@ -68,17 +69,14 @@ import org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskExecutor; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.DelegatedAdministrationException; import org.identityconnectors.framework.common.objects.ObjectClass; -import org.quartz.JobDataMap; -import org.quartz.JobKey; -import org.quartz.SchedulerException; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; @@ -102,7 +100,7 @@ public class TaskLogic extends AbstractExecutableLogic { public TaskLogic( final JobManager jobManager, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final JobStatusDAO jobStatusDAO, final TaskDAO taskDAO, final TaskExecDAO taskExecDAO, @@ -152,9 +150,11 @@ public T createSchedTask(final TaskType type, final T ta jobManager.register( task, task.getStartAt(), - AuthContextUtils.getUsername()); + AuthContextUtils.getUsername(), + false, + Map.of()); } catch (Exception e) { - LOG.error("While registering quartz job for task " + task.getKey(), e); + LOG.error("While registering job for task " + task.getKey(), e); SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); sce.getElements().add(e.getMessage()); @@ -187,9 +187,11 @@ public T updateSchedTask(final TaskType type, final Sche jobManager.register( task, task.getStartAt(), - AuthContextUtils.getUsername()); + AuthContextUtils.getUsername(), + false, + Map.of()); } catch (Exception e) { - LOG.error("While registering quartz job for task " + task.getKey(), e); + LOG.error("While registering job for task " + task.getKey(), e); SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); sce.getElements().add(e.getMessage()); @@ -325,15 +327,12 @@ public ExecTO execute(final String key, final OffsetDateTime startAt, final bool } try { - Map jobDataMap = jobManager.register( + jobManager.register( (SchedTask) task, - startAt, - executor); - jobDataMap.put(JobManager.DRY_RUN_JOBDETAIL_KEY, dryRun); - - if (startAt == null) { - scheduler.getScheduler().triggerJob(JobNamer.getJobKey(task), new JobDataMap(jobDataMap)); - } + Optional.ofNullable(startAt).orElseGet(() -> OffsetDateTime.now()), + executor, + dryRun, + Map.of()); } catch (Exception e) { LOG.error("While executing task {}", task, e); @@ -348,7 +347,7 @@ public ExecTO execute(final String key, final OffsetDateTime startAt, final bool result.setRefDesc(binder.buildRefDesc(task)); result.setStart(OffsetDateTime.now()); result.setExecutor(executor); - result.setStatus("JOB_FIRED"); + result.setStatus(JobStatusDAO.JOB_FIRED_STATUS); result.setMessage("Job fired; waiting for results..."); break; @@ -478,13 +477,11 @@ public List deleteExecutions( } @Override - protected Triple getReference(final JobKey jobKey) { - String key = JobNamer.getTaskKeyFromJobName(jobKey.getName()); + protected Triple getReference(final String jobName) { + String key = JobNamer.getTaskKeyFromJobName(jobName); - Task task = taskDAO.findById(key).orElse(null); - return task == null || !(task instanceof SchedTask) - ? null - : Triple.of(JobType.TASK, key, binder.buildRefDesc(task)); + return taskDAO.findById(key).filter(SchedTask.class::isInstance). + map(t -> Triple.of(JobType.TASK, key, binder.buildRefDesc(t))).orElse(null); } @PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_LIST + "')") @@ -502,20 +499,8 @@ public JobTO getJob(final String key) { securityChecks(IdRepoEntitlement.TASK_READ, macroTask.getRealm().getFullPath()); } - JobTO jobTO = null; - try { - jobTO = getJobTO(JobNamer.getJobKey(task), false); - } catch (SchedulerException e) { - LOG.error("Problems while retrieving scheduled job {}", JobNamer.getJobKey(task), e); - - SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Scheduling); - sce.getElements().add(e.getMessage()); - throw sce; - } - if (jobTO == null) { - throw new NotFoundException("Job for task " + key); - } - return jobTO; + return getJobTO(JobNamer.getJobName(task), false). + orElseThrow(() -> new NotFoundException("Job for task " + key)); } @PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_EXECUTE + "')") @@ -527,7 +512,7 @@ public void actionJob(final String key, final JobAction action) { securityChecks(IdRepoEntitlement.TASK_EXECUTE, macroTask.getRealm().getFullPath()); } - doActionJob(JobNamer.getJobKey(task), action); + doActionJob(JobNamer.getJobName(task), action); } @PreAuthorize("hasRole('" + IdRepoEntitlement.TASK_DELETE + "')") diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java index 11180ad54c..38e5587548 100644 --- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java +++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/job/MacroRunJobDelegate.java @@ -29,11 +29,11 @@ import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.task.MacroTask; import org.apache.syncope.core.persistence.api.entity.task.TaskExec; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate; import org.apache.syncope.core.spring.implementation.ImplementationManager; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class MacroRunJobDelegate extends AbstractSchedTaskJobDelegate { diff --git a/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/ReportLogicTest.java b/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/ReportLogicTest.java index 56f7cb755d..33d9e4466b 100644 --- a/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/ReportLogicTest.java +++ b/core/idrepo/logic/src/test/java/org/apache/syncope/core/logic/ReportLogicTest.java @@ -28,12 +28,12 @@ import java.io.IOException; import java.io.OutputStream; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.to.ReportTO; import org.apache.syncope.common.lib.types.IdMEntitlement; -import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.job.report.ReportJobDelegate; import org.apache.syncope.core.provisioning.java.job.report.AbstractReportJobDelegate; import org.apache.syncope.core.spring.ApplicationContextProvider; @@ -42,9 +42,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; @@ -115,9 +112,8 @@ public void executeAndExport() throws Exception { report = logic.read(report.getKey()); assertTrue(report.getExecutions().isEmpty()); - JobDataMap jobDataMap = new JobDataMap(Map.of(JobManager.EXECUTOR_KEY, "test")); JobExecutionContext ctx = mock(JobExecutionContext.class); - when(ctx.getMergedJobDataMap()).thenReturn(jobDataMap); + when(ctx.getExecutor()).thenReturn("test"); ReportJobDelegate delegate = ApplicationContextProvider.getBeanFactory().createBean(TestReportJobDelegate.class); diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/MDCInInterceptor.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/MDCInInterceptor.java index 5117610665..da13da7e30 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/MDCInInterceptor.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/MDCInInterceptor.java @@ -23,7 +23,7 @@ import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; -import org.apache.syncope.core.provisioning.api.job.JobDelegate; +import org.apache.syncope.core.provisioning.java.job.Job; import org.apache.syncope.core.spring.security.SecureRandomUtils; import org.slf4j.MDC; @@ -53,6 +53,6 @@ public void handleMessage(final Message message) throws Fault { exchange.put(KEY_EXCHANGE_ID, exchangeId); } - MDC.put(JobDelegate.OPERATION_ID, exchangeId); + MDC.put(Job.OPERATION_ID, exchangeId); } } diff --git a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java index 6d796ce8ee..49d18996fc 100644 --- a/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java +++ b/core/idrepo/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/SyncopeOpenApiCustomizer.java @@ -20,7 +20,9 @@ import io.swagger.v3.oas.integration.api.OpenAPIConfiguration; import io.swagger.v3.oas.models.ExternalDocumentation; +import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.Paths; import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.media.ArraySchema; import io.swagger.v3.oas.models.media.Content; @@ -70,6 +72,15 @@ public OpenAPIConfiguration customize(final OpenAPIConfiguration configuration) return configuration; } + @Override + public void customize(final OpenAPI oas) { + if (oas.getPaths() == null) { + oas.setPaths(new Paths()); + } + + super.customize(oas); + } + @Override protected void addParameters(final List parameters) { Optional domainHeaderParameter = parameters.stream(). diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/JobStatusDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/JobStatusDAO.java index 32311f070d..40114748d7 100644 --- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/JobStatusDAO.java +++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/JobStatusDAO.java @@ -21,4 +21,10 @@ import org.apache.syncope.core.persistence.api.entity.JobStatus; public interface JobStatusDAO extends DAO { + + String JOB_FIRED_STATUS = "JOB_FIRED"; + + boolean lock(String key); + + void unlock(String key); } diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java index 1b26a60c3c..a1e3ecf7f7 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java +++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/MyJPAJSONPersistenceContext.java @@ -39,12 +39,12 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtMyJSONImpl; import org.apache.syncope.core.persistence.jpa.entity.MyJPAJSONEntityFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; -@ConditionalOnExpression("#{'${provisioning.quartz.sql}' matches '.*mysql.*'}") +@ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver") public class MyJPAJSONPersistenceContext extends JPAJSONPersistenceContext { @ConditionalOnMissingBean(name = "myJPAJSONEntityFactory") diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java index 028bdff336..7ae9cd72d9 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java +++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/OJPAJSONPersistenceContext.java @@ -39,12 +39,12 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtOJSONImpl; import org.apache.syncope.core.persistence.jpa.entity.OJPAJSONEntityFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; -@ConditionalOnExpression("#{'${provisioning.quartz.sql}' matches '.*oracle.*'}") +@ConditionalOnClass(name = "oracle.jdbc.OracleDriver") public class OJPAJSONPersistenceContext extends JPAJSONPersistenceContext { @ConditionalOnMissingBean(name = "oJPAJSONEntityFactory") diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java index 3b8e10e4a7..808fd970b0 100644 --- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java +++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/PGJPAJSONPersistenceContext.java @@ -39,12 +39,12 @@ import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExt; import org.apache.syncope.core.persistence.jpa.dao.repo.PlainSchemaRepoExtPGJSONImpl; import org.apache.syncope.core.persistence.jpa.entity.PGJPAJSONEntityFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; -@ConditionalOnExpression("#{'${provisioning.quartz.sql}' matches '.*postgres.*'}") +@ConditionalOnClass(name = "org.postgresql.Driver") public class PGJPAJSONPersistenceContext extends JPAJSONPersistenceContext { @ConditionalOnMissingBean(name = "pgJPAJSONEntityFactory") diff --git a/core/persistence-jpa-json/src/main/resources/core-myjson.properties b/core/persistence-jpa-json/src/main/resources/core-myjson.properties index ad42d0562f..e4bfef36fc 100644 --- a/core/persistence-jpa-json/src/main/resources/core-myjson.properties +++ b/core/persistence-jpa-json/src/main/resources/core-myjson.properties @@ -28,6 +28,3 @@ persistence.domain[0].orm=META-INF/spring-orm-myjson.xml persistence.domain[0].auditSql=audit_myjson.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql diff --git a/core/persistence-jpa-json/src/main/resources/core-ojson.properties b/core/persistence-jpa-json/src/main/resources/core-ojson.properties index 4da7b2e9af..b56a86a7d6 100644 --- a/core/persistence-jpa-json/src/main/resources/core-ojson.properties +++ b/core/persistence-jpa-json/src/main/resources/core-ojson.properties @@ -29,6 +29,3 @@ persistence.domain[0].orm=META-INF/spring-orm-ojson.xml persistence.domain[0].auditSql=audit_ojson.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql diff --git a/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties b/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties index d0254a98a4..7f2cb06b4d 100644 --- a/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties +++ b/core/persistence-jpa-json/src/main/resources/core-pgjsonb.properties @@ -28,6 +28,3 @@ persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml persistence.domain[0].auditSql=audit_pgjsonb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql diff --git a/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml b/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml index 94a8d4510d..adff54198e 100644 --- a/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml +++ b/core/persistence-jpa-json/src/main/resources/domains/jpa-json/MasterContent.xml @@ -46,6 +46,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + diff --git a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java index 6d7261e15b..df3f61773f 100644 --- a/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java +++ b/core/persistence-jpa-json/src/test/java/org/apache/syncope/core/persistence/jpa/JPAJSONTestContextCustomizer.java @@ -24,7 +24,6 @@ import org.springframework.context.annotation.AnnotatedBeanDefinitionReader; import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.MergedContextConfiguration; -import org.springframework.test.context.support.TestPropertySourceUtils; public class JPAJSONTestContextCustomizer implements ContextCustomizer { @@ -40,26 +39,6 @@ private static BeanDefinitionRegistry getBeanDefinitionRegistry(final Applicatio @Override public void customizeContext(final ConfigurableApplicationContext ctx, final MergedContextConfiguration cfg) { - switch (System.getProperty("profileId")) { - case "pgjsonb" -> - TestPropertySourceUtils.addInlinedPropertiesToEnvironment( - ctx, - "provisioning.quartz.sql=tables_postgres.sql"); - - case "myjson" -> - TestPropertySourceUtils.addInlinedPropertiesToEnvironment( - ctx, - "provisioning.quartz.sql=tables_mysql_innodb.sql"); - - case "ojson" -> - TestPropertySourceUtils.addInlinedPropertiesToEnvironment( - ctx, - "provisioning.quartz.sql=tables_oracle.sql"); - - default -> { - } - } - AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(getBeanDefinitionRegistry(ctx)); reader.registerBean(PGJPAJSONPersistenceContext.class, "PGJPAJSONPersistenceContext"); reader.registerBean(MyJPAJSONPersistenceContext.class, "MyJPAJSONPersistenceContext"); diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml index 232469af4b..2a7d5a0275 100644 --- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml @@ -689,6 +689,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + domainHolder, - final PersistenceProperties persistenceProperties, + final PersistenceProperties props, final ResourceLoader resourceLoader, final Environment env) { return new XMLContentLoader( domainHolder, - resourceLoader.getResource(persistenceProperties.getViewsXML()), - resourceLoader.getResource(persistenceProperties.getIndexesXML()), + resourceLoader.getResource(props.getViewsXML()), + resourceLoader.getResource(props.getIndexesXML()), env); } @@ -339,13 +339,13 @@ public RuntimeDomainLoader runtimeDomainLoader( @ConditionalOnMissingBean @Bean public StartupDomainLoader startupDomainLoader( - final PersistenceProperties persistenceProperties, + final PersistenceProperties props, final ResourceLoader resourceLoader, final DomainOps domainOps, final DomainHolder domainHolder, final DomainRegistry domainRegistry) { - return new StartupDomainLoader(domainOps, domainHolder, persistenceProperties, resourceLoader, domainRegistry); + return new StartupDomainLoader(domainOps, domainHolder, props, resourceLoader, domainRegistry); } @ConditionalOnMissingBean diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java index f9a7b70795..761347e301 100644 --- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java +++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAJobStatusDAO.java @@ -26,20 +26,28 @@ import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; import org.apache.syncope.core.persistence.api.entity.JobStatus; import org.apache.syncope.core.persistence.jpa.entity.JPAJobStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = Throwable.class) public class JPAJobStatusDAO implements JobStatusDAO { + protected static final Logger LOG = LoggerFactory.getLogger(JobStatusDAO.class); + protected final EntityManager entityManager; public JPAJobStatusDAO(final EntityManager entityManager) { this.entityManager = entityManager; } + @Transactional(readOnly = true) @Override public boolean existsById(final String key) { - return findById(key).isPresent(); + Query query = entityManager.createQuery( + "SELECT COUNT(e) FROM " + JPAJobStatus.class.getSimpleName() + " e WHERE e.id = :key"); + query.setParameter("key", key); + return ((Number) query.getSingleResult()).longValue() > 0; } @Transactional(readOnly = true) @@ -78,4 +86,28 @@ public void delete(final JobStatus jobStatus) { public void deleteById(final String key) { findById(key).ifPresent(this::delete); } + + @Override + public boolean lock(final String key) { + if (existsById(key)) { + return false; + } + + try { + JobStatus jobStatus = new JPAJobStatus(); + jobStatus.setKey(key); + jobStatus.setStatus(JOB_FIRED_STATUS); + save(jobStatus); + + return true; + } catch (Exception e) { + LOG.debug("Could not lock job {}", key, e); + return false; + } + } + + @Override + public void unlock(final String key) { + deleteById(key); + } } diff --git a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml index 868dd99699..434d824f62 100644 --- a/core/persistence-jpa/src/main/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/main/resources/domains/MasterContent.xml @@ -45,6 +45,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java index 42be5770e2..5401ef43f8 100644 --- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java +++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/ImplementationTest.java @@ -51,7 +51,7 @@ public void findAll() { List implementations = implementationDAO.findAll(); assertFalse(implementations.isEmpty()); - assertEquals(19, implementations.size()); + assertEquals(20, implementations.size()); implementations = implementationDAO.findByType(IdMImplementationType.PULL_ACTIONS); assertEquals(1, implementations.size()); @@ -60,7 +60,7 @@ public void findAll() { assertEquals(2, implementations.size()); implementations = implementationDAO.findByType(IdRepoImplementationType.TASKJOB_DELEGATE); - assertEquals(6, implementations.size()); + assertEquals(7, implementations.size()); implementations = implementationDAO.findByType(IdRepoImplementationType.REPORT_DELEGATE); assertEquals(1, implementations.size()); diff --git a/core/persistence-jpa/src/test/resources/core-test.properties b/core/persistence-jpa/src/test/resources/core-test.properties index bcd721e584..8234e088f0 100644 --- a/core/persistence-jpa/src/test/resources/core-test.properties +++ b/core/persistence-jpa/src/test/resources/core-test.properties @@ -42,7 +42,4 @@ persistence.domain[1].poolMinIdle=5 persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 persistence.domain[1].adminCipherAlgorithm=SHA -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_h2.sql - provisioning.connIdLocation=${syncope.connid.location} diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index f1b2734ad8..b462dda389 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -775,6 +775,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + + diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/MasterDomain.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/MasterDomain.java index d4dd9c5336..b8cdb3b2b6 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/MasterDomain.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/MasterDomain.java @@ -25,14 +25,11 @@ import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.Logging; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ResourceLoader; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager; @EnableConfigurationProperties(PersistenceProperties.class) @Configuration(proxyBeanMethods = false) @@ -50,19 +47,6 @@ public Driver masterDriver(final PersistenceProperties props) { withLogging(Logging.slf4j()).build()); } - @ConditionalOnMissingBean(name = "MasterNeo4jClient") - @Bean(name = "MasterNeo4jClient") - public Neo4jClient masterNeo4jClient( - @Qualifier("MasterDriver") - final Driver driver, - final Neo4jBookmarkManager bookmarkManager) { - - return Neo4jClient. - with(driver). - withNeo4jBookmarkManager(bookmarkManager). - build(); - } - @Bean(name = "MasterContentXML") public InputStream masterContentXML( final ResourceLoader resourceLoader, diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/Neo4jDomainRegistry.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/Neo4jDomainRegistry.java index ca8a4974c3..a485ad24de 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/Neo4jDomainRegistry.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/Neo4jDomainRegistry.java @@ -22,8 +22,6 @@ import org.apache.syncope.common.keymaster.client.api.model.Neo4jDomain; import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.DomainRegistry; -import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingNeo4jClient; -import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingNeo4jTransactionManager; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; @@ -32,9 +30,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.transaction.Neo4jBookmarkManager; -import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; public class Neo4jDomainRegistry implements DomainRegistry { @@ -78,22 +73,6 @@ public void register(final Neo4jDomain domain) { domainHolder().getDomains().put(domain.getKey(), driver); - // domainNeo4jClient - Neo4jClient neo4jClient = Neo4jClient. - with(driver). - withNeo4jBookmarkManager(ctx.getBean(Neo4jBookmarkManager.class)).build(); - registerSingleton(domain.getKey().toLowerCase() + "Neo4jClient", neo4jClient); - - // DomainRoutingNeo4jClient#add - beanFactory().getBean(DomainRoutingNeo4jClient.class).add(domain.getKey(), neo4jClient); - - // DomainRoutingTransactionManager#add - Neo4jTransactionManager transactionManager = Neo4jTransactionManager. - with(driver). - withBookmarkManager(ctx.getBean(Neo4jBookmarkManager.class)). - build(); - beanFactory().getBean(DomainRoutingNeo4jTransactionManager.class).add(domain.getKey(), transactionManager); - // domainContentXML beanFactory().registerBeanDefinition(domain.getKey() + "ContentXML", BeanDefinitionBuilder.rootBeanDefinition(ByteArrayInputStream.class). @@ -117,14 +96,6 @@ public void unregister(final String domain) { unregisterSingleton(domain + "ContentXML"); beanFactory().removeBeanDefinition(domain + "ContentXML"); - // DomainRoutingTransactionManager#remove - beanFactory().getBean(DomainRoutingNeo4jTransactionManager.class).remove(domain); - - // domainNeo4jClient - unregisterSingleton(domain + "Neo4jClient"); - // DomainRoutingNeo4jClient#remove - beanFactory().getBean(DomainRoutingNeo4jClient.class).remove(domain); - // domainDriver unregisterSingleton(domain + "Driver"); diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java index cceea022e0..01325e09a0 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/PersistenceContext.java @@ -198,8 +198,7 @@ import org.apache.syncope.core.persistence.neo4j.entity.task.Neo4jTaskUtilsFactory; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jLAPlainAttr; import org.apache.syncope.core.persistence.neo4j.entity.user.Neo4jUPlainAttr; -import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingNeo4jClient; -import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingNeo4jTransactionManager; +import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingDriver; import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator; import org.apache.syncope.core.persistence.neo4j.spring.PlainsAttrsConverter; import org.apache.syncope.core.spring.security.SecurityProperties; @@ -265,19 +264,24 @@ public Neo4jBookmarkManager bookmarkManager() { } @Primary + @Bean + public DomainRoutingDriver driver(final DomainHolder domainHolder) { + return new DomainRoutingDriver(domainHolder); + } + @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) public Neo4jClient neo4jClient( - @Qualifier("MasterNeo4jClient") - final Neo4jClient masterNeo4jClient) { + final DomainRoutingDriver driver, + final Neo4jBookmarkManager bookmarkManager) { - DomainRoutingNeo4jClient neo4jClient = new DomainRoutingNeo4jClient(); - neo4jClient.add(SyncopeConstants.MASTER_DOMAIN, masterNeo4jClient); - return neo4jClient; + return Neo4jClient. + with(driver). + withNeo4jBookmarkManager(bookmarkManager). + build(); } @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_TEMPLATE_BEAN_NAME) public Neo4jOperations neo4jTemplate( - @Qualifier(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) final Neo4jClient neo4jClient, final Neo4jMappingContext mappingContext) { @@ -286,18 +290,13 @@ public Neo4jOperations neo4jTemplate( @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) public PlatformTransactionManager transactionManager( - @Qualifier("MasterDriver") - final Driver driver, + final DomainRoutingDriver driver, final Neo4jBookmarkManager bookmarkManager) { - DomainRoutingNeo4jTransactionManager transactionManager = new DomainRoutingNeo4jTransactionManager(); - transactionManager.add( - SyncopeConstants.MASTER_DOMAIN, - Neo4jTransactionManager. - with(driver). - withBookmarkManager(bookmarkManager). - build()); - return transactionManager; + return Neo4jTransactionManager. + with(driver). + withBookmarkManager(bookmarkManager). + build(); } @Bean(name = "uPlainAttrsConverter") diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jJobStatusDAO.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jJobStatusDAO.java index 67a088162a..62d7948183 100644 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jJobStatusDAO.java +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/dao/Neo4jJobStatusDAO.java @@ -24,12 +24,16 @@ import org.apache.syncope.core.persistence.api.entity.JobStatus; import org.apache.syncope.core.persistence.neo4j.entity.Neo4jJobStatus; import org.apache.syncope.core.persistence.neo4j.spring.NodeValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.neo4j.core.Neo4jTemplate; import org.springframework.transaction.annotation.Transactional; @Transactional(rollbackFor = Throwable.class) public class Neo4jJobStatusDAO implements JobStatusDAO { + protected static final Logger LOG = LoggerFactory.getLogger(JobStatusDAO.class); + protected final Neo4jTemplate neo4jTemplate; protected final NodeValidator nodeValidator; @@ -39,6 +43,7 @@ public Neo4jJobStatusDAO(final Neo4jTemplate neo4jTemplate, final NodeValidator this.nodeValidator = nodeValidator; } + @Transactional(readOnly = true) @Override public boolean existsById(final String key) { return neo4jTemplate.existsById(key, Neo4jJobStatus.class); @@ -76,4 +81,28 @@ public void delete(final JobStatus jobStatus) { public void deleteById(final String key) { findById(key).ifPresent(this::delete); } + + @Override + public boolean lock(final String key) { + if (existsById(key)) { + return false; + } + + try { + JobStatus jobStatus = new Neo4jJobStatus(); + jobStatus.setKey(key); + jobStatus.setStatus(JOB_FIRED_STATUS); + save(jobStatus); + + return true; + } catch (Exception e) { + LOG.debug("Could not lock job {}", key, e); + return false; + } + } + + @Override + public void unlock(final String key) { + deleteById(key); + } } diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingDriver.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingDriver.java new file mode 100644 index 0000000000..2a86dfe3d0 --- /dev/null +++ b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingDriver.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.neo4j.spring; + +import java.util.concurrent.CompletionStage; +import org.apache.syncope.core.persistence.api.DomainHolder; +import org.apache.syncope.core.spring.security.AuthContextUtils; +import org.neo4j.driver.AuthToken; +import org.neo4j.driver.BaseSession; +import org.neo4j.driver.BookmarkManager; +import org.neo4j.driver.Driver; +import org.neo4j.driver.ExecutableQuery; +import org.neo4j.driver.Metrics; +import org.neo4j.driver.SessionConfig; +import org.neo4j.driver.types.TypeSystem; + +public class DomainRoutingDriver implements Driver { + + protected final DomainHolder domainHolder; + + public DomainRoutingDriver(final DomainHolder domainHolder) { + this.domainHolder = domainHolder; + } + + protected Driver delegate() { + return domainHolder.getDomains().computeIfAbsent(AuthContextUtils.getDomain(), domain -> { + throw new IllegalStateException("Could not find Driver for domain " + domain); + }); + } + + @Override + public ExecutableQuery executableQuery(final String query) { + return delegate().executableQuery(query); + } + + @Override + public BookmarkManager executableQueryBookmarkManager() { + return delegate().executableQueryBookmarkManager(); + } + + @Override + public boolean isEncrypted() { + return delegate().isEncrypted(); + } + + @Override + public T session( + final Class sessionClass, + final SessionConfig sessionConfig, + final AuthToken sessionAuthToken) { + + return delegate().session(sessionClass, sessionConfig, sessionAuthToken); + } + + @Override + public void close() { + delegate().close(); + } + + @Override + public CompletionStage closeAsync() { + return delegate().closeAsync(); + } + + @Override + public Metrics metrics() { + return delegate().metrics(); + } + + @Override + public boolean isMetricsEnabled() { + return delegate().isMetricsEnabled(); + } + + @SuppressWarnings("deprecation") + @Override + public TypeSystem defaultTypeSystem() { + return delegate().defaultTypeSystem(); + } + + @Override + public void verifyConnectivity() { + delegate().verifyConnectivity(); + } + + @Override + public CompletionStage verifyConnectivityAsync() { + return delegate().verifyConnectivityAsync(); + } + + @Override + public boolean verifyAuthentication(final AuthToken sessionAuthToken) { + return delegate().verifyAuthentication(sessionAuthToken); + } + + @Override + public boolean supportsSessionAuth() { + return delegate().supportsSessionAuth(); + } + + @Override + public boolean supportsMultiDb() { + return delegate().supportsMultiDb(); + } + + @Override + public CompletionStage supportsMultiDbAsync() { + return delegate().supportsMultiDbAsync(); + } +} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jClient.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jClient.java deleted file mode 100644 index 454456fccb..0000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jClient.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.spring; - -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Supplier; -import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.neo4j.driver.QueryRunner; -import org.springframework.data.neo4j.core.DatabaseSelection; -import org.springframework.data.neo4j.core.DatabaseSelectionProvider; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.core.UserSelection; - -public class DomainRoutingNeo4jClient implements Neo4jClient { - - protected final Map delegates = new ConcurrentHashMap<>(); - - public void add(final String domain, final Neo4jClient neo4jClient) { - delegates.put(domain, neo4jClient); - } - - public void remove(final String domain) { - delegates.remove(domain); - } - - protected Neo4jClient delegate() { - return delegates.computeIfAbsent(AuthContextUtils.getDomain(), domain -> { - throw new IllegalStateException("Could not find Neo4jClient for domain " + domain); - }); - } - - @Override - public QueryRunner getQueryRunner(final DatabaseSelection databaseSelection, final UserSelection asUser) { - return delegate().getQueryRunner(databaseSelection, asUser); - } - - @Override - public UnboundRunnableSpec query(final String cypher) { - return delegate().query(cypher); - } - - @Override - public UnboundRunnableSpec query(final Supplier cypherSupplier) { - return delegate().query(cypherSupplier); - } - - @Override - public OngoingDelegation delegateTo(final Function> callback) { - return delegate().delegateTo(callback); - } - - @Override - public DatabaseSelectionProvider getDatabaseSelectionProvider() { - return delegate().getDatabaseSelectionProvider(); - } -} diff --git a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jTransactionManager.java b/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jTransactionManager.java deleted file mode 100644 index cecff40bad..0000000000 --- a/core/persistence-neo4j/src/main/java/org/apache/syncope/core/persistence/neo4j/spring/DomainRoutingNeo4jTransactionManager.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.persistence.neo4j.spring; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.TransactionStatus; - -public class DomainRoutingNeo4jTransactionManager implements PlatformTransactionManager { - - protected final Map delegates = new ConcurrentHashMap<>(); - - public void add(final String domain, final Neo4jTransactionManager neo4jTransactionManager) { - delegates.put(domain, neo4jTransactionManager); - } - - public void remove(final String domain) { - delegates.remove(domain); - } - - protected Neo4jTransactionManager delegate() { - return delegates.computeIfAbsent(AuthContextUtils.getDomain(), domain -> { - throw new IllegalStateException("Could not find Neo4jTransactionManager for domain " + domain); - }); - } - - @Override - public TransactionStatus getTransaction(final TransactionDefinition definition) throws TransactionException { - return delegate().getTransaction(definition); - } - - @Override - public void commit(final TransactionStatus status) throws TransactionException { - delegate().commit(status); - } - - @Override - public void rollback(final TransactionStatus status) throws TransactionException { - delegate().rollback(status); - } -} diff --git a/core/persistence-neo4j/src/main/resources/domains/MasterContent.xml b/core/persistence-neo4j/src/main/resources/domains/MasterContent.xml index 94a8d4510d..adff54198e 100644 --- a/core/persistence-neo4j/src/main/resources/domains/MasterContent.xml +++ b/core/persistence-neo4j/src/main/resources/domains/MasterContent.xml @@ -46,6 +46,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/PersistenceTestContext.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/PersistenceTestContext.java index 19904f044a..43e5a79d06 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/PersistenceTestContext.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/PersistenceTestContext.java @@ -27,14 +27,13 @@ import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.DomainRegistry; import org.apache.syncope.core.persistence.api.content.ContentLoader; -import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingNeo4jClient; +import org.apache.syncope.core.persistence.neo4j.spring.DomainRoutingDriver; import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.ImplementationLookup; import org.apache.syncope.core.spring.security.DefaultPasswordGenerator; import org.apache.syncope.core.spring.security.PasswordGenerator; import org.apache.syncope.core.spring.security.SecurityProperties; import org.neo4j.driver.Driver; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; @@ -44,8 +43,6 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; -import org.springframework.data.neo4j.core.Neo4jClient; -import org.springframework.data.neo4j.repository.config.Neo4jRepositoryConfigurationExtension; @Import(PersistenceContext.class) @Configuration(proxyBeanMethods = false) @@ -125,21 +122,16 @@ public ConnectorManager connectorManager() { } @Primary - @Bean(Neo4jRepositoryConfigurationExtension.DEFAULT_NEO4J_CLIENT_BEAN_NAME) - public Neo4jClient neo4jClient( - @Qualifier("MasterNeo4jClient") - final Neo4jClient masterNeo4jClient) { - - DomainRoutingNeo4jClient neo4jClient = new DomainRoutingNeo4jClient() { + @Bean + public DomainRoutingDriver driver(final DomainHolder domainHolder) { + return new DomainRoutingDriver(domainHolder) { @Override - protected Neo4jClient delegate() { - return delegates.getOrDefault( + protected Driver delegate() { + return domainHolder.getDomains().getOrDefault( TEST_DOMAIN.get(), - delegates.get(SyncopeConstants.MASTER_DOMAIN)); + domainHolder.getDomains().get(SyncopeConstants.MASTER_DOMAIN)); } }; - neo4jClient.add(SyncopeConstants.MASTER_DOMAIN, masterNeo4jClient); - return neo4jClient; } } diff --git a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ImplementationTest.java b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ImplementationTest.java index ef2a1b73b9..839739eac0 100644 --- a/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ImplementationTest.java +++ b/core/persistence-neo4j/src/test/java/org/apache/syncope/core/persistence/neo4j/inner/ImplementationTest.java @@ -51,7 +51,7 @@ public void findAll() { List implementations = implementationDAO.findAll(); assertFalse(implementations.isEmpty()); - assertEquals(19, implementations.size()); + assertEquals(20, implementations.size()); implementations = implementationDAO.findByType(IdMImplementationType.PULL_ACTIONS); assertEquals(1, implementations.size()); @@ -60,7 +60,7 @@ public void findAll() { assertEquals(2, implementations.size()); implementations = implementationDAO.findByType(IdRepoImplementationType.TASKJOB_DELEGATE); - assertEquals(6, implementations.size()); + assertEquals(7, implementations.size()); implementations = implementationDAO.findByType(IdRepoImplementationType.REPORT_DELEGATE); assertEquals(1, implementations.size()); diff --git a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml index 490a7756a5..c72042fc0b 100644 --- a/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-neo4j/src/test/resources/domains/MasterContent.xml @@ -701,6 +701,8 @@ under the License. body="org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate"/> + + diff --git a/core/provisioning-api/pom.xml b/core/provisioning-api/pom.xml index 75b1c709ef..d6afcf9030 100644 --- a/core/provisioning-api/pom.xml +++ b/core/provisioning-api/pom.xml @@ -38,17 +38,17 @@ under the License. - - org.springframework.boot - spring-boot-starter-quartz - - org.apache.syncope.core syncope-core-persistence-api ${project.version} + + org.springframework + spring-tx + + org.apache.commons commons-jexl3 diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/JobStatusEvent.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/JobStatusEvent.java index 68e1c50a64..886081b508 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/JobStatusEvent.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/event/JobStatusEvent.java @@ -26,14 +26,14 @@ public class JobStatusEvent extends ApplicationEvent { private final String domain; - private final String jobRefDesc; + private final String jobName; private final String jobStatus; - public JobStatusEvent(final Object source, final String domain, final String jobRefDesc, final String jobStatus) { + public JobStatusEvent(final Object source, final String domain, final String jobName, final String jobStatus) { super(source); this.domain = domain; - this.jobRefDesc = jobRefDesc; + this.jobName = jobName; this.jobStatus = jobStatus; } @@ -41,8 +41,8 @@ public String getDomain() { return domain; } - public String getJobRefDesc() { - return jobRefDesc; + public String getJobName() { + return jobName; } public String getJobStatus() { @@ -53,7 +53,7 @@ public String getJobStatus() { public String toString() { return "JobStatusEvent{" + "domain=" + domain - + ", jobRefDesc=" + jobRefDesc + + ", jobName=" + jobName + ", jobStatus=" + jobStatus + '}'; } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionContext.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionContext.java new file mode 100644 index 0000000000..f8af53230f --- /dev/null +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionContext.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.api.job; + +import java.util.HashMap; +import java.util.Map; + +public class JobExecutionContext { + + private final String domain; + + private final String jobName; + + private final String executor; + + private final boolean dryRun; + + private final Map data = new HashMap<>(); + + public JobExecutionContext(final String domain, final String jobName, final String executor, final boolean dryRun) { + this.domain = domain; + this.jobName = jobName; + this.executor = executor; + this.dryRun = dryRun; + } + + public String getDomain() { + return domain; + } + + public String getJobName() { + return jobName; + } + + public String getExecutor() { + return executor; + } + + public boolean isDryRun() { + return dryRun; + } + + public Map getData() { + return data; + } +} diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionException.java similarity index 67% rename from core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobDelegate.java rename to core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionException.java index 9addc1b2e0..a5f1d9a778 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobDelegate.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobExecutionException.java @@ -18,14 +18,19 @@ */ package org.apache.syncope.core.provisioning.api.job; -/** - * Implementations of this interface will perform the actual operations required to Quartz's {@link org.quartz.Job}. - */ -public interface JobDelegate { +public class JobExecutionException extends Exception { + + private static final long serialVersionUID = -4545623806027347816L; - String OPERATION_ID = "operation.id"; + public JobExecutionException(final String message) { + super(message); + } - void interrupt(); + public JobExecutionException(final String message, final Throwable cause) { + super(message, cause); + } - boolean isInterrupted(); + public JobExecutionException(final Throwable cause) { + super(cause); + } } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java index b699780fa0..25323e47fd 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobManager.java @@ -23,9 +23,6 @@ import org.apache.syncope.core.persistence.api.entity.Report; import org.apache.syncope.core.persistence.api.entity.task.SchedTask; import org.apache.syncope.core.persistence.api.entity.task.Task; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; @SuppressWarnings("squid:S1214") public interface JobManager { @@ -36,27 +33,24 @@ public interface JobManager { String REPORT_KEY = "reportKey"; - String DOMAIN_KEY = "domain"; - - String EXECUTOR_KEY = "executor"; - - String DRY_RUN_JOBDETAIL_KEY = "dryRun"; - String DELEGATE_IMPLEMENTATION = "delegateImpl"; - JobKey NOTIFICATION_JOB = new JobKey("notificationJob", Scheduler.DEFAULT_GROUP); + String NOTIFICATION_JOB = "notificationJob"; - boolean isRunning(JobKey jobKey) throws SchedulerException; + boolean isRunning(String jobName); - Map register( + void register( SchedTask task, OffsetDateTime startAt, - String executor) throws SchedulerException; + String executor, + boolean dryRun, + Map jobData); - Map register( + void register( Report report, OffsetDateTime startAt, - String executor) throws SchedulerException; + String executor, + boolean dryRun); void unregister(Task task); diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java index 498cff6695..d031bac6d7 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/JobNamer.java @@ -23,8 +23,6 @@ import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.core.persistence.api.entity.Report; import org.apache.syncope.core.persistence.api.entity.task.Task; -import org.quartz.JobKey; -import org.quartz.Scheduler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,16 +53,12 @@ public static String getReportKeyFromJobName(final String name) { return getKeyFromJobName(name, "reportJob" + SyncopeConstants.UUID_REGEX, 9); } - public static JobKey getJobKey(final Task task) { - return new JobKey("taskJob" + task.getKey(), Scheduler.DEFAULT_GROUP); + public static String getJobName(final Task task) { + return "taskJob" + task.getKey(); } - public static JobKey getJobKey(final Report report) { - return new JobKey("reportJob" + report.getKey(), Scheduler.DEFAULT_GROUP); - } - - public static String getTriggerName(final String jobName) { - return "Trigger_" + jobName; + public static String getJobName(final Report report) { + return "reportJob" + report.getKey(); } private JobNamer() { diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java index ebd2bdf963..7d3dc0026a 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/SchedTaskJobDelegate.java @@ -19,18 +19,16 @@ package org.apache.syncope.core.provisioning.api.job; import org.apache.syncope.common.lib.types.TaskType; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -public interface SchedTaskJobDelegate extends JobDelegate { +public interface SchedTaskJobDelegate { /** - * Executes a Quartz Job to run the given Task. + * Executes a Job to run the given Task. * * @param taskType Type of task to run * @param taskKey Task key to run * @param dryRun indicates if execution shall be simulated with no actual changes - * @param context Quartz' execution context, can be used to pass parameters to the job + * @param context execution context, can be used to pass parameters to the job * @throws JobExecutionException if anything goes wrong */ void execute( diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java index 3687f0259a..c39af58179 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/job/report/ReportJobDelegate.java @@ -19,11 +19,10 @@ package org.apache.syncope.core.provisioning.api.job.report; import org.apache.syncope.common.lib.report.ReportConf; -import org.apache.syncope.core.provisioning.api.job.JobDelegate; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; -public interface ReportJobDelegate extends JobDelegate { +public interface ReportJobDelegate { /** * Optional configuration. @@ -34,11 +33,11 @@ default void setConf(ReportConf conf) { } /** - * Executes a Quartz Job to run the given Report. + * Executes a Job to run the given Report. * * @param reportKey Report key to run * @param dryRun indicates if execution shall be simulated with no actual changes - * @param context Quartz' execution context, can be used to pass parameters to the job + * @param context execution context, can be used to pass parameters to the job * @throws JobExecutionException if anything goes wrong */ void execute( diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java index 98400a17ce..0537906551 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/notification/NotificationJobDelegate.java @@ -20,10 +20,9 @@ import org.apache.syncope.core.persistence.api.entity.task.NotificationTask; import org.apache.syncope.core.persistence.api.entity.task.TaskExec; -import org.apache.syncope.core.provisioning.api.job.JobDelegate; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; -public interface NotificationJobDelegate extends JobDelegate { +public interface NotificationJobDelegate { TaskExec executeSingle(NotificationTask task, String executor); diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java index afbf49aac2..f5eddf68c3 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/ProvisioningActions.java @@ -18,7 +18,7 @@ */ package org.apache.syncope.core.provisioning.api.pushpull; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; public interface ProvisioningActions { diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java index 5e3e82501a..34e5599a5f 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PullActions.java @@ -27,8 +27,8 @@ import org.apache.syncope.common.lib.to.Provision; import org.apache.syncope.common.lib.to.ProvisioningReport; import org.apache.syncope.common.lib.to.RealmTO; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; /** * Interface for actions to be performed during pull. diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java index aed56efe60..b9aa0430d1 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/PushActions.java @@ -22,7 +22,7 @@ import java.util.Set; import org.apache.syncope.common.lib.to.ProvisioningReport; import org.apache.syncope.core.persistence.api.entity.Entity; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; /** * Interface for actions to be performed during push. diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullExecutor.java index 5290c3598e..ccba96e807 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullExecutor.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePullExecutor.java @@ -26,8 +26,4 @@ public interface SyncopePullExecutor { void setLatestSyncToken(String objectClass, SyncToken latestSyncToken); void reportHandled(String objectClass, Name name); - - boolean wasInterruptRequested(); - - void setInterrupted(); } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushExecutor.java index 6e6cfd9340..83d985cc0b 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushExecutor.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopePushExecutor.java @@ -22,7 +22,4 @@ public interface SyncopePushExecutor { void reportHandled(String anyType, String key); - boolean wasInterruptRequested(); - - void setInterrupted(); } diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java index a7e0311876..601cbc8ee1 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePullExecutor.java @@ -25,7 +25,7 @@ import org.apache.syncope.common.lib.to.PullTaskTO; import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.provisioning.api.Connector; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; @FunctionalInterface public interface SyncopeSinglePullExecutor { diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java index 2a367e3fdd..afc7dd990d 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/SyncopeSinglePushExecutor.java @@ -26,7 +26,7 @@ import org.apache.syncope.core.persistence.api.entity.ExternalResource; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.provisioning.api.Connector; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; public interface SyncopeSinglePushExecutor { diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java index 40440508a3..b31d8912c5 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPullExecutor.java @@ -24,7 +24,7 @@ import org.apache.syncope.common.lib.types.ConflictResolutionAction; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.provisioning.api.Connector; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; @FunctionalInterface public interface SyncopeStreamPullExecutor { diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java index f8242a1df2..aecdab1c1c 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/pushpull/stream/SyncopeStreamPushExecutor.java @@ -24,7 +24,7 @@ import org.apache.syncope.core.persistence.api.entity.Any; import org.apache.syncope.core.persistence.api.entity.AnyType; import org.apache.syncope.core.provisioning.api.Connector; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; @FunctionalInterface public interface SyncopeStreamPushExecutor { diff --git a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/job/JobNamerTest.java b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/job/JobNamerTest.java index 3739ab7a2d..ef8a1a5e19 100644 --- a/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/job/JobNamerTest.java +++ b/core/provisioning-api/src/test/java/org/apache/syncope/core/provisioning/api/job/JobNamerTest.java @@ -20,18 +20,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.when; import java.util.UUID; -import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.syncope.core.persistence.api.entity.Report; import org.apache.syncope.core.persistence.api.entity.task.Task; import org.apache.syncope.core.provisioning.api.AbstractTest; import org.junit.jupiter.api.Test; import org.mockito.Mock; -import org.quartz.JobKey; -import org.quartz.Scheduler; public class JobNamerTest extends AbstractTest { @@ -61,21 +57,13 @@ public void getReportKeyFromJobName() { public void getJobKey(final @Mock Task task) { String uuid = UUID.randomUUID().toString(); when(task.getKey()).thenReturn(uuid); - assertTrue(EqualsBuilder.reflectionEquals(new JobKey("taskJob" + task.getKey(), Scheduler.DEFAULT_GROUP), - JobNamer.getJobKey(task))); + assertEquals("taskJob" + task.getKey(), JobNamer.getJobName(task)); } @Test public void getJobKey(final @Mock Report report) { String uuid = UUID.randomUUID().toString(); when(report.getKey()).thenReturn(uuid); - assertTrue(EqualsBuilder.reflectionEquals(new JobKey("reportJob" + report.getKey(), Scheduler.DEFAULT_GROUP), - JobNamer.getJobKey(report))); - } - - @Test - public void getTriggerName() { - String jobName = "testJobName"; - assertEquals("Trigger_" + jobName, JobNamer.getTriggerName(jobName)); + assertEquals("reportJob" + report.getKey(), JobNamer.getJobName(report)); } } diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml index 9313ccb682..2288625249 100644 --- a/core/provisioning-java/pom.xml +++ b/core/provisioning-java/pom.xml @@ -53,15 +53,12 @@ under the License. org.springframework.retry spring-retry - - org.springframework - spring-jdbc - com.fasterxml.jackson.dataformat jackson-dataformat-csv + org.apache.pdfbox pdfbox @@ -135,6 +132,11 @@ under the License. h2 test + + org.awaitility + awaitility + test + org.springframework spring-test @@ -197,13 +199,6 @@ under the License. src/test/resources true - - ${basedir}/../persistence-jpa/src/main/resources - - persistence.properties - - true - ${basedir}/../persistence-jpa/src/test/resources true diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java index c8e32d2ebe..4534ae04a0 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningContext.java @@ -18,12 +18,8 @@ */ package org.apache.syncope.core.provisioning.java; -import jakarta.annotation.Resource; -import java.nio.charset.StandardCharsets; -import java.util.Properties; import java.util.concurrent.Executor; import java.util.concurrent.Executors; -import javax.sql.DataSource; import org.apache.syncope.common.keymaster.client.api.ConfParamOps; import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.attrvalue.PlainAttrValidationManager; @@ -152,8 +148,7 @@ import org.apache.syncope.core.provisioning.java.data.wa.WAClientAppDataBinderImpl; import org.apache.syncope.core.provisioning.java.job.DefaultJobManager; import org.apache.syncope.core.provisioning.java.job.JobStatusUpdater; -import org.apache.syncope.core.provisioning.java.job.SchedulerDBInit; -import org.apache.syncope.core.provisioning.java.job.SyncopeSpringBeanJobFactory; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.job.SystemLoadReporterJob; import org.apache.syncope.core.provisioning.java.job.notification.MailNotificationJobDelegate; import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob; @@ -179,30 +174,20 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Primary; -import org.springframework.core.io.ClassPathResource; import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.support.TaskExecutorAdapter; -import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.annotation.EnableAsync; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; -import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.scheduling.concurrent.SimpleAsyncTaskScheduler; @EnableAsync @EnableConfigurationProperties(ProvisioningProperties.class) @Configuration(proxyBeanMethods = false) public class ProvisioningContext { - @Resource(name = "MasterDataSource") - private DataSource masterDataSource; - - @Resource(name = "domainTransactionManager") - private PlatformTransactionManager domainTransactionManager; - @ConditionalOnMissingBean @Bean public AsyncConnectorFacade asyncConnectorFacade() { @@ -272,82 +257,39 @@ public VirtualThreadPoolTaskExecutor propagationTaskExecutorAsyncExecutor(final } @Bean - public SchedulerDBInit quartzDataSourceInit(final ProvisioningProperties provisioningProperties) { - SchedulerDBInit init = new SchedulerDBInit(); - init.setDataSource(masterDataSource); - - ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); - databasePopulator.setContinueOnError(true); - databasePopulator.setIgnoreFailedDrops(true); - databasePopulator.setSqlScriptEncoding(StandardCharsets.UTF_8.name()); - databasePopulator.setScripts(new ClassPathResource("/quartz/" + provisioningProperties.getQuartz().getSql())); - init.setDatabasePopulator(databasePopulator); - - return init; - } - - @DependsOn("quartzDataSourceInit") - @Lazy(false) - @Bean - public SchedulerFactoryBean scheduler(final ApplicationContext ctx, final ProvisioningProperties props) { - SchedulerFactoryBean scheduler = new SchedulerFactoryBean(); - scheduler.setAutoStartup(true); - scheduler.setApplicationContext(ctx); - scheduler.setWaitForJobsToCompleteOnShutdown(props.getQuartz().isWaitForJobsToCompleteOnShutdown()); - scheduler.setOverwriteExistingJobs(true); - scheduler.setDataSource(masterDataSource); - scheduler.setTransactionManager(domainTransactionManager); - scheduler.setJobFactory(new SyncopeSpringBeanJobFactory()); - - Properties quartzProperties = new Properties(); - quartzProperties.setProperty( - "org.quartz.scheduler.idleWaitTime", - String.valueOf(props.getQuartz().getIdleWaitTime())); - quartzProperties.setProperty( - "org.quartz.jobStore.misfireThreshold", - String.valueOf(props.getQuartz().getMisfireThreshold())); - quartzProperties.setProperty( - "org.quartz.jobStore.driverDelegateClass", - props.getQuartz().getDelegate().getName()); - quartzProperties.setProperty( - "org.quartz.jobStore.class", - "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); - quartzProperties.setProperty("org.quartz.threadPool.makeThreadsDaemons", "true"); - quartzProperties.setProperty("org.quartz.scheduler.makeSchedulerThreadDaemon", "true"); - quartzProperties.setProperty("org.quartz.jobStore.isClustered", "true"); - quartzProperties.setProperty("org.quartz.jobStore.clusterCheckinInterval", "20000"); - quartzProperties.setProperty("org.quartz.scheduler.instanceName", "SyncopeClusteredScheduler"); - quartzProperties.setProperty("org.quartz.scheduler.instanceId", "AUTO"); - quartzProperties.setProperty("org.quartz.scheduler.jmx.export", "true"); - scheduler.setQuartzProperties(quartzProperties); - - return scheduler; + public SyncopeTaskScheduler taskScheduler(final ProvisioningProperties props, final JobStatusDAO jobStatusDAO) { + SimpleAsyncTaskScheduler taskScheduler = new SimpleAsyncTaskScheduler(); + taskScheduler.setVirtualThreads(true); + taskScheduler.setConcurrencyLimit(props.getScheduling().getPoolSize()); + taskScheduler.setTaskTerminationTimeout(props.getScheduling().getAwaitTerminationSeconds() * 1000); + taskScheduler.setThreadNamePrefix("TaskScheduler-"); + + return new SyncopeTaskScheduler(taskScheduler, jobStatusDAO); } @ConditionalOnMissingBean @Bean public JobManager jobManager( - final ProvisioningProperties provisioningProperties, final DomainHolder domainHolder, final SecurityProperties securityProperties, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, + final JobStatusDAO jobStatusDAO, final TaskDAO taskDAO, final ReportDAO reportDAO, final ImplementationDAO implementationDAO, final TaskUtilsFactory taskUtilsFactory, final ConfParamOps confParamOps) { - DefaultJobManager jobManager = new DefaultJobManager( + return new DefaultJobManager( domainHolder, scheduler, + jobStatusDAO, taskDAO, reportDAO, implementationDAO, taskUtilsFactory, confParamOps, securityProperties); - jobManager.setDisableQuartzInstance(provisioningProperties.getQuartz().isDisableInstance()); - return jobManager; } @ConditionalOnMissingBean @@ -1019,7 +961,7 @@ public RemediationDataBinder remediationDataBinder() { public ReportDataBinder reportDataBinder( final ReportExecDAO reportExecDAO, final ImplementationDAO implementationDAO, - final SchedulerFactoryBean scheduler) { + final SyncopeTaskScheduler scheduler) { return new ReportDataBinderImpl(reportExecDAO, implementationDAO, scheduler); } @@ -1129,7 +1071,7 @@ public TaskDataBinder taskDataBinder( final TaskExecDAO taskExecDAO, final AnyTypeDAO anyTypeDAO, final ImplementationDAO implementationDAO, - final SchedulerFactoryBean scheduler) { + final SyncopeTaskScheduler scheduler) { return new TaskDataBinderImpl( realmSearchDAO, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningProperties.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningProperties.java index 9eea8ace4c..d5c67fe797 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningProperties.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/ProvisioningProperties.java @@ -20,85 +20,21 @@ import java.util.ArrayList; import java.util.List; -import org.quartz.impl.jdbcjobstore.DriverDelegate; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties("provisioning") public class ProvisioningProperties { - public static class QuartzProperties { - - private Class delegate; - - private String sql; - - private boolean disableInstance = false; - - private boolean waitForJobsToCompleteOnShutdown = true; - - private int idleWaitTime = 30000; - - private int misfireThreshold = 60000; - - public Class getDelegate() { - return delegate; - } - - public void setDelegate(final Class delegate) { - this.delegate = delegate; - } - - public String getSql() { - return sql; - } - - public void setSql(final String sql) { - this.sql = sql; - } - - public boolean isDisableInstance() { - return disableInstance; - } - - public void setDisableInstance(final boolean disableInstance) { - this.disableInstance = disableInstance; - } - - public boolean isWaitForJobsToCompleteOnShutdown() { - return waitForJobsToCompleteOnShutdown; - } - - public void setWaitForJobsToCompleteOnShutdown(final boolean waitForJobsToCompleteOnShutdown) { - this.waitForJobsToCompleteOnShutdown = waitForJobsToCompleteOnShutdown; - } - - public int getIdleWaitTime() { - return idleWaitTime; - } - - public void setIdleWaitTime(final int idleWaitTime) { - this.idleWaitTime = idleWaitTime; - } - - public int getMisfireThreshold() { - return misfireThreshold; - } - - public void setMisfireThreshold(final int misfireThreshold) { - this.misfireThreshold = misfireThreshold; - } - } + private String virAttrCacheSpec = "maximumSize=5000,expireAfterAccess=1m"; private final ExecutorProperties asyncConnectorFacadeExecutor = new ExecutorProperties(); private final ExecutorProperties propagationTaskExecutorAsyncExecutor = new ExecutorProperties(); - private String virAttrCacheSpec = "maximumSize=5000,expireAfterAccess=1m"; + private final ExecutorProperties scheduling = new ExecutorProperties(); private final List connIdLocation = new ArrayList<>(); - private final QuartzProperties quartz = new QuartzProperties(); - public String getVirAttrCacheSpec() { return virAttrCacheSpec; } @@ -115,11 +51,12 @@ public ExecutorProperties getPropagationTaskExecutorAsyncExecutor() { return propagationTaskExecutorAsyncExecutor; } + public ExecutorProperties getScheduling() { + return scheduling; + } + public List getConnIdLocation() { return connIdLocation; } - public QuartzProperties getQuartz() { - return quartz; - } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java index 9f35d74365..a2e2e790c6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ReportDataBinderImpl.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.provisioning.java.data; +import java.util.Comparator; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.to.ExecTO; @@ -32,13 +33,10 @@ import org.apache.syncope.core.persistence.api.entity.ReportExec; import org.apache.syncope.core.provisioning.api.data.ReportDataBinder; import org.apache.syncope.core.provisioning.api.job.JobNamer; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.TriggerKey; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; +import org.apache.syncope.core.spring.security.AuthContextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; public class ReportDataBinderImpl extends AbstractExecutableDatabinder implements ReportDataBinder { @@ -48,12 +46,12 @@ public class ReportDataBinderImpl extends AbstractExecutableDatabinder implement protected final ImplementationDAO implementationDAO; - protected final SchedulerFactoryBean scheduler; + protected final SyncopeTaskScheduler scheduler; public ReportDataBinderImpl( final ReportExecDAO reportExecDAO, final ImplementationDAO implementationDAO, - final SchedulerFactoryBean scheduler) { + final SyncopeTaskScheduler scheduler) { this.reportExecDAO = reportExecDAO; this.implementationDAO = implementationDAO; @@ -100,19 +98,13 @@ public ReportTO getReportTO(final Report report) { reportTO.setLastExec(reportTO.getStart()); } - reportTO.getExecutions().addAll(report.getExecs().stream(). - map(this::getExecTO).toList()); - - String triggerName = JobNamer.getTriggerName(JobNamer.getJobKey(report).getName()); - try { - Trigger trigger = scheduler.getScheduler().getTrigger(new TriggerKey(triggerName, Scheduler.DEFAULT_GROUP)); - if (trigger != null) { - reportTO.setLastExec(toOffsetDateTime(trigger.getPreviousFireTime())); - reportTO.setNextExec(toOffsetDateTime(trigger.getNextFireTime())); - } - } catch (SchedulerException e) { - LOG.warn("While trying to get to " + triggerName, e); - } + reportTO.getExecutions().addAll(report.getExecs().stream().map(this::getExecTO).toList()); + + reportTO.getExecutions().stream().sorted(Comparator.comparing(ExecTO::getStart).reversed()).findFirst(). + map(ExecTO::getStart).ifPresent(reportTO::setLastExec); + + scheduler.getNextTrigger(AuthContextUtils.getDomain(), JobNamer.getJobName(report)). + ifPresent(reportTO::setNextExec); return reportTO; } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java index d9d9d40ffa..119eeea76d 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/TaskDataBinderImpl.java @@ -18,6 +18,7 @@ */ package org.apache.syncope.core.provisioning.java.data; +import java.util.Comparator; import java.util.Objects; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.lib.SyncopeClientException; @@ -61,17 +62,14 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory; import org.apache.syncope.core.provisioning.api.data.TaskDataBinder; import org.apache.syncope.core.provisioning.api.job.JobNamer; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate; import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate; import org.apache.syncope.core.provisioning.java.utils.TemplateUtils; import org.apache.syncope.core.spring.implementation.ImplementationManager; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.TriggerKey; +import org.apache.syncope.core.spring.security.AuthContextUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; public class TaskDataBinderImpl extends AbstractExecutableDatabinder implements TaskDataBinder { @@ -91,7 +89,7 @@ public class TaskDataBinderImpl extends AbstractExecutableDatabinder implements protected final EntityFactory entityFactory; - protected final SchedulerFactoryBean scheduler; + protected final SyncopeTaskScheduler scheduler; protected final TaskUtilsFactory taskUtilsFactory; @@ -102,7 +100,7 @@ public TaskDataBinderImpl( final AnyTypeDAO anyTypeDAO, final ImplementationDAO implementationDAO, final EntityFactory entityFactory, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, final TaskUtilsFactory taskUtilsFactory) { this.realmSearchDAO = realmSearchDAO; @@ -377,18 +375,13 @@ protected void fill(final SchedTaskTO schedTaskTO, final SchedTask schedTask) { schedTaskTO.setCronExpression(schedTask.getCronExpression()); schedTaskTO.setActive(schedTask.isActive()); - schedTaskTO.setLastExec(schedTaskTO.getStart()); + schedTaskTO.getExecutions().stream().sorted(Comparator.comparing(ExecTO::getStart).reversed()).findFirst(). + map(ExecTO::getStart).ifPresentOrElse( + schedTaskTO::setLastExec, + () -> schedTaskTO.setLastExec(schedTaskTO.getStart())); - String triggerName = JobNamer.getTriggerName(JobNamer.getJobKey(schedTask).getName()); - try { - Trigger trigger = scheduler.getScheduler().getTrigger(new TriggerKey(triggerName, Scheduler.DEFAULT_GROUP)); - if (trigger != null) { - schedTaskTO.setLastExec(toOffsetDateTime(trigger.getPreviousFireTime())); - schedTaskTO.setNextExec(toOffsetDateTime(trigger.getNextFireTime())); - } - } catch (SchedulerException e) { - LOG.warn("While trying to get to " + triggerName, e); - } + scheduler.getNextTrigger(AuthContextUtils.getDomain(), JobNamer.getJobName(schedTask)). + ifPresent(schedTaskTO::setNextExec); if (schedTaskTO instanceof ProvisioningTaskTO && schedTask instanceof ProvisioningTask) { ProvisioningTaskTO provisioningTaskTO = (ProvisioningTaskTO) schedTaskTO; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java deleted file mode 100644 index 3889ee56ae..0000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractInterruptableJob.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.job; - -import org.apache.syncope.core.provisioning.api.job.JobDelegate; -import org.quartz.DisallowConcurrentExecution; -import org.quartz.InterruptableJob; -import org.quartz.UnableToInterruptJobException; - -@DisallowConcurrentExecution -public abstract class AbstractInterruptableJob implements InterruptableJob { - - private final JobDelegate embeddedDelegate = new JobDelegate() { - - @Override - public void interrupt() { - } - - @Override - public boolean isInterrupted() { - return false; - } - }; - - public JobDelegate getDelegate() { - return embeddedDelegate; - } - - @Override - public void interrupt() throws UnableToInterruptJobException { - getDelegate().interrupt(); - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java index d51763dfa3..69a633d486 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AbstractSchedTaskJobDelegate.java @@ -29,16 +29,15 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory; import org.apache.syncope.core.persistence.api.utils.ExceptionUtils2; import org.apache.syncope.core.provisioning.api.AuditManager; -import org.apache.syncope.core.provisioning.api.data.TaskDataBinder; import org.apache.syncope.core.provisioning.api.event.JobStatusEvent; -import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobNamer; import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecureRandomUtils; import org.apache.syncope.core.spring.security.SecurityProperties; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -75,9 +74,6 @@ public abstract class AbstractSchedTaskJobDelegate implemen @Autowired protected TaskUtilsFactory taskUtilsFactory; - @Autowired - protected TaskDataBinder taskDataBinder; - /** * Notification manager. */ @@ -93,23 +89,9 @@ public abstract class AbstractSchedTaskJobDelegate implemen @Autowired protected ApplicationEventPublisher publisher; - protected boolean interrupt; - - protected boolean interrupted; - protected void setStatus(final String status) { publisher.publishEvent(new JobStatusEvent( - this, AuthContextUtils.getDomain(), taskDataBinder.buildRefDesc(task), status)); - } - - @Override - public void interrupt() { - interrupt = true; - } - - @Override - public boolean isInterrupted() { - return interrupted; + this, AuthContextUtils.getDomain(), JobNamer.getJobName(task), status)); } @SuppressWarnings("unchecked") @@ -131,15 +113,14 @@ public void execute( return; } - boolean manageOperationId = Optional.ofNullable(MDC.get(OPERATION_ID)). + boolean manageOperationId = Optional.ofNullable(MDC.get(Job.OPERATION_ID)). map(operationId -> false). orElseGet(() -> { - MDC.put(OPERATION_ID, SecureRandomUtils.generateRandomUUID().toString()); + MDC.put(Job.OPERATION_ID, SecureRandomUtils.generateRandomUUID().toString()); return true; }); - String executor = Optional.ofNullable(context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY)). - orElse(securityProperties.getAdminUser()); + String executor = Optional.ofNullable(context.getExecutor()).orElse(securityProperties.getAdminUser()); TaskExec execution = taskUtilsFactory.getInstance(taskType).newTaskExec(); execution.setStart(OffsetDateTime.now()); execution.setTask(task); @@ -168,8 +149,6 @@ public void execute( } task = taskDAO.save(task); - setStatus(null); - notificationManager.createTasks( executor, AuditElements.EventCategoryType.TASK, @@ -191,7 +170,7 @@ public void execute( null); if (manageOperationId) { - MDC.remove(OPERATION_ID); + MDC.remove(Job.OPERATION_ID); } } @@ -200,7 +179,7 @@ public void execute( * * @param dryRun whether to actually touch the data * @param executor the user executing this task - * @param context Quartz' execution context, can be used to pass parameters to the job + * @param context job execution context, can be used to pass parameters to the job * @return the task execution status to be set * @throws JobExecutionException if anything goes wrong */ diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java index 7e639f09c5..afe24e202a 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java @@ -18,56 +18,44 @@ */ package org.apache.syncope.core.provisioning.java.job; +import java.time.Instant; import java.util.Map; +import java.util.Optional; import org.apache.syncope.core.provisioning.api.AuditManager; import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent; -import org.apache.syncope.core.provisioning.api.job.JobManager; -import org.apache.syncope.core.provisioning.api.job.JobNamer; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecureRandomUtils; -import org.quartz.JobBuilder; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.TriggerBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; +import org.springframework.core.task.TaskRejectedException; /** - * Quartz job for asynchronous handling of notification / audit events. + * Job for asynchronous handling of notification / audit events. * Instead of direct synchronous invocation - which occurs in the same transaction where the event is generated, the * execution of the scheduled code happens in a new transaction. */ -public class AfterHandlingJob extends AbstractInterruptableJob { +public class AfterHandlingJob extends Job { private static final Logger LOG = LoggerFactory.getLogger(AfterHandlingJob.class); - public static void schedule(final SchedulerFactoryBean scheduler, final Map jobMap) { - AfterHandlingJob jobInstance = ApplicationContextProvider.getBeanFactory().createBean(AfterHandlingJob.class); - String jobName = AfterHandlingJob.class.getSimpleName() + SecureRandomUtils.generateRandomUUID(); - - jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain()); - - ApplicationContextProvider.getBeanFactory().registerSingleton(jobName, jobInstance); - - JobBuilder jobDetailBuilder = JobBuilder.newJob(AfterHandlingJob.class). - withIdentity(jobName, Scheduler.DEFAULT_GROUP). - usingJobData(new JobDataMap(jobMap)); - - TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(). - withIdentity(JobNamer.getTriggerName(jobName), Scheduler.DEFAULT_GROUP). - startNow(); + public static void schedule(final SyncopeTaskScheduler scheduler, final Map jobMap) { + JobExecutionContext context = new JobExecutionContext( + AuthContextUtils.getDomain(), + AfterHandlingJob.class.getSimpleName() + "_" + SecureRandomUtils.generateRandomUUID(), + AuthContextUtils.getWho(), + false); + context.getData().putAll(jobMap); try { - scheduler.getScheduler().scheduleJob(jobDetailBuilder.build(), triggerBuilder.build()); - } catch (SchedulerException e) { + AfterHandlingJob job = ApplicationContextProvider.getBeanFactory().createBean(AfterHandlingJob.class); + job.setContext(context); + scheduler.schedule(job, Instant.now()); + } catch (TaskRejectedException e) { LOG.error("Could not schedule, aborting", e); } } @@ -79,19 +67,23 @@ public static void schedule(final SchedulerFactoryBean scheduler, final Map event = Optional.ofNullable( + context.getData().get(AfterHandlingEvent.JOBMAP_KEY)).map(AfterHandlingEvent.class::cast); + if (event.isEmpty()) { + LOG.debug("No event to process, aborting"); + return; + } + try { - AuthContextUtils.runAsAdmin(context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY), + AuthContextUtils.runAsAdmin( + context.getDomain(), () -> { - notificationManager.createTasks( - (AfterHandlingEvent) context.getMergedJobDataMap().get(AfterHandlingEvent.JOBMAP_KEY)); - auditManager.audit( - (AfterHandlingEvent) context.getMergedJobDataMap().get(AfterHandlingEvent.JOBMAP_KEY)); + notificationManager.createTasks(event.get()); + auditManager.audit(event.get()); }); } catch (RuntimeException e) { throw new JobExecutionException("While handling notification / audit events", e); - } finally { - ApplicationContextProvider.getBeanFactory().destroySingleton(context.getJobDetail().getKey().getName()); } } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/DefaultJobManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/DefaultJobManager.java index 671f0cf7cf..535359b3f6 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/DefaultJobManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/DefaultJobManager.java @@ -19,14 +19,10 @@ package org.apache.syncope.core.provisioning.java.job; import java.time.OffsetDateTime; -import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; -import java.util.Optional; import java.util.Set; -import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.common.keymaster.client.api.ConfParamOps; import org.apache.syncope.common.lib.SyncopeConstants; @@ -35,6 +31,7 @@ import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.SyncopeCoreLoader; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; +import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; import org.apache.syncope.core.persistence.api.dao.ReportDAO; import org.apache.syncope.core.persistence.api.dao.TaskDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; @@ -44,6 +41,7 @@ import org.apache.syncope.core.persistence.api.entity.task.SchedTask; import org.apache.syncope.core.persistence.api.entity.task.Task; import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; import org.apache.syncope.core.provisioning.api.job.JobManager; import org.apache.syncope.core.provisioning.api.job.JobNamer; import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate; @@ -51,23 +49,12 @@ import org.apache.syncope.core.provisioning.java.job.report.ReportJob; import org.apache.syncope.core.provisioning.java.pushpull.PullJobDelegate; import org.apache.syncope.core.provisioning.java.pushpull.PushJobDelegate; +import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecurityProperties; -import org.quartz.CronScheduleBuilder; -import org.quartz.Job; -import org.quartz.JobBuilder; -import org.quartz.JobDataMap; -import org.quartz.JobKey; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.TriggerBuilder; -import org.quartz.TriggerKey; -import org.quartz.impl.jdbcjobstore.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; +import org.springframework.scheduling.support.CronTrigger; import org.springframework.transaction.annotation.Transactional; public class DefaultJobManager implements JobManager, SyncopeCoreLoader { @@ -76,7 +63,9 @@ public class DefaultJobManager implements JobManager, SyncopeCoreLoader { protected final DomainHolder domainHolder; - protected final SchedulerFactoryBean scheduler; + protected final SyncopeTaskScheduler scheduler; + + protected final JobStatusDAO jobStatusDAO; protected final TaskDAO taskDAO; @@ -90,11 +79,10 @@ public class DefaultJobManager implements JobManager, SyncopeCoreLoader { protected final SecurityProperties securityProperties; - protected boolean disableQuartzInstance; - public DefaultJobManager( final DomainHolder domainHolder, - final SchedulerFactoryBean scheduler, + final SyncopeTaskScheduler scheduler, + final JobStatusDAO jobStatusDAO, final TaskDAO taskDAO, final ReportDAO reportDAO, final ImplementationDAO implementationDAO, @@ -104,6 +92,7 @@ public DefaultJobManager( this.domainHolder = domainHolder; this.scheduler = scheduler; + this.jobStatusDAO = jobStatusDAO; this.taskDAO = taskDAO; this.reportDAO = reportDAO; this.implementationDAO = implementationDAO; @@ -112,90 +101,52 @@ public DefaultJobManager( this.securityProperties = securityProperties; } - public void setDisableQuartzInstance(final boolean disableQuartzInstance) { - this.disableQuartzInstance = disableQuartzInstance; - } - - protected boolean isRunningHere(final JobKey jobKey) throws SchedulerException { - return scheduler.getScheduler().getCurrentlyExecutingJobs().stream(). - anyMatch(jec -> jobKey.equals(jec.getJobDetail().getKey())); - } - - protected boolean isRunningElsewhere(final JobKey jobKey) throws SchedulerException { - if (!scheduler.getScheduler().getMetaData().isJobStoreClustered()) { - return false; - } - - Object v = domainHolder.getDomains().get(SyncopeConstants.MASTER_DOMAIN); - if (v instanceof DataSource dataSource) { - JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); - return jdbcTemplate.queryForObject( - "SELECT COUNT(ENTRY_ID) FROM " + Constants.DEFAULT_TABLE_PREFIX + "FIRED_TRIGGERS " - + "WHERE JOB_NAME = ? AND JOB_GROUP = ?", - Integer.class, - jobKey.getName(), - jobKey.getGroup()) > 0; - } - - LOG.warn("Unsupported persistence source: " + v.getClass().getName()); - return false; - } - @Override - public boolean isRunning(final JobKey jobKey) throws SchedulerException { - return isRunningHere(jobKey) || isRunningElsewhere(jobKey); + public boolean isRunning(final String jobName) { + boolean locked = jobStatusDAO.lock(jobName); + if (locked) { + jobStatusDAO.unlock(jobName); + } + return !locked; } protected void registerJob( - final String jobName, + final JobExecutionContext context, final Class jobClass, final String cronExpression, - final Date startAt, - final Map jobMap) - throws SchedulerException { + final OffsetDateTime startAt) { - if (isRunning(new JobKey(jobName, Scheduler.DEFAULT_GROUP))) { - LOG.debug("Job {} already running, cancel", jobName); + if (isRunning(context.getJobName())) { + LOG.debug("Job {} already running, cancel", context.getJobName()); return; } // 0. unregister job - unregisterJob(jobName); + unregisterJob(context.getJobName()); - // 1. JobDetail - JobBuilder jobDetailBuilder = JobBuilder.newJob(jobClass). - withIdentity(jobName). - usingJobData(new JobDataMap(jobMap)); + // 1. prepare job + Job job = ApplicationContextProvider.getBeanFactory().createBean(jobClass); + job.setContext(context); - // 2. Trigger + // 2. schedule if (cronExpression == null && startAt == null) { - // Jobs added with no trigger must be durable - scheduler.getScheduler().addJob(jobDetailBuilder.storeDurably().build(), true); + scheduler.register(job); } else { - TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(). - withIdentity(JobNamer.getTriggerName(jobName)); - if (cronExpression == null) { - triggerBuilder.startAt(startAt); + scheduler.schedule(job, startAt.toInstant()); } else { - triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)); - - if (startAt == null) { - triggerBuilder.startNow(); - } else { - triggerBuilder.startAt(startAt); - } + scheduler.schedule(job, new CronTrigger(cronExpression)); } - - scheduler.getScheduler().scheduleJob(jobDetailBuilder.build(), triggerBuilder.build()); } } - @Override - public Map register( + protected void register( + final String domain, final SchedTask task, final OffsetDateTime startAt, - final String executor) throws SchedulerException { + final String executor, + final boolean dryRun, + final Map jobData) { Implementation jobDelegate = task.getJobDelegate() == null ? task instanceof PullTask @@ -213,63 +164,79 @@ public Map register( + " does not provide any " + SchedTaskJobDelegate.class.getSimpleName()); } - Map jobMap = createJobMapForExecutionContext(executor); - jobMap.put(JobManager.TASK_TYPE, taskUtilsFactory.getInstance(task).getType()); - jobMap.put(JobManager.TASK_KEY, task.getKey()); - jobMap.put(JobManager.DELEGATE_IMPLEMENTATION, jobDelegate.getKey()); + JobExecutionContext context = new JobExecutionContext( + domain, + JobNamer.getJobName(task), + executor, + dryRun); + context.getData().put(JobManager.TASK_TYPE, taskUtilsFactory.getInstance(task).getType()); + context.getData().put(JobManager.TASK_KEY, task.getKey()); + context.getData().put(JobManager.DELEGATE_IMPLEMENTATION, jobDelegate.getKey()); + context.getData().putAll(jobData); registerJob( - JobNamer.getJobKey(task).getName(), + context, TaskJob.class, task.getCronExpression(), - Optional.ofNullable(startAt).map(s -> new Date(s.toInstant().toEpochMilli())).orElse(null), - jobMap); - return jobMap; + startAt); } @Override - public Map register( + public void register( + final SchedTask task, + final OffsetDateTime startAt, + final String executor, + final boolean dryRun, + final Map jobData) { + + register(AuthContextUtils.getDomain(), task, startAt, executor, dryRun, jobData); + } + + protected void register( + final String domain, final Report report, final OffsetDateTime startAt, - final String executor) throws SchedulerException { + final String executor, + final boolean dryRun) { - Map jobMap = createJobMapForExecutionContext(executor); - jobMap.put(JobManager.REPORT_KEY, report.getKey()); - jobMap.put(JobManager.DELEGATE_IMPLEMENTATION, report.getJobDelegate().getKey()); + JobExecutionContext context = new JobExecutionContext( + domain, + JobNamer.getJobName(report), + executor, + dryRun); + context.getData().put(JobManager.REPORT_KEY, report.getKey()); + context.getData().put(JobManager.DELEGATE_IMPLEMENTATION, report.getJobDelegate().getKey()); registerJob( - JobNamer.getJobKey(report).getName(), + context, ReportJob.class, report.getCronExpression(), - Optional.ofNullable(startAt).map(s -> new Date(s.toInstant().toEpochMilli())).orElse(null), - jobMap); - return jobMap; + startAt); } - protected Map createJobMapForExecutionContext(final String executor) { - Map jobMap = new HashMap<>(); - jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain()); - jobMap.put(JobManager.EXECUTOR_KEY, executor); - return jobMap; + @Override + public void register( + final Report report, + final OffsetDateTime startAt, + final String executor, + final boolean dryRun) { + + register(AuthContextUtils.getDomain(), report, startAt, executor, dryRun); } protected void unregisterJob(final String jobName) { - try { - scheduler.getScheduler().unscheduleJob(new TriggerKey(jobName, Scheduler.DEFAULT_GROUP)); - scheduler.getScheduler().deleteJob(new JobKey(jobName, Scheduler.DEFAULT_GROUP)); - } catch (SchedulerException e) { - LOG.error("Could not remove job " + jobName, e); - } + scheduler.cancel(AuthContextUtils.getDomain(), jobName); + scheduler.delete(AuthContextUtils.getDomain(), jobName); } @Override public void unregister(final Task task) { - unregisterJob(JobNamer.getJobKey(task).getName()); + unregisterJob(JobNamer.getJobName(task)); } @Override public void unregister(final Report report) { - unregisterJob(JobNamer.getJobKey(report).getName()); + unregisterJob(JobNamer.getJobName(report)); } @Override @@ -280,20 +247,6 @@ public int getOrder() { @Transactional @Override public void load(final String domain) { - if (disableQuartzInstance) { - String instanceId = "AUTO"; - try { - instanceId = scheduler.getScheduler().getSchedulerInstanceId(); - scheduler.getScheduler().standby(); - - LOG.info("Successfully put Quartz instance {} in standby", instanceId); - } catch (SchedulerException e) { - LOG.error("Could not put Quartz instance {} in standby", instanceId, e); - } - - return; - } - String notificationJobCronExp = AuthContextUtils.callAsAdmin(SyncopeConstants.MASTER_DOMAIN, () -> { String result = StringUtils.EMPTY; @@ -317,7 +270,7 @@ public void load(final String domain) { for (Iterator it = tasks.iterator(); it.hasNext() && !loadException;) { SchedTask task = it.next(); try { - register(task, task.getStartAt(), securityProperties.getAdminUser()); + register(domain, task, task.getStartAt(), securityProperties.getAdminUser(), false, Map.of()); } catch (Exception e) { LOG.error("While loading job instance for task " + task.getKey(), e); loadException = true; @@ -331,7 +284,7 @@ public void load(final String domain) { for (Iterator it = reportDAO.findAll().iterator(); it.hasNext() && !loadException;) { Report report = it.next(); try { - register(report, null, securityProperties.getAdminUser()); + register(domain, report, null, securityProperties.getAdminUser(), false); } catch (Exception e) { LOG.error("While loading job instance for report " + report.getName(), e); loadException = true; @@ -347,20 +300,22 @@ public void load(final String domain) { if (SyncopeConstants.MASTER_DOMAIN.equals(domain)) { // 3. NotificationJob if (StringUtils.isBlank(notificationJobCronExp)) { - LOG.debug("Empty value provided for {}'s cron, not registering anything on Quartz", - NotificationJob.class.getSimpleName()); + LOG.debug("Empty value provided for {}'s cron, not scheduling", NotificationJob.class.getSimpleName()); } else { - LOG.debug("{}'s cron expression: {} - registering Quartz job and trigger", + LOG.debug("{}'s cron expression: {} - scheduling", NotificationJob.class.getSimpleName(), notificationJobCronExp); + JobExecutionContext context = new JobExecutionContext( + domain, + NOTIFICATION_JOB, + securityProperties.getAdminUser(), + false); try { - Map jobData = createJobMapForExecutionContext(securityProperties.getAdminUser()); registerJob( - NOTIFICATION_JOB.getName(), + context, NotificationJob.class, notificationJobCronExp, - null, - jobData); + null); } catch (Exception e) { LOG.error("While loading {} instance", NotificationJob.class.getSimpleName(), e); } @@ -368,14 +323,18 @@ public void load(final String domain) { // 4. SystemLoadReporterJob (fixed schedule, every minute) LOG.debug("Registering {}", SystemLoadReporterJob.class); + + JobExecutionContext context = new JobExecutionContext( + domain, + StringUtils.uncapitalize(SystemLoadReporterJob.class.getSimpleName()), + securityProperties.getAdminUser(), + false); try { - Map jobData = createJobMapForExecutionContext(securityProperties.getAdminUser()); registerJob( - StringUtils.uncapitalize(SystemLoadReporterJob.class.getSimpleName()), + context, SystemLoadReporterJob.class, "0 * * * * ?", - null, - jobData); + null); } catch (Exception e) { LOG.error("While loading {} instance", SystemLoadReporterJob.class.getSimpleName(), e); } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredAccessTokenCleanup.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredAccessTokenCleanup.java index 60c626b5ef..7d6c5816b3 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredAccessTokenCleanup.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredAccessTokenCleanup.java @@ -21,8 +21,8 @@ import java.time.OffsetDateTime; import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO; import org.apache.syncope.core.persistence.api.entity.task.SchedTask; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class ExpiredAccessTokenCleanup extends AbstractSchedTaskJobDelegate { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredBatchCleanup.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredBatchCleanup.java index 0b229ccf26..34f1d5b589 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredBatchCleanup.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ExpiredBatchCleanup.java @@ -20,8 +20,8 @@ import org.apache.syncope.core.persistence.api.dao.BatchDAO; import org.apache.syncope.core.persistence.api.entity.task.SchedTask; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class ExpiredBatchCleanup extends AbstractSchedTaskJobDelegate { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/GroupMemberProvisionTaskJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/GroupMemberProvisionTaskJobDelegate.java index 74d9ef1e87..4e39971930 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/GroupMemberProvisionTaskJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/GroupMemberProvisionTaskJobDelegate.java @@ -36,8 +36,8 @@ import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.AnyObjectProvisioningManager; import org.apache.syncope.core.provisioning.api.UserProvisioningManager; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -72,8 +72,8 @@ public void execute( final JobExecutionContext context) throws JobExecutionException { - groupKey = context.getMergedJobDataMap().getString(GROUP_KEY_JOBDETAIL_KEY); - action = (ProvisionAction) context.getMergedJobDataMap().get(ACTION_JOBDETAIL_KEY); + groupKey = (String) context.getData().get(GROUP_KEY_JOBDETAIL_KEY); + action = (ProvisionAction) context.getData().get(ACTION_JOBDETAIL_KEY); super.execute(taskType, taskKey, dryRun, context); } @@ -100,14 +100,14 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo + (action == ProvisionAction.DEPROVISION ? "de" : "") + "provision " + users.size() + " users from " + gResources); - for (int i = 0; i < users.size() && !interrupt; i++) { + for (User user : users) { List statuses = action == ProvisionAction.DEPROVISION ? userProvisioningManager.deprovision( - users.get(i).getKey(), gResources, false, executor) + user.getKey(), gResources, false, executor) : userProvisioningManager.provision( - users.get(i).getKey(), true, null, gResources, false, executor); + user.getKey(), true, null, gResources, false, executor); for (PropagationStatus propagationStatus : statuses) { - result.append("User ").append(users.get(i).getKey()).append('\t'). + result.append("User ").append(user.getKey()).append('\t'). append("Resource ").append(propagationStatus.getResource()).append('\t'). append(propagationStatus.getStatus()); if (StringUtils.isNotBlank(propagationStatus.getFailureReason())) { @@ -117,11 +117,6 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo } result.append('\n'); } - if (interrupt) { - LOG.debug("Group assignment interrupted"); - interrupted = true; - return result.append("\n*** Group assignment interrupted ***\n").toString(); - } membershipCond = new MembershipCond(); membershipCond.setGroup(groupKey); @@ -130,16 +125,16 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo + (action == ProvisionAction.DEPROVISION ? "de" : "") + "provision " + anyObjects.size() + " any objects from " + gResources); - for (int i = 0; i < anyObjects.size() && !interrupt; i++) { + for (AnyObject anyObject : anyObjects) { List statuses = action == ProvisionAction.DEPROVISION ? anyObjectProvisioningManager.deprovision( - anyObjects.get(i).getKey(), gResources, false, executor) + anyObject.getKey(), gResources, false, executor) : anyObjectProvisioningManager.provision( - anyObjects.get(i).getKey(), gResources, false, executor); + anyObject.getKey(), gResources, false, executor); for (PropagationStatus propagationStatus : statuses) { - result.append(anyObjects.get(i).getType().getKey()).append(' '). - append(anyObjects.get(i).getKey()).append('\t'). + result.append(anyObject.getType().getKey()).append(' '). + append(anyObject.getKey()).append('\t'). append("Resource ").append(propagationStatus.getResource()).append('\t'). append(propagationStatus.getStatus()); if (StringUtils.isNotBlank(propagationStatus.getFailureReason())) { @@ -149,11 +144,6 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo } result.append('\n'); } - if (interrupt) { - LOG.debug("Group assignment interrupted"); - interrupted = true; - result.append("\n*** Group assignment interrupted ***\n"); - } return result.toString(); } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/Job.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/Job.java new file mode 100644 index 0000000000..054530f619 --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/Job.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.java.job; + +import java.util.Optional; +import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; +import org.apache.syncope.core.spring.security.AuthContextUtils; +import org.apache.syncope.core.spring.security.SecureRandomUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +public abstract class Job implements Runnable { + + private static final Logger LOG = LoggerFactory.getLogger(Job.class); + + public static final String OPERATION_ID = "operation.id"; + + @Autowired + private JobStatusDAO jobStatusDAO; + + private JobExecutionContext context; + + public JobExecutionContext getContext() { + return context; + } + + public void setContext(final JobExecutionContext context) { + this.context = context; + } + + protected abstract void execute(JobExecutionContext context) throws JobExecutionException; + + @Override + public void run() { + setContext(Optional.ofNullable(context).orElseGet(() -> new JobExecutionContext( + AuthContextUtils.getDomain(), + getClass().getName() + "_" + SecureRandomUtils.generateRandomUUID().toString(), + AuthContextUtils.getWho(), + false))); + + if (AuthContextUtils.callAsAdmin(context.getDomain(), () -> jobStatusDAO.lock(context.getJobName()))) { + LOG.debug("Job {} locked, starting execution", context.getJobName()); + + try { + execute(context); + } catch (JobExecutionException e) { + LOG.error("While executing job {}", context.getJobName(), e); + } finally { + AuthContextUtils.runAsAdmin(context.getDomain(), () -> jobStatusDAO.unlock(context.getJobName())); + } + } else { + LOG.info("Could not lock job {}, skipping execution", context.getJobName()); + } + } +} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java index e8eb09fe2b..e1668fe935 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdater.java @@ -64,16 +64,18 @@ public void update(final JobStatusEvent event) { } if (event.getJobStatus() == null) { - LOG.debug("Deleting status for job '{}#{}'", event.getDomain(), event.getJobRefDesc()); - - AuthContextUtils.runAsAdmin(event.getDomain(), () -> jobStatusDAO.deleteById(event.getJobRefDesc())); + LOG.debug("Requesting to delete status for job '{}#{}', ignoring", event.getDomain(), event.getJobName()); } else { LOG.debug("Updating job '{}#{}' with status '{}'", - event.getDomain(), event.getJobRefDesc(), event.getJobStatus()); + event.getDomain(), event.getJobName(), event.getJobStatus()); AuthContextUtils.runAsAdmin(event.getDomain(), () -> { - JobStatus jobStatus = entityFactory.newEntity(JobStatus.class); - jobStatus.setKey(event.getJobRefDesc()); + JobStatus jobStatus = jobStatusDAO.findById(event.getJobName()).orElse(null); + if (jobStatus == null) { + jobStatus = entityFactory.newEntity(JobStatus.class); + jobStatus.setKey(event.getJobName()); + } + jobStatus.setStatus(event.getJobStatus()); jobStatusDAO.save(jobStatus); }); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SchedulerDBInit.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SchedulerDBInit.java deleted file mode 100644 index f94cce8597..0000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SchedulerDBInit.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.job; - -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.jdbc.BadSqlGrammarException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.init.DatabasePopulator; -import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; -import org.springframework.util.Assert; - -/** - * Ensure Quartz database initialization occurs only if Quartz tables are not already present. - * - * @see org.springframework.jdbc.datasource.init.DataSourceInitializer - */ -public class SchedulerDBInit implements InitializingBean { - - private static final Logger LOG = LoggerFactory.getLogger(SchedulerDBInit.class); - - private DataSource dataSource; - - private DatabasePopulator databasePopulator; - - public void setDataSource(final DataSource dataSource) { - this.dataSource = dataSource; - } - - public void setDatabasePopulator(final DatabasePopulator databasePopulator) { - this.databasePopulator = databasePopulator; - } - - @Override - public void afterPropertiesSet() throws Exception { - Assert.state(this.dataSource != null, "DataSource must be set"); - Assert.state(this.databasePopulator != null, "DatabasePopulator must be set"); - - JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource); - boolean existingData; - try { - existingData = jdbcTemplate.queryForObject("SELECT COUNT(0) FROM QRTZ_SCHEDULER_STATE", Integer.class) >= 0; - } catch (BadSqlGrammarException e) { - LOG.debug("Could not access to table QRTZ_SCHEDULER_STATE", e); - existingData = false; - } - - if (existingData) { - LOG.info("Quartz tables found in the database, leaving untouched"); - } else { - LOG.info("No Quartz tables found, creating"); - - DatabasePopulatorUtils.execute(databasePopulator, this.dataSource); - } - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeSpringBeanJobFactory.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeSpringBeanJobFactory.java deleted file mode 100644 index aee29b1909..0000000000 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeSpringBeanJobFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.syncope.core.provisioning.java.job; - -import org.apache.syncope.core.spring.ApplicationContextProvider; -import org.quartz.spi.TriggerFiredBundle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.scheduling.quartz.SpringBeanJobFactory; - -public class SyncopeSpringBeanJobFactory extends SpringBeanJobFactory { - - private static final Logger LOG = LoggerFactory.getLogger(SyncopeSpringBeanJobFactory.class); - - @Override - protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception { - Object job = super.createJobInstance(bundle); - - DefaultListableBeanFactory factory = ApplicationContextProvider.getBeanFactory(); - try { - if (factory.containsSingleton(bundle.getJobDetail().getKey().getName())) { - factory.destroySingleton(bundle.getJobDetail().getKey().getName()); - } - factory.registerSingleton(bundle.getJobDetail().getKey().getName(), job); - } catch (Exception e) { - LOG.error("While attempting to replace job instance as singleton Spring bean", e); - } - - return job; - } -} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskScheduler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskScheduler.java new file mode 100644 index 0000000000..d9ca2a048a --- /dev/null +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskScheduler.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.java.job; + +import java.time.Instant; +import java.time.OffsetDateTime; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; +import org.apache.syncope.core.spring.security.AuthContextUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.aop.support.AopUtils; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.scheduling.support.CronTrigger; + +public class SyncopeTaskScheduler { + + protected static final Logger LOG = LoggerFactory.getLogger(SyncopeTaskScheduler.class); + + protected final TaskScheduler scheduler; + + protected final JobStatusDAO jobStatusDAO; + + protected final Map, Pair>> tasks = new ConcurrentHashMap<>(); + + public SyncopeTaskScheduler(final TaskScheduler scheduler, final JobStatusDAO jobStatusDAO) { + this.scheduler = scheduler; + this.jobStatusDAO = jobStatusDAO; + } + + public void register(final Job job) { + tasks.put( + Pair.of(job.getContext().getDomain(), job.getContext().getJobName()), + Pair.of(job, null)); + } + + public void start(final String domain, final String jobName) { + Optional.ofNullable(tasks.get(Pair.of(domain, jobName))). + ifPresent(pair -> schedule(pair.getLeft(), Instant.now())); + } + + public void schedule(final Job job, final CronTrigger trigger) { + ScheduledFuture future = scheduler.schedule(job, trigger); + tasks.put( + Pair.of(job.getContext().getDomain(), job.getContext().getJobName()), + Pair.of(job, future)); + } + + public void schedule(final Job job, final Instant startTime) { + ScheduledFuture future = scheduler.schedule(job, startTime); + tasks.put( + Pair.of(job.getContext().getDomain(), job.getContext().getJobName()), + Pair.of(job, future)); + } + + public boolean contains(final String domain, final String jobName) { + return tasks.containsKey(Pair.of(domain, jobName)); + } + + public Optional> getJobClass(final String domain, final String jobName) { + return Optional.ofNullable(tasks.get(Pair.of(domain, jobName))). + map(pair -> AopUtils.getTargetClass(pair.getLeft())); + } + + public Optional getNextTrigger(final String domain, final String jobName) { + return Optional.ofNullable(tasks.get(Pair.of(domain, jobName))). + filter(f -> f.getRight() != null). + map(f -> f.getRight().getDelay(TimeUnit.SECONDS)). + filter(delay -> delay > 0). + map(delay -> OffsetDateTime.now().plusSeconds(delay)); + } + + public void cancel(final String domain, final String jobName) { + Optional.ofNullable(tasks.get(Pair.of(domain, jobName))). + filter(f -> f.getRight() != null).ifPresent(f -> f.getRight().cancel(true)); + } + + public void delete(final String domain, final String jobName) { + tasks.remove(Pair.of(domain, jobName)); + AuthContextUtils.runAsAdmin(domain, () -> jobStatusDAO.unlock(jobName)); + } + + public List getJobNames(final String domain) { + return tasks.keySet().stream().filter(pair -> domain.equals(pair.getLeft())).map(Pair::getRight).toList(); + } +} diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SystemLoadReporterJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SystemLoadReporterJob.java index a8d5b34663..5b8a223405 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SystemLoadReporterJob.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SystemLoadReporterJob.java @@ -20,14 +20,14 @@ import java.lang.management.ManagementFactory; import org.apache.syncope.common.lib.info.SystemInfo; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.springframework.context.ApplicationEventPublisher; /** * Reports about system load. */ -public class SystemLoadReporterJob extends AbstractInterruptableJob { +public class SystemLoadReporterJob extends Job { protected static final Integer MB = 1024 * 1024; @@ -38,7 +38,7 @@ public SystemLoadReporterJob(final ApplicationEventPublisher publisher) { } @Override - public void execute(final JobExecutionContext context) throws JobExecutionException { + protected void execute(final JobExecutionContext context) throws JobExecutionException { SystemInfo.LoadInstant instant = new SystemInfo.LoadInstant(); instant.setSystemLoadAverage(ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java index 1e493b8d9e..3acb31d25c 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/TaskJob.java @@ -22,18 +22,17 @@ import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; -import org.apache.syncope.core.provisioning.api.job.JobDelegate; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.job.JobManager; import org.apache.syncope.core.provisioning.api.job.SchedTaskJobDelegate; import org.apache.syncope.core.spring.implementation.ImplementationManager; import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -public class TaskJob extends AbstractInterruptableJob { +public class TaskJob extends Job { private static final Logger LOG = LoggerFactory.getLogger(TaskJob.class); @@ -53,35 +52,27 @@ public enum Status { @Autowired private DomainHolder domainHolder; - private SchedTaskJobDelegate delegate; - - @Override - public JobDelegate getDelegate() { - return delegate; - } - @Override - public void execute(final JobExecutionContext context) throws JobExecutionException { - String domain = context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY); - if (!domainHolder.getDomains().containsKey(domain)) { - LOG.debug("Domain {} not found, skipping", domain); + protected void execute(final JobExecutionContext context) throws JobExecutionException { + if (!domainHolder.getDomains().containsKey(context.getDomain())) { + LOG.debug("Domain {} not found, skipping", context.getDomain()); return; } - String taskKey = context.getMergedJobDataMap().getString(JobManager.TASK_KEY); + String taskKey = (String) context.getData().get(JobManager.TASK_KEY); try { - AuthContextUtils.runAsAdmin(domain, () -> { + AuthContextUtils.runAsAdmin(context.getDomain(), () -> { try { - String implKey = context.getMergedJobDataMap().getString(JobManager.DELEGATE_IMPLEMENTATION); + String implKey = (String) context.getData().get(JobManager.DELEGATE_IMPLEMENTATION); Implementation impl = implementationDAO.findById(implKey).orElse(null); if (impl == null) { LOG.error("Could not find Implementation '{}', aborting", implKey); } else { - delegate = ImplementationManager.build(impl); + SchedTaskJobDelegate delegate = ImplementationManager.build(impl); delegate.execute( - (TaskType) context.getMergedJobDataMap().get(JobManager.TASK_TYPE), + (TaskType) context.getData().get(JobManager.TASK_TYPE), taskKey, - context.getMergedJobDataMap().getBoolean(JobManager.DRY_RUN_JOBDETAIL_KEY), + context.isDryRun(), context); } } catch (Exception e) { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/AbstractNotificationJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/AbstractNotificationJobDelegate.java index f1462388d6..ad135b627c 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/AbstractNotificationJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/AbstractNotificationJobDelegate.java @@ -31,11 +31,11 @@ import org.apache.syncope.core.persistence.api.utils.ExceptionUtils2; import org.apache.syncope.core.provisioning.api.AuditManager; import org.apache.syncope.core.provisioning.api.event.JobStatusEvent; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.job.JobManager; import org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationEventPublisher; @@ -55,10 +55,6 @@ public abstract class AbstractNotificationJobDelegate implements NotificationJob protected final ApplicationEventPublisher publisher; - protected boolean interrupt; - - protected boolean interrupted; - protected AbstractNotificationJobDelegate( final TaskDAO taskDAO, final TaskUtilsFactory taskUtilsFactory, @@ -75,17 +71,7 @@ protected AbstractNotificationJobDelegate( protected void setStatus(final String status) { publisher.publishEvent(new JobStatusEvent( - this, AuthContextUtils.getDomain(), JobManager.NOTIFICATION_JOB.getName(), status)); - } - - @Override - public void interrupt() { - interrupt = true; - } - - @Override - public boolean isInterrupted() { - return interrupted; + this, AuthContextUtils.getDomain(), JobManager.NOTIFICATION_JOB, status)); } protected abstract void notify(String to, NotificationTask task, TaskExec execution) @@ -118,14 +104,12 @@ public TaskExec executeSingle(final NotificationTask task, fin execution.setMessage(message); } } else { - if (LOG.isDebugEnabled()) { - LOG.debug("About to send notifications:\n" - + task.getRecipients() + '\n' - + task.getSender() + '\n' - + task.getSubject() + '\n' - + task.getHtmlBody() + '\n' - + task.getTextBody() + '\n'); - } + LOG.debug("About to send notifications:\n{}\n{}\n{}\n{}\n{}", + task.getRecipients(), + task.getSender(), + task.getSubject(), + task.getHtmlBody(), + task.getTextBody()); setStatus("Sending notifications to " + task.getRecipients()); @@ -190,17 +174,11 @@ public void execute(final String executor) throws JobExecutionException { setStatus("Sending out " + tasks.size() + " notifications"); - for (int i = 0; i < tasks.size() && !interrupt; i++) { + for (int i = 0; i < tasks.size(); i++) { LOG.debug("Found notification task {} to be executed: starting...", tasks.get(i)); executeSingle(tasks.get(i), executor); LOG.debug("Notification task {} executed", tasks.get(i)); } - if (interrupt) { - LOG.debug("Notification job interrupted"); - interrupted = true; - } - - setStatus(null); } protected static boolean hasToBeRegistered(final TaskExec execution) { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java index 4d43eaa9a2..860f471ba7 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/notification/NotificationJob.java @@ -20,14 +20,12 @@ import java.util.Optional; import org.apache.syncope.core.persistence.api.DomainHolder; -import org.apache.syncope.core.provisioning.api.job.JobDelegate; -import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.notification.NotificationJobDelegate; -import org.apache.syncope.core.provisioning.java.job.AbstractInterruptableJob; +import org.apache.syncope.core.provisioning.java.job.Job; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecurityProperties; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +34,7 @@ * * @see org.apache.syncope.core.persistence.api.entity.task.NotificationTask */ -public class NotificationJob extends AbstractInterruptableJob { +public class NotificationJob extends Job { public enum Status { @@ -66,15 +64,9 @@ public NotificationJob( } @Override - public JobDelegate getDelegate() { - return delegate; - } - - @Override - public void execute(final JobExecutionContext context) throws JobExecutionException { + protected void execute(final JobExecutionContext context) throws JobExecutionException { LOG.debug("Waking up..."); - String executor = Optional.ofNullable(context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY)). - orElse(securityProperties.getAdminUser()); + String executor = Optional.ofNullable(context.getExecutor()).orElse(securityProperties.getAdminUser()); for (String domain : domainHolder.getDomains().keySet()) { try { AuthContextUtils.runAsAdmin(domain, () -> { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java index 2081dfdf17..dfa3beb1f3 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/AbstractReportJobDelegate.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.OutputStream; import java.time.OffsetDateTime; -import java.util.Objects; import java.util.Optional; import java.util.zip.Deflater; import java.util.zip.ZipEntry; @@ -35,15 +34,14 @@ import org.apache.syncope.core.persistence.api.entity.ReportExec; import org.apache.syncope.core.persistence.api.utils.ExceptionUtils2; import org.apache.syncope.core.provisioning.api.AuditManager; -import org.apache.syncope.core.provisioning.api.data.ReportDataBinder; import org.apache.syncope.core.provisioning.api.event.JobStatusEvent; -import org.apache.syncope.core.provisioning.api.job.JobManager; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; +import org.apache.syncope.core.provisioning.api.job.JobNamer; import org.apache.syncope.core.provisioning.api.job.report.ReportJobDelegate; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.core.spring.security.SecurityProperties; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -73,9 +71,6 @@ public abstract class AbstractReportJobDelegate implements ReportJobDelegate { @Autowired protected EntityFactory entityFactory; - @Autowired - protected ReportDataBinder reportDataBinder; - /** * Notification manager. */ @@ -91,29 +86,14 @@ public abstract class AbstractReportJobDelegate implements ReportJobDelegate { @Autowired protected ApplicationEventPublisher publisher; - protected boolean interrupt; - - protected boolean interrupted; - @Override public void setConf(final ReportConf conf) { this.conf = conf; } protected void setStatus(final String status) { - Objects.requireNonNull(report, "Report cannot be undefined"); publisher.publishEvent(new JobStatusEvent( - this, AuthContextUtils.getDomain(), reportDataBinder.buildRefDesc(report), status)); - } - - @Override - public void interrupt() { - interrupt = true; - } - - @Override - public boolean isInterrupted() { - return interrupted; + this, AuthContextUtils.getDomain(), JobNamer.getJobName(report), status)); } @Transactional @@ -131,8 +111,7 @@ public void execute( return; } - String executor = Optional.ofNullable(context.getMergedJobDataMap().getString(JobManager.EXECUTOR_KEY)). - orElse(securityProperties.getAdminUser()); + String executor = Optional.ofNullable(context.getExecutor()).orElse(securityProperties.getAdminUser()); ReportExec execution = entityFactory.newEntity(ReportExec.class); execution.setStart(OffsetDateTime.now()); execution.setReport(report); @@ -149,7 +128,7 @@ public void execute( // a single ZipEntry in the ZipOutputStream zos.putNextEntry(new ZipEntry(report.getName())); } catch (IOException e) { - throw new JobExecutionException("While configuring for output", e, true); + throw new JobExecutionException("While configuring for output", e); } setStatus("Starting"); @@ -165,8 +144,6 @@ public void execute( execution.setMessage(ExceptionUtils2.getFullStackTrace(e)); execution.setStatus(ReportJob.Status.FAILURE.name()); } finally { - setStatus(null); - try { zos.closeEntry(); zos.close(); @@ -182,8 +159,6 @@ public void execute( report.add(execution); report = reportDAO.save(report); - setStatus(null); - notificationManager.createTasks( executor, AuditElements.EventCategoryType.REPORT, @@ -211,7 +186,7 @@ public void execute( * @param dryRun whether to actually touch the data * @param os where to stream report execution's data * @param executor the user executing this report - * @param context Quartz' execution context, can be used to pass parameters to the job + * @param context job execution context, can be used to pass parameters to the job * @return the report execution status to be set * @throws JobExecutionException if anything goes wrong */ diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java index c5afc00247..d3d827fb19 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/report/ReportJob.java @@ -23,22 +23,21 @@ import org.apache.syncope.core.persistence.api.DomainHolder; import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.entity.Implementation; -import org.apache.syncope.core.provisioning.api.job.JobDelegate; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.job.JobManager; import org.apache.syncope.core.provisioning.api.job.report.ReportJobDelegate; -import org.apache.syncope.core.provisioning.java.job.AbstractInterruptableJob; +import org.apache.syncope.core.provisioning.java.job.Job; import org.apache.syncope.core.spring.implementation.ImplementationManager; import org.apache.syncope.core.spring.security.AuthContextUtils; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; /** - * Quartz job for executing a given report. + * Job executing a given report. */ -public class ReportJob extends AbstractInterruptableJob { +public class ReportJob extends Job { private static final Logger LOG = LoggerFactory.getLogger(ReportJob.class); @@ -60,31 +59,23 @@ public enum Status { @Autowired private DomainHolder domainHolder; - private ReportJobDelegate delegate; - - @Override - public JobDelegate getDelegate() { - return delegate; - } - @Override - public void execute(final JobExecutionContext context) throws JobExecutionException { - String domain = context.getMergedJobDataMap().getString(JobManager.DOMAIN_KEY); - if (!domainHolder.getDomains().containsKey(domain)) { - LOG.debug("Domain {} not found, skipping", domain); + protected void execute(final JobExecutionContext context) throws JobExecutionException { + if (!domainHolder.getDomains().containsKey(context.getDomain())) { + LOG.debug("Domain {} not found, skipping", context.getDomain()); return; } - String reportKey = context.getMergedJobDataMap().getString(JobManager.REPORT_KEY); + String reportKey = (String) context.getData().get(JobManager.REPORT_KEY); try { - AuthContextUtils.runAsAdmin(domain, () -> { + AuthContextUtils.runAsAdmin(context.getDomain(), () -> { try { - String implKey = context.getMergedJobDataMap().getString(JobManager.DELEGATE_IMPLEMENTATION); + String implKey = (String) context.getData().get(JobManager.DELEGATE_IMPLEMENTATION); Implementation impl = implementationDAO.findById(implKey).orElse(null); if (impl == null) { LOG.error("Could not find Implementation '{}', aborting", implKey); } else { - delegate = ImplementationManager.buildReportJobDelegate( + ReportJobDelegate delegate = ImplementationManager.buildReportJobDelegate( impl, () -> perContextReportJobDelegates.get(impl.getKey()), instance -> perContextReportJobDelegates.put(impl.getKey(), instance)). @@ -92,7 +83,7 @@ public void execute(final JobExecutionContext context) throws JobExecutionExcept "Could not instantiate " + impl.getBody())); delegate.execute( reportKey, - context.getMergedJobDataMap().getBoolean(JobManager.DRY_RUN_JOBDETAIL_KEY), + context.isDryRun(), context); } } catch (Exception e) { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java index 7155fcfa56..8c64619fb9 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractProvisioningJobDelegate.java @@ -40,11 +40,11 @@ import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.ConnectorManager; import org.apache.syncope.core.provisioning.api.ProvisionSorter; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate; import org.apache.syncope.core.provisioning.java.job.TaskJob; import org.apache.syncope.core.spring.implementation.ImplementationManager; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public abstract class AbstractProvisioningJobDelegate> @@ -157,9 +157,6 @@ protected String createReport( if (dryRun) { report.append("==> Dry run only, no modifications were made <==\n\n"); } - if (interrupted) { - report.append("==> Execution was interrupted <==\n\n"); - } List rSuccCreate = new ArrayList<>(); List rFailCreate = new ArrayList<>(); @@ -204,203 +201,182 @@ protected String createReport( for (ProvisioningReport provResult : provResults) { switch (provResult.getStatus()) { - case SUCCESS: + case SUCCESS -> { switch (provResult.getOperation()) { - case CREATE: + case CREATE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rSuccCreate.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uSuccCreate.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laSuccCreate.add(provResult); - break; - case GROUP: + case GROUP -> gSuccCreate.add(provResult); - break; - default: + default -> aSuccCreate.add(provResult); } } - break; + } - case UPDATE: + case UPDATE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rSuccUpdate.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uSuccUpdate.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laSuccUpdate.add(provResult); - break; - case GROUP: + case GROUP -> gSuccUpdate.add(provResult); - break; - default: + default -> aSuccUpdate.add(provResult); } } - break; + } - case DELETE: + case DELETE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rSuccDelete.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uSuccDelete.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laSuccDelete.add(provResult); - break; - case GROUP: + case GROUP -> gSuccDelete.add(provResult); - break; - default: + default -> aSuccDelete.add(provResult); } } - break; + } - case NONE: + case NONE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rSuccNone.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uSuccNone.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laSuccNone.add(provResult); - break; - case GROUP: + case GROUP -> gSuccNone.add(provResult); - break; - default: + default -> aSuccNone.add(provResult); } } - break; + } - default: + default -> { + } } - break; + } - case FAILURE: + case FAILURE -> { switch (provResult.getOperation()) { - case CREATE: + case CREATE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rFailCreate.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uFailCreate.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laFailCreate.add(provResult); - break; - case GROUP: + case GROUP -> gFailCreate.add(provResult); - break; - default: + default -> aFailCreate.add(provResult); } } - break; + } - case UPDATE: + case UPDATE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rFailUpdate.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uFailUpdate.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laFailUpdate.add(provResult); - break; - case GROUP: + case GROUP -> gFailUpdate.add(provResult); - break; - default: + default -> aFailUpdate.add(provResult); } } - break; + } - case DELETE: + case DELETE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rFailDelete.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uFailDelete.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laFailDelete.add(provResult); - break; - case GROUP: + case GROUP -> gFailDelete.add(provResult); - break; - default: + default -> aFailDelete.add(provResult); } } - break; + } - default: + default -> { + } } - break; + } - case IGNORE: + case IGNORE -> { if (StringUtils.isBlank(provResult.getAnyType())) { rIgnore.add(provResult); } else { switch (provResult.getAnyType()) { - case USER: + case USER -> uIgnore.add(provResult); - break; - case LINKED_ACCOUNT: + case LINKED_ACCOUNT -> laIgnore.add(provResult); - break; - case GROUP: + case GROUP -> gIgnore.add(provResult); - break; - default: + default -> aIgnore.add(provResult); } } - break; + } - default: + default -> { + } } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java index 7b0fd0c5c4..551dd061f3 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPullResultHandler.java @@ -55,6 +55,7 @@ import org.apache.syncope.core.provisioning.api.cache.VirAttrCache; import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheKey; import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheValue; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationException; import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException; @@ -65,7 +66,6 @@ import org.apache.syncope.core.spring.security.DelegatedAdministrationException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java index c687ac791c..d6dc1d043c 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/AbstractPushResultHandler.java @@ -47,6 +47,7 @@ import org.apache.syncope.core.provisioning.api.MappingManager; import org.apache.syncope.core.provisioning.api.PropagationByResource; import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.notification.NotificationManager; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; @@ -54,18 +55,59 @@ import org.apache.syncope.core.provisioning.api.pushpull.PushActions; import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler; import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.identityconnectors.framework.common.objects.ConnectorObject; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler implements SyncopePushResultHandler { + protected static void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) { + if (!reporter.getStatuses().isEmpty()) { + result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus())); + result.setMessage(reporter.getStatuses().get(0).getFailureReason()); + } + } + + protected static ResourceOperation toResourceOperation(final UnmatchingRule rule) { + return switch (rule) { + case ASSIGN, PROVISION -> + ResourceOperation.CREATE; + default -> + ResourceOperation.NONE; + }; + } + + protected static ResourceOperation toResourceOperation(final MatchingRule rule) { + return switch (rule) { + case UPDATE -> + ResourceOperation.UPDATE; + case DEPROVISION, UNASSIGN -> + ResourceOperation.DELETE; + default -> + ResourceOperation.NONE; + }; + } + + protected static ProvisioningReport.Status toProvisioningReportStatus(final ExecStatus status) { + switch (status) { + case FAILURE: + return ProvisioningReport.Status.FAILURE; + + case SUCCESS: + return ProvisioningReport.Status.SUCCESS; + + case CREATED: + case NOT_ATTEMPTED: + default: + return ProvisioningReport.Status.IGNORE; + } + } + @Autowired protected OutboundMatcher outboundMatcher; @@ -85,7 +127,7 @@ public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHan protected MappingManager mappingManager; @Autowired - protected SchedulerFactoryBean scheduler; + protected SyncopeTaskScheduler scheduler; protected abstract String getName(Any any); @@ -321,7 +363,7 @@ protected void doHandle(final Any any, final Provision provision) throws JobE result.setOperation(toResourceOperation(profile.getTask().getUnmatchingRule())); switch (profile.getTask().getUnmatchingRule()) { - case ASSIGN: + case ASSIGN -> { for (PushActions action : profile.getActions()) { action.beforeAssign(profile, any); } @@ -332,9 +374,9 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { assign(any, enable, result); } - break; + } - case PROVISION: + case PROVISION -> { for (PushActions action : profile.getActions()) { action.beforeProvision(profile, any); } @@ -345,9 +387,9 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { provision(any, enable, result); } - break; + } - case UNLINK: + case UNLINK -> { for (PushActions action : profile.getActions()) { action.beforeUnlink(profile, any); } @@ -358,21 +400,22 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { link(any, true, result); } - break; + } - case IGNORE: + case IGNORE -> { LOG.debug("Ignored any: {}", any); result.setStatus(ProvisioningReport.Status.IGNORE); - break; + } - default: - // do nothing + default -> { + } } + // do nothing } else { result.setOperation(toResourceOperation(profile.getTask().getMatchingRule())); switch (profile.getTask().getMatchingRule()) { - case UPDATE: + case UPDATE -> { for (PushActions action : profile.getActions()) { action.beforeUpdate(profile, any); } @@ -382,9 +425,9 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { update(any, enable, beforeObj, result); } - break; + } - case DEPROVISION: + case DEPROVISION -> { for (PushActions action : profile.getActions()) { action.beforeDeprovision(profile, any); } @@ -395,9 +438,9 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { deprovision(any, beforeObj, result); } - break; + } - case UNASSIGN: + case UNASSIGN -> { for (PushActions action : profile.getActions()) { action.beforeUnassign(profile, any); } @@ -408,9 +451,9 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { unassign(any, beforeObj, result); } - break; + } - case LINK: + case LINK -> { for (PushActions action : profile.getActions()) { action.beforeLink(profile, any); } @@ -421,9 +464,9 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { link(any, false, result); } - break; + } - case UNLINK: + case UNLINK -> { for (PushActions action : profile.getActions()) { action.beforeUnlink(profile, any); } @@ -434,17 +477,17 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } else { link(any, true, result); } + } - break; - - case IGNORE: + case IGNORE -> { LOG.debug("Ignored any: {}", any); result.setStatus(ProvisioningReport.Status.IGNORE); - break; + } - default: - // do nothing + default -> { + } } + // do nothing } for (PushActions action : profile.getActions()) { @@ -500,48 +543,4 @@ protected void doHandle(final Any any, final Provision provision) throws JobE } } } - - protected static void reportPropagation(final ProvisioningReport result, final PropagationReporter reporter) { - if (!reporter.getStatuses().isEmpty()) { - result.setStatus(toProvisioningReportStatus(reporter.getStatuses().get(0).getStatus())); - result.setMessage(reporter.getStatuses().get(0).getFailureReason()); - } - } - - protected static ResourceOperation toResourceOperation(final UnmatchingRule rule) { - switch (rule) { - case ASSIGN: - case PROVISION: - return ResourceOperation.CREATE; - default: - return ResourceOperation.NONE; - } - } - - protected static ResourceOperation toResourceOperation(final MatchingRule rule) { - switch (rule) { - case UPDATE: - return ResourceOperation.UPDATE; - case DEPROVISION: - case UNASSIGN: - return ResourceOperation.DELETE; - default: - return ResourceOperation.NONE; - } - } - - protected static ProvisioningReport.Status toProvisioningReportStatus(final ExecStatus status) { - switch (status) { - case FAILURE: - return ProvisioningReport.Status.FAILURE; - - case SUCCESS: - return ProvisioningReport.Status.SUCCESS; - - case CREATED: - case NOT_ATTEMPTED: - default: - return ProvisioningReport.Status.IGNORE; - } - } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java index a4a65f11f3..a2372d3ae5 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActions.java @@ -32,10 +32,10 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.ConnInstance; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java index 7fcb75bbb6..a26e156af8 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPullResultHandler.java @@ -48,6 +48,7 @@ import org.apache.syncope.core.persistence.api.entity.Realm; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.PropagationByResource; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.propagation.PropagationException; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException; @@ -58,7 +59,6 @@ import org.apache.syncope.core.spring.security.DelegatedAdministrationException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java index 3df775cf66..e4fcc49a11 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultRealmPushResultHandler.java @@ -45,12 +45,14 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource; import org.apache.syncope.core.provisioning.api.TimeoutException; import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException; import org.apache.syncope.core.provisioning.api.pushpull.PushActions; import org.apache.syncope.core.provisioning.api.pushpull.RealmPushResultHandler; import org.apache.syncope.core.provisioning.java.job.AfterHandlingJob; +import org.apache.syncope.core.provisioning.java.job.SyncopeTaskScheduler; import org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.spring.security.AuthContextUtils; @@ -58,9 +60,7 @@ import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.ObjectClass; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -107,7 +107,7 @@ protected static ProvisioningReport.Status toProvisioningReportStatus(final Exec private MappingManager mappingManager; @Autowired - private SchedulerFactoryBean scheduler; + private SyncopeTaskScheduler scheduler; @Transactional(propagation = Propagation.REQUIRES_NEW) @Override diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java index ca968b2393..13f90f2f5e 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPullResultHandler.java @@ -54,13 +54,13 @@ import org.apache.syncope.core.provisioning.api.ProvisioningManager; import org.apache.syncope.core.provisioning.api.UserProvisioningManager; import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.propagation.PropagationException; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; import org.apache.syncope.core.provisioning.api.pushpull.UserPullResultHandler; import org.apache.syncope.core.provisioning.api.rules.PullMatch; import org.identityconnectors.framework.common.objects.AttributeUtil; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class DefaultUserPullResultHandler extends AbstractPullResultHandler implements UserPullResultHandler { diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java index b7f6be3e81..7c4e09c8ea 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/DefaultUserPushResultHandler.java @@ -42,6 +42,7 @@ import org.apache.syncope.core.provisioning.api.PropagationByResource; import org.apache.syncope.core.provisioning.api.UserWorkflowResult; import org.apache.syncope.core.provisioning.api.WorkflowResult; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.propagation.PropagationReporter; import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo; import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException; @@ -50,7 +51,6 @@ import org.apache.syncope.core.provisioning.java.propagation.DefaultPropagationReporter; import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.identityconnectors.framework.common.objects.ConnectorObject; -import org.quartz.JobExecutionException; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java index 5f916b7f3b..78d7198b64 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActions.java @@ -40,6 +40,7 @@ import org.apache.syncope.core.persistence.api.dao.NotFoundException; import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.UserProvisioningManager; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; import org.apache.syncope.core.provisioning.api.rules.PullMatch; @@ -50,7 +51,6 @@ import org.identityconnectors.framework.common.objects.ObjectClass; import org.identityconnectors.framework.common.objects.OperationOptionsBuilder; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java index 94245dae5b..6e45eae041 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActions.java @@ -30,6 +30,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; import org.identityconnectors.common.security.GuardedString; @@ -37,7 +38,6 @@ import org.identityconnectors.framework.common.objects.AttributeUtil; import org.identityconnectors.framework.common.objects.OperationalAttributes; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java index f57d1a3e1c..467ba0fa4b 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullJobDelegate.java @@ -51,6 +51,8 @@ import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.ProvisionSorter; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPullResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; @@ -69,8 +71,6 @@ import org.identityconnectors.framework.common.objects.ObjectClass; import org.identityconnectors.framework.common.objects.OperationOptions; import org.identityconnectors.framework.common.objects.SyncToken; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class PullJobDelegate extends AbstractProvisioningJobDelegate implements SyncopePullExecutor { @@ -130,16 +130,6 @@ public void reportHandled(final String objectClass, final Name name) { } } - @Override - public boolean wasInterruptRequested() { - return interrupt; - } - - @Override - public void setInterrupted() { - this.interrupted = true; - } - protected void setGroupOwners(final GroupPullResultHandler ghandler) { ghandler.getGroupOwnerMap().forEach((groupKey, ownerKey) -> { Group group = groupDAO.findById(groupKey). diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullResultHandlerDispatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullResultHandlerDispatcher.java index 974ff8a542..7fb2d56a0e 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullResultHandlerDispatcher.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PullResultHandlerDispatcher.java @@ -45,12 +45,6 @@ public PullResultHandlerDispatcher( @Transactional @Override public boolean handle(final SyncDelta delta) { - if (executor.wasInterruptRequested()) { - LOG.debug("Pull interrupted"); - executor.setInterrupted(); - return false; - } - if (tpte.isEmpty()) { boolean result = nonConcurrentHandler(delta.getObjectClass().getObjectClassValue()).handle(delta); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java index a2344c27b9..000887b815 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushJobDelegate.java @@ -46,6 +46,8 @@ import org.apache.syncope.core.persistence.api.search.SearchCondVisitor; import org.apache.syncope.core.provisioning.api.Connector; import org.apache.syncope.core.provisioning.api.ProvisionSorter; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; @@ -56,8 +58,6 @@ import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.implementation.ImplementationManager; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -102,16 +102,6 @@ public void reportHandled(final String anyType, final String key) { } } - @Override - public boolean wasInterruptRequested() { - return interrupt; - } - - @Override - public void setInterrupted() { - this.interrupted = true; - } - protected boolean doHandle( final List> anys, final PushResultHandlerDispatcher dispatcher, diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushResultHandlerDispatcher.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushResultHandlerDispatcher.java index 0f50511326..9d4e06ce87 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushResultHandlerDispatcher.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/PushResultHandlerDispatcher.java @@ -39,12 +39,6 @@ public PushResultHandlerDispatcher( } public boolean handle(final String anyType, final String anyKey) { - if (executor.wasInterruptRequested()) { - LOG.debug("Push interrupted"); - executor.setInterrupted(); - return false; - } - if (tpte.isEmpty()) { boolean result = nonConcurrentHandler(anyType).handle(anyKey); diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java index 74ae55aa96..a0e5cc69f1 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePullJobDelegate.java @@ -42,6 +42,7 @@ import org.apache.syncope.core.persistence.api.entity.task.AnyTemplatePullTask; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; @@ -51,7 +52,6 @@ import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.provisioning.java.utils.TemplateUtils; import org.identityconnectors.framework.common.objects.ObjectClass; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class SinglePullJobDelegate extends PullJobDelegate implements SyncopeSinglePullExecutor { @@ -169,8 +169,6 @@ public List pull( throw e instanceof JobExecutionException ? (JobExecutionException) e : new JobExecutionException("While pulling from connector", e); - } finally { - setStatus(null); } } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java index 034d852f7b..12fba70677 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SinglePushJobDelegate.java @@ -35,12 +35,12 @@ import org.apache.syncope.core.persistence.api.entity.task.PushTask; import org.apache.syncope.core.persistence.api.entity.user.LinkedAccount; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PushActions; import org.apache.syncope.core.provisioning.api.pushpull.SyncopePushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.SyncopeSinglePushExecutor; import org.apache.syncope.core.provisioning.api.pushpull.UserPushResultHandler; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class SinglePushJobDelegate extends PushJobDelegate implements SyncopeSinglePushExecutor { @@ -127,8 +127,6 @@ public List push( throw e instanceof JobExecutionException ? (JobExecutionException) e : new JobExecutionException("While pushing to connector", e); - } finally { - setStatus(null); } } @@ -158,8 +156,6 @@ public ProvisioningReport push( throw e instanceof JobExecutionException ? (JobExecutionException) e : new JobExecutionException("While pushing to connector", e); - } finally { - setStatus(null); } } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java index 2e160619e5..6e280a7337 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegate.java @@ -45,6 +45,7 @@ import org.apache.syncope.core.persistence.api.entity.policy.PullPolicy; import org.apache.syncope.core.persistence.api.entity.task.PullTask; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.GroupPullResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; @@ -54,7 +55,6 @@ import org.apache.syncope.core.provisioning.java.utils.MappingUtils; import org.apache.syncope.core.spring.security.SecureRandomUtils; import org.identityconnectors.framework.common.objects.ObjectClass; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class StreamPullJobDelegate extends PullJobDelegate implements SyncopeStreamPullExecutor { @@ -240,8 +240,6 @@ public List pull( throw e instanceof JobExecutionException ? (JobExecutionException) e : new JobExecutionException("While stream pulling", e); - } finally { - setStatus(null); } } } diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java index 9692385b5d..dfd95b72ab 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPushJobDelegate.java @@ -36,6 +36,7 @@ import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.task.PushTask; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.AnyObjectPushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.GroupPushResultHandler; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; @@ -47,7 +48,6 @@ import org.apache.syncope.core.provisioning.java.pushpull.PushResultHandlerDispatcher; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.SecureRandomUtils; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; public class StreamPushJobDelegate extends PushJobDelegate implements SyncopeStreamPushExecutor { @@ -181,8 +181,6 @@ public List push( throw e instanceof JobExecutionException ? (JobExecutionException) e : new JobExecutionException("While stream pushing", e); - } finally { - setStatus(null); } } } diff --git a/core/provisioning-java/src/main/resources/quartz/tables_h2.sql b/core/provisioning-java/src/main/resources/quartz/tables_h2.sql deleted file mode 100644 index 50785b4621..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_h2.sql +++ /dev/null @@ -1,265 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - --- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database, --- and verifying that it works with Quartz's StdJDBCDelegate --- --- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE --- setting on your H2 database, or you will experience dead-locks --- --- --- In your Quartz properties file, you'll need to set --- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate - -CREATE TABLE QRTZ_CALENDARS ( - SCHED_NAME VARCHAR(120) NOT NULL, - CALENDAR_NAME VARCHAR (200) NOT NULL , - CALENDAR IMAGE NOT NULL -); - -CREATE TABLE QRTZ_CRON_TRIGGERS ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - CRON_EXPRESSION VARCHAR (120) NOT NULL , - TIME_ZONE_ID VARCHAR (80) -); - -CREATE TABLE QRTZ_FIRED_TRIGGERS ( - SCHED_NAME VARCHAR(120) NOT NULL, - ENTRY_ID VARCHAR (95) NOT NULL , - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - INSTANCE_NAME VARCHAR (200) NOT NULL , - FIRED_TIME BIGINT NOT NULL , - SCHED_TIME BIGINT NOT NULL , - PRIORITY INTEGER NOT NULL , - STATE VARCHAR (16) NOT NULL, - JOB_NAME VARCHAR (200) NULL , - JOB_GROUP VARCHAR (200) NULL , - IS_NONCONCURRENT BOOLEAN NULL , - REQUESTS_RECOVERY BOOLEAN NULL -); - -CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_GROUP VARCHAR (200) NOT NULL -); - -CREATE TABLE QRTZ_SCHEDULER_STATE ( - SCHED_NAME VARCHAR(120) NOT NULL, - INSTANCE_NAME VARCHAR (200) NOT NULL , - LAST_CHECKIN_TIME BIGINT NOT NULL , - CHECKIN_INTERVAL BIGINT NOT NULL -); - -CREATE TABLE QRTZ_LOCKS ( - SCHED_NAME VARCHAR(120) NOT NULL, - LOCK_NAME VARCHAR (40) NOT NULL -); - -CREATE TABLE QRTZ_JOB_DETAILS ( - SCHED_NAME VARCHAR(120) NOT NULL, - JOB_NAME VARCHAR (200) NOT NULL , - JOB_GROUP VARCHAR (200) NOT NULL , - DESCRIPTION VARCHAR (250) NULL , - JOB_CLASS_NAME VARCHAR (250) NOT NULL , - IS_DURABLE BOOLEAN NOT NULL , - IS_NONCONCURRENT BOOLEAN NOT NULL , - IS_UPDATE_DATA BOOLEAN NOT NULL , - REQUESTS_RECOVERY BOOLEAN NOT NULL , - JOB_DATA IMAGE NULL -); - -CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - REPEAT_COUNT BIGINT NOT NULL , - REPEAT_INTERVAL BIGINT NOT NULL , - TIMES_TRIGGERED BIGINT NOT NULL -); - -CREATE TABLE QRTZ_SIMPROP_TRIGGERS ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - STR_PROP_1 VARCHAR(512) NULL, - STR_PROP_2 VARCHAR(512) NULL, - STR_PROP_3 VARCHAR(512) NULL, - INT_PROP_1 INTEGER NULL, - INT_PROP_2 INTEGER NULL, - LONG_PROP_1 BIGINT NULL, - LONG_PROP_2 BIGINT NULL, - DEC_PROP_1 NUMERIC(13,4) NULL, - DEC_PROP_2 NUMERIC(13,4) NULL, - BOOL_PROP_1 BOOLEAN NULL, - BOOL_PROP_2 BOOLEAN NULL -); - -CREATE TABLE QRTZ_BLOB_TRIGGERS ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - BLOB_DATA IMAGE NULL -); - -CREATE TABLE QRTZ_TRIGGERS ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR (200) NOT NULL , - TRIGGER_GROUP VARCHAR (200) NOT NULL , - JOB_NAME VARCHAR (200) NOT NULL , - JOB_GROUP VARCHAR (200) NOT NULL , - DESCRIPTION VARCHAR (250) NULL , - NEXT_FIRE_TIME BIGINT NULL , - PREV_FIRE_TIME BIGINT NULL , - PRIORITY INTEGER NULL , - TRIGGER_STATE VARCHAR (16) NOT NULL , - TRIGGER_TYPE VARCHAR (8) NOT NULL , - START_TIME BIGINT NOT NULL , - END_TIME BIGINT NULL , - CALENDAR_NAME VARCHAR (200) NULL , - MISFIRE_INSTR SMALLINT NULL , - JOB_DATA IMAGE NULL -); - -ALTER TABLE QRTZ_CALENDARS ADD - CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY - ( - SCHED_NAME, - CALENDAR_NAME - ); - -ALTER TABLE QRTZ_CRON_TRIGGERS ADD - CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_FIRED_TRIGGERS ADD - CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY - ( - SCHED_NAME, - ENTRY_ID - ); - -ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS ADD - CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY - ( - SCHED_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_SCHEDULER_STATE ADD - CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY - ( - SCHED_NAME, - INSTANCE_NAME - ); - -ALTER TABLE QRTZ_LOCKS ADD - CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY - ( - SCHED_NAME, - LOCK_NAME - ); - -ALTER TABLE QRTZ_JOB_DETAILS ADD - CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY - ( - SCHED_NAME, - JOB_NAME, - JOB_GROUP - ); - -ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD - CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD - CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_TRIGGERS ADD - CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ); - -ALTER TABLE QRTZ_CRON_TRIGGERS ADD - CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ) REFERENCES QRTZ_TRIGGERS ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ) ON DELETE CASCADE; - - -ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD - CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ) REFERENCES QRTZ_TRIGGERS ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ) ON DELETE CASCADE; - -ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD - CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY - ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ) REFERENCES QRTZ_TRIGGERS ( - SCHED_NAME, - TRIGGER_NAME, - TRIGGER_GROUP - ) ON DELETE CASCADE; - - -ALTER TABLE QRTZ_TRIGGERS ADD - CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY - ( - SCHED_NAME, - JOB_NAME, - JOB_GROUP - ) REFERENCES QRTZ_JOB_DETAILS ( - SCHED_NAME, - JOB_NAME, - JOB_GROUP - ); - -COMMIT; diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql b/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql deleted file mode 100644 index ebb8e59702..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_mariadb.sql +++ /dev/null @@ -1,206 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - --- --- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar --- --- PLEASE consider using mysql with innodb tables to avoid locking issues --- --- In your Quartz properties file, you'll need to set --- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate --- - -BEGIN; -DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; -DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; -DROP TABLE IF EXISTS QRTZ_LOCKS; -DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; -DROP TABLE IF EXISTS QRTZ_CALENDARS; -COMMIT; - - -BEGIN; -CREATE TABLE QRTZ_JOB_DETAILS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - JOB_CLASS_NAME VARCHAR(250) NOT NULL, - IS_DURABLE VARCHAR(1) NOT NULL, - IS_NONCONCURRENT VARCHAR(1) NOT NULL, - IS_UPDATE_DATA VARCHAR(1) NOT NULL, - REQUESTS_RECOVERY VARCHAR(1) NOT NULL, - JOB_DATA BLOB NULL, - PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - NEXT_FIRE_TIME BIGINT(13) NULL, - PREV_FIRE_TIME BIGINT(13) NULL, - PRIORITY INTEGER NULL, - TRIGGER_STATE VARCHAR(16) NOT NULL, - TRIGGER_TYPE VARCHAR(8) NOT NULL, - START_TIME BIGINT(13) NOT NULL, - END_TIME BIGINT(13) NULL, - CALENDAR_NAME VARCHAR(200) NULL, - MISFIRE_INSTR SMALLINT(2) NULL, - JOB_DATA BLOB NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) - REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SIMPLE_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - REPEAT_COUNT BIGINT(7) NOT NULL, - REPEAT_INTERVAL BIGINT(12) NOT NULL, - TIMES_TRIGGERED BIGINT(10) NOT NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_CRON_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - CRON_EXPRESSION VARCHAR(200) NOT NULL, - TIME_ZONE_ID VARCHAR(80), - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SIMPROP_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - STR_PROP_1 VARCHAR(512) NULL, - STR_PROP_2 VARCHAR(512) NULL, - STR_PROP_3 VARCHAR(512) NULL, - INT_PROP_1 INT NULL, - INT_PROP_2 INT NULL, - LONG_PROP_1 BIGINT NULL, - LONG_PROP_2 BIGINT NULL, - DEC_PROP_1 NUMERIC(13,4) NULL, - DEC_PROP_2 NUMERIC(13,4) NULL, - BOOL_PROP_1 VARCHAR(1) NULL, - BOOL_PROP_2 VARCHAR(1) NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_BLOB_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - BLOB_DATA BLOB NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_CALENDARS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - CALENDAR_NAME VARCHAR(200) NOT NULL, - CALENDAR BLOB NOT NULL, - PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_FIRED_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - ENTRY_ID VARCHAR(95) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - FIRED_TIME BIGINT(13) NOT NULL, - SCHED_TIME BIGINT(13) NOT NULL, - PRIORITY INTEGER NOT NULL, - STATE VARCHAR(16) NOT NULL, - JOB_NAME VARCHAR(200) NULL, - JOB_GROUP VARCHAR(200) NULL, - IS_NONCONCURRENT VARCHAR(1) NULL, - REQUESTS_RECOVERY VARCHAR(1) NULL, - PRIMARY KEY (SCHED_NAME,ENTRY_ID) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SCHEDULER_STATE - ( - SCHED_NAME VARCHAR(120) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - LAST_CHECKIN_TIME BIGINT(13) NOT NULL, - CHECKIN_INTERVAL BIGINT(13) NOT NULL, - PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_LOCKS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - LOCK_NAME VARCHAR(40) NOT NULL, - PRIMARY KEY (SCHED_NAME,LOCK_NAME) -); -COMMIT; diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql b/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql deleted file mode 100644 index ebb8e59702..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_mysql.sql +++ /dev/null @@ -1,206 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - --- --- Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar --- --- PLEASE consider using mysql with innodb tables to avoid locking issues --- --- In your Quartz properties file, you'll need to set --- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate --- - -BEGIN; -DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; -DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; -DROP TABLE IF EXISTS QRTZ_LOCKS; -DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; -DROP TABLE IF EXISTS QRTZ_CALENDARS; -COMMIT; - - -BEGIN; -CREATE TABLE QRTZ_JOB_DETAILS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - JOB_CLASS_NAME VARCHAR(250) NOT NULL, - IS_DURABLE VARCHAR(1) NOT NULL, - IS_NONCONCURRENT VARCHAR(1) NOT NULL, - IS_UPDATE_DATA VARCHAR(1) NOT NULL, - REQUESTS_RECOVERY VARCHAR(1) NOT NULL, - JOB_DATA BLOB NULL, - PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - NEXT_FIRE_TIME BIGINT(13) NULL, - PREV_FIRE_TIME BIGINT(13) NULL, - PRIORITY INTEGER NULL, - TRIGGER_STATE VARCHAR(16) NOT NULL, - TRIGGER_TYPE VARCHAR(8) NOT NULL, - START_TIME BIGINT(13) NOT NULL, - END_TIME BIGINT(13) NULL, - CALENDAR_NAME VARCHAR(200) NULL, - MISFIRE_INSTR SMALLINT(2) NULL, - JOB_DATA BLOB NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) - REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SIMPLE_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - REPEAT_COUNT BIGINT(7) NOT NULL, - REPEAT_INTERVAL BIGINT(12) NOT NULL, - TIMES_TRIGGERED BIGINT(10) NOT NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_CRON_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - CRON_EXPRESSION VARCHAR(200) NOT NULL, - TIME_ZONE_ID VARCHAR(80), - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SIMPROP_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - STR_PROP_1 VARCHAR(512) NULL, - STR_PROP_2 VARCHAR(512) NULL, - STR_PROP_3 VARCHAR(512) NULL, - INT_PROP_1 INT NULL, - INT_PROP_2 INT NULL, - LONG_PROP_1 BIGINT NULL, - LONG_PROP_2 BIGINT NULL, - DEC_PROP_1 NUMERIC(13,4) NULL, - DEC_PROP_2 NUMERIC(13,4) NULL, - BOOL_PROP_1 VARCHAR(1) NULL, - BOOL_PROP_2 VARCHAR(1) NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_BLOB_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - BLOB_DATA BLOB NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_CALENDARS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - CALENDAR_NAME VARCHAR(200) NOT NULL, - CALENDAR BLOB NOT NULL, - PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_FIRED_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - ENTRY_ID VARCHAR(95) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - FIRED_TIME BIGINT(13) NOT NULL, - SCHED_TIME BIGINT(13) NOT NULL, - PRIORITY INTEGER NOT NULL, - STATE VARCHAR(16) NOT NULL, - JOB_NAME VARCHAR(200) NULL, - JOB_GROUP VARCHAR(200) NULL, - IS_NONCONCURRENT VARCHAR(1) NULL, - REQUESTS_RECOVERY VARCHAR(1) NULL, - PRIMARY KEY (SCHED_NAME,ENTRY_ID) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SCHEDULER_STATE - ( - SCHED_NAME VARCHAR(120) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - LAST_CHECKIN_TIME BIGINT(13) NOT NULL, - CHECKIN_INTERVAL BIGINT(13) NOT NULL, - PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) -); -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_LOCKS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - LOCK_NAME VARCHAR(40) NOT NULL, - PRIMARY KEY (SCHED_NAME,LOCK_NAME) -); -COMMIT; diff --git a/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql b/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql deleted file mode 100644 index c54493ed85..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_mysql_innodb.sql +++ /dev/null @@ -1,221 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - --- --- In your Quartz properties file, you'll need to set --- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate --- --- --- By: Ron Cordell - roncordell --- I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM. --- - -BEGIN; -DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; -DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; -DROP TABLE IF EXISTS QRTZ_LOCKS; -DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; -DROP TABLE IF EXISTS QRTZ_CALENDARS; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_JOB_DETAILS( -SCHED_NAME VARCHAR(120) NOT NULL, -JOB_NAME VARCHAR(200) NOT NULL, -JOB_GROUP VARCHAR(200) NOT NULL, -DESCRIPTION VARCHAR(250) NULL, -JOB_CLASS_NAME VARCHAR(250) NOT NULL, -IS_DURABLE VARCHAR(1) NOT NULL, -IS_NONCONCURRENT VARCHAR(1) NOT NULL, -IS_UPDATE_DATA VARCHAR(1) NOT NULL, -REQUESTS_RECOVERY VARCHAR(1) NOT NULL, -JOB_DATA BLOB NULL, -PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_TRIGGERS ( -SCHED_NAME VARCHAR(120) NOT NULL, -TRIGGER_NAME VARCHAR(200) NOT NULL, -TRIGGER_GROUP VARCHAR(200) NOT NULL, -JOB_NAME VARCHAR(200) NOT NULL, -JOB_GROUP VARCHAR(200) NOT NULL, -DESCRIPTION VARCHAR(250) NULL, -NEXT_FIRE_TIME BIGINT(13) NULL, -PREV_FIRE_TIME BIGINT(13) NULL, -PRIORITY INTEGER NULL, -TRIGGER_STATE VARCHAR(16) NOT NULL, -TRIGGER_TYPE VARCHAR(8) NOT NULL, -START_TIME BIGINT(13) NOT NULL, -END_TIME BIGINT(13) NULL, -CALENDAR_NAME VARCHAR(200) NULL, -MISFIRE_INSTR SMALLINT(2) NULL, -JOB_DATA BLOB NULL, -PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), -FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) -REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SIMPLE_TRIGGERS ( -SCHED_NAME VARCHAR(120) NOT NULL, -TRIGGER_NAME VARCHAR(200) NOT NULL, -TRIGGER_GROUP VARCHAR(200) NOT NULL, -REPEAT_COUNT BIGINT(7) NOT NULL, -REPEAT_INTERVAL BIGINT(12) NOT NULL, -TIMES_TRIGGERED BIGINT(10) NOT NULL, -PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), -FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_CRON_TRIGGERS ( -SCHED_NAME VARCHAR(120) NOT NULL, -TRIGGER_NAME VARCHAR(200) NOT NULL, -TRIGGER_GROUP VARCHAR(200) NOT NULL, -CRON_EXPRESSION VARCHAR(120) NOT NULL, -TIME_ZONE_ID VARCHAR(80), -PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), -FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SIMPROP_TRIGGERS - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - STR_PROP_1 VARCHAR(512) NULL, - STR_PROP_2 VARCHAR(512) NULL, - STR_PROP_3 VARCHAR(512) NULL, - INT_PROP_1 INT NULL, - INT_PROP_2 INT NULL, - LONG_PROP_1 BIGINT NULL, - LONG_PROP_2 BIGINT NULL, - DEC_PROP_1 NUMERIC(13,4) NULL, - DEC_PROP_2 NUMERIC(13,4) NULL, - BOOL_PROP_1 VARCHAR(1) NULL, - BOOL_PROP_2 VARCHAR(1) NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_BLOB_TRIGGERS ( -SCHED_NAME VARCHAR(120) NOT NULL, -TRIGGER_NAME VARCHAR(200) NOT NULL, -TRIGGER_GROUP VARCHAR(200) NOT NULL, -BLOB_DATA BLOB NULL, -PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), -INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP), -FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_CALENDARS ( -SCHED_NAME VARCHAR(120) NOT NULL, -CALENDAR_NAME VARCHAR(200) NOT NULL, -CALENDAR BLOB NOT NULL, -PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS ( -SCHED_NAME VARCHAR(120) NOT NULL, -TRIGGER_GROUP VARCHAR(200) NOT NULL, -PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_FIRED_TRIGGERS ( -SCHED_NAME VARCHAR(120) NOT NULL, -ENTRY_ID VARCHAR(95) NOT NULL, -TRIGGER_NAME VARCHAR(200) NOT NULL, -TRIGGER_GROUP VARCHAR(200) NOT NULL, -INSTANCE_NAME VARCHAR(200) NOT NULL, -FIRED_TIME BIGINT(13) NOT NULL, -SCHED_TIME BIGINT(13) NOT NULL, -PRIORITY INTEGER NOT NULL, -STATE VARCHAR(16) NOT NULL, -JOB_NAME VARCHAR(200) NULL, -JOB_GROUP VARCHAR(200) NULL, -IS_NONCONCURRENT VARCHAR(1) NULL, -REQUESTS_RECOVERY VARCHAR(1) NULL, -PRIMARY KEY (SCHED_NAME,ENTRY_ID)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_SCHEDULER_STATE ( -SCHED_NAME VARCHAR(120) NOT NULL, -INSTANCE_NAME VARCHAR(200) NOT NULL, -LAST_CHECKIN_TIME BIGINT(13) NOT NULL, -CHECKIN_INTERVAL BIGINT(13) NOT NULL, -PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE TABLE QRTZ_LOCKS ( -SCHED_NAME VARCHAR(120) NOT NULL, -LOCK_NAME VARCHAR(40) NOT NULL, -PRIMARY KEY (SCHED_NAME,LOCK_NAME)) -ENGINE=InnoDB; -COMMIT; - -BEGIN; -CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY); -CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP); - -CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); -CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP); -CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME); -CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); -CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME); -CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); -CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); -CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); - -CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME); -CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); -CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP); -CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP); -CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); -CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP); -COMMIT; diff --git a/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql b/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql deleted file mode 100644 index 4384ac5949..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_oracle.sql +++ /dev/null @@ -1,208 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - --- --- A hint submitted by a user: Oracle DB MUST be created as "shared" and the --- job_queue_processes parameter must be greater than 2 --- However, these settings are pretty much standard after any --- Oracle install, so most users need not worry about this. --- --- Many other users (including the primary author of Quartz) have had success --- runing in dedicated mode, so only consider the above as a hint ;-) --- - -delete from qrtz_fired_triggers; -delete from qrtz_simple_triggers; -delete from qrtz_simprop_triggers; -delete from qrtz_cron_triggers; -delete from qrtz_blob_triggers; -delete from qrtz_triggers; -delete from qrtz_job_details; -delete from qrtz_calendars; -delete from qrtz_paused_trigger_grps; -delete from qrtz_locks; -delete from qrtz_scheduler_state; - -drop table qrtz_calendars; -drop table qrtz_fired_triggers; -drop table qrtz_blob_triggers; -drop table qrtz_cron_triggers; -drop table qrtz_simple_triggers; -drop table qrtz_simprop_triggers; -drop table qrtz_triggers; -drop table qrtz_job_details; -drop table qrtz_paused_trigger_grps; -drop table qrtz_locks; -drop table qrtz_scheduler_state; - - -CREATE TABLE qrtz_job_details - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - JOB_NAME VARCHAR2(200) NOT NULL, - JOB_GROUP VARCHAR2(200) NOT NULL, - DESCRIPTION VARCHAR2(250) NULL, - JOB_CLASS_NAME VARCHAR2(250) NOT NULL, - IS_DURABLE VARCHAR2(1) NOT NULL, - IS_NONCONCURRENT VARCHAR2(1) NOT NULL, - IS_UPDATE_DATA VARCHAR2(1) NOT NULL, - REQUESTS_RECOVERY VARCHAR2(1) NOT NULL, - JOB_DATA BLOB NULL, - CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) -); -CREATE TABLE qrtz_triggers - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - TRIGGER_NAME VARCHAR2(200) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - JOB_NAME VARCHAR2(200) NOT NULL, - JOB_GROUP VARCHAR2(200) NOT NULL, - DESCRIPTION VARCHAR2(250) NULL, - NEXT_FIRE_TIME NUMBER(13) NULL, - PREV_FIRE_TIME NUMBER(13) NULL, - PRIORITY NUMBER(13) NULL, - TRIGGER_STATE VARCHAR2(16) NOT NULL, - TRIGGER_TYPE VARCHAR2(8) NOT NULL, - START_TIME NUMBER(13) NOT NULL, - END_TIME NUMBER(13) NULL, - CALENDAR_NAME VARCHAR2(200) NULL, - MISFIRE_INSTR NUMBER(2) NULL, - JOB_DATA BLOB NULL, - CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) - REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) -); -CREATE TABLE qrtz_simple_triggers - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - TRIGGER_NAME VARCHAR2(200) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - REPEAT_COUNT NUMBER(7) NOT NULL, - REPEAT_INTERVAL NUMBER(12) NOT NULL, - TIMES_TRIGGERED NUMBER(10) NOT NULL, - CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -CREATE TABLE qrtz_cron_triggers - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - TRIGGER_NAME VARCHAR2(200) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - CRON_EXPRESSION VARCHAR2(120) NOT NULL, - TIME_ZONE_ID VARCHAR2(80), - CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -CREATE TABLE qrtz_simprop_triggers - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - TRIGGER_NAME VARCHAR2(200) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - STR_PROP_1 VARCHAR2(512) NULL, - STR_PROP_2 VARCHAR2(512) NULL, - STR_PROP_3 VARCHAR2(512) NULL, - INT_PROP_1 NUMBER(10) NULL, - INT_PROP_2 NUMBER(10) NULL, - LONG_PROP_1 NUMBER(13) NULL, - LONG_PROP_2 NUMBER(13) NULL, - DEC_PROP_1 NUMERIC(13,4) NULL, - DEC_PROP_2 NUMERIC(13,4) NULL, - BOOL_PROP_1 VARCHAR2(1) NULL, - BOOL_PROP_2 VARCHAR2(1) NULL, - CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -CREATE TABLE qrtz_blob_triggers - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - TRIGGER_NAME VARCHAR2(200) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - BLOB_DATA BLOB NULL, - CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); -CREATE TABLE qrtz_calendars - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - CALENDAR_NAME VARCHAR2(200) NOT NULL, - CALENDAR BLOB NOT NULL, - CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) -); -CREATE TABLE qrtz_paused_trigger_grps - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) -); -CREATE TABLE qrtz_fired_triggers - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - ENTRY_ID VARCHAR2(95) NOT NULL, - TRIGGER_NAME VARCHAR2(200) NOT NULL, - TRIGGER_GROUP VARCHAR2(200) NOT NULL, - INSTANCE_NAME VARCHAR2(200) NOT NULL, - FIRED_TIME NUMBER(13) NOT NULL, - SCHED_TIME NUMBER(13) NOT NULL, - PRIORITY NUMBER(13) NOT NULL, - STATE VARCHAR2(16) NOT NULL, - JOB_NAME VARCHAR2(200) NULL, - JOB_GROUP VARCHAR2(200) NULL, - IS_NONCONCURRENT VARCHAR2(1) NULL, - REQUESTS_RECOVERY VARCHAR2(1) NULL, - CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID) -); -CREATE TABLE qrtz_scheduler_state - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - INSTANCE_NAME VARCHAR2(200) NOT NULL, - LAST_CHECKIN_TIME NUMBER(13) NOT NULL, - CHECKIN_INTERVAL NUMBER(13) NOT NULL, - CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) -); -CREATE TABLE qrtz_locks - ( - SCHED_NAME VARCHAR2(120) NOT NULL, - LOCK_NAME VARCHAR2(40) NOT NULL, - CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME) -); - -create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY); -create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); - -create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); -create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP); -create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME); -create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP); -create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE); -create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); -create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); -create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME); -create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); -create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); -create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); -create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); - -create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME); -create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); -create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); -create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP); -create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); -create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); diff --git a/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql b/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql deleted file mode 100644 index 634ade5aeb..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_postgres.sql +++ /dev/null @@ -1,204 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - --- Thanks to Patrick Lightbody for submitting this... --- --- In your Quartz properties file, you'll need to set --- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate - -DROP TABLE IF EXISTS qrtz_fired_triggers; -DROP TABLE IF EXISTS qrtz_paused_trigger_grps; -DROP TABLE IF EXISTS qrtz_scheduler_state; -DROP TABLE IF EXISTS qrtz_locks; -DROP TABLE IF EXISTS qrtz_simple_triggers; -DROP TABLE IF EXISTS qrtz_cron_triggers; -DROP TABLE IF EXISTS qrtz_simprop_triggers; -DROP TABLE IF EXISTS qrtz_blob_triggers; -DROP TABLE IF EXISTS qrtz_triggers; -DROP TABLE IF EXISTS qrtz_job_details; -DROP TABLE IF EXISTS qrtz_calendars; - -CREATE TABLE qrtz_job_details - ( - SCHED_NAME VARCHAR(120) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - JOB_CLASS_NAME VARCHAR(250) NOT NULL, - IS_DURABLE BOOL NOT NULL, - IS_NONCONCURRENT BOOL NOT NULL, - IS_UPDATE_DATA BOOL NOT NULL, - REQUESTS_RECOVERY BOOL NOT NULL, - JOB_DATA BYTEA NULL, - PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) -); - -CREATE TABLE qrtz_triggers - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - NEXT_FIRE_TIME BIGINT NULL, - PREV_FIRE_TIME BIGINT NULL, - PRIORITY INTEGER NULL, - TRIGGER_STATE VARCHAR(16) NOT NULL, - TRIGGER_TYPE VARCHAR(8) NOT NULL, - START_TIME BIGINT NOT NULL, - END_TIME BIGINT NULL, - CALENDAR_NAME VARCHAR(200) NULL, - MISFIRE_INSTR SMALLINT NULL, - JOB_DATA BYTEA NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) - REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP) -); - -CREATE TABLE qrtz_simple_triggers - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - REPEAT_COUNT BIGINT NOT NULL, - REPEAT_INTERVAL BIGINT NOT NULL, - TIMES_TRIGGERED BIGINT NOT NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); - -CREATE TABLE qrtz_cron_triggers - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - CRON_EXPRESSION VARCHAR(120) NOT NULL, - TIME_ZONE_ID VARCHAR(80), - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); - -CREATE TABLE qrtz_simprop_triggers - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - STR_PROP_1 VARCHAR(512) NULL, - STR_PROP_2 VARCHAR(512) NULL, - STR_PROP_3 VARCHAR(512) NULL, - INT_PROP_1 INT NULL, - INT_PROP_2 INT NULL, - LONG_PROP_1 BIGINT NULL, - LONG_PROP_2 BIGINT NULL, - DEC_PROP_1 NUMERIC(13,4) NULL, - DEC_PROP_2 NUMERIC(13,4) NULL, - BOOL_PROP_1 BOOL NULL, - BOOL_PROP_2 BOOL NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); - -CREATE TABLE qrtz_blob_triggers - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - BLOB_DATA BYTEA NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) -); - -CREATE TABLE qrtz_calendars - ( - SCHED_NAME VARCHAR(120) NOT NULL, - CALENDAR_NAME VARCHAR(200) NOT NULL, - CALENDAR BYTEA NOT NULL, - PRIMARY KEY (SCHED_NAME,CALENDAR_NAME) -); - - -CREATE TABLE qrtz_paused_trigger_grps - ( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP) -); - -CREATE TABLE qrtz_fired_triggers - ( - SCHED_NAME VARCHAR(120) NOT NULL, - ENTRY_ID VARCHAR(95) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - FIRED_TIME BIGINT NOT NULL, - SCHED_TIME BIGINT NOT NULL, - PRIORITY INTEGER NOT NULL, - STATE VARCHAR(16) NOT NULL, - JOB_NAME VARCHAR(200) NULL, - JOB_GROUP VARCHAR(200) NULL, - IS_NONCONCURRENT BOOL NULL, - REQUESTS_RECOVERY BOOL NULL, - PRIMARY KEY (SCHED_NAME,ENTRY_ID) -); - -CREATE TABLE qrtz_scheduler_state - ( - SCHED_NAME VARCHAR(120) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - LAST_CHECKIN_TIME BIGINT NOT NULL, - CHECKIN_INTERVAL BIGINT NOT NULL, - PRIMARY KEY (SCHED_NAME,INSTANCE_NAME) -); - -CREATE TABLE qrtz_locks - ( - SCHED_NAME VARCHAR(120) NOT NULL, - LOCK_NAME VARCHAR(40) NOT NULL, - PRIMARY KEY (SCHED_NAME,LOCK_NAME) -); - -create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY); -create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP); - -create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); -create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP); -create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME); -create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP); -create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE); -create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE); -create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE); -create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME); -create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME); -create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME); -create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE); -create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE); - -create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME); -create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY); -create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP); -create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP); -create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP); -create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP); - - -commit; diff --git a/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql b/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql deleted file mode 100644 index 288b990f9b..0000000000 --- a/core/provisioning-java/src/main/resources/quartz/tables_sqlServer.sql +++ /dev/null @@ -1,296 +0,0 @@ --- Licensed to the Apache Software Foundation (ASF) under one --- or more contributor license agreements. See the NOTICE file --- distributed with this work for additional information --- regarding copyright ownership. The ASF licenses this file --- to you under the Apache License, Version 2.0 (the --- "License"); you may not use this file except in compliance --- with the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, --- software distributed under the License is distributed on an --- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY --- KIND, either express or implied. See the License for the --- specific language governing permissions and limitations --- under the License. - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) -ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) -ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) -ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1) -ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_CALENDARS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_LOCKS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_JOB_DETAILS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS]; - -IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1) -DROP TABLE [dbo].[QRTZ_TRIGGERS]; - -CREATE TABLE [dbo].[QRTZ_CALENDARS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [CALENDAR_NAME] [VARCHAR] (200) NOT NULL , - [CALENDAR] [IMAGE] NOT NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , - [CRON_EXPRESSION] [VARCHAR] (120) NOT NULL , - [TIME_ZONE_ID] [VARCHAR] (80) -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [ENTRY_ID] [VARCHAR] (95) NOT NULL , - [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , - [INSTANCE_NAME] [VARCHAR] (200) NOT NULL , - [FIRED_TIME] [BIGINT] NOT NULL , - [SCHED_TIME] [BIGINT] NOT NULL , - [PRIORITY] [INTEGER] NOT NULL , - [STATE] [VARCHAR] (16) NOT NULL, - [JOB_NAME] [VARCHAR] (200) NULL , - [JOB_GROUP] [VARCHAR] (200) NULL , - [IS_NONCONCURRENT] [VARCHAR] (1) NULL , - [REQUESTS_RECOVERY] [VARCHAR] (1) NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [INSTANCE_NAME] [VARCHAR] (200) NOT NULL , - [LAST_CHECKIN_TIME] [BIGINT] NOT NULL , - [CHECKIN_INTERVAL] [BIGINT] NOT NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_LOCKS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [LOCK_NAME] [VARCHAR] (40) NOT NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [JOB_NAME] [VARCHAR] (200) NOT NULL , - [JOB_GROUP] [VARCHAR] (200) NOT NULL , - [DESCRIPTION] [VARCHAR] (250) NULL , - [JOB_CLASS_NAME] [VARCHAR] (250) NOT NULL , - [IS_DURABLE] [VARCHAR] (1) NOT NULL , - [IS_NONCONCURRENT] [VARCHAR] (1) NOT NULL , - [IS_UPDATE_DATA] [VARCHAR] (1) NOT NULL , - [REQUESTS_RECOVERY] [VARCHAR] (1) NOT NULL , - [JOB_DATA] [IMAGE] NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , - [REPEAT_COUNT] [BIGINT] NOT NULL , - [REPEAT_INTERVAL] [BIGINT] NOT NULL , - [TIMES_TRIGGERED] [BIGINT] NOT NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , - [STR_PROP_1] [VARCHAR] (512) NULL, - [STR_PROP_2] [VARCHAR] (512) NULL, - [STR_PROP_3] [VARCHAR] (512) NULL, - [INT_PROP_1] [INT] NULL, - [INT_PROP_2] [INT] NULL, - [LONG_PROP_1] [BIGINT] NULL, - [LONG_PROP_2] [BIGINT] NULL, - [DEC_PROP_1] [NUMERIC] (13,4) NULL, - [DEC_PROP_2] [NUMERIC] (13,4) NULL, - [BOOL_PROP_1] [VARCHAR] (1) NULL, - [BOOL_PROP_2] [VARCHAR] (1) NULL, -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , - [BLOB_DATA] [IMAGE] NULL -) ON [PRIMARY]; - -CREATE TABLE [dbo].[QRTZ_TRIGGERS] ( - [SCHED_NAME] [VARCHAR] (120) NOT NULL , - [TRIGGER_NAME] [VARCHAR] (200) NOT NULL , - [TRIGGER_GROUP] [VARCHAR] (200) NOT NULL , - [JOB_NAME] [VARCHAR] (200) NOT NULL , - [JOB_GROUP] [VARCHAR] (200) NOT NULL , - [DESCRIPTION] [VARCHAR] (250) NULL , - [NEXT_FIRE_TIME] [BIGINT] NULL , - [PREV_FIRE_TIME] [BIGINT] NULL , - [PRIORITY] [INTEGER] NULL , - [TRIGGER_STATE] [VARCHAR] (16) NOT NULL , - [TRIGGER_TYPE] [VARCHAR] (8) NOT NULL , - [START_TIME] [BIGINT] NOT NULL , - [END_TIME] [BIGINT] NULL , - [CALENDAR_NAME] [VARCHAR] (200) NULL , - [MISFIRE_INSTR] [SMALLINT] NULL , - [JOB_DATA] [IMAGE] NULL -) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [CALENDAR_NAME] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [ENTRY_ID] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [TRIGGER_GROUP] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [INSTANCE_NAME] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [LOCK_NAME] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [JOB_NAME], - [JOB_GROUP] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD - CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON [PRIMARY]; - -ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD - CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON DELETE CASCADE; - -ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD - CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON DELETE CASCADE; - -ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD - CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY - ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) REFERENCES [dbo].[QRTZ_TRIGGERS] ( - [SCHED_NAME], - [TRIGGER_NAME], - [TRIGGER_GROUP] - ) ON DELETE CASCADE; - -ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD - CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY - ( - [SCHED_NAME], - [JOB_NAME], - [JOB_GROUP] - ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] ( - [SCHED_NAME], - [JOB_NAME], - [JOB_GROUP] - ); diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdaterTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdaterTest.java index bee7895c67..bdf7078d55 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdaterTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/JobStatusUpdaterTest.java @@ -41,15 +41,16 @@ public class JobStatusUpdaterTest extends AbstractTest { @Test public void verifyUpdate() { - String refDesc = "JobRefDesc-" + SecureRandomUtils.generateRandomNumber(); + String jobName = "job-" + SecureRandomUtils.generateRandomNumber(); JobStatusUpdater jobStatusUpdater = new JobStatusUpdater(jobStatusDAO, entityFactory); jobStatusUpdater.initComplete(); - jobStatusUpdater.update(new JobStatusEvent(this, SyncopeConstants.MASTER_DOMAIN, refDesc, "Started")); - assertTrue(jobStatusDAO.findById(refDesc).isPresent()); + jobStatusUpdater.update(new JobStatusEvent(this, SyncopeConstants.MASTER_DOMAIN, jobName, "Started")); + assertTrue(jobStatusDAO.findById(jobName).isPresent()); - jobStatusUpdater.update(new JobStatusEvent(this, SyncopeConstants.MASTER_DOMAIN, refDesc, null)); - assertTrue(jobStatusDAO.findById(refDesc).isEmpty()); + jobStatusUpdater.update(new JobStatusEvent(this, SyncopeConstants.MASTER_DOMAIN, jobName, null)); + // no change is expected + assertTrue(jobStatusDAO.findById(jobName).isPresent()); } } diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java new file mode 100644 index 0000000000..50969dd3b5 --- /dev/null +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/job/SyncopeTaskSchedulerTest.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.provisioning.java.job; + +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.time.Instant; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import org.apache.syncope.core.persistence.api.dao.JobStatusDAO; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; +import org.apache.syncope.core.provisioning.java.AbstractTest; +import org.apache.syncope.core.spring.security.AuthContextUtils; +import org.apache.syncope.core.spring.security.SecureRandomUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public class SyncopeTaskSchedulerTest extends AbstractTest { + + private static final AtomicInteger VALUE = new AtomicInteger(); + + private static class TestJob extends Job { + + @Override + protected void execute(final JobExecutionContext context) throws JobExecutionException { + VALUE.set(1); + } + } + + @Autowired + private SyncopeTaskScheduler scheduler; + + @Test + public void schedule() { + JobExecutionContext context = new JobExecutionContext( + AuthContextUtils.getDomain(), + TestJob.class.getSimpleName() + "_" + SecureRandomUtils.generateRandomUUID(), + AuthContextUtils.getWho(), + false); + TestJob job = new TestJob(); + job.setContext(context); + + JobStatusDAO jobStatusDAO = mock(JobStatusDAO.class); + when(jobStatusDAO.lock(anyString())).thenReturn(true); + doNothing().when(jobStatusDAO).unlock(anyString()); + ReflectionTestUtils.setField(job, "jobStatusDAO", jobStatusDAO); + + scheduler.schedule(job, Instant.now().plusSeconds(5)); + + assertTrue(scheduler.contains(AuthContextUtils.getDomain(), job.getContext().getJobName())); + + assertTrue(scheduler.getNextTrigger(AuthContextUtils.getDomain(), job.getContext().getJobName()).isPresent()); + + await().atMost(10, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> VALUE.get() == 1); + } +} diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActionsTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActionsTest.java index e84e80319b..540718c2a2 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActionsTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/DBPasswordPullActionsTest.java @@ -42,6 +42,7 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstance; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.java.AbstractTest; import org.identityconnectors.framework.common.objects.SyncDelta; @@ -49,7 +50,6 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.quartz.JobExecutionException; import org.springframework.test.util.ReflectionTestUtils; public class DBPasswordPullActionsTest extends AbstractTest { diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java index 3437bc992d..baf4043842 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPMembershipPullActionsTest.java @@ -56,6 +56,7 @@ import org.apache.syncope.core.persistence.api.entity.user.UMembership; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.Connector; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.rules.PullMatch; import org.apache.syncope.core.provisioning.java.AbstractTest; @@ -66,7 +67,6 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.util.ReflectionTestUtils; diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java index ea3dcb1ca3..a582f1f9b9 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/LDAPPasswordPullActionsTest.java @@ -33,6 +33,7 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.java.AbstractTest; import org.identityconnectors.common.security.GuardedString; @@ -49,7 +50,6 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.quartz.JobExecutionException; public class LDAPPasswordPullActionsTest extends AbstractTest { diff --git a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java index a6b625137f..8eb4699326 100644 --- a/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java +++ b/core/provisioning-java/src/test/java/org/apache/syncope/core/provisioning/java/pushpull/stream/StreamPullJobDelegateTest.java @@ -38,12 +38,12 @@ import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.stream.SyncopeStreamPullExecutor; import org.apache.syncope.core.provisioning.java.AbstractTest; import org.apache.syncope.core.spring.ApplicationContextProvider; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.junit.jupiter.api.Test; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; diff --git a/core/self-keymaster-starter/src/test/resources/core-debug.properties b/core/self-keymaster-starter/src/test/resources/core-debug.properties index 6876fce530..a887a9d2ac 100644 --- a/core/self-keymaster-starter/src/test/resources/core-debug.properties +++ b/core/self-keymaster-starter/src/test/resources/core-debug.properties @@ -44,7 +44,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.H2Dictionary persistence.domain[0].auditSql=audit.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_h2.sql -provisioning.quartz.waitForJobsToCompleteOnShutdown=false diff --git a/core/self-keymaster-starter/src/test/resources/log4j2.xml b/core/self-keymaster-starter/src/test/resources/log4j2.xml index 91ab9b6611..7bf54970d0 100644 --- a/core/self-keymaster-starter/src/test/resources/log4j2.xml +++ b/core/self-keymaster-starter/src/test/resources/log4j2.xml @@ -77,9 +77,6 @@ under the License. - - - diff --git a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java index 2fb90fb940..b42bb3ded2 100644 --- a/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java +++ b/core/starter/src/main/java/org/apache/syncope/core/starter/SyncopeCoreApplication.java @@ -61,9 +61,9 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; import org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration; import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; +import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @@ -84,8 +84,8 @@ SqlInitializationAutoConfiguration.class, HibernateJpaAutoConfiguration.class, JdbcTemplateAutoConfiguration.class, - QuartzAutoConfiguration.class, TaskExecutionAutoConfiguration.class, + TaskSchedulingAutoConfiguration.class, ElasticsearchRestClientAutoConfiguration.class, ElasticsearchClientAutoConfiguration.class }, proxyBeanMethods = false) diff --git a/core/starter/src/main/resources/core.properties b/core/starter/src/main/resources/core.properties index 4e3322372d..dd486fc74c 100644 --- a/core/starter/src/main/resources/core.properties +++ b/core/starter/src/main/resources/core.properties @@ -68,10 +68,6 @@ provisioning.virAttrCacheSpec=maximumSize=5000,expireAfterAccess=1m provisioning.connIdLocation=${syncope.connid.location} -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql -provisioning.quartz.disableInstance=false - ######### # Email # ######### diff --git a/docker/core/LICENSE b/docker/core/LICENSE index 246ecdc3a9..6f80a52433 100644 --- a/docker/core/LICENSE +++ b/docker/core/LICENSE @@ -1292,11 +1292,6 @@ This is licensed under the AL 2.0, see above. == -For Quartz Scheduler (http://quartz-scheduler.org/): -This is licensed under the AL 2.0, see above. - -== - For Simple Logging Facade for Java - SLF4J (http://www.slf4j.org/): This is licensed under the MIT license, see above. diff --git a/docker/core/NOTICE b/docker/core/NOTICE index cbe155e22d..addaec3185 100644 --- a/docker/core/NOTICE +++ b/docker/core/NOTICE @@ -242,11 +242,6 @@ Copyright (C) 2003-2022 Virginia Tech. All rights reserved. == -This product includes software developed by Terracotta. Inc. -Quartz Scheduler source code and documentation are Copyright (c) Terracotta, Inc. - -== - This products includes software developed by the Simple Logging Facade for Java (SLF4J) project. Copyright (c) 2004-2016 QOS.ch. diff --git a/docker/core/src/main/resources/core-mariadb.properties b/docker/core/src/main/resources/core-mariadb.properties index a1412f4f2c..0b18f60136 100644 --- a/docker/core/src/main/resources/core-mariadb.properties +++ b/docker/core/src/main/resources/core-mariadb.properties @@ -23,6 +23,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictio persistence.domain[0].auditSql=audit_mariadb.sql persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql diff --git a/docker/core/src/main/resources/core-myjson.properties b/docker/core/src/main/resources/core-myjson.properties index a8bbea0634..83a9ad502a 100644 --- a/docker/core/src/main/resources/core-myjson.properties +++ b/docker/core/src/main/resources/core-myjson.properties @@ -29,6 +29,3 @@ persistence.domain[0].orm=META-INF/spring-orm-myjson.xml persistence.domain[0].auditSql=audit_myjson.sql persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql diff --git a/docker/core/src/main/resources/core-mysql.properties b/docker/core/src/main/resources/core-mysql.properties index f268bc84c5..2ccd02e348 100644 --- a/docker/core/src/main/resources/core-mysql.properties +++ b/docker/core/src/main/resources/core-mysql.properties @@ -23,6 +23,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictiona persistence.domain[0].auditSql=audit_mysql_innodb.sql persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql diff --git a/docker/core/src/main/resources/core-ojson.properties b/docker/core/src/main/resources/core-ojson.properties index 70731922ad..1af9339431 100644 --- a/docker/core/src/main/resources/core-ojson.properties +++ b/docker/core/src/main/resources/core-ojson.properties @@ -29,6 +29,3 @@ persistence.domain[0].poolMinIdle=${DB_POOL_MIN} persistence.indexesXML=classpath:ojson/indexes.xml persistence.viewsXML=classpath:ojson/views.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql diff --git a/docker/core/src/main/resources/core-oracle.properties b/docker/core/src/main/resources/core-oracle.properties index 041a4746c0..f4d7be2262 100644 --- a/docker/core/src/main/resources/core-oracle.properties +++ b/docker/core/src/main/resources/core-oracle.properties @@ -28,6 +28,3 @@ persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} persistence.indexesXML=classpath:oracle_indexes.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql diff --git a/docker/core/src/main/resources/core-pgjsonb.properties b/docker/core/src/main/resources/core-pgjsonb.properties index 996113be46..adaae036d7 100644 --- a/docker/core/src/main/resources/core-pgjsonb.properties +++ b/docker/core/src/main/resources/core-pgjsonb.properties @@ -29,6 +29,3 @@ persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml persistence.domain[0].auditSql=audit_pgjsonb.sql persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql diff --git a/docker/core/src/main/resources/core-postgresql.properties b/docker/core/src/main/resources/core-postgresql.properties index d35e3303d4..c322ca5c2f 100644 --- a/docker/core/src/main/resources/core-postgresql.properties +++ b/docker/core/src/main/resources/core-postgresql.properties @@ -23,6 +23,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDicti persistence.domain[0].auditSql=audit.sql persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql diff --git a/docker/core/src/main/resources/core-sqlserver.properties b/docker/core/src/main/resources/core-sqlserver.properties index 91d29096a9..17fa6da561 100644 --- a/docker/core/src/main/resources/core-sqlserver.properties +++ b/docker/core/src/main/resources/core-sqlserver.properties @@ -28,6 +28,3 @@ persistence.domain[0].poolMaxActive=${DB_POOL_MAX} persistence.domain[0].poolMinIdle=${DB_POOL_MIN} persistence.viewsXML=classpath:sqlserver_views.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.MSSQLDelegate -provisioning.quartz.sql=tables_sqlServer.sql diff --git a/docker/core/src/main/resources/log4j2.xml b/docker/core/src/main/resources/log4j2.xml index 91ab9b6611..7bf54970d0 100644 --- a/docker/core/src/main/resources/log4j2.xml +++ b/docker/core/src/main/resources/log4j2.xml @@ -77,9 +77,6 @@ under the License. - - - diff --git a/docker/wa/LICENSE b/docker/wa/LICENSE index 6dec4fe5fe..6984f5ccab 100644 --- a/docker/wa/LICENSE +++ b/docker/wa/LICENSE @@ -1694,11 +1694,6 @@ This is licensed under the MIT license, see above. == -For Quartz Scheduler (http://quartz-scheduler.org/): -This is licensed under the AL 2.0, see above. - -== - For Reactive Streams (http://www.reactive-streams.org/): This is licensed under the CC0 1.0, see above. diff --git a/docker/wa/NOTICE b/docker/wa/NOTICE index b4e6316c56..f160ece768 100644 --- a/docker/wa/NOTICE +++ b/docker/wa/NOTICE @@ -441,11 +441,6 @@ Copyright (C) 2009-2021 The Project Lombok Authors. == -This product includes software developed by Terracotta. Inc. -Quartz Scheduler source code and documentation are Copyright (c) Terracotta, Inc. - -== - This product includes software developed by the Reflections project. == diff --git a/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java b/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java index f7fd004679..35ec152561 100644 --- a/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java +++ b/ext/elasticsearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/ElasticsearchReindex.java @@ -44,11 +44,11 @@ import org.apache.syncope.core.persistence.api.entity.task.SchedTask; import org.apache.syncope.core.persistence.api.entity.task.TaskExec; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.ext.elasticsearch.client.ElasticsearchIndexManager; import org.apache.syncope.ext.elasticsearch.client.ElasticsearchUtils; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; diff --git a/ext/opensearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/OpenSearchReindex.java b/ext/opensearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/OpenSearchReindex.java index 632a2ed8d9..bf17760e59 100644 --- a/ext/opensearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/OpenSearchReindex.java +++ b/ext/opensearch/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/OpenSearchReindex.java @@ -32,6 +32,8 @@ import org.apache.syncope.core.persistence.api.entity.task.SchedTask; import org.apache.syncope.core.persistence.api.entity.task.TaskExec; import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.spring.security.AuthContextUtils; import org.apache.syncope.ext.opensearch.client.OpenSearchIndexManager; import org.apache.syncope.ext.opensearch.client.OpenSearchUtils; @@ -40,8 +42,6 @@ import org.opensearch.client.opensearch.core.BulkRequest; import org.opensearch.client.opensearch.core.BulkResponse; import org.opensearch.client.opensearch.indices.IndexSettings; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; diff --git a/fit/build-tools/pom.xml b/fit/build-tools/pom.xml index 571f0302c6..8b28e82e66 100644 --- a/fit/build-tools/pom.xml +++ b/fit/build-tools/pom.xml @@ -396,7 +396,7 @@ under the License. true - wildfly30x + wildfly31x https://github.com/wildfly/wildfly/releases/download/${wildfly.version}/wildfly-${wildfly.version}.zip ${settings.localRepository}/org/codehaus/cargo/cargo-container-archives diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml index 18677558d6..186d300d1c 100644 --- a/fit/core-reference/pom.xml +++ b/fit/core-reference/pom.xml @@ -1714,7 +1714,7 @@ under the License. true - wildfly30x + wildfly31x https://github.com/wildfly/wildfly/releases/download/${wildfly.version}/wildfly-${wildfly.version}.zip ${settings.localRepository}/org/codehaus/cargo/cargo-container-archives diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SampleReportJobDelegate.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SampleReportJobDelegate.java index c4c7434727..7bc3381201 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SampleReportJobDelegate.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/SampleReportJobDelegate.java @@ -30,10 +30,10 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName; import org.apache.syncope.common.lib.report.ReportConf; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.job.report.ReportConfClass; import org.apache.syncope.core.provisioning.java.job.report.AbstractReportJobDelegate; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.springframework.http.MediaType; @ReportConfClass(SampleReportConf.class) diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java index 8d937ea8a6..28542b2097 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPullActions.java @@ -25,11 +25,11 @@ import org.apache.syncope.common.lib.request.UserCR; import org.apache.syncope.common.lib.to.EntityTO; import org.apache.syncope.common.lib.types.PatchOperation; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.api.pushpull.IgnoreProvisionException; import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile; import org.apache.syncope.core.provisioning.api.pushpull.PullActions; import org.identityconnectors.framework.common.objects.SyncDelta; -import org.quartz.JobExecutionException; /** * Test pull action. diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java index 9cffdeee43..6f47a50223 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestSampleJobDelegate.java @@ -18,12 +18,12 @@ */ package org.apache.syncope.fit.core.reference; -import java.util.Date; +import java.time.OffsetDateTime; import org.apache.syncope.core.persistence.api.entity.task.SchedTask; import org.apache.syncope.core.persistence.api.entity.task.TaskExec; +import org.apache.syncope.core.provisioning.api.job.JobExecutionContext; +import org.apache.syncope.core.provisioning.api.job.JobExecutionException; import org.apache.syncope.core.provisioning.java.job.AbstractSchedTaskJobDelegate; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; /** * Sample implementation for executing a scheduled task. @@ -35,7 +35,7 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo throws JobExecutionException { for (int i = 0; i < 2; i++) { - LOG.debug("TestSampleJob#doExecute round {} time {}", i, new Date().toString()); + LOG.debug("TestSampleJob#doExecute round {} time {}", i, OffsetDateTime.now()); try { Thread.sleep(1000); } catch (InterruptedException ex) { @@ -52,15 +52,6 @@ protected String doExecute(final boolean dryRun, final String executor, final Jo : "") + "RUNNING"; } - @Override - public void interrupt() { - } - - @Override - public boolean isInterrupted() { - return false; - } - @Override protected boolean hasToBeRegistered(final TaskExec execution) { return true; diff --git a/fit/core-reference/src/main/resources/core-embedded.properties b/fit/core-reference/src/main/resources/core-embedded.properties index 778a6d3478..59045d104e 100644 --- a/fit/core-reference/src/main/resources/core-embedded.properties +++ b/fit/core-reference/src/main/resources/core-embedded.properties @@ -64,10 +64,6 @@ persistence.domain[1].poolMinIdle=5 persistence.domain[1].adminPassword=2AA60A8FF7FCD473D321E0146AFD9E26DF395147 persistence.domain[1].adminCipherAlgorithm=SHA -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_h2.sql -provisioning.quartz.waitForJobsToCompleteOnShutdown=false - provisioning.connIdLocation=${syncope.connid.location},\ connid://${testconnectorserver.key}@localhost:${testconnectorserver.port} diff --git a/fit/core-reference/src/main/resources/core-mariadb.properties b/fit/core-reference/src/main/resources/core-mariadb.properties index 978a496e0e..281411894b 100644 --- a/fit/core-reference/src/main/resources/core-mariadb.properties +++ b/fit/core-reference/src/main/resources/core-mariadb.properties @@ -24,6 +24,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictio persistence.domain[0].auditSql=audit_mariadb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql diff --git a/fit/core-reference/src/main/resources/core-myjson.properties b/fit/core-reference/src/main/resources/core-myjson.properties index 5d6ccc7b38..466e6aa6dc 100644 --- a/fit/core-reference/src/main/resources/core-myjson.properties +++ b/fit/core-reference/src/main/resources/core-myjson.properties @@ -28,6 +28,3 @@ persistence.domain[0].orm=META-INF/spring-orm-myjson.xml persistence.domain[0].auditSql=audit_myjson.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql diff --git a/fit/core-reference/src/main/resources/core-mysql.properties b/fit/core-reference/src/main/resources/core-mysql.properties index fff945790c..18b1dfbc0a 100644 --- a/fit/core-reference/src/main/resources/core-mysql.properties +++ b/fit/core-reference/src/main/resources/core-mysql.properties @@ -24,6 +24,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictiona persistence.domain[0].auditSql=audit_mysql_innodb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql diff --git a/fit/core-reference/src/main/resources/core-ojson.properties b/fit/core-reference/src/main/resources/core-ojson.properties index bd1b785b54..286625f645 100644 --- a/fit/core-reference/src/main/resources/core-ojson.properties +++ b/fit/core-reference/src/main/resources/core-ojson.properties @@ -29,6 +29,3 @@ persistence.domain[0].orm=META-INF/spring-orm-ojson.xml persistence.domain[0].auditSql=audit_ojson.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql diff --git a/fit/core-reference/src/main/resources/core-oracle.properties b/fit/core-reference/src/main/resources/core-oracle.properties index ae2398604d..7bd8e76a54 100644 --- a/fit/core-reference/src/main/resources/core-oracle.properties +++ b/fit/core-reference/src/main/resources/core-oracle.properties @@ -28,6 +28,3 @@ persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 persistence.indexesXML=classpath:oracle_indexes.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql diff --git a/fit/core-reference/src/main/resources/core-pgjsonb.properties b/fit/core-reference/src/main/resources/core-pgjsonb.properties index 0cefc40dbd..91eb4483fc 100644 --- a/fit/core-reference/src/main/resources/core-pgjsonb.properties +++ b/fit/core-reference/src/main/resources/core-pgjsonb.properties @@ -28,6 +28,3 @@ persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml persistence.domain[0].auditSql=audit_pgjsonb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql diff --git a/fit/core-reference/src/main/resources/core-postgres.properties b/fit/core-reference/src/main/resources/core-postgres.properties index a39dfee940..a7779ec089 100644 --- a/fit/core-reference/src/main/resources/core-postgres.properties +++ b/fit/core-reference/src/main/resources/core-postgres.properties @@ -24,6 +24,3 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDicti persistence.domain[0].auditSql=audit.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql diff --git a/fit/core-reference/src/main/resources/core-sqlserver.properties b/fit/core-reference/src/main/resources/core-sqlserver.properties index 79fed5b4b6..461724ce41 100644 --- a/fit/core-reference/src/main/resources/core-sqlserver.properties +++ b/fit/core-reference/src/main/resources/core-sqlserver.properties @@ -28,6 +28,3 @@ persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 persistence.viewsXML=classpath:sqlserver_views.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.MSSQLDelegate -provisioning.quartz.sql=tables_sqlServer.sql diff --git a/fit/core-reference/src/main/resources/core-wildfly.properties b/fit/core-reference/src/main/resources/core-wildfly.properties index 80b4640e12..454c92984c 100644 --- a/fit/core-reference/src/main/resources/core-wildfly.properties +++ b/fit/core-reference/src/main/resources/core-wildfly.properties @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -persistence.metaDataFactory=jpa(URLs=vfs:${project.build.directory}/cargo/configurations/wildfly30x/deployments/syncope.war/WEB-INF/lib/syncope-core-persistence-jpa-${syncope.version}.jar; vfs:${project.build.directory}/cargo/configurations/wildfly30x/deployments/syncope.war/WEB-INF/lib/syncope-core-self-keymaster-starter-${syncope.version}.jar, Resources=##orm##) +persistence.metaDataFactory=jpa(URLs=vfs:${project.build.directory}/cargo/configurations/wildfly31x/deployments/syncope.war/WEB-INF/lib/syncope-core-persistence-jpa-${syncope.version}.jar; vfs:${project.build.directory}/cargo/configurations/wildfly31x/deployments/syncope.war/WEB-INF/lib/syncope-core-self-keymaster-starter-${syncope.version}.jar, Resources=##orm##) javadocPaths=/WEB-INF/lib/syncope-common-idrepo-rest-api-${syncope.version}-javadoc.jar,\ /WEB-INF/lib/syncope-common-idm-rest-api-${syncope.version}-javadoc.jar,\ diff --git a/fit/core-reference/src/main/resources/log4j2.xml b/fit/core-reference/src/main/resources/log4j2.xml index 445aff41e2..bfd5920d63 100644 --- a/fit/core-reference/src/main/resources/log4j2.xml +++ b/fit/core-reference/src/main/resources/log4j2.xml @@ -123,9 +123,6 @@ under the License. - - - diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java index f0b246855d..1ac6ea0705 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AbstractTaskITCase.java @@ -26,8 +26,6 @@ import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -47,6 +45,7 @@ import org.apache.syncope.common.rest.api.beans.TaskQuery; import org.apache.syncope.common.rest.api.service.TaskService; import org.apache.syncope.fit.AbstractITCase; +import org.springframework.core.task.SimpleAsyncTaskExecutor; public abstract class AbstractTaskITCase extends AbstractITCase { @@ -135,11 +134,12 @@ protected void execProvisioningTasks( final int maxWaitSeconds, final boolean dryRun) throws Exception { - ExecutorService service = Executors.newVirtualThreadPerTaskExecutor(); + SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor(); + executor.setVirtualThreads(true); List> futures = new ArrayList<>(); taskKeys.forEach(taskKey -> { - futures.add(service.submit(() -> { + futures.add(executor.submit(() -> { try { return execSchedTask(taskService, type, taskKey, maxWaitSeconds, dryRun); } catch (Exception e) { @@ -166,8 +166,6 @@ protected void execProvisioningTasks( LOG.error("While getting futures", e); } }); - - service.shutdownNow(); } protected NotificationTaskTO findNotificationTask(final String notification, final int maxWaitSeconds) { diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java index 59edeab89c..fbb50762f0 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java @@ -36,6 +36,7 @@ import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashSet; @@ -46,8 +47,7 @@ import java.util.Properties; import java.util.Set; import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.naming.NamingException; @@ -119,6 +119,7 @@ import org.identityconnectors.framework.common.objects.Name; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.jdbc.core.JdbcTemplate; public class PullTaskITCase extends AbstractTaskITCase { @@ -951,10 +952,13 @@ public void concurrentPull() throws NamingException, InterruptedException { // 0. first cleanup then create 20 users on LDAP ldapCleanup(); - ExecutorService tp = Executors.newVirtualThreadPerTaskExecutor(); + SimpleAsyncTaskExecutor tp = new SimpleAsyncTaskExecutor(); + tp.setVirtualThreads(true); + List> futures = new ArrayList<>(); + for (int i = 0; i < 20; i++) { String idx = StringUtils.leftPad(String.valueOf(i), 2, "0"); - tp.submit(() -> { + futures.add(tp.submit(() -> { try { createLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, prepareLdapAttributes( "pullFromLDAP_" + idx, @@ -968,10 +972,15 @@ public void concurrentPull() throws NamingException, InterruptedException { } catch (NamingException e) { LOG.error("While creating LDAP {}-th user", idx, e); } - }); + })); } - tp.shutdown(); - tp.awaitTermination(MAX_WAIT_SECONDS, TimeUnit.SECONDS); + futures.forEach(future -> { + try { + future.get(MAX_WAIT_SECONDS, TimeUnit.SECONDS); + } catch (Exception e) { + LOG.error("While getting futures", e); + } + }); // 1. create new concurrent pull task PullTaskTO pullTask = TASK_SERVICE.read(TaskType.PULL, "1e419ca4-ea81-4493-a14f-28b90113686d", false); diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java index a97ea55baa..4139ff2278 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SchedTaskITCase.java @@ -28,10 +28,11 @@ import jakarta.ws.rs.core.Response; import java.time.OffsetDateTime; -import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; import org.apache.syncope.common.lib.to.ExecTO; import org.apache.syncope.common.lib.to.ImplementationTO; import org.apache.syncope.common.lib.to.JobTO; @@ -163,8 +164,7 @@ public void issueSYNCOPE144() { @Test public void issueSYNCOPE660() { - List jobs = TASK_SERVICE.listJobs(); - int oldSize = jobs.size(); + int oldSize = TASK_SERVICE.listJobs().size(); ImplementationTO taskJobDelegate = IMPLEMENTATION_SERVICE.read( IdRepoImplementationType.TASKJOB_DELEGATE, TestSampleJobDelegate.class.getSimpleName()); @@ -176,32 +176,25 @@ public void issueSYNCOPE660() { task.setJobDelegate(taskJobDelegate.getKey()); Response response = TASK_SERVICE.create(TaskType.SCHEDULED, task); - task = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class); + String taskKey = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class).getKey(); - jobs = TASK_SERVICE.listJobs(); - assertEquals(oldSize + 1, jobs.size()); + assertEquals(oldSize + 1, TASK_SERVICE.listJobs().size()); - TASK_SERVICE.actionJob(task.getKey(), JobAction.START); + TASK_SERVICE.actionJob(taskKey, JobAction.START); - AtomicReference> run = new AtomicReference<>(); await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - run.set(TASK_SERVICE.listJobs().stream().filter(JobTO::isRunning).toList()); - return !run.get().isEmpty(); + return Optional.of(TASK_SERVICE.getJob(taskKey)).filter(JobTO::isRunning).isPresent(); } catch (Exception e) { return false; } }); - assertEquals(1, run.get().size()); - assertEquals(task.getKey(), run.get().get(0).getRefKey()); - TASK_SERVICE.actionJob(task.getKey(), JobAction.STOP); + TASK_SERVICE.actionJob(taskKey, JobAction.STOP); - run.set(List.of()); await().atMost(MAX_WAIT_SECONDS, TimeUnit.SECONDS).pollInterval(1, TimeUnit.SECONDS).until(() -> { try { - run.set(TASK_SERVICE.listJobs().stream().filter(JobTO::isRunning).toList()); - return run.get().isEmpty(); + return Optional.of(TASK_SERVICE.getJob(taskKey)).filter(Predicate.not(JobTO::isRunning)).isPresent(); } catch (Exception e) { return false; } diff --git a/pom.xml b/pom.xml index 35af87a17a..3b95bd6085 100644 --- a/pom.xml +++ b/pom.xml @@ -494,14 +494,14 @@ under the License. 60000 10.1.19 - 30.0.1.Final - 6.2023.11 + 31.0.1.Final + 6.2024.2 4.0.5 16 8.0 11 - 5.16.0 + 5.17.0 42.7.2 8.3.0 @@ -592,7 +592,7 @@ under the License. io.swagger.core.v3 - swagger-annotations + swagger-annotations-jakarta ${swagger-core.version} @@ -748,30 +748,6 @@ under the License. - - org.springframework.boot - spring-boot-starter-quartz - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter-logging - - - - - - org.springframework.boot - spring-boot-starter-aop - ${spring-boot.version} - - - org.springframework.boot - spring-boot-starter-logging - - - - org.springframework.boot spring-boot-starter-mail @@ -918,6 +894,12 @@ under the License. ${connid.version} + + org.jasypt + jasypt + ${jasypt.version} + + org.apache.groovy groovy @@ -969,36 +951,6 @@ under the License. ${groovy.version} - - com.icegreen - greenmail - 2.1.0-alpha-4 - - - com.sun.mail - jakarta.mail - - - jakarta.activation - jakarta.activation-api - - - org.slf4j - slf4j-api - - - junit - junit - - - - - - org.jasypt - jasypt - ${jasypt.version} - - org.flowable @@ -1302,6 +1254,30 @@ under the License. 1.17.2 + + com.icegreen + greenmail + 2.1.0-alpha-4 + + + com.sun.mail + jakarta.mail + + + jakarta.activation + jakarta.activation-api + + + org.slf4j + slf4j-api + + + junit + junit + + + + org.apache.curator diff --git a/src/main/asciidoc/reference-guide/concepts/reports.adoc b/src/main/asciidoc/reference-guide/concepts/reports.adoc index 6089538897..7fd4e59691 100644 --- a/src/main/asciidoc/reference-guide/concepts/reports.adoc +++ b/src/main/asciidoc/reference-guide/concepts/reports.adoc @@ -34,4 +34,4 @@ endif::[] providing the custom logic to extract information from Syncope and generate output according to the configured mime type * scheduling information: ** when to start -** http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/crontrigger.html[cron expression^] +** https://docs.spring.io/spring-framework/reference/integration/scheduling.html#scheduling-cron-expression[cron expression^] diff --git a/src/main/asciidoc/reference-guide/concepts/tasks.adoc b/src/main/asciidoc/reference-guide/concepts/tasks.adoc index 2e20d40304..044a863c90 100644 --- a/src/main/asciidoc/reference-guide/concepts/tasks.adoc +++ b/src/main/asciidoc/reference-guide/concepts/tasks.adoc @@ -101,7 +101,7 @@ When defining a pull task, the following information must be provided: * <> * scheduling information: ** when to start -** http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/crontrigger.html[cron expression^] +** https://docs.spring.io/spring-framework/reference/integration/scheduling.html#scheduling-cron-expression[cron expression^] [NOTE] ==== @@ -150,7 +150,7 @@ When defining a push task, the following information must be provided: * optional <> * scheduling information: ** when to start -** http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/crontrigger.html[cron expression^] +** https://docs.spring.io/spring-framework/reference/integration/scheduling.html#scheduling-cron-expression[cron expression^] [NOTE] ==== @@ -219,7 +219,7 @@ When defining a macro task, the following information must be provided: list, update or execute the given macro task * scheduling information: ** when to start -** http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/crontrigger.html[cron expression^] +** https://docs.spring.io/spring-framework/reference/integration/scheduling.html#scheduling-cron-expression[cron expression^] [[tasks-scheduled]] ==== Scheduled @@ -238,7 +238,7 @@ endif::[] providing the custom logic to execute * scheduling information: ** when to start -** http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/crontrigger.html[cron expression^] +** https://docs.spring.io/spring-framework/reference/integration/scheduling.html#scheduling-cron-expression[cron expression^] [TIP] ==== diff --git a/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc b/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc index 474a17655a..1eb6011bca 100644 --- a/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc +++ b/src/main/asciidoc/reference-guide/configuration/configurationparameters.adoc @@ -34,7 +34,7 @@ at runtime, expecially with high-availability. * `jwt.lifetime.minutes` - validity of https://en.wikipedia.org/wiki/JSON_Web_Token[JSON Web Token^] values used for <> (in minutes); * `notificationjob.cronExpression` - -http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/crontrigger.html[cron^] expression describing how +https://docs.spring.io/spring-framework/reference/integration/scheduling.html#scheduling-cron-expression[cron^] expression describing how frequently the pending <> are processed: empty means disabled; [NOTE] Restarting the deployment is required when changing value for this parameter. diff --git a/src/main/asciidoc/reference-guide/configuration/dbms.adoc b/src/main/asciidoc/reference-guide/configuration/dbms.adoc index 3b17f1e103..6a3be70ae7 100644 --- a/src/main/asciidoc/reference-guide/configuration/dbms.adoc +++ b/src/main/asciidoc/reference-guide/configuration/dbms.adoc @@ -36,9 +36,6 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.PostgresDicti persistence.domain[0].auditSql=audit.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql .... as `core/src/main/resources/core-postgres.properties`. @@ -88,9 +85,6 @@ persistence.domain[0].orm=META-INF/spring-orm-pgjsonb.xml persistence.domain[0].auditSql=audit_pgjsonb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -provisioning.quartz.sql=tables_postgres.sql .... as `core/src/main/resources/core-pgjsonb.properties`. @@ -121,9 +115,6 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictiona persistence.domain[0].auditSql=audit_mysql_innodb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql .... as `core/src/main/resources/core-mysql.properties`. @@ -180,9 +171,6 @@ persistence.domain[0].orm=META-INF/spring-orm-myjson.xml persistence.domain[0].auditSql=audit_myjson.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mysql_innodb.sql .... as `core/src/main/resources/core-myjson.properties`. @@ -219,9 +207,6 @@ persistence.domain[0].databasePlatform=org.apache.openjpa.jdbc.sql.MariaDBDictio persistence.domain[0].auditSql=audit_mariadb.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.StdJDBCDelegate -provisioning.quartz.sql=tables_mariadb.sql .... as `core/src/main/resources/core-mariadb.properties`. @@ -259,9 +244,6 @@ persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 persistence.indexesXML=classpath:oracle_indexes.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql .... as `core/src/main/resources/core-oracle.properties`. @@ -312,9 +294,6 @@ persistence.domain[0].orm=META-INF/spring-orm-ojson.xml persistence.domain[0].auditSql=audit_ojson.sql persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate -provisioning.quartz.sql=tables_oracle.sql .... as `core/src/main/resources/core-ojson.properties`. @@ -349,9 +328,6 @@ persistence.domain[0].poolMaxActive=20 persistence.domain[0].poolMinIdle=5 persistence.viewsXML=classpath:sqlserver_views.xml - -provisioning.quartz.delegate=org.quartz.impl.jdbcjobstore.MSSQLDelegate -provisioning.quartz.sql=tables_sqlServer.sql .... as `core/src/main/resources/core-sqlserver.properties`. diff --git a/src/main/asciidoc/reference-guide/configuration/highavailability.adoc b/src/main/asciidoc/reference-guide/configuration/highavailability.adoc index 0186816a39..40741b795e 100644 --- a/src/main/asciidoc/reference-guide/configuration/highavailability.adoc +++ b/src/main/asciidoc/reference-guide/configuration/highavailability.adoc @@ -54,26 +54,3 @@ becomes: persistence.remoteCommitProvider=tcp(Addresses=10.0.1.10;10.0.1.11,TransmitPersistedObjectIds=true) .... ==== - -[discrete] -===== Quartz - -The http://www.quartz-scheduler.org[Quartz^] scheduler is largely used within <> to schedule the execution -of jobs, including <>, <>, <>, <> and -<> tasks, and <>. - -By default, Quartz is configured for -http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/ConfigJDBCJobStoreClustering.html[clustering^], -where each node is automatically handled via the underlying JDBC store, and all cluster nodes are equally selectable -for processing jobs. - -There are deployment scenarios which might have different requirements: for example, there could be three Core nodes -configured with OpenJPA remote commit provider (see above), where two of them are dedicated to serve REST requests, -leaving the third for running Quartz jobs. - -In such cases, it is possible to prevent Quartz from running on a given node by setting the following parameter in -`core.properties`: - -.... -provisioning.quartz.disableInstance=true -.... diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java index a032941680..b5e4525c47 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/SyncopeWAApplication.java @@ -18,21 +18,15 @@ */ package org.apache.syncope.wa.starter; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Date; +import java.time.Instant; import java.util.Map; import org.apache.syncope.wa.bootstrap.WAProperties; +import org.apache.syncope.wa.bootstrap.WARestClient; import org.apache.syncope.wa.starter.config.WARefreshContextJob; import org.apereo.cas.config.GoogleAuthenticatorLdapConfiguration; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.configuration.CasConfigurationPropertiesValidator; -import org.quartz.JobBuilder; -import org.quartz.JobDetail; -import org.quartz.JobKey; -import org.quartz.SchedulerException; -import org.quartz.Trigger; -import org.quartz.TriggerBuilder; +import org.apereo.cas.support.saml.idp.metadata.generator.SamlIdPMetadataGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -52,11 +46,13 @@ import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.event.EventListener; +import org.springframework.core.task.TaskRejectedException; +import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; @SpringBootApplication(exclude = { @@ -111,28 +107,22 @@ protected SpringApplicationBuilder configure(final SpringApplicationBuilder buil @EventListener public void handleApplicationReadyEvent(final ApplicationReadyEvent event) { new CasConfigurationPropertiesValidator(event.getApplicationContext()).validate(); - final WAProperties waProperties = event.getApplicationContext().getBean(WAProperties.class); - final SchedulerFactoryBean scheduler = event.getApplicationContext().getBean(SchedulerFactoryBean.class); - scheduleJobToRefreshContext(waProperties, scheduler); - } - protected void scheduleJobToRefreshContext( - final WAProperties waProperties, - final SchedulerFactoryBean scheduler) { + WARestClient waRestClient = event.getApplicationContext().getBean(WARestClient.class); + ContextRefresher contextRefresher = event.getApplicationContext().getBean(ContextRefresher.class); + SamlIdPMetadataGenerator metadataGenerator = + event.getApplicationContext().getBean(SamlIdPMetadataGenerator.class); - try { - Date date = Date.from(LocalDateTime.now().plusSeconds(waProperties.getContextRefreshDelay()). - atZone(ZoneId.systemDefault()).toInstant()); - Trigger trigger = TriggerBuilder.newTrigger().startAt(date).build(); - JobKey jobKey = new JobKey(getClass().getSimpleName()); + WARefreshContextJob job = new WARefreshContextJob(waRestClient, contextRefresher, metadataGenerator); - JobDetail job = JobBuilder.newJob(WARefreshContextJob.class). - withIdentity(jobKey). - build(); - LOG.info("Scheduled job to refresh application context @ [{}]", date); - scheduler.getScheduler().scheduleJob(job, trigger); - } catch (final SchedulerException e) { - throw new RuntimeException("Could not schedule refresh job", e); + WAProperties waProperties = event.getApplicationContext().getBean(WAProperties.class); + TaskScheduler scheduler = event.getApplicationContext().getBean(TaskScheduler.class); + Instant startAt = Instant.now().plusSeconds(waProperties.getContextRefreshDelay()); + try { + scheduler.schedule(job, startAt); + LOG.info("Scheduled job to refresh application context @ [{}]", startAt); + } catch (TaskRejectedException e) { + throw new IllegalStateException("Could not schedule refresh job", e); } } } diff --git a/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WARefreshContextJob.java b/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WARefreshContextJob.java index 620c29f754..207e2ec868 100644 --- a/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WARefreshContextJob.java +++ b/wa/starter/src/main/java/org/apache/syncope/wa/starter/config/WARefreshContextJob.java @@ -24,29 +24,37 @@ import org.apereo.cas.support.saml.idp.metadata.generator.SamlIdPMetadataGenerator; import org.apereo.cas.support.saml.services.idp.metadata.SamlIdPMetadataDocument; import org.apereo.cas.util.AsciiArtUtils; -import org.quartz.Job; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.refresh.ContextRefresher; -public class WARefreshContextJob implements Job { +public class WARefreshContextJob implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger(WARefreshContextJob.class); + protected static final Logger LOG = LoggerFactory.getLogger(WARefreshContextJob.class); - @Autowired - private WARestClient waRestClient; + protected static void advertiseReady() { + AsciiArtUtils.printAsciiArtReady(LOG, StringUtils.EMPTY); + LOG.info("Ready to process requests"); + } - @Autowired - private ContextRefresher contextRefresher; + protected final WARestClient waRestClient; - @Autowired - private SamlIdPMetadataGenerator metadataGenerator; + protected final ContextRefresher contextRefresher; + + protected final SamlIdPMetadataGenerator metadataGenerator; + + public WARefreshContextJob( + final WARestClient waRestClient, + final ContextRefresher contextRefresher, + final SamlIdPMetadataGenerator metadataGenerator) { + + this.waRestClient = waRestClient; + this.contextRefresher = contextRefresher; + this.metadataGenerator = metadataGenerator; + } @Override - public void execute(final JobExecutionContext jobExecutionContext) throws JobExecutionException { + public void run() { try { LOG.debug("Attempting to refresh WA application context"); if (!waRestClient.isReady()) { @@ -62,12 +70,7 @@ public void execute(final JobExecutionContext jobExecutionContext) throws JobExe advertiseReady(); } catch (Throwable t) { - throw new JobExecutionException("While generating SAML2 IdP metadata", t); + throw new IllegalStateException("While generating SAML2 IdP metadata", t); } } - - private static void advertiseReady() { - AsciiArtUtils.printAsciiArtReady(LOG, StringUtils.EMPTY); - LOG.info("Ready to process requests"); - } }