From aaff8bbe83e02bba861c5cf1c6645dedc4e0ac1d Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Tue, 07 Aug 2007 21:45:40 +0000
Subject: [PATCH] Add support for a new type of plugin which can be used to detect changes and take some action whenever a subordinate entry is modified as a result of a modify DN operation that targets an entry that has one or more children (i.e., a subtree move or subtree rename operation). At present, subordinate modify DN plugins are not allowed to change the contents of the entry as it is being moved/renamed, but an appropriate API is in place if we decide to add this functionality in the future.
---
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 111 insertions(+), 9 deletions(-)
diff --git a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
index 8113b85..6e9bfe8 100644
--- a/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
+++ b/opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -32,9 +32,11 @@
import org.opends.server.api.Backend;
import org.opends.server.api.EntryCache;
import org.opends.server.api.ClientConnection;
+import org.opends.server.api.plugin.SubordinateModifyDNPluginResult;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.PluginConfigManager;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.SearchOperation;
@@ -3391,14 +3393,64 @@
}
- // Change the entry DN.
- oldEntry.setDN(newDN);
+
+ // Create a new entry that is a copy of the old entry but with the new DN.
+ // Also invoke any subordinate modify DN plugins on the entry.
+ // FIXME -- At the present time, we don't support subordinate modify DN
+ // plugins that make changes to subordinate entries and therefore
+ // provide an unmodifiable list for the modifications element.
+ // FIXME -- This will need to be updated appropriately if we decided that
+ // these plugins should be invoked for synchronization
+ // operations.
+ Entry newEntry = oldEntry.duplicate(false);
+ newEntry.setDN(newDN);
+
+ if (! modifyDNOperation.isSynchronizationOperation())
+ {
+ PluginConfigManager pluginManager =
+ DirectoryServer.getPluginConfigManager();
+ List<Modification> modifications =
+ Collections.unmodifiableList(new ArrayList<Modification>(0));
+ SubordinateModifyDNPluginResult pluginResult =
+ pluginManager.invokeSubordinateModifyDNPlugins(
+ modifyDNOperation, oldEntry, newEntry, modifications);
+
+ if (pluginResult.connectionTerminated() ||
+ pluginResult.abortModifyDNOperation())
+ {
+ int msgID = MSGID_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_PLUGIN;
+ String message = getMessage(msgID, oldDN.toString(),
+ newDN.toString());
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(), message,
+ msgID);
+ }
+
+ if (! modifications.isEmpty())
+ {
+ indexModifications(txn, oldEntry, newEntry, newID, modifications);
+
+ StringBuilder invalidReason = new StringBuilder();
+ if (! newEntry.conformsToSchema(null, false, false, false,
+ invalidReason))
+ {
+ int msgID = MSGID_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_SCHEMA_ERROR;
+ String message = getMessage(msgID, oldDN.toString(),
+ newDN.toString(),
+ invalidReason.toString());
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(), message,
+ msgID);
+ }
+ }
+ }
+
// Add any referral records for the new DN.
- dn2uri.addEntry(txn, oldEntry);
+ dn2uri.addEntry(txn, newEntry);
// Put the new entry (old entry with new DN) in id2entry.
- id2entry.put(txn, newID, oldEntry);
+ id2entry.put(txn, newID, newEntry);
if (!newID.equals(oldID))
{
@@ -3456,7 +3508,7 @@
*/
private void renameSubordinateEntry(Transaction txn, EntryID entryID,
Entry oldEntry, DN newDN)
- throws DirectoryException, DatabaseException
+ throws DirectoryException, JebException, DatabaseException
{
DN oldDN = oldEntry.getDN();
@@ -3475,14 +3527,64 @@
// Delete any existing referral records for the old DN.
dn2uri.deleteEntry(txn, oldEntry);
- // Change the entry DN.
- oldEntry.setDN(newDN);
+
+ // Create a new entry that is a copy of the old entry but with the new DN.
+ // Also invoke any subordinate modify DN plugins on the entry.
+ // FIXME -- At the present time, we don't support subordinate modify DN
+ // plugins that make changes to subordinate entries and therefore
+ // provide an unmodifiable list for the modifications element.
+ // FIXME -- This will need to be updated appropriately if we decided that
+ // these plugins should be invoked for synchronization
+ // operations.
+ Entry newEntry = oldEntry.duplicate(false);
+ newEntry.setDN(newDN);
+
+ if (! modifyDNOperation.isSynchronizationOperation())
+ {
+ PluginConfigManager pluginManager =
+ DirectoryServer.getPluginConfigManager();
+ List<Modification> modifications =
+ Collections.unmodifiableList(new ArrayList<Modification>(0));
+ SubordinateModifyDNPluginResult pluginResult =
+ pluginManager.invokeSubordinateModifyDNPlugins(
+ modifyDNOperation, oldEntry, newEntry, modifications);
+
+ if (pluginResult.connectionTerminated() ||
+ pluginResult.abortModifyDNOperation())
+ {
+ int msgID = MSGID_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_PLUGIN;
+ String message = getMessage(msgID, oldDN.toString(),
+ newDN.toString());
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(),
+ message, msgID);
+ }
+
+ if (! modifications.isEmpty())
+ {
+ indexModifications(txn, oldEntry, newEntry, entryID, modifications);
+
+ StringBuilder invalidReason = new StringBuilder();
+ if (! newEntry.conformsToSchema(null, false, false, false,
+ invalidReason))
+ {
+ int msgID = MSGID_JEB_MODIFYDN_ABORTED_BY_SUBORDINATE_SCHEMA_ERROR;
+ String message = getMessage(msgID, oldDN.toString(),
+ newDN.toString(),
+ invalidReason.toString());
+ throw new DirectoryException(
+ DirectoryServer.getServerErrorResultCode(), message,
+ msgID);
+ }
+ }
+ }
+
// Add any referral records for the new DN.
- dn2uri.addEntry(txn, oldEntry);
+ dn2uri.addEntry(txn, newEntry);
// Replace the entry in id2entry.
- id2entry.put(txn, entryID, oldEntry);
+ id2entry.put(txn, entryID, newEntry);
// Remove the entry from the entry cache.
EntryCache entryCache = DirectoryServer.getEntryCache();
--
Gitblit v1.10.0