/*******************************************************************************
* Copyright (c) 2009 Daniel Grout.
*
* GNU GENERAL PUBLIC LICENSE - Version 3
*
* This file is part of Report Runner (http://code.google.com/p/reportrunner).
*
* Report Runner is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Report Runner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Report Runner. If not, see <http://www.gnu.org/licenses/>.
*
* Module: SchedulerImpl.java
******************************************************************************/
package binky.reportrunner.scheduler.impl;
import java.text.ParseException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.impl.StdScheduler;
import binky.reportrunner.engine.ReportGenerationJob;
import binky.reportrunner.engine.dashboard.AlertProcessor;
import binky.reportrunner.scheduler.Scheduler;
import binky.reportrunner.scheduler.SchedulerException;
public class SchedulerImpl implements Scheduler {
private StdScheduler quartzScheduler;
private Logger logger = Logger.getLogger(SchedulerImpl.class);
private boolean clustered;
public StdScheduler getQuartzScheduler() {
return quartzScheduler;
}
public void setQuartzScheduler(StdScheduler quartzScheduler) {
this.quartzScheduler = quartzScheduler;
}
public int getJobCount() throws org.quartz.SchedulerException {
/*int i = 0;
for (String groupName : this.quartzScheduler.getJobGroupNames()) {
for (String jobName : this.quartzScheduler.getJobNames(groupName)) {
logger.debug("found " + jobName + "/" + groupName);
i++;
}
}
return i;*/
return this.quartzScheduler.getJobGroupNames().length;
}
public void addJob(String jobName, String groupName, String cronString,
Date startDate, Date endDate) throws SchedulerException {
// Create our job with the specification RunnerJob
JobDetail jobDetail;
try {
if (this.quartzScheduler.getJobDetail(jobName, groupName) != null) {
removeJob(jobName, groupName);
}
jobDetail = new JobDetail(jobName, groupName, ReportGenerationJob.class);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error with scheduler", e);
}
// Create the trigger
CronTrigger jobTrigger = new CronTrigger();
try {
jobTrigger.setCronExpression(cronString);
} catch (ParseException e) {
throw new SchedulerException("Error with cron configuration", e);
}
jobTrigger.setStartTime(startDate);
if (endDate != null)
jobTrigger.setEndTime(endDate);
jobTrigger.setName(jobName + ":" + groupName + ":trigger");
jobTrigger.setGroup("RunnerTriggers");
// clusterting
if (clustered)
jobDetail.setRequestsRecovery(true);
// Bind the listener
// jobDetail.addJobListener("ReportRunnerCoreJobListener");
// schedule the job
try {
this.quartzScheduler.scheduleJob(jobDetail, jobTrigger);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error scheduling with quartz", e);
}
}
public void startScheduler() throws SchedulerException {
try {
this.quartzScheduler.start();
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error starting scheduler", e);
}
}
public void stopScheduler() throws SchedulerException {
this.quartzScheduler.standby();
}
public Date getNextRunTime(String jobName, String groupName)
throws SchedulerException {
try {
Trigger trig =this.quartzScheduler.getTrigger(
jobName + ":" + groupName + ":trigger", "RunnerTriggers");
Date next= trig.getNextFireTime();
return next;
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error next run time for " + jobName
+ "/" + groupName, e);
}
}
public Date getPreviousRunTime(String jobName, String groupName)
throws SchedulerException {
try {
return this.quartzScheduler.getTrigger(
jobName + ":" + groupName + ":trigger", "RunnerTriggers")
.getPreviousFireTime();
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error last run time for " + jobName
+ "/" + groupName, e);
}
}
public Boolean isJobActive(String jobName, String groupName)
throws SchedulerException {
try {
return !(this.quartzScheduler.getTriggerState(jobName + ":"
+ groupName + ":trigger", "RunnerTriggers") == Trigger.STATE_PAUSED);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error getting state for " + jobName
+ "/" + groupName, e);
}
}
public Boolean isScheduled(String jobName, String groupName)
throws SchedulerException {
try {
return !(this.quartzScheduler.getTrigger(jobName + ":" + groupName
+ ":trigger", "RunnerTriggers") == null);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error getting state for " + jobName
+ "/" + groupName, e);
}
}
public void invokeJob(String jobName, String groupName)
throws SchedulerException {
logger.debug("invoke job: " + groupName + "." + jobName);
try {
this.quartzScheduler.triggerJob(jobName, groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error triggering job " + jobName
+ "/" + groupName, e);
}
}
public Boolean isSchedulerActive() throws SchedulerException {
return !this.quartzScheduler.isInStandbyMode();
}
public void pauseJob(String jobName, String groupName)
throws SchedulerException {
logger.debug("pause job: " + groupName + "." + jobName);
try {
this.quartzScheduler.pauseJob(jobName, groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error pausing job " + jobName + "/"
+ groupName, e);
}
}
public void removeJob(String jobName, String groupName)
throws SchedulerException {
logger.debug("remove job: " + groupName + "." + jobName);
try {
this.quartzScheduler.deleteJob(jobName, groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error removing job " + jobName + "/"
+ groupName, e);
}
}
public void resumeJob(String jobName, String groupName)
throws SchedulerException {
logger.debug("resume job: " + groupName + "." + jobName);
try {
this.quartzScheduler.resumeJob(jobName, groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error resuming job " + jobName + "/"
+ groupName, e);
}
}
public void interruptRunningJob(String jobName, String groupName)
throws SchedulerException {
logger.debug("interrupt job: " + groupName + "." + jobName);
try {
this.quartzScheduler.interrupt(jobName, groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error interrupting job " + jobName
+ "/" + groupName, e);
}
}
@SuppressWarnings("unchecked")
public List<String> getCurrentRunningJobs() {
List<String> currentRunningJobs = new LinkedList<String>();
List<JobExecutionContext> cej = quartzScheduler
.getCurrentlyExecutingJobs();
for (JobExecutionContext je : cej) {
currentRunningJobs.add(je.getJobDetail().getGroup() + ":|:"
+ je.getJobDetail().getName());
}
return currentRunningJobs;
}
public void pauseGroup(String groupName) throws SchedulerException {
logger.debug("pause group: " + groupName);
try {
this.quartzScheduler.pauseJobGroup(groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error pausing group " + groupName, e);
}
}
public void resumeGroup(String groupName) throws SchedulerException {
logger.debug("resume group: " + groupName);
try {
this.quartzScheduler.resumeJobGroup(groupName);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error resuming group " + groupName, e);
}
}
public void addDashboardAlert(Integer alertId, String cronTab)
throws SchedulerException {
// Create our job with the specification RunnerJob
String jobName = alertId.toString();
JobDetail jobDetail;
logger.debug("scheduling:" + alertId + "/" + dashboardSchedulerGroup);
try {
if (this.quartzScheduler.getJobDetail(jobName,
dashboardSchedulerGroup) != null) {
removeJob(jobName, dashboardSchedulerGroup);
}
jobDetail = new JobDetail(jobName, dashboardSchedulerGroup,
AlertProcessor.class);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error with scheduler", e);
}
// Create the trigger
CronTrigger jobTrigger = new CronTrigger();
try {
jobTrigger.setCronExpression(cronTab);
} catch (ParseException e) {
throw new SchedulerException("Error with cron configuration", e);
}
jobTrigger.setStartTime(new Date());
jobTrigger
.setName(jobName + ":" + dashboardSchedulerGroup + ":trigger");
jobTrigger.setGroup("RunnerTriggers");
// clusterting
if (clustered)
jobDetail.setRequestsRecovery(true);
// Bind the listener
// jobDetail.addJobListener("ReportRunnerCoreJobListener");
// schedule the job
try {
this.quartzScheduler.scheduleJob(jobDetail, jobTrigger);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException(
"Error dashboard alert scheduling with quartz", e);
}
}
public void removedDashboardAlert(Integer alertId)
throws SchedulerException {
logger.debug("remove alert: " + alertId);
try {
this.quartzScheduler.deleteJob(alertId.toString(),
dashboardSchedulerGroup);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException(
"Error removing dashboard alert from scheduler: RR-DASHBOARD"
+ alertId + "/RR3DASHBOARDS", e);
}
}
public boolean isClustered() {
return clustered;
}
public boolean getClustered() {
return clustered;
}
public void setClustered(boolean clustered) {
this.clustered = clustered;
}
public void interruptRunningDashboardAlert(Integer alertId)
throws SchedulerException {
this.interruptRunningJob("" + alertId, dashboardSchedulerGroup);
}
public Date getNextRunTime(Integer alertId) throws SchedulerException {
try {
Trigger trigger = this.quartzScheduler.getTrigger(alertId
.toString()
+ ":" + dashboardSchedulerGroup + ":trigger",
"RunnerTriggers");
if (trigger != null) {
return trigger.getNextFireTime();
} else {
return null;
}
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error next run time for alert "
+ alertId, e);
}
}
public Date getPreviousRunTime(Integer alertId) throws SchedulerException {
try {
Trigger t = this.quartzScheduler.getTrigger(alertId.toString()
+ ":" + dashboardSchedulerGroup + ":trigger",
"RunnerTriggers");
if (t != null) {
return t.getPreviousFireTime();
} else {
return null;
}
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error last run time for alert "
+ alertId, e);
}
}
public void invokeDashboardItem(Integer itemId) throws SchedulerException {
logger.debug("invoke alert: " + itemId + "." + itemId);
try {
this.quartzScheduler.triggerJob("" + itemId,
dashboardSchedulerGroup);
} catch (org.quartz.SchedulerException e) {
throw new SchedulerException("Error triggering job " + itemId
+ "/" + dashboardSchedulerGroup, e);
}
}
public Date getActiveFrom() {
return this.quartzScheduler.getMetaData().getRunningSince();
}
public int getJobsExecuted() {
return this.quartzScheduler.getMetaData().getNumberOfJobsExecuted();
}
public String getSummary() throws SchedulerException {
try {
return this.quartzScheduler.getMetaData().getSummary();
} catch (org.quartz.SchedulerException e) {
logger.error(e.getMessage(),e);
throw new SchedulerException(e.getMessage(),e);
}
}
}