package org.fenixedu.bennu.scheduler; import java.util.concurrent.Callable; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.bennu.scheduler.annotation.Task; import org.fenixedu.bennu.scheduler.domain.SchedulerSystem; import org.fenixedu.bennu.scheduler.log.ExecutionLog; import org.fenixedu.commons.StringNormalizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pt.ist.esw.advice.pt.ist.fenixframework.AtomicInstance; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.Atomic.TxMode; import pt.ist.fenixframework.FenixFramework; public abstract class CronTask implements Runnable { private Logger logger; protected transient ExecutionLog log; private final Atomic atomic; public CronTask() { atomic = new AtomicInstance(getTxMode(), true); } protected TxMode getTxMode() { Task annotation = this.getClass().getAnnotation(Task.class); return annotation == null || annotation.readOnly() ? TxMode.READ : TxMode.WRITE; } public String getLocalizedName() { return SchedulerSystem.getTaskName(getClassName()); } public String getClassName() { return this.getClass().getName(); } public Logger getLogger() { if (logger == null) { logger = LoggerFactory.getLogger(getClassName()); } return logger; } public abstract void runTask() throws Exception; @Override public final void run() { log = createExecutionLog(); SchedulerSystem.getLogRepository().newExecution(log); try { innerAtomicRun(); updateLog(log.withSuccess()); } catch (Throwable t) { t.printStackTrace(); updateLog(log.withError(t)); } finally { resetLoggers(); Authenticate.unmock(); } } protected ExecutionLog createExecutionLog() { return ExecutionLog.newExecutionFor(getClassName()); } private void resetLoggers() { logger = null; log = null; } private void innerAtomicRun() throws Exception { FenixFramework.getTransactionManager().withTransaction(new Callable<Void>() { @Override public Void call() throws Exception { runTask(); return null; } }, atomic); } public void output(String filename, byte[] fileContent, boolean append) { String sanitized = StringNormalizer.slugify(filename); SchedulerSystem.getLogRepository().storeFile(log, sanitized, fileContent, append); updateLog(log.withFile(sanitized)); } public void output(String filename, byte[] fileContent) { output(filename, fileContent, false); } protected final void taskLog(String format, Object... args) { if (args == null || args.length < 1) { SchedulerSystem.getLogRepository().appendTaskLog(log, format + "\n"); } else { SchedulerSystem.getLogRepository().appendTaskLog(log, String.format(format, args)); } } protected final void taskLog() { taskLog(""); } private void updateLog(ExecutionLog log) { this.log = log; SchedulerSystem.getLogRepository().update(log); } }