package org.molgenis.data.jobs;
import org.joda.time.Duration;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import org.molgenis.data.jobs.model.JobExecution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import java.util.Date;
import static org.molgenis.data.jobs.model.JobExecution.Status.*;
/**
* Tracks progress and stores it in a {@link JobExecution} entity.
* The entity may be a subclass of {@link JobExecution}.
*/
public class ProgressImpl implements Progress
{
private static final Logger LOG = LoggerFactory.getLogger(ProgressImpl.class);
private static final Logger JOB_EXECUTION_LOG = LoggerFactory.getLogger(JobExecution.class);
private final JobExecution jobExecution;
private final JobExecutionUpdater updater;
private final MailSender mailSender;
public ProgressImpl(JobExecution jobExecution, JobExecutionUpdater updater, MailSender mailSender)
{
this.jobExecution = jobExecution;
this.mailSender = mailSender;
this.updater = updater;
}
private void update()
{
updater.update(jobExecution);
}
@Override
public void start()
{
JobExecutionContext.set(jobExecution);
JOB_EXECUTION_LOG.info("Execution started.");
jobExecution.setStartDate(new Date());
jobExecution.setStatus(RUNNING);
update();
}
@Override
public void progress(int progress, String message)
{
jobExecution.setProgressInt(progress);
jobExecution.setProgressMessage(message);
JOB_EXECUTION_LOG.debug("progress ({}, {})", progress, message);
update();
}
@Override
public void success()
{
jobExecution.setEndDate(new Date());
jobExecution.setStatus(SUCCESS);
jobExecution.setProgressInt(jobExecution.getProgressMax());
Duration yourDuration = Duration.millis(timeRunning());
Period period = yourDuration.toPeriod();
PeriodFormatter periodFormatter = new PeriodFormatterBuilder().appendDays().appendSuffix("d ").appendMinutes()
.appendSuffix("m ").appendSeconds().appendSuffix("s ").appendMillis().appendSuffix("ms ").toFormatter();
String timeSpent = periodFormatter.print(period);
JOB_EXECUTION_LOG.info("Execution successful. Time spent: {}", timeSpent);
sendEmail(jobExecution.getSuccessEmail(), jobExecution.getType() + " job succeeded.", jobExecution.getLog());
update();
JobExecutionContext.unset();
}
private void sendEmail(String[] to, String subject, String text) throws MailException
{
if (to.length > 0)
{
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(to);
mailMessage.setSubject(subject);
mailMessage.setText(text);
mailSender.send(mailMessage);
}
}
@Override
public void failed(Exception ex)
{
JOB_EXECUTION_LOG.error("Failed. " + ex.getMessage(), ex);
jobExecution.setEndDate(new Date());
jobExecution.setStatus(FAILED);
jobExecution.setProgressMessage(ex.getMessage());
sendEmail(jobExecution.getFailureEmail(), jobExecution.getType() + " job failed.", jobExecution.getLog());
update();
JobExecutionContext.unset();
}
@Override
public void canceled()
{
JOB_EXECUTION_LOG.warn("Canceled");
jobExecution.setEndDate(new Date());
jobExecution.setStatus(CANCELED);
sendEmail(jobExecution.getFailureEmail(), jobExecution.getType() + " job failed.", jobExecution.getLog());
update();
JobExecutionContext.unset();
}
@Override
public Long timeRunning()
{
Date startDate = jobExecution.getStartDate();
if (startDate == null)
{
return null;
}
return System.currentTimeMillis() - startDate.getTime();
}
@Override
public void setProgressMax(int max)
{
jobExecution.setProgressMax(max);
update();
}
@Override
public void status(String message)
{
JOB_EXECUTION_LOG.info(message);
jobExecution.setProgressMessage(message);
update();
}
@Override
public void setResultUrl(String string)
{
jobExecution.setResultUrl(string);
}
}