protected void updateJobState(
      Scheduler scheduler, JobKey jobKey, TriggerState triggerState, boolean suppressError)
      throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    if (jobDetail == null) {
      return;
    }

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    JobState jobState = getJobState(jobDataMap);

    if (triggerState != null) {
      jobState.setTriggerState(triggerState);
    }

    if (suppressError) {
      jobState.clearExceptions();
    }

    jobDataMap.put(SchedulerEngine.JOB_STATE, JobStateSerializeUtil.serialize(jobState));

    scheduler.addJob(jobDetail, true);
  }
  /** 启动定时调度程序 */
  public synchronized void start() {
    if (started) {
      return;
    }
    try {
      Scheduler scheduler = this.getSyncScheduler();
      if (!scheduler.isStarted()) {
        scheduler.start();
      }

      CronTrigger trigger = new CronTrigger();
      trigger.setName(this.getName() + "SynchronizerTrigger");
      trigger.setCronExpression("0/" + this.repeatInterval + " * * * * ?");
      trigger.setGroup(this.getName() + "SynchronizerGroup");

      String jobDetailName = this.getName() + "SynchronizeJob";
      String jobDetailGroup = this.getName() + "SynchronizeSchduler";
      JobDetail job = new JobDetail(jobDetailName, jobDetailGroup, this.getClass());
      job.getJobDataMap().put(JobDataMapKey.RUN_OBJECT, this);
      job.getJobDataMap().put(JobDataMapKey.RUN_MAGIC, appName);

      JobDetail j = scheduler.getJobDetail(jobDetailName, jobDetailGroup);
      if (j == null) {
        scheduler.scheduleJob(job, trigger);
        logger.info(this.getName() + "SynchronizeJob started");
      } else {
        logger.warn("{}SynchronizeJob already started.", this.getName());
      }
    } catch (Exception e) {
      logger.error("启动时间程序同步程序失败: ", e);
    }
  }
  protected void update(
      Scheduler scheduler,
      com.liferay.portal.kernel.scheduler.Trigger trigger,
      StorageType storageType)
      throws Exception {

    Trigger quartzTrigger = getQuartzTrigger(trigger, storageType);

    if (quartzTrigger == null) {
      return;
    }

    TriggerKey triggerKey = quartzTrigger.getKey();

    if (scheduler.getTrigger(triggerKey) != null) {
      scheduler.rescheduleJob(triggerKey, quartzTrigger);
    } else {
      JobKey jobKey = quartzTrigger.getJobKey();

      JobDetail jobDetail = scheduler.getJobDetail(jobKey);

      if (jobDetail == null) {
        return;
      }

      synchronized (this) {
        scheduler.deleteJob(jobKey);
        scheduler.scheduleJob(jobDetail, quartzTrigger);
      }

      updateJobState(scheduler, jobKey, TriggerState.NORMAL, true);
    }
  }
  protected void unregisterMessageListener(Scheduler scheduler, JobKey jobKey) throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    if (jobDetail == null) {
      return;
    }

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    if (jobDataMap == null) {
      return;
    }

    Message message = getMessage(jobDataMap);

    String messageListenerUUID = message.getString(SchedulerEngine.MESSAGE_LISTENER_UUID);

    if (messageListenerUUID == null) {
      return;
    }

    String destinationName = jobDataMap.getString(SchedulerEngine.DESTINATION_NAME);

    Destination destination = _messageBus.getDestination(destinationName);

    if (destination == null) {
      return;
    }

    Set<MessageListener> messageListeners = destination.getMessageListeners();

    for (MessageListener messageListener : messageListeners) {
      if (!(messageListener instanceof InvokerMessageListener)) {
        continue;
      }

      InvokerMessageListener invokerMessageListener = (InvokerMessageListener) messageListener;

      messageListener = invokerMessageListener.getMessageListener();

      if (!(messageListener instanceof SchedulerEventMessageListenerWrapper)) {

        continue;
      }

      SchedulerEventMessageListenerWrapper schedulerMessageListener =
          (SchedulerEventMessageListenerWrapper) messageListener;

      if (messageListenerUUID.equals(schedulerMessageListener.getMessageListenerUUID())) {

        _messageBus.unregisterMessageListener(destinationName, schedulerMessageListener);

        return;
      }
    }
  }
  protected SchedulerResponse getScheduledJob(Scheduler scheduler, JobKey jobKey) throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    if (jobDetail == null) {
      return null;
    }

    SchedulerResponse schedulerResponse = new SchedulerResponse();

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    String description = jobDataMap.getString(SchedulerEngine.DESCRIPTION);

    schedulerResponse.setDescription(description);

    String destinationName = jobDataMap.getString(SchedulerEngine.DESTINATION_NAME);

    schedulerResponse.setDestinationName(destinationName);

    Message message = getMessage(jobDataMap);

    JobState jobState = getJobState(jobDataMap);

    message.put(SchedulerEngine.JOB_STATE, jobState);

    schedulerResponse.setMessage(message);

    StorageType storageType =
        StorageType.valueOf(jobDataMap.getString(SchedulerEngine.STORAGE_TYPE));

    schedulerResponse.setStorageType(storageType);

    String jobName = jobKey.getName();
    String groupName = jobKey.getGroup();

    TriggerKey triggerKey = new TriggerKey(jobName, groupName);

    Trigger trigger = scheduler.getTrigger(triggerKey);

    if (trigger == null) {
      schedulerResponse.setGroupName(groupName);
      schedulerResponse.setJobName(jobName);

      return schedulerResponse;
    }

    message.put(SchedulerEngine.END_TIME, trigger.getEndTime());
    message.put(SchedulerEngine.FINAL_FIRE_TIME, trigger.getFinalFireTime());
    message.put(SchedulerEngine.NEXT_FIRE_TIME, trigger.getNextFireTime());
    message.put(SchedulerEngine.PREVIOUS_FIRE_TIME, trigger.getPreviousFireTime());
    message.put(SchedulerEngine.START_TIME, trigger.getStartTime());

    schedulerResponse.setTrigger(new QuartzTrigger(trigger));

    return schedulerResponse;
  }
