/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.cms.timer; import java.text.ParseException; import java.util.List; import org.apache.log4j.Logger; import org.quartz.CronTrigger; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.impl.StdSchedulerFactory; import org.springframework.beans.factory.annotation.Autowired; import com.jinhe.tss.cms.CMSConstants; import com.jinhe.tss.cms.entity.TimerStrategy; import com.jinhe.tss.core.exception.BusinessException; import com.jinhe.tss.core.sso.IdentityCard; import com.jinhe.tss.core.sso.TokenUtil; import com.jinhe.tss.core.sso.context.Context; import com.jinhe.tss.um.UMConstants; import com.jinhe.tss.um.helper.dto.OperatorDTO; /** * <p> SchedulerManager.java </p> * 定时器调度。 */ public class SchedulerBean { protected static Logger log = Logger.getLogger(SchedulerBean.class); private static final String TIME_STRATEGY_NAME = "timerStrategy"; @Autowired private TimerService timerService; private static Scheduler scheduler; /** 定时任务。*/ public class TimerJob implements Job { public void execute(JobExecutionContext context) throws JobExecutionException { //添加管理员的用户信息 String token = TokenUtil.createToken("1234567890", UMConstants.ADMIN_USER_ID); IdentityCard card = new IdentityCard(token, OperatorDTO.ADMIN); Context.initIdentityInfo(card); //定时功能 TimerStrategy timerStrategy = (TimerStrategy) context.getMergedJobDataMap().get(TIME_STRATEGY_NAME); log.info("定时任务:(" + timerStrategy.getName() + ")开始执行。"); // 给当前启用状态下时间策略包括的索引策略创建索引文件 String hql = "from TimerStrategy t where t.status = ? and t.parentId = ? order by t.id"; List<?> strategyList = SchedulerBean.this.timerService.getEntities(hql, CMSConstants.STATUS_START, timerStrategy.getId()); for ( Object temp : strategyList) { TimerStrategy strategy = (TimerStrategy) temp; // 取父节点(即定时策略)的indexPath做为索引/或发布路径 strategy.setIndexPath(timerStrategy.getIndexPath()); // 执行时间策略下的其他策略 SchedulerBean.this.timerService.excuteStrategy(strategy); } log.info("定时任务:(" + timerStrategy.getName() + ")执行完成。"); } } private static String genJobName(Long timerStrategyId) { return "Job" + timerStrategyId; } private static String genTriggerName(Long timerStrategyId) { return "Trigger" + timerStrategyId; } private static JobDetail createJobDetail(TimerStrategy timerStrategy) { String jobDetailName = genJobName(timerStrategy.getId()); return new JobDetail(jobDetailName, Scheduler.DEFAULT_GROUP, TimerJob.class); } private static CronTrigger createCronTrigger(TimerStrategy timerStrategy) throws ParseException { String triggerName = genTriggerName(timerStrategy.getId()); return new CronTrigger(triggerName, Scheduler.DEFAULT_GROUP, timerStrategy.getContent()); // 第三个参数为定时时间 } private static void scheduleJob(TimerStrategy timerStrategy) { try { JobDetail jobDetail = createJobDetail(timerStrategy); jobDetail.getJobDataMap().put(TIME_STRATEGY_NAME, timerStrategy); Trigger trigger = createCronTrigger(timerStrategy); scheduler.scheduleJob(jobDetail, trigger); } catch (SchedulerException e) { throw new BusinessException("初始化索引策略出错!", e); } catch (java.text.ParseException e) { throw new BusinessException("初始化索引策略出错!", e); } } /** * <bean class="com.jinhe.tss.cms.timer.SchedulerManager" init-method="init"> * 在创建service时指定了调用本方法进行初始化 */ public void init() { if (scheduler != null) return; try { scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); // 获取所有的定时策略 String hql = "from TimerStrategy t where t.type = ? and t.status <> 1"; List<?> timerStrategys = timerService.getEntities(hql, CMSConstants.TACTIC_TIME_TYPE); for (Object temp : timerStrategys) { TimerStrategy timerStrategy = (TimerStrategy) temp; scheduleJob(timerStrategy); if (CMSConstants.STATUS_STOP.equals(timerStrategy.getStatus())) { scheduler.pauseTrigger(genTriggerName(timerStrategy.getId()), Scheduler.DEFAULT_GROUP); } } log.info("定时器管理对象初始化工作完成"); } catch (SchedulerException e) { throw new BusinessException("初始化索引策略出错!", e); } } /** * 启用一个定时器。 */ public static void startScheduler(Long timerStrategyId) { if(scheduler == null) return; try { scheduler.resumeTrigger(genTriggerName(timerStrategyId), Scheduler.DEFAULT_GROUP); log.info("成功启用定时任务, 定时器ID为:" + timerStrategyId); } catch (Exception e) { throw new BusinessException("启用定时任务时出错!可能是时间策略不合法,请正确设置时间策略", e); } } /** * 停用一个定时器。 */ public static void stopScheduler(Long timerStrategyId) { if(scheduler == null) return; try { scheduler.pauseTrigger(genTriggerName(timerStrategyId), Scheduler.DEFAULT_GROUP); log.debug("成功停用定时任务, 定时器ID为:" + timerStrategyId); } catch (SchedulerException e) { throw new BusinessException("停用定时任务时出错!", e); } } /** * 修改触发器和定时任务(带有job任务的回滚功能) * @param newTS * @param oldTS */ public static void editTriggerAndJob(TimerStrategy newTS, TimerStrategy oldTS){ if(scheduler == null) return; try { scheduleJob(newTS); log.info("成功修改定时任务, 定时器名称为:" + newTS.getName()); } catch (java.lang.Exception e) { try { scheduleJob(oldTS); } catch(java.lang.Exception e1) { log.error("修改触发器和定时任务时,加入至定时器不成功后回滚又失败", e1); } // job回滚后再抛出异常信息 throw new BusinessException("修改定时任务时, 发现时间策略(" + newTS.getContent() + ")不合法!", e); } } /** * 新建触发器和定时任务 */ public static void addTriggerAndJob(TimerStrategy timerStrategy) { if(scheduler == null) return; try { scheduleJob(timerStrategy); log.info("成功新增定时任务, 定时器名称为:" + timerStrategy.getName()); } catch (Exception e) { throw new BusinessException("新增定时任务时 时间策略(" + timerStrategy.getContent() + ")不合法!", e); } } /** * 删除触发器和定时任务 */ public static void removeTriggerAndJob(Long timerStrategyId) { if(scheduler == null) return; try { scheduler.unscheduleJob( genTriggerName(timerStrategyId), Scheduler.DEFAULT_GROUP ); scheduler.deleteJob( genJobName(timerStrategyId), Scheduler.DEFAULT_GROUP ); log.info("成功删除定时任务, 定时器ID为:" + timerStrategyId); } catch (SchedulerException e) { throw new BusinessException("删除定时任务错误!", e); } } }