From: <bla...@us...> - 2008-11-13 03:54:10
|
Revision: 55 http://drawbridge.svn.sourceforge.net/drawbridge/?rev=55&view=rev Author: blamonica Date: 2008-11-13 03:54:04 +0000 (Thu, 13 Nov 2008) Log Message: ----------- * Added a way for Jobs to show their next scheduled time to run. * Added unit tests for the Schedule and Job classes in order to test the getNextFireTime methods. * Added the "Schedule" column back to the manage.jsp for Jobs, this will now show the next time the job is scheduled to run (or blank if it is disabled or has no schedule). * Fixed the Scheduler so that it only loads jobs that are active. Modified Paths: -------------- trunk/drawbridge/WebContent/WEB-INF/jsp/job/manage.jsp trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java trunk/drawbridge/src/java/net/sf/drawbridge/dao/hibernate/HibernateJobDaoImpl.java trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java trunk/drawbridge/src/java/net/sf/drawbridge/vo/Job.java trunk/drawbridge/src/java/net/sf/drawbridge/vo/Schedule.java Added Paths: ----------- trunk/drawbridge/src/test/net/sf/drawbridge/vo/ trunk/drawbridge/src/test/net/sf/drawbridge/vo/JobTest.java trunk/drawbridge/src/test/net/sf/drawbridge/vo/ScheduleTest.java Modified: trunk/drawbridge/WebContent/WEB-INF/jsp/job/manage.jsp =================================================================== --- trunk/drawbridge/WebContent/WEB-INF/jsp/job/manage.jsp 2008-11-13 02:16:25 UTC (rev 54) +++ trunk/drawbridge/WebContent/WEB-INF/jsp/job/manage.jsp 2008-11-13 03:54:04 UTC (rev 55) @@ -28,9 +28,7 @@ <display:column property="name" title="Name" sortable="true"/> <display:column title="Run As" sortable="true"><c:out value="${row.runAsAccount.userName}"/></display:column> <display:column property="active" title="Active" sortable="true"/> - <%-- TODO: find a way to display the schedule, perhaps display the next time it's scheduled to run? - <display:column title="Schedule" sortable="true"><c:out value="${row.schedule}" default="none"/></display:column> - --%> + <display:column title="Scheduled" sortable="true"><fmt:formatDate type="both" value="${row.nextFireDate}" dateStyle="yyyy-MM-dd HH:mm"/></display:column> <display:column title="Handler" sortable="true"><c:out value="${row.handler}" default="none"/></display:column> <display:column title="Action" style="text-align: center;"> <a href="RunJob.do?jobId=<c:out value="${row.id}"/>"><img src="images/icons/22x22/emblem-system.png" title="Run" border="0"></a> Modified: trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java =================================================================== --- trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java 2008-11-13 02:16:25 UTC (rev 54) +++ trunk/drawbridge/src/java/net/sf/drawbridge/dao/JobDao.java 2008-11-13 03:54:04 UTC (rev 55) @@ -25,5 +25,7 @@ public static final String BEAN_NAME = "JobDao"; List<Job> getJobsForDatabase(Integer databaseId); + + List<Job> getAllActive(); } Modified: trunk/drawbridge/src/java/net/sf/drawbridge/dao/hibernate/HibernateJobDaoImpl.java =================================================================== --- trunk/drawbridge/src/java/net/sf/drawbridge/dao/hibernate/HibernateJobDaoImpl.java 2008-11-13 02:16:25 UTC (rev 54) +++ trunk/drawbridge/src/java/net/sf/drawbridge/dao/hibernate/HibernateJobDaoImpl.java 2008-11-13 03:54:04 UTC (rev 55) @@ -40,4 +40,12 @@ criteria.addOrder(Order.asc("name")); return getHibernateTemplate().findByCriteria(criteria); } + + @SuppressWarnings("unchecked") + public List<Job> getAllActive() { + DetachedCriteria criteria = DetachedCriteria.forClass(voClass); + criteria.add(Expression.eq("active", "Y")); + criteria.addOrder(Order.asc("id")); + return (List<Job>) getHibernateTemplate().findByCriteria(criteria); + } } Modified: trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java =================================================================== --- trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java 2008-11-13 02:16:25 UTC (rev 54) +++ trunk/drawbridge/src/java/net/sf/drawbridge/sched/QuartzDrawbridgeScheduleLoader.java 2008-11-13 03:54:04 UTC (rev 55) @@ -53,38 +53,32 @@ } public void loadSchedule() throws Exception{ - List<Job> jobs = jobDao.getAll(); + List<Job> jobs = jobDao.getAllActive(); for (Job job : jobs) { - if (job.isActive()) { - if (log.isDebugEnabled()) { - log.debug("Scheduling Job #" + job.getId() + ": " + job.getName() + "."); + if (log.isDebugEnabled()) { + log.debug("Scheduling Job #" + job.getId() + ": " + job.getName() + "."); + } + + String jobId = String.valueOf(job.getId()); + String jobGroupId = String.valueOf(job.getRunAsAccount().getId()); + JobDetail detail = new JobDetail(jobId, jobGroupId, jobClass); + detail.setDescription(job.getName()); + for (Schedule schedule : job.getSchedules()) { + Trigger trigger = new CronTrigger( + String.valueOf(schedule.getId()), // trigger id + jobId, // trigger group + jobId, // job id + jobGroupId, // job group id + schedule.getStartDate(), // start time + schedule.getStopDate(), // stop time + schedule.getSchedule()); // cron expression + + try { + scheduler.scheduleJob(detail, trigger); + } catch (SchedulerException e) { + log.error("Unable to schedule Job #" + job.getId() + ": " + job.getName() + ".", e); } - - String jobId = String.valueOf(job.getId()); - String jobGroupId = String.valueOf(job.getRunAsAccount().getId()); - JobDetail detail = new JobDetail(jobId, jobGroupId, jobClass); - detail.setDescription(job.getName()); - for (Schedule schedule : job.getSchedules()) { - Trigger trigger = new CronTrigger( - String.valueOf(schedule.getId()), // trigger id - jobId, // trigger group - jobId, // job id - jobGroupId, // job group id - schedule.getStartDate(), // start time - schedule.getStopDate(), // stop time - schedule.getSchedule()); // cron expression - - try { - scheduler.scheduleJob(detail, trigger); - } catch (SchedulerException e) { - log.error("Unable to schedule Job #" + job.getId() + ": " + job.getName() + ".", e); - } - } - } else { - if (log.isDebugEnabled()) { - log.debug("Job #" + job.getId() + ": " + job.getName() + " is not active, will not schedule."); - } } } } Modified: trunk/drawbridge/src/java/net/sf/drawbridge/vo/Job.java =================================================================== --- trunk/drawbridge/src/java/net/sf/drawbridge/vo/Job.java 2008-11-13 02:16:25 UTC (rev 54) +++ trunk/drawbridge/src/java/net/sf/drawbridge/vo/Job.java 2008-11-13 03:54:04 UTC (rev 55) @@ -20,6 +20,7 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.Set; @@ -145,6 +146,20 @@ this.handlerParams = handlerParams; } + public Date getNextFireDate() { + Date nextFireDate = null; + if (isActive() && !getSchedules().isEmpty()) { + for (Schedule schedule : getSchedules()) { + Date fireDate = schedule.getNextFireDate(); + // find the min(fireDate) + if (nextFireDate == null || (fireDate != null && nextFireDate.after(fireDate))) { + nextFireDate = fireDate; + } + } + } + + return nextFireDate; + } @Override public int hashCode() { final int prime = 31; Modified: trunk/drawbridge/src/java/net/sf/drawbridge/vo/Schedule.java =================================================================== --- trunk/drawbridge/src/java/net/sf/drawbridge/vo/Schedule.java 2008-11-13 02:16:25 UTC (rev 54) +++ trunk/drawbridge/src/java/net/sf/drawbridge/vo/Schedule.java 2008-11-13 03:54:04 UTC (rev 55) @@ -19,6 +19,8 @@ import java.util.Date; +import org.quartz.CronExpression; + public class Schedule extends ValueObject<Long> { private Long jobId; private String schedule; @@ -67,7 +69,37 @@ public void setStopDate(Date stopDate) { this.stopDate = stopDate; } + + public Date getNextFireDate() { + Date nextFireDate = null; + Date triggerTime = null; + Date now = new Date(); + + try { + // take max(startDate, now) and use that for the triggerTime + if (getStartDate() == null || getStartDate().before(now)) { + triggerTime = now; + } else { + triggerTime = getStartDate(); + } + CronExpression exp = new CronExpression(getSchedule()); + // if the current date is between the start and the stop dates, then get the next fire date. + if (getStopDate() == null || getStopDate().after(now)) { + nextFireDate = exp.getNextValidTimeAfter(triggerTime); + + // we're not goign to fire if it is after the stop date + if (getStopDate() != null && getStopDate().before(nextFireDate)) { + nextFireDate = null; + } + } + } catch (Exception e) { + // do nothing, we don't have a the necessary information to figure out the next date. + } + + return nextFireDate; + } + @Override public int hashCode() { final int prime = 31; Added: trunk/drawbridge/src/test/net/sf/drawbridge/vo/JobTest.java =================================================================== --- trunk/drawbridge/src/test/net/sf/drawbridge/vo/JobTest.java (rev 0) +++ trunk/drawbridge/src/test/net/sf/drawbridge/vo/JobTest.java 2008-11-13 03:54:04 UTC (rev 55) @@ -0,0 +1,51 @@ +/* + * This file is part of DrawBridge. + * Copyright 2008 Ben La Monica + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation,Inc.,51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.sf.drawbridge.vo; + +import java.text.SimpleDateFormat; + +import junit.framework.TestCase; + +public class JobTest extends TestCase { + + public void testShouldReturnNullForNextFireDateIfJobNotActive() { + Job target = new Job(); + target.setActive("N"); + assertNull(target.getNextFireDate()); + } + + public void testShouldReturnNullForNextFireDateIfNoSchedulesAreDefined() { + Job target = new Job(); + target.setActive("Y"); + assertEquals(0, target.getSchedules().size()); + assertNull(target.getNextFireDate()); + } + + public void testShouldReturnEarliestNextFireDateFromMultipleSchedules() { + Job target = new Job(); + target.setId(-1L); + Schedule sched1 = new Schedule(1, 1, "* * 5 ? * * 2080", null, null); + Schedule sched2 = new Schedule(2, 1, "* * 5 ? * * 2079", null, null); + target.setActive("Y"); + target.addSchedule(sched1); + target.addSchedule(sched2); + SimpleDateFormat df = new SimpleDateFormat("yyyy"); + assertEquals("2079", df.format(target.getNextFireDate())); + } +} Added: trunk/drawbridge/src/test/net/sf/drawbridge/vo/ScheduleTest.java =================================================================== --- trunk/drawbridge/src/test/net/sf/drawbridge/vo/ScheduleTest.java (rev 0) +++ trunk/drawbridge/src/test/net/sf/drawbridge/vo/ScheduleTest.java 2008-11-13 03:54:04 UTC (rev 55) @@ -0,0 +1,69 @@ +/* + * This file is part of DrawBridge. + * Copyright 2008 Ben La Monica + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation,Inc.,51 Franklin Street,Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package net.sf.drawbridge.vo; + +import java.util.Calendar; +import java.util.Date; + +import junit.framework.TestCase; + +public class ScheduleTest extends TestCase { + + public void testShouldReturnNullIfNotEnoughInformationIsAvailableToDetermineNextFireDate() throws Exception { + Schedule target = new Schedule(); + assertNull("should return null because there is no cron expression set", target.getNextFireDate()); + } + + public void testShouldReturnNullIfTodayIsAfterStopDate() throws Exception { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DATE, -1); + Schedule target = new Schedule(); + target.setStopDate(cal.getTime()); + target.setSchedule("* 0 0 ? 2 * *"); + assertNull(target.getNextFireDate()); + } + + public void testShouldReturnNextFireDate() throws Exception { + Schedule target = new Schedule(); + target.setSchedule("* 0 0 ? 2 * *"); + assertNotNull("should return null because there is no cron expression set", target.getNextFireDate()); + } + + public void testShouldUseStartDateWhenFiguringTheNextFireDate() throws Exception { + Schedule startDateSet = new Schedule(); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DATE, 2); + startDateSet.setStartDate(cal.getTime()); + startDateSet.setSchedule("* 0 5 ? * * *"); + Date result = startDateSet.getNextFireDate(); + Schedule noStartDateSet = new Schedule(); + noStartDateSet.setSchedule("* 0 5 ? * * *"); + Date result2 = noStartDateSet.getNextFireDate(); + assertTrue("the result with a start date should be after the result without a start date", result2.before(result)); + } + + public void testShouldReturnNullIfNextFireDateIsAfterStopDate() throws Exception { + Schedule target = new Schedule(); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.DATE, 2); + target.setStopDate(cal.getTime()); + target.setSchedule("* 0 5 ? * * 2080"); + assertNull("should be null since the fire date would be in the year 2080, but the stop date is 2 days from now.", target.getNextFireDate()); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |