Как сделать динамический интервал для операций по расписанию
Реализованный механизм находится в проекте скриптов в папке etc/development/scripts. Реализация написана в утилитном классе ItitialJob.
package scripts; import com.trackstudio.app.UdfValue; import com.trackstudio.app.adapter.scheduler.SchedulerManager; import com.trackstudio.exception.GranException; import com.trackstudio.kernel.cache.TaskRelatedInfo; import com.trackstudio.kernel.cache.TaskRelatedManager; import com.trackstudio.tools.Pair; import org.quartz.Job; import org.quartz.JobBuilder; import org.quartz.impl.triggers.CronTriggerImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TODO: comment * @author parsentev * @since 25.04.2016 */ public class InitialJob { private static final Logger log = LoggerFactory.getLogger(InitialJob.class); private final TaskRelatedInfo info; private final TaskRelatedManager manager; public InitialJob(TaskRelatedInfo info) { this.info = info; this.manager = TaskRelatedManager.getInstance(); } public void init() throws GranException { try { String jobClass = null; String cronTime = null; for (UdfValue ul : manager.getUDFValues(info.getId())) { if ("scheduler job".equals(ul.getCaption()) && ul.getValueContainer().getValue(null)!=null) { jobClass = "scripts." + ((Pair) ul.getValueContainer() .getValue(null)).getValue(); } else if ("cron time".equals(ul.getCaption()) && ul.getValueContainer().getValue(null)!=null) { cronTime = ((Pair) ul.getValueContainer() .getValue(null)).getValue(); } } if (jobClass != null && !"scripts.none".equals(jobClass) && cronTime != null && !"none".equals(cronTime)) { SchedulerManager.getInstance().deleteJob(info.getId()); CronTriggerImpl trigger = new CronTriggerImpl(); trigger.setName(String.format("trigger %s", info.getId())); trigger.setCronExpression(cronTime); SchedulerManager.getInstance().scheduleJob( JobBuilder.newJob((Class) Class.forName(jobClass)).withIdentity(info.getId()).build(), trigger ); } } catch (Exception e) { throw new GranException(e); } } }
Объект InitialJob в качестве параметра принимает задачу и в методе init() проверяет у нее дополнительные поля "scheduler job" и "cron time". В случае, когда оба поля заполнены, создается новое задание по расписанию из поля "scheduler job" с временем выполнения из "cron time".
Оба поля являются пользовательскими полями типа "Список" в процессе. В значения поля "cron time" записываются нужные интервалы в синтаксисе quartz. В значения же поля "scheduler job" записываются имена классов, которые лежат в папке etc/plugins/scripts (в проекте это класс AlertToConsole).
package scripts; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TODO: comment * @author parsentev * @since 25.04.2016 */ public class AlertToConsole implements Job { private static final Logger log = LoggerFactory.getLogger(AlertToConsole.class); @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("Alert"); } }
Класс с заданием по расписанию должен реализовывать интерфейс Job. Все необходимые действия реализуются в переопределенном методе execute(JobExecutionContext jobExecutionContext);
Операция по расписанию запускается after_create скриптом InitialSchedulerJob, после создания задачи. Скрипт подключается в настройках категории.
package scripts.after_create_task.example; import com.trackstudio.exception.GranException; import com.trackstudio.external.TaskTrigger; import com.trackstudio.secured.SecuredTaskTriggerBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scripts.InitialJob; /** * TODO: comment * @author parsentev * @since 25.04.2016 */ public class InitialSchedulerJob implements TaskTrigger { private static final Logger log = LoggerFactory.getLogger(InitialSchedulerJob.class); @Override public SecuredTaskTriggerBean execute(SecuredTaskTriggerBean task) throws GranException { new InitialJob(task.getTask()).init(); return task; } }
В случае необходимости можно сделать after скрипты, срабатывающие после операций или редактирования задачи.
Скрипт InitialLoader при перезапуске сервера проверяет все задачи в системе и перезагружает для них задания по расписанию.
package scripts.scheduler.example; import com.trackstudio.app.adapter.scheduler.SchedulerManager; import com.trackstudio.external.IGeneralScheduler; import com.trackstudio.kernel.cache.TaskRelatedInfo; import com.trackstudio.kernel.cache.TaskRelatedManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scripts.InitialJob; /** * TODO: comment * @author parsentev * @since 25.04.2016 */ public class InitialLoader implements IGeneralScheduler{ private static final Logger log = LoggerFactory.getLogger(InitialLoader.class); @Override public String getClassName() { return InitialLoader.class.getName(); } @Override public String getCronTime() { return "0/1 * * * * ?"; } @Override public String getName() { return "initial loader"; } @Override public String execute() throws Exception { TaskRelatedManager manager = TaskRelatedManager.getInstance(); for (TaskRelatedInfo info : manager.getCacheContents()) { new InitialJob(info).init(); } SchedulerManager.getInstance().deleteJob(this.getName()); return null; } @Override public boolean isUse() { return true; } }