mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

abobrov
01.28.2009 db546bbe84d1b7d765241d9396f429cc0c50dee3
- [Issue 4257]  deleting recurring task throws error : rework recurring tasks and iterations cancellation process.
3 files modified
199 ■■■■ changed files
opends/src/server/org/opends/server/backends/task/RecurringTask.java 12 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/task/TaskBackend.java 22 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/task/TaskScheduler.java 165 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/task/RecurringTask.java
@@ -386,17 +386,18 @@
  /**
   * Schedules the next iteration of this recurring task for processing.
   *
   * @param  calendar date and time to schedule next iteration from.
   * @return The task that has been scheduled for processing.
   * @throws DirectoryException to indicate an error.
   */
  public Task scheduleNextIteration() throws DirectoryException
  public Task scheduleNextIteration(GregorianCalendar calendar)
          throws DirectoryException
  {
    Task nextTask = null;
    Date nextTaskDate = null;
    try {
      nextTaskDate = getNextIteration();
      nextTaskDate = getNextIteration(calendar);
    } catch (IllegalArgumentException e) {
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION,
        ERR_RECURRINGTASK_INVALID_TOKENS_COMBO.get(
@@ -596,13 +597,14 @@
  /**
   * Get next task iteration date according to recurring schedule.
   * @param  calendar date and time to schedule from.
   * @return next task iteration date.
   * @throws IllegalArgumentException if recurring schedule is invalid.
   */
  private Date getNextIteration() throws IllegalArgumentException
  private Date getNextIteration(GregorianCalendar calendar)
          throws IllegalArgumentException
  {
    int minute, hour, day, month, weekday;
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setFirstDayOfWeek(GregorianCalendar.SUNDAY);
    calendar.add(GregorianCalendar.MINUTE, 1);
    calendar.set(GregorianCalendar.SECOND, 0);
opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -38,6 +38,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -649,7 +650,16 @@
      if (TaskState.isPending(state))
      {
        if (t.isRecurring()) {
          taskScheduler.removeRecurringTaskIteration(t.getTaskID());
          taskScheduler.removePendingTask(t.getTaskID());
          long scheduledStartTime = t.getScheduledStartTime();
          long currentSystemTime = System.currentTimeMillis();
          if (scheduledStartTime < currentSystemTime) {
            scheduledStartTime = currentSystemTime;
          }
          GregorianCalendar calendar = new GregorianCalendar();
          calendar.setTimeInMillis(scheduledStartTime);
          taskScheduler.scheduleNextRecurringTaskIteration(t,
                  calendar);
        } else {
          taskScheduler.removePendingTask(t.getTaskID());
        }
@@ -787,7 +797,15 @@
              TaskState.CANCELED_BEFORE_STARTING)
            {
              taskScheduler.removePendingTask(t.getTaskID());
              taskScheduler.scheduleTask(newTask, true);
              long scheduledStartTime = t.getScheduledStartTime();
              long currentSystemTime = System.currentTimeMillis();
              if (scheduledStartTime < currentSystemTime) {
                scheduledStartTime = currentSystemTime;
              }
              GregorianCalendar calendar = new GregorianCalendar();
              calendar.setTimeInMillis(scheduledStartTime);
              taskScheduler.scheduleNextRecurringTaskIteration(
                      newTask, calendar);
            }
            else if (newTask.getTaskState() ==
              TaskState.STOPPED_BY_ADMINISTRATOR)
opends/src/server/org/opends/server/backends/task/TaskScheduler.java
@@ -38,6 +38,7 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -199,7 +200,7 @@
    for (RecurringTask recurringTask : recurringTasks.values()) {
      Task task = null;
      try {
        task = recurringTask.scheduleNextIteration();
        task = recurringTask.scheduleNextIteration(new GregorianCalendar());
      } catch (DirectoryException de) {
        logError(de.getMessageObject());
      }
@@ -258,7 +259,8 @@
      if (scheduleIteration)
      {
        Task task = recurringTask.scheduleNextIteration();
        Task task = recurringTask.scheduleNextIteration(
                new GregorianCalendar());
        if (task != null)
        {
          // If there is an existing task with the same id
@@ -311,7 +313,8 @@
        if ((t.getRecurringTaskID() != null) &&
            (t.getRecurringTaskID().equals(recurringTaskID)))
        {
          if (!TaskState.isDone(t.getTaskState()))
          TaskState state = t.getTaskState();
          if (!TaskState.isDone(state) && !TaskState.isCancelled(state))
          {
            cancelTask(t.getTaskID());
          }
@@ -525,53 +528,6 @@
  /**
   * Removes the specified pending iteration of recurring task. It will
   * be removed from the task set but still be kept in the pending set.
   *
   * @param  taskID  The task ID of the pending iteration to remove.
   *
   * @return  The task that was removed.
   *
   * @throws  DirectoryException  If the requested task is not in the
   *                              pending queue.
   */
  public Task removeRecurringTaskIteration(String taskID)
         throws DirectoryException
  {
    schedulerLock.lock();
    try
    {
      Task t = tasks.get(taskID);
      if (t == null)
      {
        Message message = ERR_TASKSCHED_REMOVE_PENDING_NO_SUCH_TASK.get(
            String.valueOf(taskID));
        throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
      }
      if (TaskState.isPending(t.getTaskState()))
      {
        tasks.remove(taskID);
        writeState();
        return t;
      }
      else
      {
        Message message = ERR_TASKSCHED_REMOVE_PENDING_NOT_PENDING.get(
            String.valueOf(taskID));
        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
      }
    }
    finally
    {
      schedulerLock.unlock();
    }
  }
  /**
   * Removes the specified completed task.
   *
   * @param  taskID  The task ID of the completed task to remove.
@@ -655,54 +611,10 @@
        return false;
      }
      // See if the task is part of a recurring task.  If so, then schedule the
      // next iteration.
      String recurringTaskID = completedTask.getRecurringTaskID();
      if (recurringTaskID != null)
      {
        RecurringTask recurringTask = recurringTasks.get(recurringTaskID);
        if (recurringTask != null)
        {
          Task newIteration = null;
          try {
            newIteration = recurringTask.scheduleNextIteration();
          } catch (DirectoryException de) {
            logError(de.getMessageObject());
          }
          if (newIteration != null)
          {
            try
            {
              // If there is an existing task with the same id
              // and it is in completed state, take its place.
              Task t = tasks.get(newIteration.getTaskID());
              if ((t != null) && TaskState.isDone(t.getTaskState()))
              {
                removeCompletedTask(t.getTaskID());
              }
              scheduleTask(newIteration, false);
            }
            catch (DirectoryException de)
            {
              if (debugEnabled())
              {
                TRACER.debugCaught(DebugLogLevel.ERROR, de);
              }
              Message message =
                  ERR_TASKSCHED_ERROR_SCHEDULING_RECURRING_ITERATION.
                    get(recurringTaskID, de.getMessageObject());
              logError(message);
              DirectoryServer.sendAlertNotification(this,
                   ALERT_TYPE_CANNOT_SCHEDULE_RECURRING_ITERATION,
                      message);
            }
          }
        }
      }
      // See if the task is part of a recurring task.
      // If so, then schedule the next iteration.
      scheduleNextRecurringTaskIteration(completedTask,
              new GregorianCalendar());
      writeState();
      if (isRunning)
@@ -724,6 +636,63 @@
  /**
   * Check if a given task is a recurring task iteration and re-schedule it.
   * @param  completedTask  The task for which processing has been completed.
   * @param  calendar  The calendar date and time to schedule from.
   */
  protected void scheduleNextRecurringTaskIteration(Task completedTask,
          GregorianCalendar calendar)
  {
    String recurringTaskID = completedTask.getRecurringTaskID();
    if (recurringTaskID != null)
    {
      RecurringTask recurringTask = recurringTasks.get(recurringTaskID);
      if (recurringTask != null)
      {
        Task newIteration = null;
        try {
          newIteration = recurringTask.scheduleNextIteration(calendar);
        } catch (DirectoryException de) {
          logError(de.getMessageObject());
        }
        if (newIteration != null)
        {
          try
          {
            // If there is an existing task with the same id
            // and it is in completed state, take its place.
            Task t = tasks.get(newIteration.getTaskID());
            if ((t != null) && TaskState.isDone(t.getTaskState()))
            {
              removeCompletedTask(t.getTaskID());
            }
            scheduleTask(newIteration, false);
          }
          catch (DirectoryException de)
          {
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, de);
            }
            Message message =
                ERR_TASKSCHED_ERROR_SCHEDULING_RECURRING_ITERATION.
                  get(recurringTaskID, de.getMessageObject());
            logError(message);
            DirectoryServer.sendAlertNotification(this,
                 ALERT_TYPE_CANNOT_SCHEDULE_RECURRING_ITERATION,
                    message);
          }
        }
      }
    }
  }
  /**
   * Adds the provided task to the set of completed tasks associated with the
   * scheduler.  It will be automatically removed after the appropriate
   * retention time has elapsed.