Search in sources :

Example 31 with JobKey

use of org.quartz.JobKey in project midpoint by Evolveum.

the class TaskManagerQuartzImpl method onTaskDelete.

@Override
public void onTaskDelete(String oid, OperationResult parentResult) {
    OperationResult result = parentResult.createSubresult(DOT_INTERFACE + "onTaskDelete");
    result.addParam("oid", oid);
    LOGGER.trace("onTaskDelete called for oid = " + oid);
    JobKey jobKey = TaskQuartzImplUtil.createJobKeyForTaskOid(oid);
    try {
        if (executionManager.getQuartzScheduler().checkExists(jobKey)) {
            // removes triggers as well
            executionManager.getQuartzScheduler().deleteJob(jobKey);
        }
    } catch (SchedulerException e) {
        String message = "Quartz shadow job cannot be removed; oid = " + oid;
        LoggingUtils.logUnexpectedException(LOGGER, message, e);
        result.recordFatalError(message);
    }
    result.recordSuccessIfUnknown();
}
Also used : JobKey(org.quartz.JobKey) SchedulerException(org.quartz.SchedulerException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PolyString(com.evolveum.midpoint.prism.polystring.PolyString)

Example 32 with JobKey

use of org.quartz.JobKey in project midpoint by Evolveum.

the class TaskSynchronizer method synchronizeTask.

/**
     * Task should be refreshed when entering this method.
     *
     * @return true if task info in Quartz was updated
     */
public boolean synchronizeTask(TaskQuartzImpl task, OperationResult parentResult) {
    if (!task.isPersistent()) {
        // transient tasks are not scheduled via Quartz!
        return false;
    }
    boolean changed = false;
    String message = "";
    OperationResult result = parentResult.createSubresult(TaskSynchronizer.class.getName() + ".synchronizeTask");
    result.addArbitraryObjectAsParam("task", task);
    try {
        LOGGER.trace("Synchronizing task {}; isRecreateQuartzTrigger = {}", task, task.isRecreateQuartzTrigger());
        Scheduler scheduler = taskManager.getExecutionManager().getQuartzScheduler();
        String oid = task.getOid();
        JobKey jobKey = TaskQuartzImplUtil.createJobKeyForTask(task);
        TriggerKey standardTriggerKey = TaskQuartzImplUtil.createTriggerKeyForTask(task);
        boolean waitingOrClosedOrSuspended = task.getExecutionStatus() == TaskExecutionStatus.WAITING || task.getExecutionStatus() == TaskExecutionStatus.CLOSED || task.getExecutionStatus() == TaskExecutionStatus.SUSPENDED;
        if (!scheduler.checkExists(jobKey) && !waitingOrClosedOrSuspended) {
            String m1 = "Quartz job does not exist for a task, adding it. Task = " + task;
            message += "[" + m1 + "] ";
            LOGGER.trace(" - " + m1);
            scheduler.addJob(TaskQuartzImplUtil.createJobDetailForTask(task), false);
            changed = true;
        }
        // WAITING and CLOSED tasks should have no triggers; SUSPENDED tasks should have no extra triggers
        List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
        boolean standardTriggerExists = triggers.stream().anyMatch(t -> t.getKey().equals(standardTriggerKey));
        if (waitingOrClosedOrSuspended) {
            for (Trigger trigger : triggers) {
                if (task.getExecutionStatus() != TaskExecutionStatus.SUSPENDED || !trigger.getKey().equals(standardTriggerKey)) {
                    String m1 = "Removing Quartz trigger " + trigger.getKey() + " for WAITING/CLOSED/SUSPENDED task " + task;
                    message += "[" + m1 + "] ";
                    LOGGER.trace(" - " + m1);
                    scheduler.unscheduleJob(trigger.getKey());
                    changed = true;
                } else {
                // For SUSPENDED tasks, we keep the standard trigger untouched. We want to preserve original
                // scheduled time. (This might or might not be what the user wants ... but it has been so for so
                // many years, so let's not change it now.)
                //
                // It's harmless to keep the standard trigger, because:
                // 1) If a trigger is mistakenly alive, JobExecutor will take care of it.
                // 2) If a trigger has wrong parameters, this will be corrected on task resume.
                }
            }
        } else if (task.getExecutionStatus() == TaskExecutionStatus.RUNNABLE) {
            Trigger triggerToBe;
            try {
                triggerToBe = TaskQuartzImplUtil.createTriggerForTask(task);
            } catch (ParseException e) {
                String message2 = "Cannot create a trigger for a task " + this + " because of a cron expression parsing exception";
                LoggingUtils.logUnexpectedException(LOGGER, message2, e);
                result.recordFatalError(message2, e);
                // TODO: implement error handling correctly
                throw new SystemException("Cannot a trigger for a task because of a cron expression parsing exception", e);
            }
            if (triggerToBe == null) {
                if (standardTriggerExists) {
                    // TODO what about non-standard triggers?
                    // These may be legal here (e.g. for a manually-run recurring task waiting to get a chance to run)
                    String m1 = "Removing standard Quartz trigger for RUNNABLE task that should not have it; task = " + task;
                    message += "[" + m1 + "] ";
                    LOGGER.trace(" - " + m1);
                    scheduler.unscheduleJob(TriggerKey.triggerKey(oid));
                    changed = true;
                }
            } else {
                // if the trigger should exist and it does not...
                if (!standardTriggerExists) {
                    String m1 = "Creating standard trigger for a RUNNABLE task " + task;
                    LOGGER.trace(" - " + m1);
                    message += "[" + m1 + "] ";
                    scheduler.scheduleJob(triggerToBe);
                    changed = true;
                } else {
                    // we have to compare trigger parameters with the task's ones
                    Trigger triggerAsIs = scheduler.getTrigger(standardTriggerKey);
                    if (task.isRecreateQuartzTrigger() || TaskQuartzImplUtil.triggerDataMapsDiffer(triggerAsIs, triggerToBe)) {
                        String m1 = "Existing trigger has incompatible parameters or was explicitly requested to be recreated; recreating it. Task = " + task;
                        LOGGER.trace(" - " + m1);
                        message += "[" + m1 + "] ";
                        scheduler.rescheduleJob(standardTriggerKey, triggerToBe);
                        changed = true;
                    } else {
                        String m1 = "Existing trigger is OK, leaving it as is; task = " + task;
                        LOGGER.trace(" - " + m1);
                        message += "[" + m1 + "] ";
                        Trigger.TriggerState state = scheduler.getTriggerState(standardTriggerKey);
                        if (state == Trigger.TriggerState.PAUSED) {
                            String m2 = "However, the trigger is paused, resuming it; task = " + task;
                            LOGGER.trace(" - " + m2);
                            message += "[" + m2 + "] ";
                            scheduler.resumeTrigger(standardTriggerKey);
                            changed = true;
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        // todo make this more specific (originally here was SchedulerException but e.g. for negative repeat intervals here we get unchecked IllegalArgumentException...)
        String message2 = "Cannot synchronize repository/Quartz Job Store information for task " + task;
        LoggingUtils.logUnexpectedException(LOGGER, message2, e);
        result.recordFatalError(message2, e);
    }
    if (result.isUnknown()) {
        result.computeStatus();
        result.recordStatus(result.getStatus(), message);
    }
    return changed;
}
Also used : TriggerKey(org.quartz.TriggerKey) JobKey(org.quartz.JobKey) Trigger(org.quartz.Trigger) SystemException(com.evolveum.midpoint.util.exception.SystemException) Scheduler(org.quartz.Scheduler) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ParseException(java.text.ParseException) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) SchedulerException(org.quartz.SchedulerException) ParseException(java.text.ParseException) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) SystemException(com.evolveum.midpoint.util.exception.SystemException)

Example 33 with JobKey

use of org.quartz.JobKey in project midpoint by Evolveum.

the class TaskSynchronizer method synchronizeJobStores.

/**
     * Checks for consistency between Quartz job store and midPoint repository.
     * In case of conflict, the latter is taken as authoritative source.
     *
     * (For RAM Job Store, running this method at startup effectively means that tasks from midPoint repo are imported into Quartz job store.)
     *
     */
boolean synchronizeJobStores(OperationResult parentResult) {
    OperationResult result = parentResult.createSubresult(this.getClass().getName() + ".synchronizeJobStores");
    Scheduler scheduler = taskManager.getExecutionManager().getQuartzScheduler();
    LOGGER.info("Synchronizing Quartz job store with midPoint repository.");
    List<PrismObject<TaskType>> tasks;
    try {
        tasks = getRepositoryService().searchObjects(TaskType.class, new ObjectQuery(), null, result);
    } catch (SchemaException | RuntimeException e) {
        LoggingUtils.logUnexpectedException(LOGGER, "Synchronization cannot be done, because tasks cannot be listed from the repository.", e);
        return false;
    }
    LOGGER.trace("There are {} task(s) in repository", tasks.size());
    // check consistency of tasks present in repo
    Set<String> oidsInRepo = new HashSet<>();
    int processed = 0;
    int changed = 0;
    int errors = 0;
    for (PrismObject<TaskType> taskPrism : tasks) {
        if (taskPrism.getOid() == null) {
            LOGGER.error("Skipping task with no OID: {}", taskPrism);
            errors++;
            continue;
        }
        oidsInRepo.add(taskPrism.getOid());
        TaskQuartzImpl task;
        try {
            // in order for the task to be "fresh"
            task = (TaskQuartzImpl) taskManager.getTask(taskPrism.getOid(), result);
            if (synchronizeTask(task, result)) {
                // todo are we sure that we increment this counter only for successfully processed tasks? we hope so :)
                changed++;
            }
        } catch (SchemaException e) {
            LoggingUtils.logUnexpectedException(LOGGER, "Task Manager cannot synchronize task {} due to schema exception.", e, taskPrism.getOid());
        } catch (ObjectNotFoundException e) {
            LoggingUtils.logException(LOGGER, "Task Manager cannot synchronize task {} because it does not exist", e, taskPrism.getOid());
        }
        if (result.getLastSubresultStatus() == OperationResultStatus.SUCCESS) {
            processed++;
        } else {
            errors++;
        }
    }
    // remove non-existing tasks
    int removed = 0;
    Set<JobKey> jobs = null;
    try {
        jobs = new HashSet<>(scheduler.getJobKeys(jobGroupEquals(JobKey.DEFAULT_GROUP)));
    } catch (SchedulerException e) {
        String message = "Cannot list jobs from Quartz scheduler, skipping second part of synchronization procedure.";
        LoggingUtils.logUnexpectedException(LOGGER, message, e);
        result.recordPartialError(message, e);
    }
    if (jobs != null) {
        LOGGER.trace("There are {} job(s) in Quartz job store", jobs.size());
        for (JobKey job : jobs) {
            if (!oidsInRepo.contains(job.getName()) && !RemoteNodesManager.STARTER_JOB_KEY.equals(job)) {
                LOGGER.info("Task " + job.getName() + " is not in repository, removing from Quartz job store.");
                try {
                    scheduler.deleteJob(job);
                    removed++;
                } catch (SchedulerException e) {
                    String message = "Cannot remove job " + job.getName() + " from Quartz job store";
                    LoggingUtils.logUnexpectedException(LOGGER, message, e);
                    result.createSubresult("deleteQuartzJob").recordPartialError(message, e);
                    errors++;
                }
            }
        }
    }
    String resultMessage = "Synchronization of midpoint and Quartz task store finished. " + processed + " task(s) existing in midPoint repository successfully processed, resulting in " + changed + " updated Quartz job(s). " + removed + " task(s) removed from Quartz job store. Processing of " + errors + " task(s) failed.";
    LOGGER.info(resultMessage);
    if (result.isUnknown()) {
        result.recordStatus(OperationResultStatus.SUCCESS, resultMessage);
    }
    return true;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) SchedulerException(org.quartz.SchedulerException) Scheduler(org.quartz.Scheduler) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ObjectQuery(com.evolveum.midpoint.prism.query.ObjectQuery) PrismObject(com.evolveum.midpoint.prism.PrismObject) JobKey(org.quartz.JobKey) TaskType(com.evolveum.midpoint.xml.ns._public.common.common_3.TaskType) TaskQuartzImpl(com.evolveum.midpoint.task.quartzimpl.TaskQuartzImpl) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) HashSet(java.util.HashSet)

Example 34 with JobKey

use of org.quartz.JobKey in project midpoint by Evolveum.

the class TestQuartzTaskManagerContract method test015DeleteTaskFromRepo.

@Test(enabled = true)
public void test015DeleteTaskFromRepo() throws Exception {
    final String test = "015DeleteTaskFromRepo";
    final OperationResult result = createResult(test);
    PrismObject<? extends ObjectType> object = addObjectFromFile(taskFilename(test));
    String oid = taskOid(test);
    // is the task in Quartz?
    final JobKey key = TaskQuartzImplUtil.createJobKeyForTaskOid(oid);
    AssertJUnit.assertTrue("Job in Quartz does not exist", taskManager.getExecutionManager().getQuartzScheduler().checkExists(key));
    // Remove task from repo
    repositoryService.deleteObject(TaskType.class, taskOid(test), result);
    // We need to wait for a sync interval, so the task scanner has a chance
    // to pick up this task
    waitFor("Waiting for the job to disappear from Quartz Job Store", new Checker() {

        public boolean check() throws ObjectNotFoundException, SchemaException {
            try {
                return !taskManager.getExecutionManager().getQuartzScheduler().checkExists(key);
            } catch (SchedulerException e) {
                throw new SystemException(e);
            }
        }

        @Override
        public void timeout() {
        }
    }, 10000, 2000);
}
Also used : JobKey(org.quartz.JobKey) Checker(com.evolveum.midpoint.test.Checker) SchedulerException(org.quartz.SchedulerException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) Test(org.testng.annotations.Test)

Example 35 with JobKey

use of org.quartz.JobKey in project cdap by caskdata.

the class DatasetBasedTimeScheduleStoreTest method testSchedulerWithoutPersistence.

@Test
public void testSchedulerWithoutPersistence() throws SchedulerException, UnsupportedTypeException {
    JobKey jobKey = scheduleJobWithTrigger(false);
    verifyJobAndTriggers(jobKey, 1, Trigger.TriggerState.NORMAL);
    //Shutdown scheduler.
    schedulerTearDown();
    //restart scheduler.
    schedulerSetup(false);
    //read the job
    JobDetail jobStored = scheduler.getJobDetail(jobKey);
    // The job with old job key should not exist since it is not persisted.
    Assert.assertNull(jobStored);
    schedulerTearDown();
}
Also used : JobKey(org.quartz.JobKey) JobDetail(org.quartz.JobDetail) Test(org.junit.Test)

Aggregations

JobKey (org.quartz.JobKey)65 SchedulerException (org.quartz.SchedulerException)33 JobDetail (org.quartz.JobDetail)22 Trigger (org.quartz.Trigger)19 Scheduler (org.quartz.Scheduler)17 TriggerKey (org.quartz.TriggerKey)15 Test (org.junit.Test)13 List (java.util.List)6 CronTrigger (org.quartz.CronTrigger)6 JobDataMap (org.quartz.JobDataMap)6 ArrayList (java.util.ArrayList)5 TriggerBuilder.newTrigger (org.quartz.TriggerBuilder.newTrigger)5 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)4 Date (java.util.Date)4 HashMap (java.util.HashMap)4 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)2 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)2 Hashtable (java.util.Hashtable)2 Scheduled (org.apache.deltaspike.scheduler.api.Scheduled)2 CronScheduleBuilder (org.quartz.CronScheduleBuilder)2