/** * Inform the <code>JobStore</code> that the scheduler is now firing the given <code>Trigger * </code> (executing its associated <code>Job</code>), that it had previously acquired * (reserved). * * @return null if the trigger or its job or calendar no longer exist, or if the trigger was not * successfully put into the 'executing' state. */ public TriggerFiredBundle triggerFired(SchedulingContext ctxt, Trigger trigger) throws JobPersistenceException { synchronized (m_triggerLock) { if (!isEligibleGroupName(trigger.getGroup())) { return null; } WrappedTrigger wt = m_triggersByGroupAndName.get(getTriggerKey(trigger)); if ((wt != null) && (wt.getState() == TRIGGER_STATE_CLAIMED)) { wt.setState(TRIGGER_STATE_EXECUTING); Calendar cal = null; if (trigger.getCalendarName() != null) { cal = retrieveCalendar(ctxt, trigger.getCalendarName()); } Date prevFiredTime = trigger.getPreviousFireTime(); trigger.triggered(cal); TriggerFiredBundle tfb = new TriggerFiredBundle( retrieveJob(ctxt, trigger.getJobName(), trigger.getJobGroup()), trigger, cal, false, new Date(), trigger.getPreviousFireTime(), prevFiredTime, trigger.getNextFireTime()); return tfb; } return null; } }
/** * Marks and returns the next trigger to execute, preferring the given custId. If no appropriate * trigger can be found for the given customerId, a trigger may be returned belonging to a * different custId. (Paused triggers will be ignored by this method.) */ private Trigger acquireNextTrigger(SchedulingContext ctxt, long custId) { WrappedTrigger nonCustomerMatch = null; for (Iterator<WrappedTrigger> it = m_triggersByScore.iterator(); it.hasNext(); ) { WrappedTrigger wt = it.next(); // compare customer first if we already have a non-customer match if ((custId > 0) && (custId != wt.getCustomerId()) && (nonCustomerMatch != null)) { continue; } if (wt.getState() != Trigger.STATE_NORMAL) { continue; } Trigger t = wt.getTrigger(); if (!isEligibleGroupName(t.getGroup())) { continue; } if ((custId > 0) && (custId != wt.getCustomerId())) { nonCustomerMatch = wt; } else { // s_logCategory.debug("acquireNextTrigger(" + custId + ") returning trigger for " + // wt.getCustomerId()); return claimTrigger(wt); } } if (nonCustomerMatch == null) { return null; } else { // s_logCategory.debug("acquireNextTrigger(" + custId + ") returning trigger for " + // nonCustomerMatch.getCustomerId()); return claimTrigger(nonCustomerMatch); } }
/** * Resume (un-pause) the <code>{@link org.quartz.Job}</code> with the given name. * * <p>If any of the <code>Job</code>'s<code>Trigger</code> s missed one or more fire-times, then * the <code>Trigger</code>'s misfire instruction will be applied. * * @see #pauseJob(org.quartz.core.SchedulingContext, String, String) */ public void resumeJob(SchedulingContext ctxt, String jobName, String groupName) throws JobPersistenceException { synchronized (m_triggerLock) { Trigger[] triggers = getTriggersForJob(ctxt, jobName, groupName); for (int i = 0, length = triggers.length; i < length; i++) { Trigger t = triggers[i]; resumeTrigger(ctxt, t.getName(), t.getGroup()); } } }
protected boolean triggerExists(Trigger checkTrigger) { try { Trigger trigger = resourceScheduler.getTrigger(checkTrigger.getName(), checkTrigger.getGroup()); return (trigger != null); } catch (SchedulerException e) { log.error("Failed to check if the trigger exists", e); } return false; }
/** * Inform the <code>JobStore</code> that the scheduler has completed the firing of the given * <code>Trigger</code> (and the execution its associated <code>Job</code>), and that the <code> * {@link org.quartz.JobDataMap}</code> in the given <code>JobDetail</code> should be updated if * the <code>Job</code> is stateful. */ public void triggeredJobComplete( SchedulingContext ctxt, Trigger trigger, JobDetail jobDetail, int triggerInstCode) throws JobPersistenceException { synchronized (m_triggerLock) { if (trigger.getNextFireTime() != null) { storeTrigger(ctxt, trigger, true); } else { removeTrigger(ctxt, trigger.getName(), trigger.getGroup()); } } }
protected boolean triggerChanged(Trigger checkTrigger) { try { Trigger trigger = resourceScheduler.getTrigger(checkTrigger.getName(), checkTrigger.getGroup()); if (trigger != null && trigger instanceof CronTrigger) { return !((CronTrigger) trigger) .getCronExpression() .equals(((CronTrigger) checkTrigger).getCronExpression()); } } catch (SchedulerException e) { log.error("Failed to check if the trigger has changed", e); } return false; }
public static Trigger convertTriggerFromNativeObject(org.quartz.Trigger quartzTrigger) { Trigger spagobiTrigger; spagobiTrigger = new Trigger(); spagobiTrigger.setName(quartzTrigger.getName()); spagobiTrigger.setGroupName(quartzTrigger.getGroup()); spagobiTrigger.setDescription(quartzTrigger.getDescription()); // spagobiTrigger.setCalendarName( quartzTrigger.getCalendarName() ); Assert.assertTrue( quartzTrigger.getCalendarName() == null, "quartz trigger calendar name is not null: " + quartzTrigger.getCalendarName()); spagobiTrigger.setStartTime(quartzTrigger.getStartTime()); spagobiTrigger.setEndTime(quartzTrigger.getEndTime()); // triggers that run immediately have a generated name that starts with schedule_uuid_ (see // TriggerXMLDeserializer) // It would be better anyway to relay on a specific property to recognize if a trigger is // thinked to run immediately spagobiTrigger.setRunImmediately(spagobiTrigger.getName().startsWith("schedule_uuid_")); if (quartzTrigger instanceof org.quartz.CronTrigger) { org.quartz.CronTrigger quartzCronTrigger = (org.quartz.CronTrigger) quartzTrigger; // dirty trick String expression = (String) quartzCronTrigger.getJobDataMap().get(SPAGOBI_CRON_EXPRESSION); if (expression != null) { quartzCronTrigger.getJobDataMap().remove(SPAGOBI_CRON_EXPRESSION); } else { // for back compatibility expression = (String) quartzCronTrigger.getJobDataMap().get(SPAGOBI_CRON_EXPRESSION_DEPRECATED); quartzCronTrigger.getJobDataMap().remove(SPAGOBI_CRON_EXPRESSION_DEPRECATED); } spagobiTrigger.setCronExpression(new CronExpression(expression)); } Job job = new Job(); job.setName(quartzTrigger.getJobName()); job.setGroupName(quartzTrigger.getJobGroup()); job.setVolatile(quartzTrigger.isVolatile()); Map<String, String> parameters = convertParametersFromNativeObject(quartzTrigger.getJobDataMap()); job.addParameters(parameters); spagobiTrigger.setJob(job); return spagobiTrigger; }
/** * Construct the job details using the given parameter map and schedule the job to be executed by * the given job class using the given trigger. * * @param jobName The name of the job to be executed. * @param manager The BeanManager implementation. * @param trigger The trigger representing the schedule of the job. * @param jobKlass The class which will execute the job on schedule. * @param jobParams The parameters to be passed to the job executor. * @throws SchedulerException */ private void scheduleJob(final Trigger schedTrigger, final TriggerDetail triggerDetails) throws CronProviderInitialisationException { // common Second payload sample and start time final GregorianCalendar gc = new GregorianCalendar(); gc.add(GregorianCalendar.SECOND, 1); final Date startTime = new Date(gc.getTimeInMillis()); schedTrigger.setStartTime(startTime); final String jobName = triggerDetails.toString() + "-trigger"; schedTrigger.setName(jobName); final JobDetail job = new JobDetail(jobName, schedTrigger.getGroup(), TriggerJob.class); job.setJobDataMap(new JobDataMap()); job.getJobDataMap() .put(TRIGGER_SUPPLIES, new TriggerSupplies(beanManager, triggerDetails.getQualifier())); try { getScheduler().scheduleJob(job, schedTrigger); } catch (SchedulerException e) { throw new CronProviderInitialisationException( "Error scheduling job " + jobName + " with Quartz provider", e); } log.info("Scheduler for " + jobName + " initialised"); }
/** * Schedules a given job and trigger (both wrapped by a <code>JobSchedulingBundle</code>). * * @param job job wrapper. * @param sched job scheduler. * @param localOverWriteExistingJobs locally overwrite existing jobs. * @exception SchedulerException if the Job or Trigger cannot be added to the Scheduler, or there * is an internal Scheduler error. */ public void scheduleJob( JobSchedulingBundle job, Scheduler sched, boolean localOverWriteExistingJobs) throws SchedulerException { if ((job != null) && job.isValid()) { JobDetail detail = job.getJobDetail(); JobDetail dupeJ = sched.getJobDetail(detail.getName(), detail.getGroup()); if ((dupeJ != null) && !localOverWriteExistingJobs) { getLog().info("Not overwriting existing job: " + dupeJ.getFullName()); return; } if (dupeJ != null) { getLog().info("Replacing job: " + detail.getFullName()); } else { getLog().info("Adding job: " + detail.getFullName()); } if (job.getTriggers().size() == 0 && !job.getJobDetail().isDurable()) { if (dupeJ == null) { throw new SchedulerException( "A new job defined without any triggers must be durable: " + detail.getFullName()); } if ((dupeJ.isDurable() && (sched.getTriggersOfJob(detail.getName(), detail.getGroup()).length == 0))) { throw new SchedulerException( "Can't make a durable job without triggers non-durable: " + detail.getFullName()); } } sched.addJob(detail, true); for (Iterator iter = job.getTriggers().iterator(); iter.hasNext(); ) { Trigger trigger = (Trigger) iter.next(); trigger.setJobName(detail.getName()); trigger.setJobGroup(detail.getGroup()); if (trigger.getStartTime() == null) { trigger.setStartTime(new Date()); } boolean addedTrigger = false; while (addedTrigger == false) { Trigger dupeT = sched.getTrigger(trigger.getName(), trigger.getGroup()); if (dupeT != null) { if (getLog().isDebugEnabled()) { getLog() .debug( "Rescheduling job: " + detail.getFullName() + " with updated trigger: " + trigger.getFullName()); } if (!dupeT.getJobGroup().equals(trigger.getJobGroup()) || !dupeT.getJobName().equals(trigger.getJobName())) { getLog().warn("Possibly duplicately named triggers in jobs xml file!"); } sched.rescheduleJob(trigger.getName(), trigger.getGroup(), trigger); } else { if (getLog().isDebugEnabled()) { getLog() .debug( "Scheduling job: " + detail.getFullName() + " with trigger: " + trigger.getFullName()); } try { sched.scheduleJob(trigger); } catch (ObjectAlreadyExistsException e) { if (getLog().isDebugEnabled()) { getLog() .debug( "Adding trigger: " + trigger.getFullName() + " for job: " + detail.getFullName() + " failed because the trigger already existed. " + "This is likely due to a race condition between multiple instances " + "in the cluster. Will try to reschedule instead."); } continue; } } addedTrigger = true; } } addScheduledJob(job); } }
private Pair<String, String> getTriggerKey(Trigger t) { return getTriggerKey(t.getGroup(), t.getName()); }