Beispiel #6
0
 @SuppressWarnings("unchecked")
 public List<EndpointDTO> list() {
   List<EndpointDTO> endpointDTOs = Lists.newArrayList();
   try {
     for (String groupName : scheduler.getJobGroupNames()) {
       for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
         JobDetail jobDetail = scheduler.getJobDetail(jobKey);
         List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
         endpointDTOs.add(new EndpointDTO(jobDetail, triggers));
       }
     }
   } catch (SchedulerException e) {
   }
   return endpointDTOs;
 }
  protected void unschedule(Scheduler scheduler, JobKey jobKey) throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    TriggerKey triggerKey = new TriggerKey(jobKey.getName(), jobKey.getGroup());

    if (jobDetail == null) {
      return;
    }

    unregisterMessageListener(scheduler, jobKey);

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    JobState jobState = getJobState(jobDataMap);

    Trigger trigger = scheduler.getTrigger(triggerKey);

    if (trigger == null) {
      return;
    }

    jobState.setTriggerDate(SchedulerEngine.END_TIME, new Date());
    jobState.setTriggerDate(SchedulerEngine.FINAL_FIRE_TIME, trigger.getPreviousFireTime());
    jobState.setTriggerDate(SchedulerEngine.NEXT_FIRE_TIME, null);
    jobState.setTriggerDate(SchedulerEngine.PREVIOUS_FIRE_TIME, trigger.getPreviousFireTime());
    jobState.setTriggerDate(SchedulerEngine.START_TIME, trigger.getStartTime());

    jobState.setTriggerState(TriggerState.UNSCHEDULED);

    jobState.clearExceptions();

    jobDataMap.put(SchedulerEngine.JOB_STATE, JobStateSerializeUtil.serialize(jobState));

    scheduler.unscheduleJob(triggerKey);

    scheduler.addJob(jobDetail, true);
  }
