package cz.cuni.mff.d3s.been.taskapi; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import cz.cuni.mff.d3s.been.core.StatusCode; import cz.cuni.mff.d3s.been.core.TaskMessageType; import cz.cuni.mff.d3s.been.core.TaskPropertyNames; import cz.cuni.mff.d3s.been.mq.MessagingException; import cz.cuni.mff.d3s.been.persistence.DAOException; import cz.cuni.mff.d3s.been.results.Result; import cz.cuni.mff.d3s.been.util.PropertyReader; /** * @author Kuba Brecka */ public abstract class Task { private static final Logger log = LoggerFactory.getLogger(Task.class); private String id; private String contextId; private String benchmarkId; protected final ResultFacade results = ResultFacadeFactory.getResultFacade(); /** * Returns ID of the running task. * * @return ID of the running task */ public String getId() { return id; } /** * Returns context ID the running task is associated with. * * @return context ID associated with the running task */ public String getContextId() { return contextId; } /** * Returns benchmark ID of the running task. * * @return benchmark ID of the running task */ public String getBenchmarkId() { return benchmarkId; } /** * Returns system property associated with the running task. * * @param propertyName * name of the property * @return value associated with the name */ public String getTaskProperty(String propertyName) { return System.getenv(propertyName); } /** * Returns system property associated with the running task or default value * * @param propertyName * name of the property * @param defaultValue Default value of the property (if the actual value is not found) * * @return value associated with the name or the default value when the * property is not set */ public String getTaskProperty(String propertyName, String defaultValue) { String propertyValue = System.getenv(propertyName); if (propertyValue == null) { return defaultValue; } else { return propertyValue; } } /** * Creates a {@link PropertyReader} from environment properties of the * {@link Task} which are passed to it by it's Host Runtime * * @return {@link PropertyReader} initialized from environment properties of * the {@link Task} */ public PropertyReader createPropertyReader() { Properties properties = new Properties(); properties.putAll(System.getenv()); return PropertyReader.on(properties); } /** * Stores a {@link Result} on behalf of the Task. * <p/> * taskId, contextId and contextId will be filled in to the result. * * @param result * Result to persist * @param group * Group of the result * @throws DAOException * when result cannot be persisted */ public void store(final Result result, final String group) throws DAOException { long time = System.currentTimeMillis(); result.withTaskId(getId()).withContextId(getContextId()).withBenchmarkId(getBenchmarkId()).withCreated(time); results.persistResult(result, group); } /** * The method subclasses override to implement task's functionality. * <p/> * To execute a task {@link #doMain(String[])} will be called. * * @param args Parameters passed to the task * * @throws TaskException When the task fails * @throws MessagingException When messaging with paired host runtime fails * @throws DAOException When persistent object access fails */ public abstract void run(String[] args) throws TaskException, MessagingException, DAOException; /** * The method which sets up task's environment and calls * {@link #run(String[])}. * * @param args Parameters passed to the task * * @return Task exit code */ public int doMain(String[] args) { try { initialize(); run(args); } catch (MessagingException e) { System.err.println("The task encountered "); e.printStackTrace(); return StatusCode.EX_NETWORK_ERROR.getCode(); } catch (TaskException e) { log.error("Task encountered an exception", e); return StatusCode.EX_UNKNOWN.getCode(); } catch (DAOException e) { log.error("Task cannot persist a result", e); return StatusCode.EX_UNKNOWN.getCode(); } catch (Throwable t) { log.error("Task encountered an unknown exception", t); return StatusCode.EX_UNKNOWN.getCode(); } finally { tearDown(); } return StatusCode.EX_OK.getCode(); } private void initialize() { this.id = System.getenv(TaskPropertyNames.TASK_ID); this.contextId = System.getenv(TaskPropertyNames.CONTEXT_ID); this.benchmarkId = System.getenv(TaskPropertyNames.BENCHMARK_ID); ResultFacadeFactory.setTaskId(id); ResultFacadeFactory.setContextId(contextId); ResultFacadeFactory.setBenchmarkId(benchmarkId); try { Messages.send(String.format("%s#%s", TaskMessageType.TASK_RUNNING, id)); } catch (MessagingException e) { // message passing does not work, log it with stderr ... System.err.println("Cannot send \"i'm running\" message"); } } private void tearDown() { try { ResultFacadeFactory.quit(); } catch (MessagingException e) { log.error("Failed to release results facade."); } try { Messages.terminate(); } catch (MessagingException e) { System.err.println("Failed to release Messaging"); } } }