From db546bbe84d1b7d765241d9396f429cc0c50dee3 Mon Sep 17 00:00:00 2001
From: abobrov <abobrov@localhost>
Date: Thu, 01 Oct 2009 12:28:35 +0000
Subject: [PATCH] - [Issue 4257]  deleting recurring task throws error : rework recurring tasks and iterations cancellation process.

---
 opends/src/server/org/opends/server/backends/task/TaskScheduler.java |  165 ++++++++++++++++------------------------
 opends/src/server/org/opends/server/backends/task/RecurringTask.java |   12 +-
 opends/src/server/org/opends/server/backends/task/TaskBackend.java   |   22 +++++
 3 files changed, 94 insertions(+), 105 deletions(-)

diff --git a/opends/src/server/org/opends/server/backends/task/RecurringTask.java b/opends/src/server/org/opends/server/backends/task/RecurringTask.java
index 1554835..8c26fe5 100644
--- a/opends/src/server/org/opends/server/backends/task/RecurringTask.java
+++ b/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);
diff --git a/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index c2eba38..8b6bfbf 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/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)
diff --git a/opends/src/server/org/opends/server/backends/task/TaskScheduler.java b/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
index 34781f9..6a8874d 100644
--- a/opends/src/server/org/opends/server/backends/task/TaskScheduler.java
+++ b/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.

--
Gitblit v1.10.0