package br.com.http.timer;
import javax.annotation.Resource;
import javax.ejb.NoMoreTimeoutsException;
import javax.ejb.ScheduleExpression;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerConfig;
import javax.ejb.TimerHandle;
import javax.ejb.TimerService;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import br.com.http.timer.exception.JobAlreadyExistsException;
@Stateless
public class JobManager {
private static final Logger logger = LoggerFactory.getLogger(JobManager.class);
@Resource
private TimerService timerService;
@PersistenceContext(unitName = "primary")
private EntityManager em;
@Inject
private JobExecutor executor;
public Job createJob(Job job) throws JobAlreadyExistsException {
if (job.getId() != null && em.find(Job.class, job.getId()) != null) {
throw new JobAlreadyExistsException();
}
ScheduleExpression schedule = new ScheduleExpression();
schedule.second(job.getSecond());
schedule.minute(job.getMinute());
schedule.hour(job.getHour());
schedule.dayOfMonth(job.getDayOfMonth());
schedule.dayOfWeek(job.getDayOfWeek());
schedule.month(job.getMonth());
schedule.year(job.getYear());
TimerConfig timerConfig = new TimerConfig(job.getId(), true);
Timer timer = timerService.createCalendarTimer(schedule, timerConfig);
TimerHandle timerHandle = timer.getHandle();
job.serialize(timerHandle);
logger.info("Timer {} created with cron expression {}. The next timeout is {}.", job.getId(),
job.getCronExpression(), timer.getNextTimeout());
if (job.getId() != null) {
em.merge(job);
} else {
em.persist(job);
}
return job;
}
public void removeJob(long jobId) {
Job job = em.find(Job.class, jobId);
if (job != null) {
em.remove(job);
TimerHandle timerHandle = job.geTimerHandle();
if (timerHandle != null) {
timerHandle.getTimer().cancel();
}
} else {
logger.info("Job with id {} not found. Cancelling...", jobId);
}
}
@Timeout
public void execute(Timer timer) {
try {
if (timer.getTimeRemaining() < 0) {
logger.info("Skipping missed job timeout with id {}", timer.getInfo());
return;
}
} catch (NoMoreTimeoutsException e) {
}
Job job = em.find(Job.class, timer.getInfo());
if (job == null) {
logger.info("Job with id {} not found. Cancelling...", timer.getInfo());
timer.cancel();
} else if (!job.isActivate()) {
logger.info("Skipping execution of job {} because it is marked as inactive.", timer.getInfo());
} else {
JobExecution execution = executor.createExecution(job);
executor.execute(execution, job);
}
}
}