package com.rupertjones.globalcron.server.web.service;
import com.rupertjones.globalcron.common.domain.Host;
import com.rupertjones.globalcron.common.domain.JobDescriptor;
import com.rupertjones.globalcron.common.scheduling.GlobalCronScheduler;
import com.rupertjones.globalcron.server.dao.HostDAO;
import com.rupertjones.globalcron.server.dao.JobDescriptorDAO;
import com.rupertjones.globalcron.server.web.model.DisplayableJob;
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* <p>GlobalCron © Rupert Jones 2011,2012</p>
*
* @author rup
*/
@Service
@Transactional
public class DefaultJobService implements JobService {
private static final Logger LOG = Logger.getLogger(DefaultJobService.class);
@Autowired
private JobDescriptorDAO jobDescriptorDAO;
@Autowired
private HostDAO hostDAO;
@Autowired
@Qualifier("quartzScheduler")
private GlobalCronScheduler scheduler;
@Override
public JobDescriptor getJob(int jobId) {
return jobDescriptorDAO.findById(jobId);
}
@Override
public DisplayableJob getDisplayableJob(int jobId) {
if (hasEnabledJob(jobId)) {
JobDescriptor jobDescriptor = getJob(jobId);
return asDisplayableJob(jobDescriptor);
}
return new DisplayableJob(getJob(jobId));
}
public boolean hasEnabledJob(int jobId) {
return getEnabledJob(jobId) != null;
}
@Override
public boolean runNow(JobDescriptor job) {
return scheduler.executeJob(job.getId());
}
@Override
public Host getCurrentHost() {
return hostDAO.findByHostName(Host.getCurrentHost());
}
@Override
public Host getHost(int hostId) {
return hostDAO.findById(hostId);
}
@Override
public Collection<DisplayableJob> getAllJobs() {
return asDisplayableJobs(jobDescriptorDAO.getAllJobs());
}
@Override
public void refreshJobs() {
scheduler.adjustForModifications(true);
}
@Override
public void stopAll() {
LOG.info("Stopping all jobs..");
Collection<DisplayableJob> enabledJobs = getEnabledJobs();
for (DisplayableJob job : enabledJobs) {
LOG.info("Stopping job " + job.getName());
JobDescriptor jobDescriptor = job.getJobDescriptor();
jobDescriptor.setEnabled(false);
jobDescriptorDAO.upsert(jobDescriptor);
}
scheduler.adjustForModifications();
LOG.info("Completed stopping all jobs.");
}
@Override
public void save(JobDescriptor job) {
jobDescriptorDAO.upsert(job);
}
@Override
public void save(Host host) {
hostDAO.upsert(host);
refreshJobs();
}
@Override
public void delete(JobDescriptor job) {
jobDescriptorDAO.logicalDelete(job);
scheduler.deleteJob(job.getId());
}
@Override
public Collection<DisplayableJob> getDisabledJobs(Host host) {
return asDisplayableJobs(jobDescriptorDAO.getDisabledJobsForHost(host));
}
@Override
public Collection<Host> getHosts() {
return hostDAO.findAll();
}
@Override
public Collection<DisplayableJob> getEnabledJobs(Host host) {
return sortByNextFireTime(asDisplayableJobs(jobDescriptorDAO.getEnabledJobsForHost(host)));
}
@Override
public Collection<DisplayableJob> getDisabledJobs() {
return asDisplayableJobs(jobDescriptorDAO.getDisabledJobs());
}
@Override
public Collection<DisplayableJob> getDisabledJobsForHost() {
return asDisplayableJobs(jobDescriptorDAO.getDisabledJobsForHost());
}
@Override
public Collection<DisplayableJob> getEnabledJobsForHost() {
return asDisplayableJobs(jobDescriptorDAO.getEnabledJobsForHost());
}
@Override
public Collection<DisplayableJob> getExecutingJobs() {
List<DisplayableJob> jobs = new ArrayList<DisplayableJob>();
List<JobExecutionContext> execing = scheduler.getCurrentlyExecutingJobs();
for (JobExecutionContext exec : execing) {
Trigger trigger = exec.getTrigger();
DisplayableJob job = getDisplayableJob(Integer.parseInt(trigger.getJobName()));
jobs.add(job);
}
return jobs;
}
@Override
public Collection<DisplayableJob> getEnabledJobs() {
Collection<JobDescriptor> all = jobDescriptorDAO.getEnabledJobs();
return sortByNextFireTime(asDisplayableJobs(all));
}
private Collection<DisplayableJob> sortByNextFireTime(List<DisplayableJob> input) {
Collections.sort(input, new Comparator<DisplayableJob>() {
@Override
public int compare(DisplayableJob o1, DisplayableJob o2) {
if (o1.getNextFireTimeAsDate() == null || o2.getNextFireTimeAsDate() == null) {
return -1;
}
return o1.getNextFireTimeAsDate().compareTo(o2.getNextFireTimeAsDate());
}
});
return input;
}
private List<DisplayableJob> asDisplayableJobs(Collection<JobDescriptor> jobs) {
List<DisplayableJob> displayableJobs = new ArrayList<DisplayableJob>();
for (JobDescriptor job : jobs) {
displayableJobs.add(asDisplayableJob(job));
}
return new ArrayList<DisplayableJob>(displayableJobs);
}
private DisplayableJob getEnabledJob(int id) {
for (DisplayableJob job : getEnabledJobs()) {
if (job.getId() == id) {
return job;
}
}
return null;
}
private DisplayableJob asDisplayableJob(JobDescriptor jobDescriptor) {
Trigger trigger = scheduler.getTrigger(jobDescriptor.getId());
return new DisplayableJob(jobDescriptor, trigger);
}
}