use of org.openmrs.scheduler.Task in project openmrs-core by openmrs.
the class SchedulerFormValidator method validate.
/**
* Checks the form object for any inconsistencies/errors
*
* @see org.springframework.validation.Validator#validate(java.lang.Object,
* org.springframework.validation.Errors)
* @should fail validation if name is null or empty or whitespace
* @should fail validation if taskClass is empty or whitespace
* @should fail validation if repeatInterval is null or empty or whitespace
* @should fail validation if class is not instance of Task
* @should fail validation if class is not accessible
* @should fail validation if class cannot be instantiated
* @should fail validation if class not found
* @should pass validation if all required fields have proper values
* @should pass validation if field lengths are correct
* @should fail validation if field lengths are not correct
*/
@Override
public void validate(Object obj, Errors errors) {
TaskDefinition taskDefinition = (TaskDefinition) obj;
if (taskDefinition == null) {
errors.rejectValue("task", "error.general");
} else {
// Won't work without name and description properties on Task Definition
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "Scheduler.taskForm.required", new Object[] { "Task name", taskDefinition.getName() });
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "taskClass", "Scheduler.taskForm.required", new Object[] { "Task class", taskDefinition.getTaskClass() });
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "repeatInterval", "Scheduler.taskForm.required", new Object[] { "Repeat interval", taskDefinition.getRepeatInterval() });
ValidateUtil.validateFieldLengths(errors, obj.getClass(), "name", "description", "taskClass", "startTimePattern");
// Check if the class is valid
try {
Class<?> taskClass = OpenmrsClassLoader.getInstance().loadClass(taskDefinition.getTaskClass());
Object o = taskClass.newInstance();
if (!(o instanceof Task)) {
errors.rejectValue("taskClass", "Scheduler.taskForm.classDoesNotImplementTask", new Object[] { taskDefinition.getTaskClass(), Task.class.getName() }, "Class does not implement Task interface");
}
} catch (IllegalAccessException iae) {
errors.rejectValue("taskClass", "Scheduler.taskForm.illegalAccessException", new Object[] { taskDefinition.getTaskClass() }, "Illegal access exception.");
} catch (InstantiationException ie) {
errors.rejectValue("taskClass", "Scheduler.taskForm.instantiationException", new Object[] { taskDefinition.getTaskClass() }, "Error creating new instance of class.");
} catch (ClassNotFoundException cnfe) {
errors.rejectValue("taskClass", "Scheduler.taskForm.classNotFoundException", new Object[] { taskDefinition.getTaskClass() }, "Class not found error.");
}
}
}
use of org.openmrs.scheduler.Task in project openmrs-core by openmrs.
the class TimerSchedulerServiceImpl method scheduleTask.
/**
* Schedule the given task according to the given schedule.
*
* @param taskDefinition the task to be scheduled
* @should should handle zero repeat interval
*/
@Override
public Task scheduleTask(TaskDefinition taskDefinition) throws SchedulerException {
Task clientTask = null;
if (taskDefinition != null) {
// Cancel any existing timer tasks for the same task definition
// TODO Make sure this is the desired behavior
// TODO Do we ever want the same task definition to run more than once?
TimerSchedulerTask schedulerTask = scheduledTasks.get(taskDefinition.getId());
if (schedulerTask != null) {
log.info("Shutting down the existing instance of this task to avoid conflicts!!");
schedulerTask.shutdown();
}
try {
// Create new task from task definition
clientTask = TaskFactory.getInstance().createInstance(taskDefinition);
// if we were unable to get a class, just quit
if (clientTask != null) {
schedulerTask = new TimerSchedulerTask(clientTask);
taskDefinition.setTaskInstance(clientTask);
// Once this method is called, the timer is set to start at the given start time.
// NOTE: We need to adjust the repeat interval as the JDK Timer expects time in milliseconds and
// we record by seconds.
long repeatInterval = 0;
if (taskDefinition.getRepeatInterval() != null) {
repeatInterval = taskDefinition.getRepeatInterval() * SchedulerConstants.SCHEDULER_MILLIS_PER_SECOND;
}
if (taskDefinition.getStartTime() != null) {
// Need to calculate the "next execution time" because the scheduled time is most likely in the past
// and the JDK timer will run the task X number of times from the start time until now to catch up.
Date nextTime = SchedulerUtil.getNextExecution(taskDefinition);
// Start task at fixed rate at given future date and repeat as directed
log.info("Starting task ... the task will execute for the first time at " + nextTime);
if (repeatInterval > 0) {
// Schedule the task to run at a fixed rate
getTimer(taskDefinition).scheduleAtFixedRate(schedulerTask, nextTime, repeatInterval);
} else {
// Schedule the task to be non-repeating
getTimer(taskDefinition).schedule(schedulerTask, nextTime);
}
} else if (repeatInterval > 0) {
// Start task on repeating schedule, delay for SCHEDULER_DEFAULT_DELAY seconds
log.info("Delaying start time by " + SchedulerConstants.SCHEDULER_DEFAULT_DELAY + " seconds");
getTimer(taskDefinition).scheduleAtFixedRate(schedulerTask, SchedulerConstants.SCHEDULER_DEFAULT_DELAY, repeatInterval);
} else {
// schedule for single execution, starting now
log.info("Starting one-shot task");
getTimer(taskDefinition).schedule(schedulerTask, new Date());
}
// Update task that has been started
log.debug("Registering timer for task " + taskDefinition.getId());
// Add the new timer to the scheduler running task list
scheduledTasks.put(taskDefinition.getId(), schedulerTask);
// Update the timer status in the database
taskDefinition.setStarted(true);
saveTaskDefinition(taskDefinition);
}
} catch (Exception e) {
log.error("Failed to schedule task " + taskDefinition.getName(), e);
throw new SchedulerException("Failed to schedule task", e);
}
}
return clientTask;
}
use of org.openmrs.scheduler.Task in project openmrs-core by openmrs.
the class DaemonTest method executeScheduledTask_shouldNotThrowErrorIfCalledFromATimerSchedulerTaskClass.
/**
* This uses a task that just marks itself as run when its "execute" method is called. This
* verifies that the Daemon class is getting past the class check and on to the task running
* step
*
* @see Daemon#executeScheduledTask(Task)
*/
@Test
public void executeScheduledTask_shouldNotThrowErrorIfCalledFromATimerSchedulerTaskClass() throws Throwable {
Task task = new PrivateTask();
Assert.assertTrue(new PrivateSchedulerTask(task).runTheTest());
}
use of org.openmrs.scheduler.Task in project openmrs-core by openmrs.
the class DaemonTest method runInNewDaemonThread_shouldNotThrowErrorIfCalledFromADaemonThread.
/**
* @see Daemon#runInNewDaemonThread(Runnable)
*/
@Test
public void runInNewDaemonThread_shouldNotThrowErrorIfCalledFromADaemonThread() throws Throwable {
Task taskThatStartsAnotherThread = new TaskThatStartsAnotherThread();
Assert.assertTrue(new PrivateSchedulerTask(taskThatStartsAnotherThread).runTheTest());
}
use of org.openmrs.scheduler.Task in project openmrs-core by openmrs.
the class TimerSchedulerServiceImplTest method scheduleTask_shouldHandleZeroRepeatInterval.
/**
* Tests whether the TimerScheduler schedules tasks even if the repeatInterval is zero.
*
* @throws SchedulerException
* @see TimerSchedulerServiceImpl#scheduleTask(TaskDefinition)
*/
@Test
public void scheduleTask_shouldHandleZeroRepeatInterval() throws SchedulerException {
// Represents the start time of the task (right now)
Calendar startTime = Calendar.getInstance();
// Define repeatInterval as zero
Long repeatInterval = 0L;
String taskName = "TestTask";
String className = "org.openmrs.scheduler.tasks.TestTask";
Boolean startOnStartup = false;
// Create the new task
TaskDefinition taskDefinition = new TaskDefinition();
taskDefinition.setName(taskName);
taskDefinition.setTaskClass(className);
taskDefinition.setStartTime(startTime.getTime());
taskDefinition.setRepeatInterval(repeatInterval);
taskDefinition.setStartOnStartup(startOnStartup);
Task clientTask = null;
clientTask = Context.getSchedulerService().scheduleTask(taskDefinition);
// without this commit there seems to be a table lock left on the SCHEDULER_TASK_CONFIG table, see TRUNK-4212
Context.flushSession();
// Assert that the clientTask is not null, i.e. the sheduleTask was able to successfully schedule in case of zero repeatInterval.
assertNotNull("The clientTask variable is null, so either the TimerSchedulerServiceImpl.scheduleTask method hasn't finished or didn't get run", clientTask);
}
Aggregations