content: package com.sohu.cache.schedule.impl;
  
  import com.sohu.cache.dao.QuartzDao;
  import com.sohu.cache.entity.TriggerInfo;
  import com.sohu.cache.schedule.SchedulerCenter;
  
  import org.apache.commons.lang.time.DateUtils;
  import org.quartz.*;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.util.Assert;
  
  import java.util.Date;
  import java.util.List;
  import java.util.Map;
  
  import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
  
  /**
   * 根据scheduler控制job、trigger和scheduler的执行和状态
   * <p/>
   * User: lingguo
   * Date: 14-5-18
   * Time: 下午10:15
   */
  public class SchedulerCenterImpl implements SchedulerCenter {
      private Logger logger = LoggerFactory.getLogger(this.getClass());
  
      // 注入预定义的scheduler
      private Scheduler clusterScheduler;
  
      private QuartzDao quartzDao;
  
      /**
       * 删除trigger
       *
       * @param triggerKey
       * @return
       */
      @Override
      public boolean unscheduleJob(TriggerKey triggerKey) {
          boolean opResult = true;
          try {
              opResult = clusterScheduler.checkExists(triggerKey);
              if (opResult) {
                  opResult = clusterScheduler.unscheduleJob(triggerKey);
              }
          } catch (SchedulerException e) {
              logger.error(e.getMessage(), e);
              opResult = false;
          }
          return opResult;
      }
  
      @Override
      public Trigger getTrigger(TriggerKey triggerKey) {
          Trigger trigger = null;
          try {
              trigger = clusterScheduler.getTrigger(triggerKey);
          } catch (SchedulerException e) {
              logger.error(e.getMessage(), e);
          }
          return trigger;
      }
  
      @Override
      public boolean deployJobByCron(JobKey jobKey, TriggerKey triggerKey, Map<String, Object> dataMap, String cron, boolean replace) {
          Assert.isTrue(jobKey != null);
          Assert.isTrue(triggerKey != null);
          Assert.isTrue(CronExpression.isValidExpression(cron), "invalid cron = " + cron);
          try {
              JobDetail jobDetail = clusterScheduler.getJobDetail(jobKey);
              if (jobDetail == null) {
                  logger.error("JobKey {}:{} is not exist", jobKey.getName(), jobKey.getGroup());
                  return false;
              }
              fireCronTrigger(triggerKey, jobDetail, cron, replace, dataMap);
          } catch (Exception e) {
              logger.error(e.getMessage(), e);
              return false;
          }
  
          return true;
      }
  
      @Override
      public boolean deployJobByDelay(JobKey jobKey, TriggerKey triggerKey, Map<String, Object> dataMap, int  delaySeconds, boolean replace) {
          Assert.isTrue(jobKey != null);
          Assert.isTrue(triggerKey != null);
          Assert.isTrue(delaySeconds > 0);
          try {
              JobDetail jobDetail = clusterScheduler.getJobDetail(jobKey);
              if (jobDetail == null) {
                  logger.error("JobKey {}:{} is not exist", jobKey.getName(), jobKey.getGroup());
                  return false;
              }
              fireSimpleTrigger(triggerKey, jobDetail, replace, dataMap, delaySeconds);
          } catch (Exception e) {
              logger.error(e.getMessage(), e);
              return false;
          }
  
          return true;
      }
  
      private boolean fireSimpleTrigger(TriggerKey triggerKey, JobDetail jobDetail, boolean replace, Map<String, Object> dataMap,int delaySeconds) {
          try {
              boolean isExists = clusterScheduler.checkExists(triggerKey);
              if (isExists) {
                  if (replace) {
                      logger.warn("replace trigger={}:{} ", triggerKey.getName(), triggerKey.getGroup());
                      clusterScheduler.unscheduleJob(triggerKey);
                  } else {
                      logger.info("exist trigger={}:{} ", triggerKey.getName(), triggerKey.getGroup());
                      return false;
                  }
              }
              Date startAtDate = new Date(System.currentTimeMillis() + delaySeconds * 1000);
              Trigger trigger = TriggerBuilder.newTrigger()
                      .withIdentity(triggerKey)
                      .forJob(jobDetail)
                      .withSchedule(simpleSchedule()
                              .withIntervalInSeconds(1)
  
                              .withRepeatCount(0)
                              )
                      .startAt(startAtDate)
                      .build();
              if (dataMap != null && dataMap.size() > 0) {
                  trigger.getJobDataMap().putAll(dataMap);
              }
              clusterScheduler.scheduleJob(trigger);
          } catch (SchedulerException e) {
              logger.error(e.getMessage(), e);
              return false;
          }
          return true;
      }
  
      private boolean fireCronTrigger(TriggerKey triggerKey, JobDetail jobDetail, String cron, boolean replace, Map<String, Object> dataMap) {
          try {
              boolean isExists = clusterScheduler.checkExists(triggerKey);
              if (isExists) {
                  if (replace) {
                      logger.warn("replace trigger={}:{} ", triggerKey.getName(), triggerKey.getGroup());
                      clusterScheduler.unscheduleJob(triggerKey);
                  } else {
                      logger.info("exist trigger={}:{} ", triggerKey.getName(), triggerKey.getGroup());
                      return false;
                  }
              }
              Date startDate = DateUtils.addSeconds(new Date(), 20);
              Trigger trigger = TriggerBuilder.newTrigger()
                      .withIdentity(triggerKey)
                      .forJob(jobDetail)
                      .withSchedule(
                              CronScheduleBuilder.cronSchedule(cron)
                              .withMisfireHandlingInstructionDoNothing()// 忽略misfire处理
                      )
                      .startAt(startDate)
                      .build();
              if (dataMap != null && dataMap.size() > 0) {
                  trigger.getJobDataMap().putAll(dataMap);
              }
              clusterScheduler.scheduleJob(trigger);
          } catch (SchedulerException e) {
              logger.error(e.getMessage(), e);
              return false;
          }
          return true;
      }
  
      @Override
      public List<TriggerInfo> getAllTriggers() {
          return quartzDao.getAllTriggers();
      }
  
      @Override
      public List<TriggerInfo> getTriggersByNameOrGroup(String query) {
          return quartzDao.searchTriggerByNameOrGroup(query);
      }
  
      @Override
      public boolean pauseTrigger(TriggerKey triggerKey) {
          try {
              boolean exists = clusterScheduler.checkExists(triggerKey);
              if (exists) {
                  clusterScheduler.pauseTrigger(triggerKey);
                  return true;
              }
              logger.error("triggerKey={} not exists", triggerKey);
              return false;
          } catch (Exception e) {
              logger.error(e.getMessage(), e);
              return false;
          }
      }
  
      @Override
      public boolean resumeTrigger(TriggerKey triggerKey) {
          try {
              boolean exists = clusterScheduler.checkExists(triggerKey);
              if (exists) {
                  clusterScheduler.resumeTrigger(triggerKey);
                  return true;
              }
              logger.error("triggerKey={} not exists", triggerKey);
              return false;
          } catch (Exception e) {
              logger.error(e.getMessage(), e);
              return false;
          }
      }
  
      public void setClusterScheduler(Scheduler clusterScheduler) {
          this.clusterScheduler = clusterScheduler;
      }
  
      public void setQuartzDao(QuartzDao quartzDao) {
          this.quartzDao = quartzDao;
      }
  }
  