You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by we...@apache.org on 2024/04/02 07:30:04 UTC
(dolphinscheduler) branch dev updated: Directly use Quartz replase api to bootstrap a schedule (#15781)
This is an automated email from the ASF dual-hosted git repository.
wenjun pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 0419543d81 Directly use Quartz replase api to bootstrap a schedule (#15781)
0419543d81 is described below
commit 0419543d817ad012ba534e4aa08d81c932b7ffc3
Author: Wenjun Ruan <we...@apache.org>
AuthorDate: Tue Apr 2 15:29:58 2024 +0800
Directly use Quartz replase api to bootstrap a schedule (#15781)
---
.../scheduler/api/SchedulerException.java | 8 +-
...rException.java => SchedulerExceptionEnum.java} | 10 +-
.../scheduler/quartz/ProcessScheduleTask.java | 11 +-
.../scheduler/quartz/QuartzCornTriggerBuilder.java | 95 ++++++++++++++++
.../scheduler/quartz/QuartzJobData.java | 62 +++++++++++
.../scheduler/quartz/QuartzJobDetailBuilder.java | 58 ++++++++++
.../scheduler/quartz/QuartzJobKey.java | 49 ++++++++
.../scheduler/quartz/QuartzScheduler.java | 123 ++++-----------------
.../quartz/QuartzSchedulerConfiguration.java | 14 ++-
.../scheduler/quartz/QuartzTriggerBuilder.java} | 13 +--
.../exception/QuartzSchedulerExceptionEnum.java | 48 ++++++++
.../scheduler/quartz/utils/QuartzTaskUtils.java | 59 ----------
.../scheduler/quartz/QuartzJobDataTest.java | 56 ++++++++++
.../scheduler/quartz/QuartzJobKeyTest.java} | 25 +++--
.../QuartzSchedulerExceptionEnumTest.java} | 19 ++--
15 files changed, 444 insertions(+), 206 deletions(-)
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
index c81f114204..5808787cda 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
@@ -19,12 +19,12 @@ package org.apache.dolphinscheduler.scheduler.api;
public class SchedulerException extends RuntimeException {
- public SchedulerException(String message) {
- super(message);
+ public SchedulerException(SchedulerExceptionEnum schedulerExceptionEnum) {
+ super("Scheduler[" + schedulerExceptionEnum.getCode() + "] " + schedulerExceptionEnum.getMessage());
}
- public SchedulerException(String message, Throwable cause) {
- super(message, cause);
+ public SchedulerException(SchedulerExceptionEnum schedulerExceptionEnum, Throwable cause) {
+ super("Scheduler[" + schedulerExceptionEnum.getCode() + "] " + schedulerExceptionEnum.getMessage(), cause);
}
}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerExceptionEnum.java
similarity index 78%
copy from dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
copy to dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerExceptionEnum.java
index c81f114204..d8a0a5ef4e 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerExceptionEnum.java
@@ -17,14 +17,10 @@
package org.apache.dolphinscheduler.scheduler.api;
-public class SchedulerException extends RuntimeException {
+public interface SchedulerExceptionEnum {
- public SchedulerException(String message) {
- super(message);
- }
+ String getCode();
- public SchedulerException(String message, Throwable cause) {
- super(message, cause);
- }
+ String getMessage();
}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/ProcessScheduleTask.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/ProcessScheduleTask.java
index 2c189d2bf8..c6bd4cf93f 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/ProcessScheduleTask.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/ProcessScheduleTask.java
@@ -23,7 +23,6 @@ import org.apache.dolphinscheduler.common.enums.ReleaseState;
import org.apache.dolphinscheduler.dao.entity.Command;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.Schedule;
-import org.apache.dolphinscheduler.scheduler.quartz.utils.QuartzTaskUtils;
import org.apache.dolphinscheduler.service.command.CommandService;
import org.apache.dolphinscheduler.service.process.ProcessService;
@@ -33,7 +32,6 @@ import java.util.Date;
import lombok.extern.slf4j.Slf4j;
-import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
@@ -56,10 +54,9 @@ public class ProcessScheduleTask extends QuartzJobBean {
@Timed(value = "ds.master.quartz.job.execution.time", percentiles = {0.5, 0.75, 0.95, 0.99}, histogram = true)
@Override
protected void executeInternal(JobExecutionContext context) {
- JobDataMap dataMap = context.getJobDetail().getJobDataMap();
-
- int projectId = dataMap.getInt(QuartzTaskUtils.PROJECT_ID);
- int scheduleId = dataMap.getInt(QuartzTaskUtils.SCHEDULE_ID);
+ QuartzJobData quartzJobData = QuartzJobData.of(context.getJobDetail().getJobDataMap());
+ int projectId = quartzJobData.getProjectId();
+ int scheduleId = quartzJobData.getScheduleId();
Date scheduledFireTime = context.getScheduledFireTime();
@@ -110,7 +107,7 @@ public class ProcessScheduleTask extends QuartzJobBean {
private void deleteJob(JobExecutionContext context, int projectId, int scheduleId) {
final Scheduler scheduler = context.getScheduler();
- JobKey jobKey = QuartzTaskUtils.getJobKey(scheduleId, projectId);
+ JobKey jobKey = QuartzJobKey.of(projectId, scheduleId).toJobKey();
try {
if (scheduler.checkExists(jobKey)) {
log.info("Try to delete job: {}, projectId: {}, schedulerId", projectId, scheduleId);
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzCornTriggerBuilder.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzCornTriggerBuilder.java
new file mode 100644
index 0000000000..b7177e74db
--- /dev/null
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzCornTriggerBuilder.java
@@ -0,0 +1,95 @@
+/*
+ * 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.dolphinscheduler.scheduler.quartz;
+
+import org.apache.dolphinscheduler.common.utils.DateUtils;
+import org.apache.dolphinscheduler.dao.entity.Schedule;
+
+import java.util.Date;
+
+import org.quartz.CronScheduleBuilder;
+import org.quartz.CronTrigger;
+import org.quartz.JobKey;
+import org.quartz.TriggerBuilder;
+import org.quartz.TriggerKey;
+
+/**
+ * QuartzCornTriggerBuilder used to build a {@link CronTrigger} instance.
+ */
+public class QuartzCornTriggerBuilder implements QuartzTriggerBuilder {
+
+ private Integer projectId;
+
+ private Schedule schedule;
+
+ public static QuartzCornTriggerBuilder newBuilder() {
+ return new QuartzCornTriggerBuilder();
+ }
+
+ public QuartzCornTriggerBuilder withProjectId(Integer projectId) {
+ this.projectId = projectId;
+ return this;
+ }
+
+ public QuartzCornTriggerBuilder withSchedule(Schedule schedule) {
+ this.schedule = schedule;
+ return this;
+ }
+
+ @Override
+ public CronTrigger build() {
+
+ if (projectId == null) {
+ throw new IllegalArgumentException("projectId cannot be null");
+ }
+ if (schedule == null) {
+ throw new IllegalArgumentException("schedule cannot be null");
+ }
+
+ /**
+ * transform from server default timezone to schedule timezone
+ * e.g. server default timezone is `UTC`
+ * user set a schedule with startTime `2022-04-28 10:00:00`, timezone is `Asia/Shanghai`,
+ * api skip to transform it and save into databases directly, startTime `2022-04-28 10:00:00`, timezone is `UTC`, which actually added 8 hours,
+ * so when add job to quartz, it should recover by transform timezone
+ */
+ Date startDate = DateUtils.transformTimezoneDate(schedule.getStartTime(), schedule.getTimezoneId());
+ Date endDate = DateUtils.transformTimezoneDate(schedule.getEndTime(), schedule.getTimezoneId());
+ /**
+ * If the start time is less than the current time, the start time is set to the current time.
+ * We do this change to avoid misfires all triggers when update the scheduler.
+ */
+ Date now = new Date();
+ if (startDate.before(now)) {
+ startDate = now;
+ }
+ JobKey jobKey = QuartzJobKey.of(projectId, schedule.getId()).toJobKey();
+
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), jobKey.getGroup());
+ return TriggerBuilder.newTrigger()
+ .withIdentity(triggerKey)
+ .startAt(startDate)
+ .endAt(endDate)
+ .withSchedule(
+ CronScheduleBuilder.cronSchedule(schedule.getCrontab())
+ .withMisfireHandlingInstructionIgnoreMisfires()
+ .inTimeZone(DateUtils.getTimezone(schedule.getTimezoneId())))
+ .build();
+ }
+
+}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobData.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobData.java
new file mode 100644
index 0000000000..09e255bef3
--- /dev/null
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobData.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.dolphinscheduler.scheduler.quartz;
+
+import lombok.Getter;
+
+import org.quartz.JobDataMap;
+
+@Getter
+public class QuartzJobData {
+
+ private static final String PROJECT_ID = "projectId";
+ private static final String SCHEDULE_ID = "scheduleId";
+
+ private final Integer projectId;
+
+ private final Integer scheduleId;
+
+ private QuartzJobData(Integer projectId, Integer scheduleId) {
+ if (projectId == null) {
+ throw new IllegalArgumentException("projectId cannot be null");
+ }
+ if (scheduleId == null) {
+ throw new IllegalArgumentException("schedule cannot be null");
+ }
+ this.projectId = projectId;
+ this.scheduleId = scheduleId;
+ }
+
+ public static QuartzJobData of(Integer projectId, Integer scheduleId) {
+ return new QuartzJobData(projectId, scheduleId);
+ }
+
+ public static QuartzJobData of(JobDataMap jobDataMap) {
+ Integer projectId = jobDataMap.getInt(PROJECT_ID);
+ Integer scheduleId = jobDataMap.getInt(SCHEDULE_ID);
+ return of(projectId, scheduleId);
+ }
+
+ public JobDataMap toJobDataMap() {
+ JobDataMap jobDataMap = new JobDataMap();
+ jobDataMap.put(PROJECT_ID, projectId);
+ jobDataMap.put(SCHEDULE_ID, scheduleId);
+ return jobDataMap;
+ }
+
+}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobDetailBuilder.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobDetailBuilder.java
new file mode 100644
index 0000000000..7a579d0183
--- /dev/null
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobDetailBuilder.java
@@ -0,0 +1,58 @@
+/*
+ * 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.dolphinscheduler.scheduler.quartz;
+
+import org.quartz.JobBuilder;
+import org.quartz.JobDetail;
+
+public class QuartzJobDetailBuilder {
+
+ private Integer projectId;
+
+ private Integer scheduleId;
+
+ public static QuartzJobDetailBuilder newBuilder() {
+ return new QuartzJobDetailBuilder();
+ }
+
+ public QuartzJobDetailBuilder withProjectId(Integer projectId) {
+ this.projectId = projectId;
+ return this;
+ }
+
+ public QuartzJobDetailBuilder withSchedule(Integer scheduleId) {
+ this.scheduleId = scheduleId;
+ return this;
+ }
+
+ public JobDetail build() {
+ if (projectId == null) {
+ throw new IllegalArgumentException("projectId cannot be null");
+ }
+ if (scheduleId == null) {
+ throw new IllegalArgumentException("scheduleId cannot be null");
+ }
+ QuartzJobData quartzJobData = QuartzJobData.of(projectId, scheduleId);
+
+ return JobBuilder.newJob(ProcessScheduleTask.class)
+ .withIdentity(QuartzJobKey.of(projectId, scheduleId).toJobKey())
+ .setJobData(quartzJobData.toJobDataMap())
+ .build();
+ }
+
+}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobKey.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobKey.java
new file mode 100644
index 0000000000..b7666094e2
--- /dev/null
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobKey.java
@@ -0,0 +1,49 @@
+/*
+ * 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.dolphinscheduler.scheduler.quartz;
+
+import lombok.Getter;
+
+import org.quartz.JobKey;
+
+@Getter
+public class QuartzJobKey {
+
+ private final int schedulerId;
+ private final int projectId;
+
+ private static final String QUARTZ_JOB_PREFIX = "job";
+ private static final String QUARTZ_JOB_GROUP_PREFIX = "jobgroup";
+ private static final String UNDERLINE = "_";
+
+ private QuartzJobKey(int projectId, int schedulerId) {
+ this.schedulerId = schedulerId;
+ this.projectId = projectId;
+ }
+
+ public static QuartzJobKey of(int projectId, int schedulerId) {
+ return new QuartzJobKey(projectId, schedulerId);
+ }
+
+ public JobKey toJobKey() {
+ // todo: We don't need to add prefix to job name and job group?
+ String jobName = QUARTZ_JOB_PREFIX + UNDERLINE + schedulerId;
+ String jobGroup = QUARTZ_JOB_GROUP_PREFIX + UNDERLINE + projectId;
+ return new JobKey(jobName, jobGroup);
+ }
+}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzScheduler.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzScheduler.java
index 7d0f1ce73c..70d5bf8fab 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzScheduler.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzScheduler.java
@@ -17,20 +17,10 @@
package org.apache.dolphinscheduler.scheduler.quartz;
-import static org.quartz.CronScheduleBuilder.cronSchedule;
-import static org.quartz.JobBuilder.newJob;
-import static org.quartz.TriggerBuilder.newTrigger;
-
-import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.dao.entity.Schedule;
import org.apache.dolphinscheduler.scheduler.api.SchedulerApi;
import org.apache.dolphinscheduler.scheduler.api.SchedulerException;
-import org.apache.dolphinscheduler.scheduler.quartz.utils.QuartzTaskUtils;
-
-import java.util.Date;
-import java.util.Map;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.apache.dolphinscheduler.scheduler.quartz.exception.QuartzSchedulerExceptionEnum;
import lombok.extern.slf4j.Slf4j;
@@ -38,118 +28,49 @@ import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
-import org.quartz.TriggerKey;
-import org.springframework.beans.factory.annotation.Autowired;
-import com.google.common.base.Strings;
+import com.google.common.collect.Sets;
@Slf4j
public class QuartzScheduler implements SchedulerApi {
- @Autowired
- private Scheduler scheduler;
+ private final Scheduler scheduler;
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ public QuartzScheduler(Scheduler scheduler) {
+ this.scheduler = scheduler;
+ }
@Override
public void start() throws SchedulerException {
try {
scheduler.start();
} catch (Exception e) {
- throw new SchedulerException("Failed to start quartz scheduler ", e);
+ throw new SchedulerException(QuartzSchedulerExceptionEnum.QUARTZ_SCHEDULER_START_ERROR, e);
}
}
@Override
public void insertOrUpdateScheduleTask(int projectId, Schedule schedule) throws SchedulerException {
- JobKey jobKey = QuartzTaskUtils.getJobKey(schedule.getId(), projectId);
- Map<String, Object> jobDataMap = QuartzTaskUtils.buildDataMap(projectId, schedule);
- String cronExpression = schedule.getCrontab();
- String timezoneId = schedule.getTimezoneId();
-
- /**
- * transform from server default timezone to schedule timezone
- * e.g. server default timezone is `UTC`
- * user set a schedule with startTime `2022-04-28 10:00:00`, timezone is `Asia/Shanghai`,
- * api skip to transform it and save into databases directly, startTime `2022-04-28 10:00:00`, timezone is `UTC`, which actually added 8 hours,
- * so when add job to quartz, it should recover by transform timezone
- */
- Date startDate = DateUtils.transformTimezoneDate(schedule.getStartTime(), timezoneId);
- Date endDate = DateUtils.transformTimezoneDate(schedule.getEndTime(), timezoneId);
- /**
- * If the start time is less than the current time, the start time is set to the current time.
- * We do this change to avoid misfires all triggers when update the scheduler.
- */
- Date now = new Date();
- if (startDate.before(now)) {
- startDate = now;
- }
-
- lock.writeLock().lock();
try {
-
- JobDetail jobDetail;
- // add a task (if this task already exists, return this task directly)
- if (scheduler.checkExists(jobKey)) {
-
- jobDetail = scheduler.getJobDetail(jobKey);
- jobDetail.getJobDataMap().putAll(jobDataMap);
- } else {
- jobDetail = newJob(ProcessScheduleTask.class).withIdentity(jobKey).build();
-
- jobDetail.getJobDataMap().putAll(jobDataMap);
-
- scheduler.addJob(jobDetail, false, true);
-
- log.info("Add job, job name: {}, group name: {}", jobKey.getName(), jobKey.getGroup());
- }
-
- TriggerKey triggerKey = new TriggerKey(jobKey.getName(), jobKey.getGroup());
- /*
- * Instructs the Scheduler that upon a mis-fire situation, the CronTrigger wants to have it's next-fire-time
- * updated to the next time in the schedule after the current time (taking into account any associated
- * Calendar), but it does not want to be fired now.
- */
- CronTrigger cronTrigger = newTrigger()
- .withIdentity(triggerKey)
- .startAt(startDate)
- .endAt(endDate)
- .withSchedule(
- cronSchedule(cronExpression)
- .withMisfireHandlingInstructionIgnoreMisfires()
- .inTimeZone(DateUtils.getTimezone(timezoneId)))
- .forJob(jobDetail).build();
-
- if (scheduler.checkExists(triggerKey)) {
- // updateProcessInstance scheduler trigger when scheduler cycle changes
- CronTrigger oldCronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
- String oldCronExpression = oldCronTrigger.getCronExpression();
-
- if (!Strings.nullToEmpty(cronExpression).equalsIgnoreCase(Strings.nullToEmpty(oldCronExpression))) {
- // reschedule job trigger
- scheduler.rescheduleJob(triggerKey, cronTrigger);
- log.info(
- "reschedule job trigger, triggerName: {}, triggerGroupName: {}, cronExpression: {}, startDate: {}, endDate: {}",
- triggerKey.getName(), triggerKey.getGroup(), cronExpression, startDate, endDate);
- }
- } else {
- scheduler.scheduleJob(cronTrigger);
- log.info(
- "schedule job trigger, triggerName: {}, triggerGroupName: {}, cronExpression: {}, startDate: {}, endDate: {}",
- triggerKey.getName(), triggerKey.getGroup(), cronExpression, startDate, endDate);
- }
-
+ CronTrigger cornTrigger = QuartzCornTriggerBuilder.newBuilder()
+ .withProjectId(projectId)
+ .withSchedule(schedule)
+ .build();
+ JobDetail jobDetail = QuartzJobDetailBuilder.newBuilder()
+ .withProjectId(projectId)
+ .withSchedule(schedule.getId())
+ .build();
+ scheduler.scheduleJob(jobDetail, Sets.newHashSet(cornTrigger), true);
+ log.info("Success scheduleJob: {} with trigger: {} at quartz", jobDetail, cornTrigger);
} catch (Exception e) {
log.error("Failed to add scheduler task, projectId: {}, scheduler: {}", projectId, schedule, e);
- throw new SchedulerException("Add schedule job failed", e);
- } finally {
- lock.writeLock().unlock();
+ throw new SchedulerException(QuartzSchedulerExceptionEnum.QUARTZ_UPSERT_JOB_ERROR, e);
}
}
@Override
public void deleteScheduleTask(int projectId, int scheduleId) throws SchedulerException {
- JobKey jobKey = QuartzTaskUtils.getJobKey(scheduleId, projectId);
+ JobKey jobKey = QuartzJobKey.of(projectId, scheduleId).toJobKey();
try {
if (scheduler.checkExists(jobKey)) {
log.info("Try to delete scheduler task, projectId: {}, schedulerId: {}", projectId, scheduleId);
@@ -157,7 +78,7 @@ public class QuartzScheduler implements SchedulerApi {
}
} catch (Exception e) {
log.error("Failed to delete scheduler task, projectId: {}, schedulerId: {}", projectId, scheduleId, e);
- throw new SchedulerException("Failed to delete scheduler task");
+ throw new SchedulerException(QuartzSchedulerExceptionEnum.QUARTZ_DELETE_JOB_ERROR, e);
}
}
@@ -166,8 +87,8 @@ public class QuartzScheduler implements SchedulerApi {
// nothing to do
try {
scheduler.shutdown();
- } catch (org.quartz.SchedulerException e) {
- throw new SchedulerException("Failed to shutdown scheduler", e);
+ } catch (Exception e) {
+ throw new SchedulerException(QuartzSchedulerExceptionEnum.QUARTZ_SCHEDULER_SHOWDOWN_ERROR, e);
}
}
}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java
index 123e4cde50..07ff8af434 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java
@@ -19,14 +19,20 @@ package org.apache.dolphinscheduler.scheduler.quartz;
import org.apache.dolphinscheduler.scheduler.api.SchedulerApi;
+import org.quartz.Scheduler;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-@Configuration
+@AutoConfiguration(after = {QuartzAutoConfiguration.class})
+@ConditionalOnClass(value = Scheduler.class)
public class QuartzSchedulerConfiguration {
@Bean
- public SchedulerApi schedulerApi() {
- return new QuartzScheduler();
+ @ConditionalOnMissingBean
+ public SchedulerApi schedulerApi(Scheduler scheduler) {
+ return new QuartzScheduler(scheduler);
}
}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzTriggerBuilder.java
similarity index 73%
copy from dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
copy to dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzTriggerBuilder.java
index c81f114204..06c9101c5f 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzTriggerBuilder.java
@@ -15,16 +15,11 @@
* limitations under the License.
*/
-package org.apache.dolphinscheduler.scheduler.api;
+package org.apache.dolphinscheduler.scheduler.quartz;
-public class SchedulerException extends RuntimeException {
+import org.quartz.CronTrigger;
- public SchedulerException(String message) {
- super(message);
- }
-
- public SchedulerException(String message, Throwable cause) {
- super(message, cause);
- }
+public interface QuartzTriggerBuilder {
+ CronTrigger build();
}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/exception/QuartzSchedulerExceptionEnum.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/exception/QuartzSchedulerExceptionEnum.java
new file mode 100644
index 0000000000..76fa39e911
--- /dev/null
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/exception/QuartzSchedulerExceptionEnum.java
@@ -0,0 +1,48 @@
+/*
+ * 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.dolphinscheduler.scheduler.quartz.exception;
+
+import org.apache.dolphinscheduler.scheduler.api.SchedulerExceptionEnum;
+
+public enum QuartzSchedulerExceptionEnum implements SchedulerExceptionEnum {
+
+ QUARTZ_SCHEDULER_START_ERROR("QUARTZ-001", "Quartz Scheduler start error"),
+ QUARTZ_UPSERT_JOB_ERROR("QUARTZ-002", "Upsert quartz job error"),
+ QUARTZ_DELETE_JOB_ERROR("QUARTZ-003", "Delete quartz job error"),
+ QUARTZ_SCHEDULER_SHOWDOWN_ERROR("QUARTZ-004", "Quartz Scheduler shutdown error"),
+ ;
+
+ private final String code;
+
+ private final String message;
+
+ QuartzSchedulerExceptionEnum(String code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ @Override
+ public String getCode() {
+ return code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/utils/QuartzTaskUtils.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/utils/QuartzTaskUtils.java
deleted file mode 100644
index e4f3471399..0000000000
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/utils/QuartzTaskUtils.java
+++ /dev/null
@@ -1,59 +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.dolphinscheduler.scheduler.quartz.utils;
-
-import org.apache.dolphinscheduler.common.utils.JSONUtils;
-import org.apache.dolphinscheduler.dao.entity.Schedule;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.quartz.JobKey;
-
-public final class QuartzTaskUtils {
-
- public static final String QUARTZ_JOB_PREFIX = "job";
- public static final String QUARTZ_JOB_GROUP_PREFIX = "jobgroup";
- public static final String UNDERLINE = "_";
- public static final String PROJECT_ID = "projectId";
- public static final String SCHEDULE_ID = "scheduleId";
- public static final String SCHEDULE = "schedule";
-
- /**
- * @param schedulerId scheduler id
- * @return quartz job name
- */
- public static JobKey getJobKey(int schedulerId, int projectId) {
- String jobName = QUARTZ_JOB_PREFIX + UNDERLINE + schedulerId;
- String jobGroup = QUARTZ_JOB_GROUP_PREFIX + UNDERLINE + projectId;
- return new JobKey(jobName, jobGroup);
- }
-
- /**
- * create quartz job data, include projectId and scheduleId, schedule.
- */
- public static Map<String, Object> buildDataMap(int projectId, Schedule schedule) {
- Map<String, Object> dataMap = new HashMap<>(8);
- dataMap.put(PROJECT_ID, projectId);
- dataMap.put(SCHEDULE_ID, schedule.getId());
- dataMap.put(SCHEDULE, JSONUtils.toJsonString(schedule));
-
- return dataMap;
- }
-
-}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobDataTest.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobDataTest.java
new file mode 100644
index 0000000000..e9493cc782
--- /dev/null
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobDataTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.dolphinscheduler.scheduler.quartz;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.quartz.JobDataMap;
+
+import com.google.common.collect.ImmutableMap;
+
+class QuartzJobDataTest {
+
+ @Test
+ void of() {
+ QuartzJobData quartzJobData = QuartzJobData.of(1, 2);
+ assertEquals(1, quartzJobData.getProjectId());
+ assertEquals(2, quartzJobData.getScheduleId());
+ }
+
+ @Test
+ void of_JobDataMap() {
+
+ ImmutableMap<String, Object> map = ImmutableMap.of(
+ "projectId", 1,
+ "scheduleId", 2);
+ JobDataMap jobDataMap = new JobDataMap(map);
+ QuartzJobData quartzJobData = QuartzJobData.of(jobDataMap);
+ assertEquals(1, quartzJobData.getProjectId());
+ assertEquals(2, quartzJobData.getScheduleId());
+ }
+
+ @Test
+ void toJobDataMap() {
+ QuartzJobData quartzJobData = QuartzJobData.of(1, 2);
+ JobDataMap jobDataMap = quartzJobData.toJobDataMap();
+ QuartzJobData quartzJobData1 = QuartzJobData.of(jobDataMap);
+ assertEquals(1, quartzJobData1.getProjectId());
+ assertEquals(2, quartzJobData1.getScheduleId());
+ }
+}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobKeyTest.java
similarity index 59%
copy from dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java
copy to dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobKeyTest.java
index 123e4cde50..aafbadefb1 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/main/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzSchedulerConfiguration.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/QuartzJobKeyTest.java
@@ -17,16 +17,25 @@
package org.apache.dolphinscheduler.scheduler.quartz;
-import org.apache.dolphinscheduler.scheduler.api.SchedulerApi;
+import static org.junit.jupiter.api.Assertions.assertEquals;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
+import org.junit.jupiter.api.Test;
+import org.quartz.JobKey;
-@Configuration
-public class QuartzSchedulerConfiguration {
+class QuartzJobKeyTest {
- @Bean
- public SchedulerApi schedulerApi() {
- return new QuartzScheduler();
+ @Test
+ void of() {
+ QuartzJobKey quartzJobKey = QuartzJobKey.of(1, 2);
+ assertEquals(1, quartzJobKey.getProjectId());
+ assertEquals(2, quartzJobKey.getSchedulerId());
+ }
+
+ @Test
+ void toJobKey() {
+ QuartzJobKey quartzJobKey = QuartzJobKey.of(1, 2);
+ JobKey jobKey = quartzJobKey.toJobKey();
+ assertEquals("job_2", jobKey.getName());
+ assertEquals("jobgroup_1", jobKey.getGroup());
}
}
diff --git a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/exception/QuartzSchedulerExceptionEnumTest.java
similarity index 59%
copy from dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
copy to dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/exception/QuartzSchedulerExceptionEnumTest.java
index c81f114204..943b2cc125 100644
--- a/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-api/src/main/java/org/apache/dolphinscheduler/scheduler/api/SchedulerException.java
+++ b/dolphinscheduler-scheduler-plugin/dolphinscheduler-scheduler-quartz/src/test/java/org/apache/dolphinscheduler/scheduler/quartz/exception/QuartzSchedulerExceptionEnumTest.java
@@ -15,16 +15,21 @@
* limitations under the License.
*/
-package org.apache.dolphinscheduler.scheduler.api;
+package org.apache.dolphinscheduler.scheduler.quartz.exception;
-public class SchedulerException extends RuntimeException {
+import static org.junit.jupiter.api.Assertions.assertEquals;
- public SchedulerException(String message) {
- super(message);
- }
+import org.apache.dolphinscheduler.scheduler.api.SchedulerException;
+
+import org.junit.jupiter.api.Test;
+
+class QuartzSchedulerExceptionEnumTest {
- public SchedulerException(String message, Throwable cause) {
- super(message, cause);
+ @Test
+ void testException() {
+ SchedulerException schedulerException =
+ new SchedulerException(QuartzSchedulerExceptionEnum.QUARTZ_SCHEDULER_START_ERROR);
+ assertEquals("Scheduler[QUARTZ-001] Quartz Scheduler start error", schedulerException.getMessage());
}
}