1 31 32 package org.opencms.scheduler; 33 34 import org.opencms.file.CmsObject; 35 import org.opencms.i18n.CmsMessageContainer; 36 import org.opencms.main.CmsLog; 37 import org.opencms.main.OpenCms; 38 import org.opencms.security.CmsRole; 39 import org.opencms.security.CmsRoleViolationException; 40 import org.opencms.util.CmsStringUtil; 41 import org.opencms.util.CmsUUID; 42 43 import java.text.ParseException ; 44 import java.util.ArrayList ; 45 import java.util.Collections ; 46 import java.util.Date ; 47 import java.util.Iterator ; 48 import java.util.List ; 49 import java.util.Properties ; 50 51 import org.apache.commons.logging.Log; 52 53 import org.quartz.CronTrigger; 54 import org.quartz.Job; 55 import org.quartz.JobDataMap; 56 import org.quartz.JobDetail; 57 import org.quartz.JobExecutionContext; 58 import org.quartz.Scheduler; 59 import org.quartz.SchedulerException; 60 import org.quartz.SchedulerFactory; 61 import org.quartz.impl.StdSchedulerFactory; 62 63 85 public class CmsScheduleManager implements Job { 86 87 88 public static final String SCHEDULER_JOB_INFO = "org.opencms.scheduler.CmsScheduledJobInfo"; 89 90 91 private static final Log LOG = CmsLog.getLog(CmsScheduleManager.class); 92 93 94 private static CmsObject m_adminCms; 95 96 97 private List m_configuredJobs; 98 99 100 private List m_jobs; 101 102 103 private Scheduler m_scheduler; 104 105 109 public CmsScheduleManager() { 110 111 } 114 115 120 public CmsScheduleManager(List configuredJobs) { 121 122 m_configuredJobs = configuredJobs; 123 int size = 0; 124 if (m_configuredJobs != null) { 125 size = m_configuredJobs.size(); 126 } 127 128 if (CmsLog.INIT.isInfoEnabled()) { 129 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SCHEDULER_CREATED_1, new Integer (size))); 130 } 131 } 132 133 143 public void execute(JobExecutionContext context) { 144 145 JobDataMap jobData = context.getJobDetail().getJobDataMap(); 146 CmsScheduledJobInfo jobInfo = (CmsScheduledJobInfo)jobData.get(SCHEDULER_JOB_INFO); 147 148 if (jobInfo == null) { 149 LOG.error(Messages.get().getBundle().key(Messages.LOG_INVALID_JOB_1, context.getJobDetail().getFullName())); 150 return; 152 } 153 154 if (LOG.isDebugEnabled()) { 155 LOG.debug(Messages.get().getBundle().key(Messages.LOG_JOB_STARTING_1, jobInfo.getJobName())); 156 } 157 158 I_CmsScheduledJob job = jobInfo.getJobInstance(); 159 160 if (job != null) { 161 try { 162 CmsObject cms = null; 164 165 if (m_adminCms != null) { 167 cms = OpenCms.initCmsObject(m_adminCms, jobInfo.getContextInfo()); 169 } 170 171 String result = job.launch(cms, jobInfo.getParameters()); 172 if (CmsStringUtil.isNotEmpty(result) && LOG.isInfoEnabled()) { 173 LOG.info(Messages.get().getBundle().key( 174 Messages.LOG_JOB_EXECUTION_OK_2, 175 jobInfo.getJobName(), 176 result)); 177 } 178 } catch (Throwable t) { 179 LOG.error(Messages.get().getBundle().key(Messages.LOG_JOB_EXECUTION_ERROR_1, jobInfo.getJobName()), t); 180 } 181 } 182 183 if (LOG.isDebugEnabled()) { 184 LOG.debug(Messages.get().getBundle().key(Messages.LOG_JOB_EXECUTED_1, jobInfo.getJobName())); 185 Date nextExecution = jobInfo.getExecutionTimeNext(); 186 if (nextExecution != null) { 187 LOG.info(Messages.get().getBundle().key( 188 Messages.LOG_JOB_NEXT_EXECUTION_2, 189 jobInfo.getJobName(), 190 nextExecution)); 191 } 192 } 193 } 194 195 202 public CmsScheduledJobInfo getJob(String id) { 203 204 Iterator it = m_jobs.iterator(); 205 while (it.hasNext()) { 206 CmsScheduledJobInfo job = (CmsScheduledJobInfo)it.next(); 207 if (job.getId().equals(id)) { 208 return job; 209 } 210 } 211 return null; 213 } 214 215 222 public List getJobs() { 223 224 return Collections.unmodifiableList(m_jobs); 225 } 226 227 234 public synchronized void initialize(CmsObject cms) throws CmsRoleViolationException { 235 236 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { 237 cms.checkRole(CmsRole.SCHEDULER_MANAGER); 239 } 240 241 m_jobs = new ArrayList (); 243 244 m_adminCms = cms; 246 247 Properties properties = new Properties (); 249 properties.put(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, "OpenCmsScheduler"); 250 properties.put(StdSchedulerFactory.PROP_SCHED_THREAD_NAME, "OpenCms: Scheduler"); 251 properties.put(StdSchedulerFactory.PROP_SCHED_RMI_EXPORT, CmsStringUtil.FALSE); 252 properties.put(StdSchedulerFactory.PROP_SCHED_RMI_PROXY, CmsStringUtil.FALSE); 253 properties.put(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, CmsSchedulerThreadPool.class.getName()); 254 properties.put(StdSchedulerFactory.PROP_JOB_STORE_CLASS, "org.quartz.simpl.RAMJobStore"); 255 256 try { 257 SchedulerFactory schedulerFactory = new StdSchedulerFactory(properties); 259 m_scheduler = schedulerFactory.getScheduler(); 260 } catch (Exception e) { 261 LOG.error(Messages.get().getBundle().key(Messages.LOG_NO_SCHEDULER_0), e); 262 m_scheduler = null; 264 return; 265 } 266 267 if (CmsLog.INIT.isInfoEnabled()) { 268 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SCHEDULER_INITIALIZED_0)); 269 } 270 271 if (m_configuredJobs != null) { 272 for (int i = 0; i < m_configuredJobs.size(); i++) { 274 try { 275 CmsScheduledJobInfo job = (CmsScheduledJobInfo)m_configuredJobs.get(i); 276 scheduleJob(cms, job); 277 } catch (CmsSchedulerException e) { 278 } 281 } 282 } 283 284 try { 285 m_scheduler.start(); 287 } catch (Exception e) { 288 LOG.error(Messages.get().getBundle().key(Messages.LOG_CANNOT_START_SCHEDULER_0), e); 289 m_scheduler = null; 291 return; 292 } 293 294 if (CmsLog.INIT.isInfoEnabled()) { 295 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SCHEDULER_STARTED_0)); 296 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SCHEDULER_CONFIG_FINISHED_0)); 297 } 298 } 299 300 309 public synchronized void scheduleJob(CmsObject cms, CmsScheduledJobInfo jobInfo) 310 throws CmsRoleViolationException, CmsSchedulerException { 311 312 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { 313 cms.checkRole(CmsRole.SCHEDULER_MANAGER); 315 } 316 317 if ((jobInfo == null) || (jobInfo.getClassName() == null)) { 318 CmsMessageContainer message = Messages.get().container(Messages.ERR_INVALID_JOB_CONFIGURATION_0); 320 LOG.error(message.key()); 321 throw new CmsSchedulerException(message); 323 } 324 325 if (m_scheduler == null) { 326 CmsMessageContainer message = Messages.get().container(Messages.ERR_NO_SCHEDULER_1, jobInfo.getJobName()); 327 LOG.error(message.key()); 328 throw new CmsSchedulerException(message); 330 } 331 332 Class jobClass; 333 try { 334 jobClass = Class.forName(jobInfo.getClassName()); 335 } catch (ClassNotFoundException e) { 336 CmsMessageContainer message = Messages.get().container( 338 Messages.ERR_JOB_CLASS_NOT_FOUND_1, 339 jobInfo.getClassName()); 340 LOG.error(message.key()); 341 throw new CmsSchedulerException(message); 342 } 343 if (!I_CmsScheduledJob.class.isAssignableFrom(jobClass)) { 344 CmsMessageContainer message = Messages.get().container( 346 Messages.ERR_JOB_CLASS_BAD_INTERFACE_2, 347 jobInfo.getClassName(), 348 I_CmsScheduledJob.class.getName()); 349 LOG.error(message.key()); 350 throw new CmsSchedulerException(message); 351 } 352 353 String jobId = jobInfo.getId(); 354 boolean idCreated = false; 355 if (jobId == null) { 356 CmsUUID jobUUID = new CmsUUID(); 358 jobId = "OpenCmsJob_".concat(jobUUID.toString()); 359 jobInfo.setId(jobId); 360 idCreated = true; 361 } 362 363 CronTrigger trigger = new CronTrigger(jobId, Scheduler.DEFAULT_GROUP); 365 366 try { 367 trigger.setCronExpression(jobInfo.getCronExpression()); 368 } catch (ParseException e) { 369 if (idCreated) { 370 jobInfo.setId(null); 371 } 372 CmsMessageContainer message = Messages.get().container( 373 Messages.ERR_BAD_CRON_EXPRESSION_2, 374 jobInfo.getJobName(), 375 jobInfo.getCronExpression()); 376 LOG.error(message.key()); 377 throw new CmsSchedulerException(message); 379 } 380 381 CmsScheduledJobInfo oldJob = null; 382 if (!idCreated) { 383 oldJob = unscheduleJob(cms, jobId); 387 if (oldJob == null) { 388 CmsMessageContainer message = Messages.get().container(Messages.ERR_JOB_WITH_ID_DOES_NOT_EXIST_1, jobId); 389 LOG.warn(message.key()); 390 throw new CmsSchedulerException(message); 392 } 393 jobInfo.setFrozen(false); 395 } 396 397 if (jobInfo.isActive()) { 399 400 JobDetail jobDetail = new JobDetail(jobInfo.getId(), Scheduler.DEFAULT_GROUP, CmsScheduleManager.class); 402 403 jobInfo.setTrigger(trigger); 405 406 JobDataMap jobData = new JobDataMap(); 408 jobData.put(CmsScheduleManager.SCHEDULER_JOB_INFO, jobInfo); 409 jobDetail.setJobDataMap(jobData); 410 411 try { 413 m_scheduler.scheduleJob(jobDetail, trigger); 414 } catch (Exception e) { 415 if (LOG.isDebugEnabled()) { 416 LOG.debug(e.getMessage(), e); 417 } 418 if (idCreated) { 419 jobInfo.setId(null); 420 } 421 CmsMessageContainer message = Messages.get().container( 422 Messages.ERR_COULD_NOT_SCHEDULE_JOB_2, 423 jobInfo.getJobName(), 424 jobInfo.getClassName()); 425 if (oldJob != null) { 426 jobDetail = new JobDetail(oldJob.getId(), Scheduler.DEFAULT_GROUP, CmsScheduleManager.class); 428 jobDetail.setJobDataMap(jobData); 429 try { 430 m_scheduler.scheduleJob(jobDetail, oldJob.getTrigger()); 431 m_jobs.add(oldJob); 432 } catch (SchedulerException e2) { 433 if (LOG.isDebugEnabled()) { 434 LOG.debug(e2.getMessage(), e2); 435 } 436 message = Messages.get().container( 438 Messages.ERR_COULD_NOT_RESCHEDULE_JOB_2, 439 jobInfo.getJobName(), 440 jobInfo.getClassName()); 441 } 442 } 443 if (LOG.isWarnEnabled()) { 444 LOG.warn(message.key()); 445 } 446 throw new CmsSchedulerException(message); 447 } 448 } 449 450 jobInfo.initConfiguration(); 452 453 m_jobs.add(jobInfo); 455 456 if (LOG.isInfoEnabled()) { 457 LOG.info(Messages.get().getBundle().key( 458 Messages.LOG_JOB_SCHEDULED_4, 459 new Object [] { 460 new Integer (m_jobs.size()), 461 jobInfo.getJobName(), 462 jobInfo.getClassName(), 463 jobInfo.getContextInfo().getUserName()})); 464 Date nextExecution = jobInfo.getExecutionTimeNext(); 465 if (nextExecution != null) { 466 LOG.info(Messages.get().getBundle().key( 467 Messages.LOG_JOB_NEXT_EXECUTION_2, 468 jobInfo.getJobName(), 469 nextExecution)); 470 } 471 } 472 } 473 474 477 public synchronized void shutDown() { 478 479 m_adminCms = null; 480 481 if (CmsLog.INIT.isInfoEnabled()) { 482 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SHUTDOWN_1, this.getClass().getName())); 483 } 484 485 if (m_scheduler != null) { 486 try { 487 m_scheduler.shutdown(); 488 } catch (SchedulerException e) { 489 LOG.error(Messages.get().getBundle().key(Messages.LOG_SHUTDOWN_ERROR_0)); 490 } 491 } 492 493 m_scheduler = null; 494 } 495 496 507 public synchronized CmsScheduledJobInfo unscheduleJob(CmsObject cms, String jobId) throws CmsRoleViolationException { 508 509 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_1_CORE_OBJECT) { 510 cms.checkRole(CmsRole.SCHEDULER_MANAGER); 512 } 513 514 CmsScheduledJobInfo jobInfo = null; 515 if (m_jobs.size() > 0) { 516 for (int i = (m_jobs.size() - 1); i >= 0; i--) { 518 CmsScheduledJobInfo job = (CmsScheduledJobInfo)m_jobs.get(i); 519 if (jobId.equals(job.getId())) { 520 m_jobs.remove(i); 521 if (jobInfo != null) { 522 LOG.error(Messages.get().getBundle().key(Messages.LOG_MULTIPLE_JOBS_FOUND_1, jobId)); 523 } 524 jobInfo = job; 525 } 526 } 527 } 528 529 if ((jobInfo != null) && jobInfo.isActive()) { 530 try { 532 m_scheduler.unscheduleJob(jobId, Scheduler.DEFAULT_GROUP); 534 if (LOG.isDebugEnabled()) { 535 LOG.debug(Messages.get().getBundle().key(Messages.LOG_UNSCHEDULED_JOB_1, jobId)); 536 } 537 } catch (SchedulerException e) { 538 if (LOG.isDebugEnabled()) { 539 LOG.debug(Messages.get().getBundle().key(Messages.LOG_UNSCHEDULING_ERROR_1, jobId)); 540 } 541 } 542 } 543 544 return jobInfo; 545 } 546 } | Popular Tags |