From 2a5859ba830517514ca7aa21d90988327b0b51ea Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Wed, 05 Sep 2007 06:51:34 +0000
Subject: [PATCH] Implement support for delete and modify operations in the task backend as follows:
---
opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java | 208 ++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 153 insertions(+), 55 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
index f716e0e..afe3b7c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/task/TaskBackend.java
@@ -33,6 +33,7 @@
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.Lock;
@@ -495,57 +496,6 @@
/**
- * Indicates whether an entry with the specified DN exists in the backend.
- * The default implementation obtains a read lock and calls
- * <CODE>getEntry</CODE>, but backend implementations may override this with a
- * more efficient version that does not require a lock. The caller is not
- * required to hold any locks on the specified DN.
- *
- * @param entryDN The DN of the entry for which to determine existence.
- *
- * @return <CODE>true</CODE> if the specified entry exists in this backend,
- * or <CODE>false</CODE> if it does not.
- *
- * @throws DirectoryException If a problem occurs while trying to make the
- * determination.
- */
- public boolean entryExists(DN entryDN)
- throws DirectoryException
- {
- if (entryDN == null)
- {
- return false;
- }
-
- if (entryDN.equals(taskRootDN) || entryDN.equals(scheduledTaskParentDN) ||
- entryDN.equals(recurringTaskParentDN))
- {
- return true;
- }
-
- DN parentDN = entryDN.getParentDNInSuffix();
- if (parentDN == null)
- {
- return false;
- }
-
- if (parentDN.equals(scheduledTaskParentDN))
- {
- return (taskScheduler.getScheduledTaskEntry(entryDN) != null);
- }
- else if (parentDN.equals(recurringTaskParentDN))
- {
- return (taskScheduler.getRecurringTaskEntry(entryDN) != null);
- }
- else
- {
- return false;
- }
- }
-
-
-
- /**
* Adds the provided entry to this backend. This method must ensure that the
* entry is appropriate for the backend and that no entry already exists with
* the same DN.
@@ -701,10 +651,158 @@
public void replaceEntry(Entry entry, ModifyOperation modifyOperation)
throws DirectoryException
{
- // FIXME -- We need to support this.
- throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
- Message.raw("Modify operations are not yet supported in " +
- "the task backend"));
+ DN entryDN = entry.getDN();
+
+ Lock entryLock = null;
+ if (! taskScheduler.holdsSchedulerLock())
+ {
+ for (int i=0; i < 3; i++)
+ {
+ entryLock = LockManager.lockWrite(entryDN);
+ if (entryLock != null)
+ {
+ break;
+ }
+ }
+
+ if (entryLock == null)
+ {
+ throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
+ ERR_TASKBE_MODIFY_CANNOT_LOCK_ENTRY.get(
+ String.valueOf(entryDN)));
+ }
+ }
+
+ try
+ {
+ // Get the parent for the provided entry DN. It must be either the
+ // scheduled or recurring task parent DN.
+ DN parentDN = entryDN.getParentDNInSuffix();
+ if (parentDN == null)
+ {
+ Message message =
+ ERR_TASKBE_MODIFY_INVALID_ENTRY.get(String.valueOf(entryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+ else if (parentDN.equals(scheduledTaskParentDN))
+ {
+ // It's a scheduled task. Make sure that it exists.
+ Task t = taskScheduler.getScheduledTask(entryDN);
+ if (t == null)
+ {
+ Message message =
+ ERR_TASKBE_MODIFY_NO_SUCH_TASK.get(String.valueOf(entryDN));
+ throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
+ }
+
+
+ // Look at the state of the task. We will allow anything to be altered
+ // for a pending task. For a running task, we will only allow the state
+ // to be altered in order to cancel it. We will not allow any
+ // modifications for completed tasks.
+ TaskState state = t.getTaskState();
+ if (TaskState.isPending(state))
+ {
+ Task newTask =
+ taskScheduler.entryToScheduledTask(entry, modifyOperation);
+ taskScheduler.removePendingTask(t.getTaskID());
+ taskScheduler.scheduleTask(newTask, true);
+ return;
+ }
+ else if (TaskState.isRunning(state))
+ {
+ // If the task is running, we will only allow it to be cancelled.
+ // This will only be allowed using the replace modification type on
+ // the ds-task-state attribute if the value starts with "cancel" or
+ // "stop". In that case, we'll cancel the task.
+ boolean acceptable = true;
+ for (Modification m : modifyOperation.getModifications())
+ {
+ if (m.isInternal())
+ {
+ continue;
+ }
+
+ if (m.getModificationType() != ModificationType.REPLACE)
+ {
+ acceptable = false;
+ break;
+ }
+
+ Attribute a = m.getAttribute();
+ AttributeType at = a.getAttributeType();
+ if (! at.hasName(ATTR_TASK_STATE))
+ {
+ acceptable = false;
+ break;
+ }
+
+ Iterator<AttributeValue> iterator = a.getValues().iterator();
+ if (! iterator.hasNext())
+ {
+ acceptable = false;
+ break;
+ }
+
+ AttributeValue v = iterator.next();
+ String valueString = toLowerCase(v.getStringValue());
+ if (! (valueString.startsWith("cancel") ||
+ valueString.startsWith("stop")))
+ {
+ acceptable = false;
+ break;
+ }
+
+ if (iterator.hasNext())
+ {
+ acceptable = false;
+ break;
+ }
+ }
+
+ if (acceptable)
+ {
+ Message message = INFO_TASKBE_RUNNING_TASK_CANCELLED.get();
+ t.interruptTask(TaskState.STOPPED_BY_ADMINISTRATOR, message);
+ return;
+ }
+ else
+ {
+ Message message =
+ ERR_TASKBE_MODIFY_RUNNING.get(String.valueOf(entryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ message);
+ }
+ }
+ else
+ {
+ Message message =
+ ERR_TASKBE_MODIFY_COMPLETED.get(String.valueOf(entryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ message);
+ }
+ }
+ else if (parentDN.equals(recurringTaskParentDN))
+ {
+ // We don't currently support altering recurring tasks.
+ Message message =
+ ERR_TASKBE_MODIFY_RECURRING.get(String.valueOf(entryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+ else
+ {
+ Message message =
+ ERR_TASKBE_MODIFY_INVALID_ENTRY.get(String.valueOf(entryDN));
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+ }
+ }
+ finally
+ {
+ if (entryLock != null)
+ {
+ LockManager.unlock(entryDN, entryLock);
+ }
+ }
}
--
Gitblit v1.10.0