Beispiel #1
0
  /**
   * 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;
    }
  }
Beispiel #2
0
  /**
   * 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);
    }
  }
Beispiel #3
0
 /**
  * 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;
 }
Beispiel #5
0
 /**
  * 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);
    }
  }
Beispiel #10
0
 private Pair<String, String> getTriggerKey(Trigger t) {
   return getTriggerKey(t.getGroup(), t.getName());
 }