Had taken the time and integrated quartz with grails.
Thought I will share it.
In this post I will discuss how to Install and configure quartz with jobs persistent in a database( mysql)
1.
Get quartz distribution.
Unzip to a directory.
Run the table-creation SQL scripts in the "docs/dbTables" directory of the Quartz distribution
Unzip to a directory.
Run the table-creation SQL scripts in the "docs/dbTables" directory of the Quartz distribution
2.Install quartz plugin
grails install-plugin quartz
3.
Create a file, QuartzConfig.groovy in grails-app\conf
Specify quartz startup and storage options here like this:
Specify quartz startup and storage options here like this:
quartz {
autoStartup = true
jdbcStore = true
waitForJobsToCompleteOnShutdown = true
}
autoStartup = true
jdbcStore = true
waitForJobsToCompleteOnShutdown = true
}
environments {
test {
quartz {
autoStartup = true
}
}
}
test {
quartz {
autoStartup = true
}
}
}
4.
Create a file, quartz.properties in grails-app\conf
Configure your db name in URL as well as user name and password
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 3
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass =
org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = prodDataSource
org.quartz.jobStore.isClustered = false
org.quartz.dataSource.prodDataSource.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.prodDataSource.URL = "jdbc:mysql://localhost:3306/xxx?autoreconnect=true">org.quartz.dataSource.prodDataSource.user=grails
org.quartz.dataSource.prodDataSource.password ="server"
org.quartz.jobStore.driverDelegateClass =
org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = prodDataSource
org.quartz.jobStore.isClustered = false
org.quartz.dataSource.prodDataSource.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.prodDataSource.URL = "jdbc:mysql://localhost:3306/xxx?autoreconnect=true">org.quartz.dataSource.prodDataSource.user=grails
org.quartz.dataSource.prodDataSource.password ="server"
5.
In resources.groovy in grails-app\conf\spring
add the imports:
import org.springframework.scheduling.quartz.SchedulerFactoryBean
import org.codehaus.groovy.grails.jobs.*
import org.codehaus.groovy.grails.plugins.quartz.listeners.*
import org.springframework.scheduling.quartz.SchedulerFactoryBean
import org.codehaus.groovy.grails.jobs.*
import org.codehaus.groovy.grails.plugins.quartz.listeners.*
add this to spring beans dsl:
quartzScheduler(SchedulerFactoryBean) {
autoStartup = false
dataSource = ref('dataSource')
transactionManager = ref('transactionManager')
configLocation = 'classpath:quartz.properties'
jobFactory = ref('quartzJobFactory')
jobListeners = [ref("${SessionBinderJobListener.NAME}")]
globalJobListeners = [ref("${ExceptionPrinterJobListener.NAME}")]
}
autoStartup = false
dataSource = ref('dataSource')
transactionManager = ref('transactionManager')
configLocation = 'classpath:quartz.properties'
jobFactory = ref('quartzJobFactory')
jobListeners = [ref("${SessionBinderJobListener.NAME}")]
globalJobListeners = [ref("${ExceptionPrinterJobListener.NAME}")]
}
6.
Create a service class(or where you would prefer to do this) with grails create-service
Enable the service class to be injeced with a scheduler by declaring like this
def quartzScheduler
define a method which will do the scheduling for you.
In this eg I put in a domain object for later retrieval during job execution.
Enable the service class to be injeced with a scheduler by declaring like this
def quartzScheduler
define a method which will do the scheduling for you.
In this eg I put in a domain object for later retrieval during job execution.
def schedule(my.Motd m) {
// execute task
def jobDetail = new JobDetail(m?.message, group, MotdJob.class);
jobDetail.getJobDataMap().put("job", m)
// execute task
def jobDetail = new JobDetail(m?.message, group, MotdJob.class);
jobDetail.getJobDataMap().put("job", m)
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy.MM.dd hh:mm:ss");
Date myDate = formatter.parse("2010.07.02 15:13:56");
Date myDate = formatter.parse("2010.07.02 15:13:56");
def myTrigger = new SimpleTrigger("myTrigger" + new Random().nextInt().toString(), "mygroup" + new Random().nextInt().toString(), myDate,null,0,0)
quartzScheduler.scheduleJob(jobDetail, myTrigger);
}
quartzScheduler.scheduleJob(jobDetail, myTrigger);
}
7.
Create a quartz job using
grails create-job fully-qualified-job-name
grails create-job fully-qualified-job-name
In this class define a execute method and implement your business logic
void execute(JobExecutionContext context) {
String instName = context.getJobDetail().getName();
println "I have been triggered to run instGroup"
String instGroup = context.getJobDetail().getGroup();
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
def mo =dataMap.get("job")
if(mo) {
Motd m = (Motd)mo
}
else
println "null job"
return
}
String instName = context.getJobDetail().getName();
println "I have been triggered to run instGroup"
String instGroup = context.getJobDetail().getGroup();
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
def mo =dataMap.get("job")
if(mo) {
Motd m = (Motd)mo
}
else
println "null job"
return
}
8.
If you job uses a domain class (like in example above) you need to create a jar with all the domain class used by quartz and add this to your lib directory
NOTE: This is at best a hack solution. Better option is doing this through classloader. But I wont go into it.
NOTE: This is at best a hack solution. Better option is doing this through classloader. But I wont go into it.
Thats it.
Enjoy and email me at trbala attherateof yahoo.com if you need an exmaple source or if you can offer me a good paying job in siliconvalley!!!
No comments:
Post a Comment