| 1 16 17 package org.pentaho.plugin.quartz; 18 19 import java.io.IOException ; 20 import java.text.ParseException ; 21 import java.util.ArrayList ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import org.apache.commons.logging.Log; 25 import org.apache.commons.logging.LogFactory; 26 import org.pentaho.core.session.IPentahoSession; 27 import org.pentaho.messages.Messages; 28 import org.pentaho.plugin.ComponentBase; 29 import org.quartz.CronTrigger; 30 import org.quartz.JobDataMap; 31 import org.quartz.JobDetail; 32 import org.quartz.Scheduler; 33 import org.quartz.SchedulerException; 34 import org.quartz.SimpleTrigger; 35 import org.quartz.Trigger; 36 37 43 public class JobSchedulerComponent extends ComponentBase { 44 45 48 private static final long serialVersionUID = -1770772140985331431L; 49 50 private static final String START_JOB_ACTION_STR = "startJob"; 52 private static final String SUSPEND_JOB_ACTION_STR = "suspendJob"; 54 private static final String DELETE_JOB_ACTION_STR = "deleteJob"; 56 private static final String RESUME_JOB_ACTION_STR = "resumeJob"; 58 private static final String JOB_ACTION_STR = "jobAction"; 60 private static final String SOLUTION_STR = "solution"; 62 private static final String PATH_STR = "path"; 64 private static final String ACTION_STR = "action"; 66 private static final String USER_STR = "username"; 68 private static final String DEFAULT_STR = "default"; 70 private static final String TRIGGER_TYPE_STR = "triggerType"; 72 private static final String CRON_TRIGGER_TYPE_STR = "cron"; 74 private static final String DEFAULT_CRON_EXP_STR = "0 0 12 * * ?"; 76 private static final String TRIGGER_CRON_STR = "cronString"; 78 private static final String SIMPLE_TRIGGER_TYPE_STR = "simple"; 80 private static final String TRIGGER_NAME_STR = "triggerName"; 82 private static final String REPEAT_INTERVAL_STR = "repeatInterval"; 84 private static final String REPEAT_COUNT_STR = "repeatCount"; 86 private static final String JOB_NAME_STR = "jobName"; 88 private static final String MISFIRE_POLICY = "misfirePolicy"; 91 private static final String INSTRUCTION_NOOP = "INSTRUCTION_NOOP"; 93 private static final String INSTRUCTION_RE_EXECUTE_JOB = "INSTRUCTION_RE_EXECUTE_JOB"; 95 private static final String INSTRUCTION_DELETE_TRIGGER = "INSTRUCTION_DELETE_TRIGGER"; 97 private static final String INSTRUCTION_SET_TRIGGER_COMPLETE = "INSTRUCTION_SET_TRIGGER_COMPLETE"; 99 private static final String INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE = "INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE"; 101 private static final String MISFIRE_INSTRUCTION_SMART_POLICY = "MISFIRE_INSTRUCTION_SMART_POLICY"; 103 private static final String MISFIRE_INSTRUCTION_FIRE_NOW = "MISFIRE_INSTRUCTION_FIRE_NOW"; 106 private static final String MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = "MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT"; 108 private static final String MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = "MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT"; 110 private static final String MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = "MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT"; 112 private static final String MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = "MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT"; 114 private static final String MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = "MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"; 117 private static final String MISFIRE_INSTRUCTION_DO_NOTHING = "MISFIRE_INSTRUCTION_DO_NOTHING"; 119 private Scheduler sched = null; 120 121 private List localInputNames = new ArrayList (); 122 123 128 public boolean init() { 129 localInputNames.add(JOB_ACTION_STR); 130 localInputNames.add(SOLUTION_STR); 131 localInputNames.add(PATH_STR); 132 localInputNames.add(ACTION_STR); 133 localInputNames.add(TRIGGER_TYPE_STR); 134 localInputNames.add(TRIGGER_NAME_STR); 135 localInputNames.add(REPEAT_INTERVAL_STR); 136 localInputNames.add(REPEAT_COUNT_STR); 137 localInputNames.add(JOB_NAME_STR); 138 localInputNames.add(TRIGGER_CRON_STR); 139 try { 140 sched = QuartzSystemListener.getSchedulerInstance(); 141 } catch (Exception e) { 142 error(Messages.getErrorString("JobSchedulerComponent.ERROR_0001_NoScheduler"), e); return false; 144 } 145 return true; 146 } 147 148 153 protected boolean validateAction() { 154 if (!isDefinedInput(JOB_ACTION_STR)) { 155 return false; 156 } 157 return true; 158 } 159 160 165 protected boolean validateSystemSettings() { 166 return true; 167 } 168 169 174 public void done() { 175 sched = null; 176 } 177 178 183 protected boolean executeAction() { 184 185 String jobAction = null; 186 jobAction = getInputStringValue(JOB_ACTION_STR); 187 188 if (START_JOB_ACTION_STR.equals(jobAction)) { 189 JobDetail jobDetail = createJobDetail(); 190 Trigger trigger = createTrigger(); 191 if (trigger == null || jobDetail == null) { 192 error(Messages.getErrorString("JobSchedulerComponent.ERROR_0002_UnableToCreateTriggerOrJob")); return false; 194 } 195 return startJob(jobDetail, trigger); 196 } else if (SUSPEND_JOB_ACTION_STR.equals(jobAction)) { 197 return suspendJob(getJobName(), Scheduler.DEFAULT_GROUP); 198 } else if (DELETE_JOB_ACTION_STR.equals(jobAction)) { 199 return deleteJob(getJobName(), Scheduler.DEFAULT_GROUP); 200 } else if (RESUME_JOB_ACTION_STR.equals(jobAction)) { 201 return resumeJob(getJobName(), Scheduler.DEFAULT_GROUP); 202 } else { 203 return false; 204 } 205 } 206 207 212 public Log getLogger() { 213 return LogFactory.getLog(JobSchedulerComponent.class); 214 } 215 216 219 private JobDetail createJobDetail() { 220 String jobName = getJobName(); 221 JobDetail jobDetail = new JobDetail(jobName, Scheduler.DEFAULT_GROUP, QuartzExecute.class); 222 JobDataMap jdm = jobDetail.getJobDataMap(); 223 jdm.put(SOLUTION_STR, getInputStringValue(SOLUTION_STR)); 224 jdm.put(PATH_STR, getInputStringValue(PATH_STR) == null ? "" : getInputStringValue(PATH_STR)); jdm.put(ACTION_STR, getInputStringValue(ACTION_STR)); 227 IPentahoSession session = this.getSession(); 229 if ( (session != null) && (session.isAuthenticated()) ) { 230 jdm.put(USER_STR, session.getName()); 231 } 232 Iterator inputNamesIterator = getInputNames().iterator(); 233 while (inputNamesIterator.hasNext()) { 234 String inputName = (String ) inputNamesIterator.next(); 235 if (!localInputNames.contains(inputName)) { 236 Object inputValue = getInputValue(inputName); 237 jobDetail.getJobDataMap().put(inputName, inputValue); 238 } 239 } 240 241 return jobDetail; 242 } 243 244 247 private Trigger createTrigger() { 248 Trigger trigger = null; 249 String triggerType = SIMPLE_TRIGGER_TYPE_STR; 250 if (isDefinedInput(TRIGGER_TYPE_STR)) { 251 triggerType = getInputStringValue(TRIGGER_TYPE_STR); 252 } 253 if (triggerType.equals(SIMPLE_TRIGGER_TYPE_STR)) { 254 trigger = createSimpleTrigger(); 255 } else if (triggerType.equals(CRON_TRIGGER_TYPE_STR)) { 256 trigger = createCRONTrigger(); 257 } 258 addMisfireInstruction(trigger); 259 return trigger; 260 } 261 262 private Trigger createSimpleTrigger() { 263 String triggerName = DEFAULT_STR; 264 if (isDefinedInput(TRIGGER_NAME_STR)) { 265 triggerName = getInputStringValue(TRIGGER_NAME_STR); 266 } 267 long repeatInterval = 0; 268 int repeatCount = SimpleTrigger.REPEAT_INDEFINITELY; 269 if (isDefinedInput(REPEAT_INTERVAL_STR)) { 270 repeatInterval = Long.valueOf(getInputStringValue(REPEAT_INTERVAL_STR)).longValue() * 1000; } 275 if (isDefinedInput(REPEAT_COUNT_STR)) { 276 repeatCount = Integer.valueOf(getInputStringValue(REPEAT_COUNT_STR)).intValue(); 277 } 278 Trigger trigger = new SimpleTrigger(triggerName, Scheduler.DEFAULT_GROUP, repeatCount, repeatInterval); 279 return trigger; 280 } 281 282 private Trigger createCRONTrigger() { 283 284 String triggerName = DEFAULT_STR; 285 if (isDefinedInput(TRIGGER_NAME_STR)) { 286 triggerName = getInputStringValue(TRIGGER_NAME_STR); 287 } 288 String cronExpression = DEFAULT_CRON_EXP_STR; 289 if (isDefinedInput(TRIGGER_CRON_STR)) { 290 cronExpression = getInputStringValue(TRIGGER_CRON_STR); 291 } 292 try { 293 Trigger trigger = new CronTrigger(triggerName, Scheduler.DEFAULT_GROUP, cronExpression); 294 return trigger; 295 } catch (ParseException e) { 296 error(Messages.getErrorString("JobSchedulerComponent.ERROR_0003_UnableToParse", cronExpression), e); return null; 298 } 299 } 300 301 304 private void addMisfireInstruction(Trigger trigger) { 305 306 String misfirePolicy = MISFIRE_INSTRUCTION_SMART_POLICY; 307 if (isDefinedInput(MISFIRE_POLICY)) { 308 misfirePolicy = getInputStringValue(MISFIRE_POLICY); 309 } 310 311 trigger.setMisfireInstruction(Trigger.MISFIRE_INSTRUCTION_SMART_POLICY); if (misfirePolicy.equalsIgnoreCase(INSTRUCTION_RE_EXECUTE_JOB)) { 313 trigger.setMisfireInstruction(Trigger.INSTRUCTION_RE_EXECUTE_JOB); 314 } else if (misfirePolicy.equals(INSTRUCTION_DELETE_TRIGGER)) { 315 trigger.setMisfireInstruction(Trigger.INSTRUCTION_DELETE_TRIGGER); 316 } else if (misfirePolicy.equals(INSTRUCTION_SET_TRIGGER_COMPLETE)) { 317 trigger.setMisfireInstruction(Trigger.INSTRUCTION_SET_TRIGGER_COMPLETE); 318 } else if (misfirePolicy.equals(INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE)) { 319 trigger.setMisfireInstruction(Trigger.INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE); 320 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_SMART_POLICY)) { 321 trigger.setMisfireInstruction(Trigger.MISFIRE_INSTRUCTION_SMART_POLICY); 322 } else if (misfirePolicy.equals(INSTRUCTION_NOOP)) { 323 trigger.setMisfireInstruction(Trigger.INSTRUCTION_NOOP); 324 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_FIRE_NOW) && (trigger instanceof SimpleTrigger)) { 325 trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW); 326 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT) && (trigger instanceof SimpleTrigger)) { 327 trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT); 328 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT) && (trigger instanceof SimpleTrigger)) { 329 trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT); 330 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT) && (trigger instanceof SimpleTrigger)) { 331 trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT); 332 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT) && (trigger instanceof SimpleTrigger)) { 333 trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT); 334 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) && (trigger instanceof CronTrigger)) { 335 trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW); 336 } else if (misfirePolicy.equals(MISFIRE_INSTRUCTION_DO_NOTHING) && (trigger instanceof CronTrigger)) { 337 trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); 338 } 339 } 340 341 344 private String getJobName() { 345 String jobName = DEFAULT_STR; 346 if (isDefinedInput(JOB_NAME_STR)) { 347 jobName = getInputStringValue(JOB_NAME_STR); 348 } 349 return jobName; 350 } 351 352 public boolean startJob(JobDetail jobDetail, Trigger trigger) { 353 try { if (sched.getJobDetail(jobDetail.getName(), Scheduler.DEFAULT_GROUP) != null) { 355 deleteJob(jobDetail.getName(), Scheduler.DEFAULT_GROUP); 356 } 357 sched.scheduleJob(jobDetail, trigger); 358 getFeedbackOutputStream().write(Messages.getString("JobSchedulerComponent.INFO_0001").getBytes()); } catch (SchedulerException e) { 360 error(e.getLocalizedMessage()); 361 return false; 362 } catch (IOException e) { 363 error(e.getLocalizedMessage()); 364 return false; 365 } 366 return true; 367 } 368 369 public boolean suspendJob(String jobName, String groupName) { 370 try { 371 sched.pauseJob(jobName, groupName); 372 } catch (SchedulerException e) { 373 error(e.getLocalizedMessage()); 374 return false; 375 } 376 return true; 377 } 378 379 public boolean deleteJob(String jobName, String groupName) { 380 try { 381 sched.deleteJob(jobName, groupName); 382 } catch (SchedulerException e) { 383 error(e.getLocalizedMessage()); 384 return false; 385 } 386 return true; 387 } 388 389 public boolean resumeJob(String jobName, String groupName) { 390 try { 391 sched.resumeJob(jobName, groupName); 392 } catch (SchedulerException e) { 393 error(e.getLocalizedMessage()); 394 return false; 395 } 396 return true; 397 } 398 } 399 | Popular Tags |