You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2021/09/28 10:59:21 UTC
[syncope] 02/02: [SYNCOPE-1644] Now relying on SpringBeanJobFactory
which creates the bean and immediately executes it
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git
commit f18da0d71fda4892466ea707cf297dc0f789f7ef
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Tue Sep 28 12:21:46 2021 +0200
[SYNCOPE-1644] Now relying on SpringBeanJobFactory which creates the bean and immediately executes it
---
.../core/provisioning/api/job/JobManager.java | 4 +
.../java/job/AutowiringSpringBeanJobFactory.java | 85 ----------------------
.../core/provisioning/java/job/JobManagerImpl.java | 78 +++++---------------
.../java/job/SyncopeSpringBeanJobFactory.java | 45 ++++++++++++
.../src/main/resources/provisioningContext.xml | 2 +-
5 files changed, 67 insertions(+), 147 deletions(-)
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 ddd641f..8b8ab9b 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
@@ -30,6 +30,10 @@ import org.quartz.SchedulerException;
@SuppressWarnings("squid:S1214")
public interface JobManager {
+ String TASK_KEY = "task";
+
+ String REPORT_KEY = "report";
+
String DOMAIN_KEY = "domain";
JobKey NOTIFICATION_JOB = new JobKey("notificationJob", Scheduler.DEFAULT_GROUP);
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AutowiringSpringBeanJobFactory.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AutowiringSpringBeanJobFactory.java
deleted file mode 100644
index 109c9c2..0000000
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AutowiringSpringBeanJobFactory.java
+++ /dev/null
@@ -1,85 +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.quartz.SchedulerContext;
-import org.quartz.spi.TriggerFiredBundle;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyAccessorFactory;
-import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.scheduling.quartz.SpringBeanJobFactory;
-
-/**
- * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
- * transactions work.
- */
-public class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
-
- private transient AutowireCapableBeanFactory beanFactory;
-
- private String[] ignoredUnknownProperties;
-
- private SchedulerContext schedulerContext;
-
- @Override
- public void setApplicationContext(final ApplicationContext context) {
- beanFactory = context.getAutowireCapableBeanFactory();
- }
-
- @Override
- public void setIgnoredUnknownProperties(final String... ignoredUnknownProperties) {
- String[] defensiveCopy = ignoredUnknownProperties.clone();
- super.setIgnoredUnknownProperties(defensiveCopy);
- this.ignoredUnknownProperties = defensiveCopy;
- }
-
- @Override
- public void setSchedulerContext(final SchedulerContext schedulerContext) {
- super.setSchedulerContext(schedulerContext);
- this.schedulerContext = schedulerContext;
- }
-
- @Override
- protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
- Object job = beanFactory.getBean(bundle.getJobDetail().getKey().getName());
- if (isEligibleForPropertyPopulation(job)) {
- BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
- MutablePropertyValues pvs = new MutablePropertyValues();
- if (this.schedulerContext != null) {
- pvs.addPropertyValues(this.schedulerContext);
- }
- pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
- pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
- if (this.ignoredUnknownProperties != null) {
- for (String propName : this.ignoredUnknownProperties) {
- if (pvs.contains(propName) && !bw.isWritableProperty(propName)) {
- pvs.removePropertyValue(propName);
- }
- }
- bw.setPropertyValues(pvs);
- } else {
- bw.setPropertyValues(pvs, true);
- }
- }
- return job;
- }
-}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
index 274153e..13a5b21 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/JobManagerImpl.java
@@ -36,7 +36,6 @@ import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.types.ImplementationType;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
-import org.apache.syncope.core.persistence.api.dao.NotFoundException;
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.Report;
@@ -46,7 +45,6 @@ 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.provisioning.api.job.JobNamer;
import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.apache.syncope.core.spring.ApplicationContextProvider;
import org.apache.syncope.core.persistence.api.SyncopeLoader;
import org.apache.syncope.core.persistence.api.DomainsHolder;
import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
@@ -62,9 +60,7 @@ import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.transaction.annotation.Transactional;
import org.apache.syncope.core.provisioning.api.job.JobManager;
@@ -77,6 +73,7 @@ import org.apache.syncope.core.provisioning.java.job.notification.NotificationJo
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.quartz.Trigger;
public class JobManagerImpl implements JobManager, SyncopeLoader {
@@ -144,7 +141,7 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
}
private void registerJob(
- final String jobName, final Job jobInstance,
+ final String jobName, final Class<? extends Job> jobClass,
final String cronExpression, final Date startAt,
final Map<String, Object> jobMap)
throws SchedulerException {
@@ -157,34 +154,28 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
// 0. unregister job
unregisterJob(jobName);
- // 1. Job bean
- ApplicationContextProvider.getBeanFactory().registerSingleton(jobName, jobInstance);
-
- // 2. JobDetail bean
- JobBuilder jobDetailBuilder = JobBuilder.newJob(jobInstance.getClass()).
+ // 1. JobDetail
+ JobBuilder jobDetailBuilder = JobBuilder.newJob(jobClass).
withIdentity(jobName).
usingJobData(new JobDataMap(jobMap));
- // 3. Trigger
+ // 2. Trigger
if (cronExpression == null && startAt == null) {
// Jobs added with no trigger must be durable
scheduler.getScheduler().addJob(jobDetailBuilder.storeDurably().build(), true);
} else {
- TriggerBuilder<?> triggerBuilder;
+ TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger().
+ withIdentity(JobNamer.getTriggerName(jobName));
if (cronExpression == null) {
- triggerBuilder = TriggerBuilder.newTrigger().
- withIdentity(JobNamer.getTriggerName(jobName)).
- startAt(startAt);
+ triggerBuilder.startAt(startAt);
} else {
- triggerBuilder = TriggerBuilder.newTrigger().
- withIdentity(JobNamer.getTriggerName(jobName)).
- withSchedule(CronScheduleBuilder.cronSchedule(cronExpression));
+ triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression));
if (startAt == null) {
- triggerBuilder = triggerBuilder.startNow();
+ triggerBuilder.startNow();
} else {
- triggerBuilder = triggerBuilder.startAt(startAt);
+ triggerBuilder.startAt(startAt);
}
}
@@ -192,38 +183,10 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
}
}
- @SuppressWarnings("unchecked")
- private <T> T createSpringBean(final Class<T> jobClass) {
- T jobInstance = null;
- for (int i = 0; i < 5 && jobInstance == null; i++) {
- LOG.debug("{} attempt to create Spring bean for {}", i, jobClass);
- try {
- jobInstance = (T) ApplicationContextProvider.getBeanFactory().
- createBean(jobClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
- LOG.debug("{} attempt to create Spring bean for {} succeeded", i, jobClass);
- } catch (BeanCreationException e) {
- LOG.error("Could not create Spring bean for {}", jobClass, e);
- try {
- Thread.sleep(1000);
- } catch (final InterruptedException ex) {
- // ignore
- }
- }
- }
- if (jobInstance == null) {
- throw new NotFoundException("Spring bean for " + jobClass);
- }
-
- return jobInstance;
- }
-
@Override
public Map<String, Object> register(final SchedTask task, final Date startAt, final long interruptMaxRetries)
throws SchedulerException {
- TaskJob job = createSpringBean(TaskJob.class);
- job.setTaskKey(task.getKey());
-
Implementation jobDelegate = task.getJobDelegate() == null
? task instanceof PullTask
? implementationDAO.find(ImplementationType.TASKJOB_DELEGATE).stream().
@@ -241,12 +204,13 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
}
Map<String, Object> jobMap = new HashMap<>();
+ jobMap.put(JobManager.TASK_KEY, task.getKey());
jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
jobMap.put(TaskJob.DELEGATE_IMPLEMENTATION, jobDelegate.getKey());
registerJob(
JobNamer.getJobKey(task).getName(),
- job,
+ TaskJob.class,
task.getCronExpression(),
startAt,
jobMap);
@@ -257,13 +221,11 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
public void register(final Report report, final Date startAt, final long interruptMaxRetries)
throws SchedulerException {
- ReportJob job = createSpringBean(ReportJob.class);
- job.setReportKey(report.getKey());
-
Map<String, Object> jobMap = new HashMap<>();
+ jobMap.put(JobManager.REPORT_KEY, report.getKey());
jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
- registerJob(JobNamer.getJobKey(report).getName(), job, report.getCronExpression(), startAt, jobMap);
+ registerJob(JobNamer.getJobKey(report).getName(), ReportJob.class, report.getCronExpression(), startAt, jobMap);
}
private void unregisterJob(final String jobName) {
@@ -273,10 +235,6 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
} catch (SchedulerException e) {
LOG.error("Could not remove job " + jobName, e);
}
-
- if (ApplicationContextProvider.getBeanFactory().containsSingleton(jobName)) {
- ApplicationContextProvider.getBeanFactory().destroySingleton(jobName);
- }
}
@Override
@@ -379,10 +337,9 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
NotificationJob.class.getSimpleName(), conf.getLeft());
try {
- NotificationJob job = createSpringBean(NotificationJob.class);
registerJob(
NOTIFICATION_JOB.getName(),
- job,
+ NotificationJob.class,
conf.getLeft(),
null,
jobMap);
@@ -394,10 +351,9 @@ public class JobManagerImpl implements JobManager, SyncopeLoader {
// 4. SystemLoadReporterJob (fixed schedule, every minute)
LOG.debug("Registering {}", SystemLoadReporterJob.class);
try {
- SystemLoadReporterJob job = createSpringBean(SystemLoadReporterJob.class);
registerJob(
"systemLoadReporterJob",
- job,
+ SystemLoadReporterJob.class,
"0 * * * * ?",
null,
jobMap);
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
new file mode 100644
index 0000000..c690f39
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/SyncopeSpringBeanJobFactory.java
@@ -0,0 +1,45 @@
+/*
+ * 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.provisioning.api.job.JobManager;
+import org.apache.syncope.core.provisioning.java.job.report.ReportJob;
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.scheduling.quartz.SpringBeanJobFactory;
+
+public class SyncopeSpringBeanJobFactory extends SpringBeanJobFactory {
+
+ @Override
+ protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
+ Object job = super.createJobInstance(bundle);
+
+ if (bundle.getJobDetail().getJobDataMap() != null) {
+ if (job instanceof ReportJob) {
+ Optional.ofNullable(bundle.getJobDetail().getJobDataMap().getString(JobManager.REPORT_KEY)).
+ ifPresent(((ReportJob) job)::setReportKey);
+ } else if (job instanceof TaskJob) {
+ Optional.ofNullable(bundle.getJobDetail().getJobDataMap().getString(JobManager.TASK_KEY)).
+ ifPresent(((TaskJob) job)::setTaskKey);
+ }
+ }
+
+ return job;
+ }
+}
diff --git a/core/provisioning-java/src/main/resources/provisioningContext.xml b/core/provisioning-java/src/main/resources/provisioningContext.xml
index b905294..13f4d9f 100644
--- a/core/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/core/provisioning-java/src/main/resources/provisioningContext.xml
@@ -77,7 +77,7 @@ under the License.
<property name="dataSource" ref="MasterDataSource"/>
<property name="transactionManager" ref="MasterTransactionManager"/>
<property name="jobFactory">
- <bean class="org.apache.syncope.core.provisioning.java.job.AutowiringSpringBeanJobFactory"/>
+ <bean class="org.apache.syncope.core.provisioning.java.job.SyncopeSpringBeanJobFactory"/>
</property>
<property name="quartzProperties">
<props>