update trigger of cron job - grails

I have a cron job which has multiple triggers all triggers have been scheduled for the interval of lets say 5 min, now I need to update job data map at runtime, for that I need that particular trigger which requires to update but I am failing to get that particular trigger, I am doing something like that
String cronExpression = "0 0/5 * * * ?"
String triggername = "mytrigger" + System.currentTimeMillis()
JobDataMap jobDataMap = new JobDataMap([host: config.host, port: config.port, username: config.username, password: config.password])
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggername)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).usingJobData(jobDataMap)
.build()
MyJob.schedule(trigger)
Any idea how can I get that particular trigger which I have to update?

Try something like that:
List<Trigger> triggers = quartzScheduler.jobGroupNames.collect {
quartzScheduler.getJobKeys(GroupMatcher.groupEquals(it)).collect {
quartzScheduler.getTriggersOfJob(it)
}
}.flatten()
It will return all your scheduled triggers. After get them you can do what you need in JobDataMap.
I suggest use a familiar trigger identity, it make easier to find a specific one at runtime.

I saved the trigger name in database, and when I need to update that trigger I simply fetch that trigger like this:
TriggerKey triggerKey = new TriggerKey(triggerName_from_db);
try {
Trigger trigger = quartzScheduler.getTrigger(triggerKey)
if (trigger?.key?.name) {
trigger.jobDataMap['host'] = config.host
trigger.jobDataMap['port'] = config.port
trigger.jobDataMap['username'] = config.username
trigger.jobDataMap['password'] = config.password
}
quartzScheduler.rescheduleJob(triggerKey, trigger)
}catch (SchedulerException ex) {
log.error ex.toString()
}

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

Schedule Jenkins job using Jenkins Rest API

I have a Jenkins job which is scheduled for a specific time. I want to modify that timing programmatically.
I tried to modify the build by installing Schedule Build plugin and modify it using http://jenkins_url/job/jobname/build?delay=3344sec. But this will put the job in quiet period which holds the java thread. I'm looking to modify the Schedule entry without putting it to quiet period.
You can use the Build Triggers -> Build periodically job configuration option. Use that to specify the exact time for starting a new build.
If you need to change that time, use the Jenkins REST API to...
programmatically retrieve the job configuration in XML format, then
modify the scheduling time in that configuration (see below)
re-post the new job configuration
In bash, this can be done with a one-liner (using curl and sed) to modify the XML section below (the example schedules a run for noon, Feb 29):
[...]
<triggers>
<hudson.triggers.TimerTrigger>
<spec>00 12 29 02 * </spec>
</hudson.triggers.TimerTrigger>
</triggers>
[...]
Note:
as a plus you wouldn't depend on any supplementary plugins
caveat: you cannot specify a year in the schedule -- so if you need to schedule builds more than one year in advance then you need some magic on top.
I can't get it to work, but the source code for the plugin references a "schedule" url action and a "date" param.
I tried something like:
http://localhost:8080/job/jobname/job/develop/schedule?date=2020-02-20
Which it didn't reject but I can't see a build.
below is the source code of the action performed when the button is pressed to schedule:
var newRequest = function() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
var sumbitScheduleRequest = function(absoluteUrl, quietPeriodInSeconds, isJobParameterized){
if(isJobParameterized){
// if job has parameters, redirect to build page, so user can set parameters
window.location = absoluteUrl + "build?delay=" + quietPeriodInSeconds + "sec";
}else{
// if job has NO parameters, submit build directly
var csrfCrumb;
var csrfRequest = newRequest();
csrfRequest.onreadystatechange = function() {
if (csrfRequest.readyState === 4) {
if (csrfRequest.status === 200 || csrfRequest.status === 201) {
csrfCrumb = JSON.parse(csrfRequest.responseText);
} else {
// csrf might be deactivated
}
// do the actual submit
var xmlhttp = newRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4) {
if (xmlhttp.status === 200 || xmlhttp.status === 201) {
window.location = absoluteUrl;
return false;
} else {
window.location = absoluteUrl;
return false;
}
}
};
xmlhttp.open("POST", absoluteUrl + "build?delay=" + quietPeriodInSeconds + "sec", true);
if (csrfCrumb) {
xmlhttp.setRequestHeader(csrfCrumb.crumbRequestField, csrfCrumb.crumb)
}
xmlhttp.send();
}
};
csrfRequest.open('GET', rootURL + '/crumbIssuer/api/json', false);
csrfRequest.send();
}
}

Quarz.NET throws Unexpected end of expression

I'm trying to perform the following code on a console application that uses Quarz.NET, but I got the following exception.
Here's the snippet of code
public Task AddSchedule(FlussoAnagraficaItem item)
{
if(this.scheduler == null) throw new Exception("scheduler is null, has the InitAsync method been invoked?");
var jobItemType = this.jobCreatorFactory.CreateJobFromAnagraficaFlussiItem(item);
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create(jobItemType)
.WithIdentity(item.Description, "sender")
.Build();
// Trigger the job to run now, and then repeat every 10 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity($"trigger_{item.Description}", "sender")
.StartNow().WithCronSchedule(item.Timespan)
.Build();
// Tell quartz to schedule the job using our trigger
return this.scheduler.ScheduleJob(job, trigger);
}
Where item.Timespan is "00 16 * * 5" , what's wrong?
Thanks

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 scheduler executes too many after resume jobs

i have a job with one trigger, actually my problem is similar to this Quartz Java resuming a job excecutes it many times
Here is my code when i was trying to turn on/off job. The problem is when i was trying to reschedule job after paused for long time(in my case is one day), the trigger executes too many in the same time when i reschedule the job. And how i use class PauseAwareCronTrigger in my code ? {PauseAwareCronTrigger is class solution from Quartz Java resuming a job excecutes it many times
}
def rescheduleJob(config) {
def triggerName = "com.divusi.sipfo."+getJobKeyName(config.namaNotifikasi)
def triggerName1 = getJobKeyName(config.namaNotifikasi)
//def triggers = quartzScheduler.getTriggersOfJob(new JobKey("pisReminder", "job"))
//def trigger = quartzScheduler.getTrigger(triggerKey("pisReminder", "job"))
def trigger = quartzScheduler.getTrigger(new TriggerKey(getJobKeyName(config.namaNotifikasi), "job"))
//def trigger = quartzScheduler.getTrigger(new TriggerKey("kpRealizationList", "job"))
//Trigger trigger = triggers[0];
/*quartzScheduler.rescheduleJob(trigger.getKey(), TriggerBuilder.newTrigger()
.withIdentity(triggerName,"job")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?"))
.build()) */
if(config.notifikasiAktif) {
quartzScheduler.rescheduleJob(trigger.getKey(), TriggerBuilder.newTrigger()
.withIdentity(getJobKeyName(config.namaNotifikasi),"job")
.withSchedule(CronScheduleBuilder.cronSchedule("0/1 * * * * ?"))
.build())
}else{
quartzScheduler.pauseTrigger(trigger.getKey())
}
/*trigger.cronExpression = "0/1 * * * * ?" config.cronExpression
quartzScheduler.rescheduleJob(new TriggerKey("pisReminder", "job"), trigger) */
}

Resources