Beispiel #8
0
  /**
   * Run a job from the Job Scheduler
   *
   * @param sessionId valid admin session id
   * @param jobName name of job to run
   * @return @
   */
  @WebMethod
  @Path("/runJob")
  @Produces("text/plain")
  @GET
  public String runJob(
      @WebParam(name = "sessionId", partName = "sessionId") @QueryParam("sessionId")
          String sessionId,
      @WebParam(name = "jobName", partName = "jobName") @QueryParam("jobName") String jobName) {
    Session session = establishSession(sessionId);
    if (!securityService.isSuperUser()) {
      LOG.warn("NonSuperUser trying to collect configuration: " + session.getUserId());
      return "error: NonSuperUser trying to collect configuration: " + session.getUserId();
    }

    JobDetail jobDetail = null;
    Scheduler scheduler = schedulerManager.getScheduler();

    try {
      jobDetail = scheduler.getJobDetail(new JobKey(jobName, Scheduler.DEFAULT_GROUP));
    } catch (SchedulerException e) {
      LOG.warn(e.getMessage(), e);
      return "error: " + e.getMessage();
    }

    if (jobDetail != null) {
      try {
        scheduler.triggerJob(jobDetail.getKey());
      } catch (SchedulerException e) {
        LOG.warn(e.getMessage(), e);
        return "error: " + e.getMessage();
      }
    } else {
      return "error: can't find a job with name: " + jobName;
    }

    return "success";
  }
  /**
   * 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);
    }
  }
 public RunTimeJobDetail getJobDetails(String group, String name) throws SchedulerException {
   JobKey jobKey = new JobKey(name, group);
   return new RunTimeJobDetail()
       .setJobDetail(quartzScheduler.getJobDetail(jobKey))
       .setTriggers(quartzScheduler.getTriggersOfJob(jobKey));
 }
  @RequestMapping("/cancelScheduledJob")
  public String cancelScheduledJob(
      HttpServletRequest request,
      HttpServletResponse response,
      @RequestParam("theJobName") String theJobName,
      @RequestParam("theJobGroupName") String theJobGroupName,
      @RequestParam("theTriggerName") String triggerName,
      @RequestParam("theTriggerGroupName") String triggerGroupName,
      @RequestParam("redirection") String redirection,
      ModelMap model)
      throws SchedulerException {

    scheduler.getJobDetail(theJobName, theJobGroupName);
    logger.debug("About to pause the job-->" + theJobName + "Job Group Name -->" + theJobGroupName);

    SimpleTrigger oldTrigger = (SimpleTrigger) scheduler.getTrigger(triggerName, triggerGroupName);
    if (oldTrigger != null) {
      Date startTime =
          new Date(oldTrigger.getStartTime().getTime() + oldTrigger.getRepeatInterval());
      if (triggerGroupName.equals(ExtractController.TRIGGER_GROUP_NAME)) {
        interruptQuartzJob(scheduler, theJobName, theJobGroupName);
      }

      scheduler.pauseJob(theJobName, theJobGroupName);

      SimpleTrigger newTrigger = new SimpleTrigger(triggerName, triggerGroupName);
      newTrigger.setJobName(theJobName);
      newTrigger.setJobGroup(theJobGroupName);
      newTrigger.setJobDataMap(oldTrigger.getJobDataMap());
      newTrigger.setVolatility(false);
      newTrigger.setRepeatCount(oldTrigger.getRepeatCount());
      newTrigger.setRepeatInterval(oldTrigger.getRepeatInterval());
      newTrigger.setMisfireInstruction(
          SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
      newTrigger.setStartTime(startTime);
      newTrigger.setRepeatInterval(oldTrigger.getRepeatInterval());

      scheduler.unscheduleJob(
          triggerName,
          triggerGroupName); // these are the jobs which are from extract data and are not not
      // required to be rescheduled.

      ArrayList<String> pageMessages = new ArrayList<String>();

      if (triggerGroupName.equals(ExtractController.TRIGGER_GROUP_NAME)) {
        scheduler.rescheduleJob(triggerName, triggerGroupName, newTrigger);

        pageMessages.add("The Job  " + theJobName + " has been cancelled");
      } else if (triggerGroupName.equals(XsltTriggerService.TRIGGER_GROUP_NAME)) {

        JobDetailBean jobDetailBean = new JobDetailBean();
        jobDetailBean.setGroup(XsltTriggerService.TRIGGER_GROUP_NAME);
        jobDetailBean.setName(newTrigger.getName());
        jobDetailBean.setJobClass(org.akaza.openclinica.job.XsltStatefulJob.class);
        jobDetailBean.setJobDataMap(newTrigger.getJobDataMap());
        jobDetailBean.setDurability(true); // need durability?
        jobDetailBean.setVolatility(false);

        scheduler.deleteJob(theJobName, theJobGroupName);
        scheduler.scheduleJob(jobDetailBean, newTrigger);
        pageMessages.add("The Job " + theJobName + "  has been rescheduled");
      }

      request.setAttribute("pageMessages", pageMessages);

      logger.debug("jobDetails>" + scheduler.getJobDetail(theJobName, theJobGroupName));
    }
    sdvUtil.forwardRequestFromController(request, response, "/pages/" + redirection);
    return null;
  }
  @Test
  public void testBasicStorageFunctions() throws Exception {
    Scheduler sched = createScheduler("testBasicStorageFunctions", 2);

    // test basic storage functions of scheduler...

    JobDetail job = newJob().ofType(TestJob.class).withIdentity("j1").storeDurably().build();

    assertFalse("Unexpected existence of job named 'j1'.", sched.checkExists(jobKey("j1")));

    sched.addJob(job, false);

    assertTrue(
        "Expected existence of job named 'j1' but checkExists return false.",
        sched.checkExists(jobKey("j1")));

    job = sched.getJobDetail(jobKey("j1"));

    assertNotNull("Stored job not found!", job);

    sched.deleteJob(jobKey("j1"));

    Trigger trigger =
        newTrigger()
            .withIdentity("t1")
            .forJob(job)
            .startNow()
            .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))
            .build();

    assertFalse("Unexpected existence of trigger named 't1'.", sched.checkExists(triggerKey("t1")));

    sched.scheduleJob(job, trigger);

    assertTrue(
        "Expected existence of trigger named 't1' but checkExists return false.",
        sched.checkExists(triggerKey("t1")));

    job = sched.getJobDetail(jobKey("j1"));

    assertNotNull("Stored job not found!", job);

    trigger = sched.getTrigger(triggerKey("t1"));

    assertNotNull("Stored trigger not found!", trigger);

    job = newJob().ofType(TestJob.class).withIdentity("j2", "g1").build();

    trigger =
        newTrigger()
            .withIdentity("t2", "g1")
            .forJob(job)
            .startNow()
            .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))
            .build();

    sched.scheduleJob(job, trigger);

    job = newJob().ofType(TestJob.class).withIdentity("j3", "g1").build();

    trigger =
        newTrigger()
            .withIdentity("t3", "g1")
            .forJob(job)
            .startNow()
            .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))
            .build();

    sched.scheduleJob(job, trigger);

    List<String> jobGroups = sched.getJobGroupNames();
    List<String> triggerGroups = sched.getTriggerGroupNames();

    assertTrue("Job group list size expected to be = 2 ", jobGroups.size() == 2);
    assertTrue("Trigger group list size expected to be = 2 ", triggerGroups.size() == 2);

    Set<JobKey> jobKeys = sched.getJobKeys(GroupMatcher.jobGroupEquals(JobKey.DEFAULT_GROUP));
    Set<TriggerKey> triggerKeys =
        sched.getTriggerKeys(GroupMatcher.triggerGroupEquals(TriggerKey.DEFAULT_GROUP));

    assertTrue("Number of jobs expected in default group was 1 ", jobKeys.size() == 1);
    assertTrue("Number of triggers expected in default group was 1 ", triggerKeys.size() == 1);

    jobKeys = sched.getJobKeys(GroupMatcher.jobGroupEquals("g1"));
    triggerKeys = sched.getTriggerKeys(GroupMatcher.triggerGroupEquals("g1"));

    assertTrue("Number of jobs expected in 'g1' group was 2 ", jobKeys.size() == 2);
    assertTrue("Number of triggers expected in 'g1' group was 2 ", triggerKeys.size() == 2);

    TriggerState s = sched.getTriggerState(triggerKey("t2", "g1"));
    assertTrue("State of trigger t2 expected to be NORMAL ", s.equals(TriggerState.NORMAL));

    sched.pauseTrigger(triggerKey("t2", "g1"));
    s = sched.getTriggerState(triggerKey("t2", "g1"));
    assertTrue("State of trigger t2 expected to be PAUSED ", s.equals(TriggerState.PAUSED));

    sched.resumeTrigger(triggerKey("t2", "g1"));
    s = sched.getTriggerState(triggerKey("t2", "g1"));
    assertTrue("State of trigger t2 expected to be NORMAL ", s.equals(TriggerState.NORMAL));

    Set<String> pausedGroups = sched.getPausedTriggerGroups();
    assertTrue("Size of paused trigger groups list expected to be 0 ", pausedGroups.size() == 0);

    sched.pauseTriggers(GroupMatcher.triggerGroupEquals("g1"));

    // test that adding a trigger to a paused group causes the new trigger to be paused also...
    job = newJob().ofType(TestJob.class).withIdentity("j4", "g1").build();

    trigger =
        newTrigger()
            .withIdentity("t4", "g1")
            .forJob(job)
            .startNow()
            .withSchedule(simpleSchedule().repeatForever().withIntervalInSeconds(5))
            .build();

    sched.scheduleJob(job, trigger);
    // TODO: nexus hack: JobStoreImpl DOES NOT "remember" paused groups
    sched.pauseJob(jobKey("j4", "g1"));

    pausedGroups = sched.getPausedTriggerGroups();
    assertTrue(
        "Size of paused trigger groups list expected to be 1: " + pausedGroups,
        pausedGroups.size() == 1);

    s = sched.getTriggerState(triggerKey("t2", "g1"));
    assertTrue("State of trigger t2 expected to be PAUSED ", s.equals(TriggerState.PAUSED));

    s = sched.getTriggerState(triggerKey("t4", "g1"));
    assertTrue("State of trigger t4 expected to be PAUSED ", s.equals(TriggerState.PAUSED));

    sched.resumeTriggers(GroupMatcher.triggerGroupEquals("g1"));
    s = sched.getTriggerState(triggerKey("t2", "g1"));
    assertTrue("State of trigger t2 expected to be NORMAL ", s.equals(TriggerState.NORMAL));
    s = sched.getTriggerState(triggerKey("t4", "g1"));
    assertTrue("State of trigger t4 expected to be NORMAL ", s.equals(TriggerState.NORMAL));
    pausedGroups = sched.getPausedTriggerGroups();
    assertTrue("Size of paused trigger groups list expected to be 0 ", pausedGroups.size() == 0);

    assertFalse(
        "Scheduler should have returned 'false' from attempt to unschedule non-existing trigger. ",
        sched.unscheduleJob(triggerKey("foasldfksajdflk")));

    assertTrue(
        "Scheduler should have returned 'true' from attempt to unschedule existing trigger. ",
        sched.unscheduleJob(triggerKey("t3", "g1")));

    jobKeys = sched.getJobKeys(GroupMatcher.jobGroupEquals("g1"));
    triggerKeys = sched.getTriggerKeys(GroupMatcher.triggerGroupEquals("g1"));

    assertTrue(
        "Number of jobs expected in 'g1' group was 1 ",
        jobKeys.size() == 2); // job should have been deleted also, because it is non-durable
    assertTrue("Number of triggers expected in 'g1' group was 1 ", triggerKeys.size() == 2);

    assertTrue(
        "Scheduler should have returned 'true' from attempt to unschedule existing trigger. ",
        sched.unscheduleJob(triggerKey("t1")));

    jobKeys = sched.getJobKeys(GroupMatcher.jobGroupEquals(JobKey.DEFAULT_GROUP));
    triggerKeys = sched.getTriggerKeys(GroupMatcher.triggerGroupEquals(TriggerKey.DEFAULT_GROUP));

    assertTrue(
        "Number of jobs expected in default group was 1 ",
        jobKeys.size() == 1); // job should have been left in place, because it is non-durable
    assertTrue("Number of triggers expected in default group was 0 ", triggerKeys.size() == 0);

    sched.shutdown(true);
  }
  /**
   * This method reads all the task from an xml file and registers them with the MifosScheduler
   *
   * @param document Task configuration document
   * @throws TaskSystemException when something goes wrong
   */
  @Deprecated
  private void registerTasksOldConfigurationFile(Document document) throws TaskSystemException {
    try {
      logger.warn(
          "Old format task.xml configuration file is deprecated. Please configure scheduler using spring managed beans.");
      NodeList rootSchedulerTasks =
          document.getElementsByTagName(SchedulerConstants.SCHEDULER_TASKS);
      Element rootNodeName = (Element) rootSchedulerTasks.item(0);
      NodeList collectionOfScheduledTasks =
          rootNodeName.getElementsByTagName(SchedulerConstants.SCHEDULER);

      DataSource dataSource =
          SessionFactoryUtils.getDataSource(StaticHibernateUtil.getSessionFactory());
      SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource);

      JobRegistry jobRegistry = new MapJobRegistry();
      this.jobLocator = jobRegistry;

      JdbcJobInstanceDao jobInstanceDao = new JdbcJobInstanceDao();
      jobInstanceDao.setJdbcTemplate(jdbcTemplate);
      jobInstanceDao.setJobIncrementer(
          new MySQLMaxValueIncrementer(dataSource, "BATCH_JOB_SEQ", "id"));
      jobInstanceDao.afterPropertiesSet();

      JdbcJobExecutionDao jobExecutionDao = new JdbcJobExecutionDao();
      jobExecutionDao.setJdbcTemplate(jdbcTemplate);
      jobExecutionDao.setJobExecutionIncrementer(
          new MySQLMaxValueIncrementer(dataSource, "BATCH_JOB_EXECUTION_SEQ", "id"));
      jobExecutionDao.afterPropertiesSet();

      JdbcStepExecutionDao stepExecutionDao = new JdbcStepExecutionDao();
      stepExecutionDao.setJdbcTemplate(jdbcTemplate);
      stepExecutionDao.setStepExecutionIncrementer(
          new MySQLMaxValueIncrementer(dataSource, "BATCH_STEP_EXECUTION_SEQ", "id"));
      stepExecutionDao.afterPropertiesSet();

      JdbcExecutionContextDao executionContextDao = new JdbcExecutionContextDao();
      executionContextDao.setJdbcTemplate(jdbcTemplate);
      executionContextDao.afterPropertiesSet();

      JobRepository jobRepository =
          new SimpleJobRepository(
              jobInstanceDao, jobExecutionDao, stepExecutionDao, executionContextDao);
      this.jobRepository = jobRepository;

      SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
      jobLauncher.setJobRepository(jobRepository);
      jobLauncher.setTaskExecutor(new SyncTaskExecutor());
      jobLauncher.afterPropertiesSet();
      this.jobLauncher = jobLauncher;

      JobExplorer jobExplorer =
          new SimpleJobExplorer(
              jobInstanceDao, jobExecutionDao, stepExecutionDao, executionContextDao);
      this.jobExplorer = jobExplorer;

      Map<String, Object> jobData = new HashMap<String, Object>();
      jobData.put("jobLocator", jobRegistry);
      jobData.put("jobLauncher", jobLauncher);
      jobData.put("jobExplorer", jobExplorer);
      jobData.put("jobRepository", jobRepository);

      JobRegistryBeanPostProcessor jobRegistryProcessor = new JobRegistryBeanPostProcessor();
      jobRegistryProcessor.setJobRegistry(jobRegistry);
      ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager();

      Date loanArrearsTaskInitialTime = null;
      Long loanArrearsTaskDelayTime = null;
      boolean portfolioAtRiskTaskExists = false;

      for (int i = 0; i < collectionOfScheduledTasks.getLength(); i++) {
        Element scheduledTask = (Element) collectionOfScheduledTasks.item(i);
        Element subNodeName1 =
            (Element)
                scheduledTask.getElementsByTagName(SchedulerConstants.TASK_CLASS_NAME).item(0);
        String taskName = ((Text) subNodeName1.getFirstChild()).getData().trim();
        Element subNodeName2 =
            (Element) scheduledTask.getElementsByTagName(SchedulerConstants.INITIAL_TIME).item(0);
        String initialTime = ((Text) subNodeName2.getFirstChild()).getData().trim();
        Element subNodeName3;
        String delayTime = null;
        if ((scheduledTask.getElementsByTagName(SchedulerConstants.DELAY_TIME)) != null) {
          subNodeName3 =
              (Element) scheduledTask.getElementsByTagName(SchedulerConstants.DELAY_TIME).item(0);
          if (subNodeName3.getFirstChild() != null) {
            delayTime = ((Text) subNodeName3.getFirstChild()).getData().trim();
          }
        }
        if (Long.parseLong(delayTime) < 86400) {
          throw new IllegalArgumentException("Please specify the delay time >= 86400(1 day)");
        }
        if (scheduler.getJobDetail(taskName, Scheduler.DEFAULT_GROUP) != null) {
          scheduler.unscheduleJob(taskName, Scheduler.DEFAULT_GROUP);
        }
        if ("LoanArrearsTask".equals(taskName)) {
          loanArrearsTaskInitialTime = parseInitialTime(initialTime);
          loanArrearsTaskDelayTime = Long.parseLong(delayTime) * 1000;
          continue;
        }
        if ("PortfolioAtRiskTask".equals(taskName)) {
          portfolioAtRiskTaskExists = true;
          continue;
        }
        schedule(
            taskName,
            parseInitialTime(initialTime),
            Long.parseLong(delayTime) * 1000,
            jobRegistry,
            jobRepository,
            jobData,
            transactionManager);
      }
      if (loanArrearsTaskInitialTime != null) {
        if (portfolioAtRiskTaskExists) {
          scheduleLoanArrearsAndPortfolioAtRisk(
              loanArrearsTaskInitialTime,
              loanArrearsTaskDelayTime,
              jobRegistry,
              jobRepository,
              jobData,
              transactionManager);
        } else {
          schedule(
              "LoanArrearsTask",
              loanArrearsTaskInitialTime,
              loanArrearsTaskDelayTime,
              jobRegistry,
              jobRepository,
              jobData,
              transactionManager);
        }
      }
    } catch (Exception e) {
      throw new TaskSystemException(e);
    }
  }
  public void init() {
    try {
      qrtzProperties = initQuartzConfiguration();

      qrtzProperties.setProperty("org.quartz.scheduler.instanceId", serverId);

      // note: becuase job classes are jarred , it is impossible to iterate
      // through a directory by calling listFiles on a file object.
      // Therefore, we need the class list list from spring.

      // find quartz jobs from specified 'qrtzJobs' and verify they
      // that these jobs implement the Job interface
      Iterator<String> qrtzJobsIterator = qrtzJobs.iterator();
      while (qrtzJobsIterator.hasNext()) {
        String className = (String) qrtzJobsIterator.next();
        Class cl = null;
        try {
          cl = Class.forName(className);
        } catch (ClassNotFoundException e) {
          LOG.warn("Could not locate class: " + className + " on classpath");
        }
        if (cl != null) {
          // check that each class implements the Job interface
          if (doesImplementJobInterface(cl)) {
            qrtzQualifiedJobs.put(cl.getName(), cl.getName());
          } else {
            LOG.warn("Class: " + className + " does not implement quartz Job interface");
          }
        }
      }
      // run ddl
      if (autoDdl.booleanValue()) {
        try {
          sqlService.ddl(this.getClass().getClassLoader(), "quartz2");
        } catch (Throwable t) {
          LOG.warn(this + ".init(): ", t);
        }
      }

      boolean isInitialStartup = isInitialStartup(sqlService);
      if (isInitialStartup && autoDdl.booleanValue()) {
        LOG.info("Performing initial population of the Quartz tables.");
        sqlService.ddl(this.getClass().getClassLoader(), "init_locks2");
      }
      /*
        Determine whether or not to load the jobs defined in the initialJobSchedules list. These jobs will be loaded
        under the following conditions:
           1) the server configuration property "scheduler.loadjobs" is "true"
           2) "scheduler.loadjobs" is "init" and this is the first startup for the scheduler (eg. this is a new Sakai instance)
        "scheduler.loadjobs" is set to "init" by default
      */
      String loadJobs = serverConfigurationService.getString(SCHEDULER_LOADJOBS, "init").trim();

      List<SpringInitialJobSchedule> initSchedules = getInitialJobSchedules();

      boolean loadInitSchedules =
          (initSchedules != null)
              && (initSchedules.size() > 0)
              && (("init".equalsIgnoreCase(loadJobs) && isInitialStartup)
                  || "true".equalsIgnoreCase(loadJobs));

      if (loadInitSchedules) LOG.debug("Preconfigured jobs will be loaded");
      else LOG.debug("Preconfigured jobs will not be loaded");

      // start scheduler and load jobs
      schedFactory = new StdSchedulerFactory(qrtzProperties);
      scheduler = schedFactory.getScheduler();

      // loop through persisted jobs removing both the job and associated
      // triggers for jobs where the associated job class is not found
      Set<JobKey> jobKeys =
          scheduler.getJobKeys(GroupMatcher.jobGroupEquals(Scheduler.DEFAULT_GROUP));
      for (JobKey key : jobKeys) {
        try {
          JobDetail detail = scheduler.getJobDetail(key);
          String bean = detail.getJobDataMap().getString(JobBeanWrapper.SPRING_BEAN_NAME);
          Job job = (Job) ComponentManager.get(bean);
          if (job == null) {
            LOG.warn("scheduler cannot load class for persistent job:" + key);
            scheduler.deleteJob(key);
            LOG.warn("deleted persistent job:" + key);
          }
        } catch (SchedulerException e) {
          LOG.warn("scheduler cannot load class for persistent job:" + key);
          scheduler.deleteJob(key);
          LOG.warn("deleted persistent job:" + key);
        }
      }

      for (TriggerListener tListener : globalTriggerListeners) {
        scheduler.getListenerManager().addTriggerListener(tListener);
      }

      for (JobListener jListener : globalJobListeners) {
        scheduler.getListenerManager().addJobListener(jListener);
      }

      if (loadInitSchedules) {
        LOG.debug("Loading preconfigured jobs");
        loadInitialSchedules();
      }

      // scheduler.addGlobalTriggerListener(globalTriggerListener);
      if (isStartScheduler()) {
        scheduler.start();
      } else {
        LOG.info("Scheduler Not Started, startScheduler=false");
      }
    } catch (Exception e) {
      LOG.error("Failed to start scheduler.", e);
      throw new IllegalStateException("Scheduler cannot start!", e);
    }
  }
  protected SchedulerResponse getScheduledJob(Scheduler scheduler, JobKey jobKey) throws Exception {

    JobDetail jobDetail = scheduler.getJobDetail(jobKey);

    if (jobDetail == null) {
      return null;
    }

    SchedulerResponse schedulerResponse = new SchedulerResponse();

    JobDataMap jobDataMap = jobDetail.getJobDataMap();

    String description = jobDataMap.getString(SchedulerEngine.DESCRIPTION);

    schedulerResponse.setDescription(description);

    String destinationName = jobDataMap.getString(SchedulerEngine.DESTINATION_NAME);

    schedulerResponse.setDestinationName(destinationName);

    Message message = getMessage(jobDataMap);

    JobState jobState = getJobState(jobDataMap);

    message.put(SchedulerEngine.JOB_STATE, jobState);

    schedulerResponse.setMessage(message);

    StorageType storageType =
        StorageType.valueOf(jobDataMap.getString(SchedulerEngine.STORAGE_TYPE));

    schedulerResponse.setStorageType(storageType);

    String jobName = jobKey.getName();
    String groupName = jobKey.getGroup();

    TriggerKey triggerKey = new TriggerKey(jobName, groupName);

    Trigger trigger = scheduler.getTrigger(triggerKey);

    if (trigger == null) {
      schedulerResponse.setGroupName(groupName);
      schedulerResponse.setJobName(jobName);

      return schedulerResponse;
    }

    message.put(SchedulerEngine.END_TIME, trigger.getEndTime());
    message.put(SchedulerEngine.FINAL_FIRE_TIME, trigger.getFinalFireTime());
    message.put(SchedulerEngine.NEXT_FIRE_TIME, trigger.getNextFireTime());
    message.put(SchedulerEngine.PREVIOUS_FIRE_TIME, trigger.getPreviousFireTime());
    message.put(SchedulerEngine.START_TIME, trigger.getStartTime());

    if (trigger instanceof CalendarIntervalTrigger) {
      CalendarIntervalTrigger calendarIntervalTrigger = CalendarIntervalTrigger.class.cast(trigger);

      IntervalUnit intervalUnit = calendarIntervalTrigger.getRepeatIntervalUnit();

      schedulerResponse.setTrigger(
          new IntervalTrigger(
              jobName,
              groupName,
              calendarIntervalTrigger.getStartTime(),
              calendarIntervalTrigger.getEndTime(),
              calendarIntervalTrigger.getRepeatInterval(),
              TimeUnit.valueOf(intervalUnit.name())));
    } else if (trigger instanceof CronTrigger) {
      CronTrigger cronTrigger = CronTrigger.class.cast(trigger);

      schedulerResponse.setTrigger(
          new com.liferay.portal.kernel.scheduler.CronTrigger(
              jobName,
              groupName,
              cronTrigger.getStartTime(),
              cronTrigger.getEndTime(),
              cronTrigger.getCronExpression()));
    } else if (trigger instanceof SimpleTrigger) {
      SimpleTrigger simpleTrigger = SimpleTrigger.class.cast(trigger);

      schedulerResponse.setTrigger(
          new IntervalTrigger(
              jobName,
              groupName,
              simpleTrigger.getStartTime(),
              simpleTrigger.getEndTime(),
              (int) simpleTrigger.getRepeatInterval(),
              TimeUnit.MILLISECOND));
    }

    return schedulerResponse;
  }