Revision 4971
Added by daigle almost 15 years ago
SchedulerService.java | ||
---|---|---|
73 | 73 |
return schedulerService; |
74 | 74 |
} |
75 | 75 |
|
76 |
// this is a refreshable class |
|
76 | 77 |
public boolean refreshable() { |
77 | 78 |
return true; |
78 | 79 |
} |
79 |
|
|
80 |
|
|
81 |
// do the refresh |
|
80 | 82 |
protected void doRefresh() throws ServiceException { |
81 | 83 |
stop(); |
84 |
start(); |
|
82 | 85 |
} |
83 | 86 |
|
87 |
// initialize the service |
|
84 | 88 |
protected void start() throws ServiceException { |
85 | 89 |
try { |
90 |
// get the Quartz scheduler factory |
|
86 | 91 |
SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(); |
87 | 92 |
|
93 |
// get the scheduler |
|
88 | 94 |
sched = schedFact.getScheduler(); |
89 | 95 |
sched.start(); |
90 | 96 |
|
97 |
// get all existing jobs from the database |
|
91 | 98 |
ScheduledJobAccess jobAccess = new ScheduledJobAccess(); |
92 | 99 |
HashMap<Long, ScheduledJobDAO> allJobsMap = jobAccess.getAllJobs(null); |
93 | 100 |
|
101 |
// reschedule each job that is in a SCHEDULED state. |
|
94 | 102 |
for (Long jobId : allJobsMap.keySet()) { |
95 | 103 |
ScheduledJobDAO jobDAO = allJobsMap.get(jobId); |
96 | 104 |
String[] groups = {"scheduler_group"}; |
97 | 105 |
if (jobDAO.getStatus().equals(StatusUtil.SCHEDULED)) { |
106 |
// send false as the last param so the reschedule method will not |
|
107 |
// complain that the job is already in a SCHEDULED state. |
|
98 | 108 |
rescheduleJob(jobDAO, "scheduler_user", groups, false); |
99 | 109 |
} |
100 | 110 |
} |
101 | 111 |
|
102 | 112 |
} catch (AccessException ae) { |
103 |
throw new ServiceException("DB Access issue when starting scheduler: ", ae); |
|
113 |
throw new ServiceException("SchedulerService.start - DB Access issue when starting scheduler: ", ae);
|
|
104 | 114 |
} catch (SchedulerException se) { |
105 |
throw new ServiceException("Scheduler engine issue when starting scheduler: " + se.getMessage()); |
|
115 |
throw new ServiceException("SchedulerService.start - Scheduler engine issue when starting scheduler: " + se.getMessage());
|
|
106 | 116 |
} |
107 | 117 |
} |
108 | 118 |
|
119 |
// Stop the scheduler |
|
109 | 120 |
protected void stop() throws ServiceException { |
110 | 121 |
try { |
111 | 122 |
sched.shutdown(true); |
112 | 123 |
sched = null; |
113 | 124 |
} catch (SchedulerException se) { |
114 |
throw new ServiceException("Could not shut down scheduler: " + se.getMessage()); |
|
125 |
throw new ServiceException("SchedulerService.stop - Could not shut down scheduler: " + se.getMessage());
|
|
115 | 126 |
} |
116 | 127 |
} |
117 | 128 |
|
129 |
// this will eventually return the scheduler status |
|
118 | 130 |
protected Vector<String> getStatus() throws ServiceException { |
119 | 131 |
return new Vector<String>(); |
120 | 132 |
} |
121 | 133 |
|
134 |
/** |
|
135 |
* Schedule a job |
|
136 |
* |
|
137 |
* @param jobDAO |
|
138 |
* the job data object to schedule |
|
139 |
* @param username |
|
140 |
* the user that we will use to schedule |
|
141 |
* @param groups |
|
142 |
* the user group that we will use to schedule |
|
143 |
* @return a message saying that the job was scheduled |
|
144 |
*/ |
|
122 | 145 |
public String scheduleJob(ScheduledJobDAO jobDAO, String username, String[] groups) throws ServiceException { |
123 | 146 |
|
147 |
// convert the start time to a calendar object |
|
124 | 148 |
Calendar startTimeCal = Calendar.getInstance(); |
125 | 149 |
startTimeCal.setTime(jobDAO.getStartTime()); |
126 | 150 |
|
151 |
// extract the job parameters from their data objects and put into a string map |
|
127 | 152 |
HashMap<String, String> jobParams = new HashMap<String, String>(); |
128 | 153 |
HashMap<String, ScheduledJobParamDAO> jobParamDAOs = jobDAO.getAllJobParams(); |
129 | 154 |
for (String paramName : jobParamDAOs.keySet()) { |
130 | 155 |
jobParams.put(paramName, jobParamDAOs.get(paramName).getValue()); |
131 | 156 |
} |
132 | 157 |
|
158 |
// schedule the job |
|
133 | 159 |
return scheduleJob(jobDAO.getName(), startTimeCal, jobDAO.getIntervalValue(), jobDAO.getIntervalUnit(), |
134 | 160 |
jobDAO.getClassName(), jobDAO.getGroupName(), jobParams, username, groups); |
135 | 161 |
} |
136 | 162 |
|
163 |
/** |
|
164 |
* schedule a job |
|
165 |
* |
|
166 |
* @param jobName |
|
167 |
* the name of the job |
|
168 |
* @param startCal |
|
169 |
* a calendar holding the start date of the job |
|
170 |
* @param intervalValue |
|
171 |
* the run interval for the job |
|
172 |
* @param intervalUnit |
|
173 |
* the unit of the run interval for the job |
|
174 |
* @param jobClassName |
|
175 |
* the job class name |
|
176 |
* @param jobGroup |
|
177 |
* the job group name |
|
178 |
* @param jobParams |
|
179 |
* a map of additional job parameters |
|
180 |
* @param username |
|
181 |
* the user name |
|
182 |
* @param groups |
|
183 |
* the user's group name |
|
184 |
* @return a message saying that the job was scheduled |
|
185 |
*/ |
|
137 | 186 |
public String scheduleJob(String jobName, Calendar startCal, int intervalValue, String intervalUnit, |
138 | 187 |
String jobClassName, String jobGroup, HashMap<String, String> jobParams, |
139 | 188 |
String username, String[] groups) throws ServiceException { |
... | ... | |
146 | 195 |
+ jobClassName + " : " + cnfe.getMessage()); |
147 | 196 |
} |
148 | 197 |
|
149 |
logMetacat.info("Scheduling job -- name: " + jobName + ", class: " + jobClassName |
|
198 |
logMetacat.info("SchedulerService.scheduleJob - Scheduling job -- name: " + jobName + ", class: " + jobClassName
|
|
150 | 199 |
+ ", start time: " + startCal.toString() + ", interval value: " + intervalValue |
151 | 200 |
+ ", interval unit: " + intervalUnit); |
152 | 201 |
|
202 |
// start the job in the job scheduler |
|
153 | 203 |
startJob(jobName, startCal, intervalValue, intervalUnit, jobClass, jobGroup, jobParams); |
154 | 204 |
|
205 |
// get a database access object and create the job in the database |
|
155 | 206 |
try { |
156 | 207 |
ScheduledJobAccess jobAccess = new ScheduledJobAccess(); |
157 | 208 |
jobAccess.createJob(jobName, jobName, jobGroup, jobClass, startCal, intervalValue, intervalUnit, jobParams); |
... | ... | |
160 | 211 |
deleteJob(jobName, username, groups); |
161 | 212 |
} catch (Exception e) { |
162 | 213 |
// Not much we can do here but log this |
163 |
logMetacat.error("An access exception was thrown when writing job: " + jobName |
|
214 |
logMetacat.error("SchedulerService.scheduleJob - An access exception was thrown when writing job: " + jobName
|
|
164 | 215 |
+ "to the db, and another exception was thrown when trying to remove the " |
165 | 216 |
+ "job from the scheduler. The db and scheduler may be out of sync: " + e.getMessage()); |
166 | 217 |
} |
... | ... | |
170 | 221 |
return "Scheduled: " + jobName; |
171 | 222 |
} |
172 | 223 |
|
173 |
|
|
174 |
|
|
224 |
/** |
|
225 |
* Unschedule a job. This removed it from the scheduler in memory and |
|
226 |
* changed it's status to unscheduled in the database. |
|
227 |
* |
|
228 |
* @param jobName |
|
229 |
* the name of the job to unschedule |
|
230 |
* @param username |
|
231 |
* the user name |
|
232 |
* @param groups |
|
233 |
* the user's group name |
|
234 |
* @return a message saying the job was unscheduled |
|
235 |
*/ |
|
175 | 236 |
public String unScheduleJob(String jobName, String username, |
176 | 237 |
String[] groups) throws ServiceException { |
177 | 238 |
try { |
... | ... | |
182 | 243 |
+ "not find job with name: " + jobName); |
183 | 244 |
} |
184 | 245 |
|
246 |
// remove the job from the scheduler |
|
185 | 247 |
sched.deleteJob(jobDAO.getName(), jobDAO.getGroupName()); |
186 | 248 |
|
249 |
// change the status of the job to unscheduled in the database. |
|
187 | 250 |
jobDAO.setStatus(StatusUtil.UNSCHEDULED); |
188 | 251 |
jobAccess.updateJobStatus(jobDAO); |
189 | 252 |
} catch (SchedulerException se) { |
... | ... | |
197 | 260 |
return "Unscheduled: " + jobName; |
198 | 261 |
} |
199 | 262 |
|
263 |
/** |
|
264 |
* Reschedule a job. This call will always check to make sure the status is not SCHEDULED |
|
265 |
* @param jobDAO the job data object holding the information about the job to reschedule |
|
266 |
* @param username |
|
267 |
* the user name |
|
268 |
* @param groups |
|
269 |
* the user's group name |
|
270 |
* @return a message saying that the job was rescheduled |
|
271 |
*/ |
|
200 | 272 |
public String rescheduleJob(ScheduledJobDAO jobDAO, String username, String[] groups) throws ServiceException { |
201 | 273 |
return rescheduleJob(jobDAO, username, groups, true); |
202 | 274 |
} |
203 | 275 |
|
276 |
/** |
|
277 |
* Reschedule a job. |
|
278 |
* |
|
279 |
* @param jobDAO |
|
280 |
* the job data object holding the information about the job to |
|
281 |
* reschedule |
|
282 |
* @param username |
|
283 |
* the user name |
|
284 |
* @param groups |
|
285 |
* the user's group name |
|
286 |
* @param checkStatus |
|
287 |
* if set to true, the method will check to make sure the status |
|
288 |
* is UNSCHEDULED before restarting. Otherwise, the method will |
|
289 |
* not check. This is so that we can restart a service at startup |
|
290 |
* that was running when metacat was shut down. |
|
291 |
* @return a message saying that the job was rescheduled |
|
292 |
*/ |
|
204 | 293 |
public String rescheduleJob(ScheduledJobDAO jobDAO, String username, String[] groups, boolean checkStatus) throws ServiceException { |
205 | 294 |
|
206 | 295 |
try { |
... | ... | |
210 | 299 |
throw new ServiceException("SchedulerService.reScheduleJob - Cannot reschedule nonexistant job."); |
211 | 300 |
} |
212 | 301 |
|
302 |
// if we are checking status, make sure the job is in an UNSCHEDULED state in the db |
|
213 | 303 |
if (checkStatus && !jobDAO.getStatus().equals(StatusUtil.UNSCHEDULED)) { |
214 | 304 |
throw new ServiceException("SchedulerService.reScheduleJob - Cannot reschedule a job with status: " |
215 | 305 |
+ jobDAO.getStatus() + ". Status must be 'unscheduled'."); |
... | ... | |
237 | 327 |
+ ", start time: " + startCal.toString() + ", interval value: " + jobDAO.getIntervalValue() |
238 | 328 |
+ ", interval unit: " + jobDAO.getIntervalUnit()); |
239 | 329 |
|
330 |
// start the job in the scheduler |
|
240 | 331 |
startJob(jobDAO.getName(), startCal, jobDAO.getIntervalValue(), jobDAO.getIntervalUnit(), jobClass, jobDAO.getGroupName(), jobParams); |
241 | 332 |
|
333 |
// update the status in the database |
|
242 | 334 |
jobDAO.setStatus(StatusUtil.SCHEDULED); |
243 | 335 |
jobAccess.updateJobStatus(jobDAO); |
244 | 336 |
|
... | ... | |
250 | 342 |
return "Resheduled: " + jobDAO.getName(); |
251 | 343 |
} |
252 | 344 |
|
345 |
/** |
|
346 |
* Remove the job from the scheduler and set the job status to deleted in the database |
|
347 |
* @param jobDAO |
|
348 |
* the job data object holding the information about the job to |
|
349 |
* delete |
|
350 |
* @param username |
|
351 |
* the user name |
|
352 |
* @param groups |
|
353 |
* the user's group name |
|
354 |
* @return a message saying that the job was deleted |
|
355 |
*/ |
|
253 | 356 |
public String deleteJob(String jobName, String username, |
254 | 357 |
String[] groups) throws ServiceException { |
255 | 358 |
|
... | ... | |
274 | 377 |
return "Deleted: " + jobName; |
275 | 378 |
} |
276 | 379 |
|
380 |
/** |
|
381 |
* Get information about the job in XML format |
|
382 |
* |
|
383 |
* @param jobId |
|
384 |
* the job for which we want the information |
|
385 |
* @return an XML representation of the job |
|
386 |
*/ |
|
277 | 387 |
public String getJobInfoXML(Long jobId) throws ServiceException { |
278 | 388 |
String jobInfoXML = ""; |
279 | 389 |
|
... | ... | |
292 | 402 |
return jobInfoXML; |
293 | 403 |
} |
294 | 404 |
|
405 |
/** |
|
406 |
* Get the information for jobs in a group in an xml format. A parameter |
|
407 |
* key/value pair can be provided as well to limit the jobs returned. |
|
408 |
* |
|
409 |
* @param groupName |
|
410 |
* the job group that we are searching for |
|
411 |
* @param paramName |
|
412 |
* the parameter name that we are looking for. this is ignored if |
|
413 |
* null |
|
414 |
* @param paramValue |
|
415 |
* the parameter value that we are looking for. this is ignored |
|
416 |
* if null |
|
417 |
* @return an XML representation of the jobs. |
|
418 |
*/ |
|
295 | 419 |
public String getJobsInfoXML(String groupName, String paramName, String paramValue) throws ServiceException { |
296 | 420 |
String jobInfoXML = ""; |
297 | 421 |
|
... | ... | |
319 | 443 |
return jobInfoXML; |
320 | 444 |
} |
321 | 445 |
|
446 |
/** |
|
447 |
* Convert a single job to XML |
|
448 |
* @param scheduledJobDAO the job we want to convert |
|
449 |
* @return an XML representation of the job |
|
450 |
*/ |
|
322 | 451 |
public String jobToXML(ScheduledJobDAO scheduledJobDAO) throws ServiceException { |
323 | 452 |
String jobXML = ""; |
324 | 453 |
|
... | ... | |
361 | 490 |
return jobXML; |
362 | 491 |
} |
363 | 492 |
|
364 |
|
|
493 |
/** |
|
494 |
* Start a job in the scheduler |
|
495 |
* |
|
496 |
* @param jobName |
|
497 |
* the name of the job |
|
498 |
* @param startCal |
|
499 |
* a calendar holding the start date of the job |
|
500 |
* @param intervalValue |
|
501 |
* the run interval for the job |
|
502 |
* @param intervalUnit |
|
503 |
* the unit of the run interval for the job |
|
504 |
* @param jobClassName |
|
505 |
* the job class name |
|
506 |
* @param jobGroup |
|
507 |
* the job group name |
|
508 |
* @param jobParams |
|
509 |
* a map of additional job parameters |
|
510 |
* @param username |
|
511 |
* the user name |
|
512 |
* @param groups |
|
513 |
* the user's group name |
|
514 |
*/ |
|
365 | 515 |
private void startJob(String jobName, Calendar startCal, int intervalValue, String intervalUnit, |
366 | 516 |
Class<Job> jobClass, String jobGroup, HashMap<String, String> jobParams) throws ServiceException { |
367 | 517 |
|
... | ... | |
370 | 520 |
|
371 | 521 |
char intervalChar = intervalUnit.charAt(0); |
372 | 522 |
|
523 |
// call the appropriate scheduling method depending on the schedule interval unit |
|
373 | 524 |
switch (intervalChar) { |
374 | 525 |
case 's': |
375 | 526 |
case 'S': |
... | ... | |
393 | 544 |
} |
394 | 545 |
} |
395 | 546 |
|
547 |
/** |
|
548 |
* Schedule a job in the scheduler that has an interval based in seconds |
|
549 |
* |
|
550 |
* @param jobName |
|
551 |
* the name of the job |
|
552 |
* @param jobClass |
|
553 |
* the job class object |
|
554 |
* @param startTime |
|
555 |
* the time of the first run |
|
556 |
* @param interval |
|
557 |
* the interval in seconds between runs |
|
558 |
* @param jobGroup |
|
559 |
* the group of this job |
|
560 |
* @param jobDetail |
|
561 |
* the job detail object |
|
562 |
*/ |
|
396 | 563 |
private void scheduleSecondlyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException { |
397 | 564 |
|
398 | 565 |
Trigger trigger = TriggerUtils.makeSecondlyTrigger(interval); |
... | ... | |
407 | 574 |
} |
408 | 575 |
} |
409 | 576 |
|
577 |
/** |
|
578 |
* Schedule a job in the scheduler that has an interval based in minutes |
|
579 |
* |
|
580 |
* @param jobName |
|
581 |
* the name of the job |
|
582 |
* @param jobClass |
|
583 |
* the job class object |
|
584 |
* @param startTime |
|
585 |
* the time of the first run |
|
586 |
* @param interval |
|
587 |
* the interval in minutes between runs |
|
588 |
* @param jobGroup |
|
589 |
* the group of this job |
|
590 |
* @param jobDetail |
|
591 |
* the job detail object |
|
592 |
*/ |
|
410 | 593 |
private void scheduleMinutelyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException { |
411 | 594 |
|
412 | 595 |
Trigger trigger = TriggerUtils.makeMinutelyTrigger(interval); |
... | ... | |
421 | 604 |
} |
422 | 605 |
} |
423 | 606 |
|
607 |
/** |
|
608 |
* Schedule a job in the scheduler that has an interval based in hours |
|
609 |
* |
|
610 |
* @param jobName |
|
611 |
* the name of the job |
|
612 |
* @param jobClass |
|
613 |
* the job class object |
|
614 |
* @param startTime |
|
615 |
* the time of the first run |
|
616 |
* @param interval |
|
617 |
* the interval in hours between runs |
|
618 |
* @param jobGroup |
|
619 |
* the group of this job |
|
620 |
* @param jobDetail |
|
621 |
* the job detail object |
|
622 |
*/ |
|
424 | 623 |
private void scheduleHourlyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException { |
425 | 624 |
|
426 | 625 |
Trigger trigger = TriggerUtils.makeHourlyTrigger(interval); |
... | ... | |
435 | 634 |
} |
436 | 635 |
} |
437 | 636 |
|
637 |
/** |
|
638 |
* Schedule a job in the scheduler that has an interval based in days |
|
639 |
* |
|
640 |
* @param jobName |
|
641 |
* the name of the job |
|
642 |
* @param jobClass |
|
643 |
* the job class object |
|
644 |
* @param startTime |
|
645 |
* the time of the first run |
|
646 |
* @param interval |
|
647 |
* the interval in days between runs |
|
648 |
* @param jobGroup |
|
649 |
* the group of this job |
|
650 |
* @param jobDetail |
|
651 |
* the job detail object |
|
652 |
*/ |
|
438 | 653 |
private void scheduleDailyJob(String jobName, Class<Job> jobClass, Calendar startTime, int interval, String jobGroup, JobDetail jobDetail) throws ServiceException { |
439 | 654 |
|
440 | 655 |
Trigger trigger = TriggerUtils.makeHourlyTrigger(interval * 24); |
... | ... | |
449 | 664 |
} |
450 | 665 |
} |
451 | 666 |
|
452 |
|
|
453 |
|
|
667 |
/** |
|
668 |
* Extract the start date from the delay value |
|
669 |
* |
|
670 |
* @param delay |
|
671 |
* a string representing the start delay in <value><unit> |
|
672 |
* notation where value is an integer and unit is one of s,m,h or |
|
673 |
* d |
|
674 |
* @return the calendar object holding the start date |
|
675 |
*/ |
|
454 | 676 |
public Calendar getStartDateFromDelay(String delay) throws ServiceException { |
455 | 677 |
Calendar cal = Calendar.getInstance(); |
456 | 678 |
|
... | ... | |
487 | 709 |
} |
488 | 710 |
|
489 | 711 |
return cal; |
490 |
} |
|
491 |
|
|
492 |
|
|
493 |
|
|
494 |
|
|
495 |
|
|
496 |
|
|
712 |
} |
|
497 | 713 |
} |
Also available in: Unified diff
Beef up comments