Grails Scheduled Quartz Job never runs - grails

Here is the Code:
class FollowUpJobOne {
FollowUpMailService followUpMailService;
static triggers = {
cron name: 'jobOneForFollowUp', cronExpression: "00 00 6 ? * *" //6 AM everyday as per server time
}
def execute() {
log.debug("control in Follow up job");
followUpMailService.sendFollowUpMails();
followUpMailService.sendFollowUpMailsForDandO();
}
}
*This Above Job never runs at 6 a.m.
I am unable to find the issue.
Please Help

Your class should ends with Job.
Just rename FollowUpJobOne to FollowUpOneJob

use grails create-job to create a job class which should be end with Job
cronExpression use 0 0 6 * * ?. Not sure whether quartz can parse 00.
confirm autoStartup = true

Related

How can I find out if current Jenkins build is first run of the day from trigger

I have Jenkins jobs that trigger twice a day and I would like to know if the current build is the first cron trigger of the day or not and do some action.
My cron job is as below
triggers {
// regression --> 3:00GMT, 14:00GMT
cron("00 3 * * 1-5 \n 00 14 * * 1-5")
}
Can I set some boolean param in my Jenkins file to check if it's the first trigger of the day?
The simplest option would be to check the build history. If the previous build was executed on the previous day, then the current build is the first build of the day. The logic must be defined in the executed job configurations.
The currentBuild object is an instance of the org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper class which provides all necessary information.
steps {
echo "The first build of the day started by trigger: ${isFirstBuildOfDayStartedByTrigger(currentBuild)}"
}
// ...
boolean isFirstBuildOfDayStartedByTrigger(currentBuild) {
if (isStartedByTrigger(currentBuild)) {
return false
}
def today = toLocalDate(currentBuild.startTimeInMillis)
def build = currentBuild.previousBuild
while(build != null) {
if (toLocalDate(build.startTimeInMillis).isBefore(today)) {
return true
}
if (isStartedByTrigger(build)) {
return false
}
build = build.previousBuild
}
return true
}
LocalDate toLocalDate(long millis) {
return Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDate()
}
boolean isStartedByTrigger(build) {
// TODO: use build.buildCauses or build.getBuildCauses('cause.class.Name')
// to analyze if the job was started by trigger
return true // or false
}
You have to figure out which build cause is added when the job is started by trigger.
If you just want to find the first build of the day executed by anything or anyone, then the code is much simpler:
steps {
echo "The first build of the day: ${isFirstBuildOfDay(currentBuild)}"
}
boolean isFirstBuildOfDay(currentBuild) {
def today = toLocalDate(currentBuild.startTimeInMillis)
def previousBuild = currentBuild.previousBuild
return previousBuild == null || toLocalDate(previousBuild.startTimeInMillis).isBefore(today)
}
LocalDate toLocalDate(long millis) {
return Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDate()
}
I used the new date API which I think is not whitelisted, so you have to put that code to the Jenkins library or approve the used method signatures.
Found the answer, it's simple but working fine for me.
First I am checking if this is a scheduled job or not and the current hour is less than 5 (scheduled job runs before 5)
def isItFirstScheduledJob = (params.JOB_IS_SCHEDULED && new Date().getHours() < 5) ? true : false

Grails Quartz plugin not remembering stateful data between job executions?

I need to persist a counter value between executions of a Grails Quartz plugin job. This runs at the correctly timed intervals and I can set the jobDataMap and read the value back correctly (during the same execution run), but it refuses to remember it between between executions.
I've set concurrent = false as the docs advised. Any ideas? I just need to persist and increment a counter. I want to avoid using a DB if at all possible, I think this should just use memory? Or other work arounds?
My TestJob.groovy, in /server/grails-app/jobs:
package myPackage
class MyJob {
static triggers = {
simple repeatInterval: 5000l // execute job every 5 seconds
}
def concurrent = false // Don't run multiple simultaneous instances of this job
def execute(context) {
if(context.jobDetail.jobDataMap['recCounter'] == null) { context.jobDetail.jobDataMap['recCounter'] = 1 }
else { context.jobDetail.jobDataMap['recCounter'] = context.jobDetail.jobDataMap['recCounter'] + 1 }
println(context.jobDetail.jobDataMap['recCounter'])
}
The output when run is a new line with '1' every 5 seconds. It should be incrementing the counter each time.
1
1
1
1
etc..
I'm running Grails 3.3.9 and build.gradle has compile "org.grails.plugins:grails-spring-websocket:2.4.1" in dependencies
Thanks
I have never used context object in my apps, but a counter can be implemented in a straight-forward way:
class MyJob {
//some static stuff
AtomicInteger counter = new AtomicInteger()
def execute(context) {
counter.incrementAndGet()
println counter.intValue()
}
}

DSL for triggering cron with a parameter. I have defined the parameter in the job above but unable to pass it in the cron using dsl scripts

I have created the parameter but i am unable to pass that variable while creating the cron job.
job("dev_testing")
{
parameters
{
booleanParam('security_scan', true)
choiceParam('OPTION', ['false (default)', 'true',])
}
triggers
{
cron('H 23 * * 6 %security_scan; true')
}
}
Following is the error:
ERROR: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (javaposse.jobdsl.dsl.helpers.triggers.TriggerContext parameterizedTimerTrigger script$_run_closure1$_closure2$_closure3)
I dont know which plugins you have installed, but the Parameterized Scheduler plugin should help you with your use case.
Per their documentation, the below should work:
triggers {
parameterizedCron('''H 23 * * 6 %security_scan=true''')
}
This also worked for me:
triggers {
parameterizedTimerTrigger {
parameterizedSpecification('H 23 * * 6 %security_scan=true')
}
}
I know this is an old thread - but I just ran into this lately and couldn't get multiple triggers to work for the life of me. Finally I got it working so:
triggers {
parameterizedTimerTrigger {
parameterizedSpecification('''H 21 * * 0-4 %APPLICATION=php
H 23 * * 0-4 %APPLICATION=java''')
}
}

Grails multiple trigger with identifier for CRON

I have a simple Grails application which has a cron job. I have a requirement where I need to have two triggers for this crob job and In the execute method, according to which trigger, I would get information from different source. I have outlined what I need to do in the below code.
class sampleCronJob {
static triggers = {
cron name: 'trigger1' , cronExpression: "0 15 10 1 * ?"
cron name: 'trigger2' , cronExpression: "0 45 10 1 * ?"
}
def execute() {
def info
if(name=='trigger1'){
info = sampleService.getInfoFromTable1()
} else {
info = sampleService.getInfoFromTable2()
}
//process info
}
}
}
Is there a way to do this, where I need to get the name of the trigger, and have two triggers in this format?
Thanks in advance

Quartz job triggering from Config.groovy

I have the following Quartz job running in my application:
class ScraperJob {
def scraperService
static triggers = {
cron name: 'scraperTrigger', cronExpression: "0 0 * * * ?" // run every minute
}
def execute(){
try {
scraperService.storing()
log.info "${new Date()} - Scraping went smoothly."
}
catch(IOException) { // Connexion problem
log.error "${new Date()} - Method: parsing >> Connexion down or interrupted while parsing !"
}
catch(SAXException) { // Any SAXParser exception
log.error "${new Date()} - Method: parsing >> Parser error."
}
finally { // if not closed, the application crashes when the connexion fails
scraperService.slurper.finalize()
scraperService.parser.finalize()
}
}
}
I would like to know if it is possible to set the triggers property from the Config.groovy file. If it is, could you explain how?
I have no idea if this would actually work because i'm not sure when the quartz jobs get configured but in theory it would seem to work. You could probably see how you could also make this much more dynamic if you have more than one job.
Config.groovy
quartz.yourCronJobName="0 0 * * * ?"
BootStrap.groovy
import org.codehaus.groovy.grails.commons.ConfigurationHolder as ConfigHolder
...
def cronExpression = ConfigHolder.config.yourCronJobName
ScraperJob.triggers.cronExpression = cronExpression
Good luck. Let me know if it helps.
Here is how I eventually did it:
Config.groovy
scraperJob= "0 * * * * ?"
ScraperJob.groovy
import org.codehaus.groovy.grails.commons.ConfigurationHolder as ConfigHolder
class ScraperJob {
static triggers = {
cron cronExpression: ConfigHolder.config.scraperJob // Calling the ScraperJob set in Config.groovy
}
def execute(){ ... }
}

Resources