@ -14,15 +14,76 @@
* See the License for the specific language governing permissions and
* limitations under the License .
* /
package org.apache.dolphinscheduler.service.quartz ;
import static org.apache.dolphinscheduler.common.Constants.ORG_POSTGRESQL_DRIVER ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_DATASOURCE_MYDS_CONNECTIONPROVIDER_CLASS ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_ACQUIRETRIGGERSWITHINLOCK ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_CLASS ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_CLUSTERCHECKININTERVAL ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_DATASOURCE ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_ISCLUSTERED ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_MISFIRETHRESHOLD ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_TABLEPREFIX ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_JOBSTORE_USEPROPERTIES ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_SCHEDULER_INSTANCEID ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_SCHEDULER_INSTANCENAME ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_SCHEDULER_MAKESCHEDULERTHREADDAEMON ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_THREADPOOL_CLASS ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_THREADPOOL_MAKETHREADSDAEMONS ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_THREADPOOL_THREADCOUNT ;
import static org.apache.dolphinscheduler.common.Constants.ORG_QUARTZ_THREADPOOL_THREADPRIORITY ;
import static org.apache.dolphinscheduler.common.Constants.PROJECT_ID ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_ACQUIRETRIGGERSWITHINLOCK ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_CLUSTERCHECKININTERVAL ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_DATASOURCE ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_INSTANCEID ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_INSTANCENAME ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_JOB_GROUP_PRIFIX ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_JOB_PRIFIX ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_MISFIRETHRESHOLD ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_PROPERTIES_PATH ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_TABLE_PREFIX ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_THREADCOUNT ;
import static org.apache.dolphinscheduler.common.Constants.QUARTZ_THREADPRIORITY ;
import static org.apache.dolphinscheduler.common.Constants.SCHEDULE ;
import static org.apache.dolphinscheduler.common.Constants.SCHEDULE_ID ;
import static org.apache.dolphinscheduler.common.Constants.SPRING_DATASOURCE_DRIVER_CLASS_NAME ;
import static org.apache.dolphinscheduler.common.Constants.STRING_FALSE ;
import static org.apache.dolphinscheduler.common.Constants.STRING_TRUE ;
import static org.apache.dolphinscheduler.common.Constants.UNDERLINE ;
import static org.quartz.CronScheduleBuilder.cronSchedule ;
import static org.quartz.JobBuilder.newJob ;
import static org.quartz.TriggerBuilder.newTrigger ;
import org.apache.dolphinscheduler.common.utils.JSONUtils ;
import org.apache.dolphinscheduler.common.utils.StringUtils ;
import org.apache.dolphinscheduler.dao.entity.Schedule ;
import org.apache.dolphinscheduler.service.exceptions.ServiceException ;
import org.apache.commons.configuration.Configuration ;
import org.apache.commons.configuration.ConfigurationException ;
import org.apache.commons.configuration.PropertiesConfiguration ;
import org.apache.commons.lang.StringUtils ;
import org.apache.dolphinscheduler.common.utils.* ;
import org.apache.dolphinscheduler.dao.entity.Schedule ;
import org.quartz.* ;
import java.util.ArrayList ;
import java.util.Date ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.Properties ;
import java.util.concurrent.locks.ReadWriteLock ;
import java.util.concurrent.locks.ReentrantReadWriteLock ;
import org.quartz.CronTrigger ;
import org.quartz.Job ;
import org.quartz.JobDetail ;
import org.quartz.JobKey ;
import org.quartz.Scheduler ;
import org.quartz.SchedulerException ;
import org.quartz.TriggerKey ;
import org.quartz.impl.StdSchedulerFactory ;
import org.quartz.impl.jdbcjobstore.JobStoreTX ;
import org.quartz.impl.jdbcjobstore.PostgreSQLDelegate ;
@ -32,15 +93,6 @@ import org.quartz.simpl.SimpleThreadPool;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import java.util.* ;
import java.util.concurrent.locks.ReadWriteLock ;
import java.util.concurrent.locks.ReentrantReadWriteLock ;
import static org.apache.dolphinscheduler.common.Constants.* ;
import static org.quartz.CronScheduleBuilder.cronSchedule ;
import static org.quartz.JobBuilder.newJob ;
import static org.quartz.TriggerBuilder.newTrigger ;
/ * *
* single Quartz executors instance
* /
@ -70,28 +122,27 @@ public class QuartzExecutors {
private static final QuartzExecutors instance = new QuartzExecutors ( ) ;
}
private QuartzExecutors ( ) {
try {
conf = new PropertiesConfiguration ( QUARTZ_PROPERTIES_PATH ) ;
init ( ) ;
} catch ( ConfigurationException e ) {
logger . warn ( "not loaded quartz configuration file, will used default value" , e ) ;
} catch ( ConfigurationException e ) {
logger . warn ( "not loaded quartz configuration file, will used default value" , e ) ;
}
}
/ * *
* thread safe and performance promote
*
* @return instance of Quartz Executors
* /
public static QuartzExecutors getInstance ( ) {
return Holder . instance ;
}
/ * *
* init
*
* < p >
* Returns a client - usable handle to a Scheduler .
* /
private void init ( ) {
@ -100,33 +151,33 @@ public class QuartzExecutors {
Properties properties = new Properties ( ) ;
String dataSourceDriverClass = org . apache . dolphinscheduler . dao . utils . PropertyUtils . getString ( SPRING_DATASOURCE_DRIVER_CLASS_NAME ) ;
if ( dataSourceDriverClass . equals ( ORG_POSTGRESQL_DRIVER ) ) {
properties . setProperty ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , conf . getString ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , PostgreSQLDelegate . class . getName ( ) ) ) ;
if ( dataSourceDriverClass . equals ( ORG_POSTGRESQL_DRIVER ) ) {
properties . setProperty ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , conf . getString ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , PostgreSQLDelegate . class . getName ( ) ) ) ;
} else {
properties . setProperty ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , conf . getString ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , StdJDBCDelegate . class . getName ( ) ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , conf . getString ( ORG_QUARTZ_JOBSTORE_DRIVERDELEGATECLASS , StdJDBCDelegate . class . getName ( ) ) ) ;
}
properties . setProperty ( ORG_QUARTZ_SCHEDULER_INSTANCENAME , conf . getString ( ORG_QUARTZ_SCHEDULER_INSTANCENAME , QUARTZ_INSTANCENAME ) ) ;
properties . setProperty ( ORG_QUARTZ_SCHEDULER_INSTANCEID , conf . getString ( ORG_QUARTZ_SCHEDULER_INSTANCEID , QUARTZ_INSTANCEID ) ) ;
properties . setProperty ( ORG_QUARTZ_SCHEDULER_MAKESCHEDULERTHREADDAEMON , conf . getString ( ORG_QUARTZ_SCHEDULER_MAKESCHEDULERTHREADDAEMON , STRING_TRUE ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_USEPROPERTIES , conf . getString ( ORG_QUARTZ_JOBSTORE_USEPROPERTIES , STRING_FALSE ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_CLASS , conf . getString ( ORG_QUARTZ_THREADPOOL_CLASS , SimpleThreadPool . class . getName ( ) ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_MAKETHREADSDAEMONS , conf . getString ( ORG_QUARTZ_THREADPOOL_MAKETHREADSDAEMONS , STRING_TRUE ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_THREADCOUNT , conf . getString ( ORG_QUARTZ_THREADPOOL_THREADCOUNT , QUARTZ_THREADCOUNT ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_THREADPRIORITY , conf . getString ( ORG_QUARTZ_THREADPOOL_THREADPRIORITY , QUARTZ_THREADPRIORITY ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_CLASS , conf . getString ( ORG_QUARTZ_JOBSTORE_CLASS , JobStoreTX . class . getName ( ) ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_TABLEPREFIX , conf . getString ( ORG_QUARTZ_JOBSTORE_TABLEPREFIX , QUARTZ_TABLE_PREFIX ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_ISCLUSTERED , conf . getString ( ORG_QUARTZ_JOBSTORE_ISCLUSTERED , STRING_TRUE ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_MISFIRETHRESHOLD , conf . getString ( ORG_QUARTZ_JOBSTORE_MISFIRETHRESHOLD , QUARTZ_MISFIRETHRESHOLD ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_CLUSTERCHECKININTERVAL , conf . getString ( ORG_QUARTZ_JOBSTORE_CLUSTERCHECKININTERVAL , QUARTZ_CLUSTERCHECKININTERVAL ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_ACQUIRETRIGGERSWITHINLOCK , conf . getString ( ORG_QUARTZ_JOBSTORE_ACQUIRETRIGGERSWITHINLOCK , QUARTZ_ACQUIRETRIGGERSWITHINLOCK ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_DATASOURCE , conf . getString ( ORG_QUARTZ_JOBSTORE_DATASOURCE , QUARTZ_DATASOURCE ) ) ;
properties . setProperty ( ORG_QUARTZ_DATASOURCE_MYDS_CONNECTIONPROVIDER_CLASS , conf . getString ( ORG_QUARTZ_DATASOURCE_MYDS_CONNECTIONPROVIDER_CLASS , DruidConnectionProvider . class . getName ( ) ) ) ;
properties . setProperty ( ORG_QUARTZ_SCHEDULER_MAKESCHEDULERTHREADDAEMON , conf . getString ( ORG_QUARTZ_SCHEDULER_MAKESCHEDULERTHREADDAEMON , STRING_TRUE ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_USEPROPERTIES , conf . getString ( ORG_QUARTZ_JOBSTORE_USEPROPERTIES , STRING_FALSE ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_CLASS , conf . getString ( ORG_QUARTZ_THREADPOOL_CLASS , SimpleThreadPool . class . getName ( ) ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_MAKETHREADSDAEMONS , conf . getString ( ORG_QUARTZ_THREADPOOL_MAKETHREADSDAEMONS , STRING_TRUE ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_THREADCOUNT , conf . getString ( ORG_QUARTZ_THREADPOOL_THREADCOUNT , QUARTZ_THREADCOUNT ) ) ;
properties . setProperty ( ORG_QUARTZ_THREADPOOL_THREADPRIORITY , conf . getString ( ORG_QUARTZ_THREADPOOL_THREADPRIORITY , QUARTZ_THREADPRIORITY ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_CLASS , conf . getString ( ORG_QUARTZ_JOBSTORE_CLASS , JobStoreTX . class . getName ( ) ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_TABLEPREFIX , conf . getString ( ORG_QUARTZ_JOBSTORE_TABLEPREFIX , QUARTZ_TABLE_PREFIX ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_ISCLUSTERED , conf . getString ( ORG_QUARTZ_JOBSTORE_ISCLUSTERED , STRING_TRUE ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_MISFIRETHRESHOLD , conf . getString ( ORG_QUARTZ_JOBSTORE_MISFIRETHRESHOLD , QUARTZ_MISFIRETHRESHOLD ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_CLUSTERCHECKININTERVAL , conf . getString ( ORG_QUARTZ_JOBSTORE_CLUSTERCHECKININTERVAL , QUARTZ_CLUSTERCHECKININTERVAL ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_ACQUIRETRIGGERSWITHINLOCK , conf . getString ( ORG_QUARTZ_JOBSTORE_ACQUIRETRIGGERSWITHINLOCK , QUARTZ_ACQUIRETRIGGERSWITHINLOCK ) ) ;
properties . setProperty ( ORG_QUARTZ_JOBSTORE_DATASOURCE , conf . getString ( ORG_QUARTZ_JOBSTORE_DATASOURCE , QUARTZ_DATASOURCE ) ) ;
properties . setProperty ( ORG_QUARTZ_DATASOURCE_MYDS_CONNECTIONPROVIDER_CLASS , conf . getString ( ORG_QUARTZ_DATASOURCE_MYDS_CONNECTIONPROVIDER_CLASS , DruidConnectionProvider . class . getName ( ) ) ) ;
schedulerFactory . initialize ( properties ) ;
scheduler = schedulerFactory . getScheduler ( ) ;
} catch ( SchedulerException e ) {
logger . error ( e . getMessage ( ) , e ) ;
logger . error ( e . getMessage ( ) , e ) ;
System . exit ( 1 ) ;
}
@ -138,19 +189,20 @@ public class QuartzExecutors {
* @throws SchedulerException scheduler exception
* /
public void start ( ) throws SchedulerException {
if ( ! scheduler . isStarted ( ) ) {
if ( ! scheduler . isStarted ( ) ) {
scheduler . start ( ) ;
logger . info ( "Quartz service started" ) ;
logger . info ( "Quartz service started" ) ;
}
}
/ * *
* stop all scheduled tasks
*
* < p >
* Halts the Scheduler ' s firing of Triggers ,
* and cleans up all resources associated with the Scheduler .
*
* < p >
* The scheduler cannot be re - started .
*
* @throws SchedulerException scheduler exception
* /
public void shutdown ( ) throws SchedulerException {
@ -161,7 +213,6 @@ public class QuartzExecutors {
}
}
/ * *
* add task trigger , if this task already exists , return this task with updated trigger
*
@ -173,7 +224,7 @@ public class QuartzExecutors {
* @param cronExpression cron expression
* @param jobDataMap job parameters data map
* /
public void addJob ( Class < ? extends Job > clazz , String jobName , String jobGroupName , Date startDate , Date endDate ,
public void addJob ( Class < ? extends Job > clazz , String jobName , String jobGroupName , Date startDate , Date endDate ,
String cronExpression ,
Map < String , Object > jobDataMap ) {
lock . writeLock ( ) . lock ( ) ;
@ -218,7 +269,7 @@ public class QuartzExecutors {
CronTrigger oldCronTrigger = ( CronTrigger ) scheduler . getTrigger ( triggerKey ) ;
String oldCronExpression = oldCronTrigger . getCronExpression ( ) ;
if ( ! StringUtils . equalsIgnoreCase ( cronExpression , oldCronExpression ) ) {
if ( ! StringUtils . equalsIgnoreCase ( cronExpression , oldCronExpression ) ) {
// reschedule job trigger
scheduler . rescheduleJob ( triggerKey , cronTrigger ) ;
logger . info ( "reschedule job trigger, triggerName: {}, triggerGroupName: {}, cronExpression: {}, startDate: {}, endDate: {}" ,
@ -231,14 +282,12 @@ public class QuartzExecutors {
}
} catch ( Exception e ) {
logger . error ( "add job failed" , e ) ;
throw new RuntimeException ( "add job failed" , e ) ;
throw new ServiceException ( "add job failed" , e ) ;
} finally {
lock . writeLock ( ) . unlock ( ) ;
}
}
/ * *
* delete job
*
@ -249,16 +298,16 @@ public class QuartzExecutors {
public boolean deleteJob ( String jobName , String jobGroupName ) {
lock . writeLock ( ) . lock ( ) ;
try {
JobKey jobKey = new JobKey ( jobName , jobGroupName ) ;
if ( scheduler . checkExists ( jobKey ) ) {
JobKey jobKey = new JobKey ( jobName , jobGroupName ) ;
if ( scheduler . checkExists ( jobKey ) ) {
logger . info ( "try to delete job, job name: {}, job group name: {}," , jobName , jobGroupName ) ;
return scheduler . deleteJob ( jobKey ) ;
} else {
} else {
return true ;
}
} catch ( SchedulerException e ) {
logger . error ( "delete job : {} failed" , jobName , e ) ;
logger . error ( "delete job : {} failed" , jobName , e ) ;
} finally {
lock . writeLock ( ) . unlock ( ) ;
}
@ -269,7 +318,6 @@ public class QuartzExecutors {
* delete all jobs in job group
*
* @param jobGroupName job group name
*
* @return true if all of the Jobs were found and deleted , false if
* one or more were not deleted .
* /
@ -282,7 +330,7 @@ public class QuartzExecutors {
return scheduler . deleteJobs ( jobKeys ) ;
} catch ( SchedulerException e ) {
logger . error ( "delete all jobs in job group: {} failed" , jobGroupName , e ) ;
logger . error ( "delete all jobs in job group: {} failed" , jobGroupName , e ) ;
} finally {
lock . writeLock ( ) . unlock ( ) ;
}
@ -291,6 +339,7 @@ public class QuartzExecutors {
/ * *
* build job name
*
* @param processId process id
* @return job name
* /
@ -302,6 +351,7 @@ public class QuartzExecutors {
/ * *
* build job group name
*
* @param projectId project id
* @return job group name
* /