From a09e50d8d41c0f50c486742f4cc2343083c635e3 Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 25 Jun 2010 09:25:49 +0000
Subject: [PATCH] Fixes issues #4552 #4557, making sure plugins and internal services are properly handling subtree move or delete. The changes particularly resolve problems raised by the community with the referential integrity and the isMemberOf plug-ins. Unit-tests have been updated to cover those cases

---
 opends/src/server/org/opends/server/core/PluginConfigManager.java |   92 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 91 insertions(+), 1 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/PluginConfigManager.java b/opends/src/server/org/opends/server/core/PluginConfigManager.java
index 3f0bf15..9a74cd8 100644
--- a/opends/src/server/org/opends/server/core/PluginConfigManager.java
+++ b/opends/src/server/org/opends/server/core/PluginConfigManager.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2009 Sun Microsystems, Inc.
+ *      Copyright 2006-2010 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 
@@ -136,6 +136,7 @@
   private DirectoryServerPlugin[] searchResultEntryPlugins;
   private DirectoryServerPlugin[] searchResultReferencePlugins;
   private DirectoryServerPlugin[] subordinateModifyDNPlugins;
+  private DirectoryServerPlugin[] subordinateDeletePlugins;
   private DirectoryServerPlugin[] intermediateResponsePlugins;
 
 
@@ -222,6 +223,7 @@
     searchResultEntryPlugins           = new DirectoryServerPlugin[0];
     searchResultReferencePlugins       = new DirectoryServerPlugin[0];
     subordinateModifyDNPlugins         = new DirectoryServerPlugin[0];
+    subordinateDeletePlugins           = new DirectoryServerPlugin[0];
     intermediateResponsePlugins        = new DirectoryServerPlugin[0];
     registeredPlugins                  =
          new ConcurrentHashMap<DN,
@@ -481,6 +483,7 @@
       case SEARCHRESULTENTRY:      return PluginType.SEARCH_RESULT_ENTRY;
       case SEARCHRESULTREFERENCE:  return PluginType.SEARCH_RESULT_REFERENCE;
       case SUBORDINATEMODIFYDN:    return PluginType.SUBORDINATE_MODIFY_DN;
+      case SUBORDINATEDELETE:      return PluginType.SUBORDINATE_DELETE;
       case INTERMEDIATERESPONSE:   return PluginType.INTERMEDIATE_RESPONSE;
       case POSTSYNCHRONIZATIONADD:
                 return PluginType.POST_SYNCHRONIZATION_ADD;
@@ -863,6 +866,11 @@
             addPlugin(subordinateModifyDNPlugins, plugin, t,
                 pluginRootConfig.getPluginOrderSubordinateModifyDN());
         break;
+      case SUBORDINATE_DELETE:
+        subordinateDeletePlugins =
+            addPlugin(subordinateDeletePlugins, plugin, t,
+                pluginRootConfig.getPluginOrderSubordinateDelete());
+        break;
       case INTERMEDIATE_RESPONSE:
         intermediateResponsePlugins =
             addPlugin(intermediateResponsePlugins, plugin, t,
@@ -1373,6 +1381,10 @@
           subordinateModifyDNPlugins =
                removePlugin(subordinateModifyDNPlugins, plugin);
           break;
+        case SUBORDINATE_DELETE:
+          subordinateDeletePlugins =
+               removePlugin(subordinateDeletePlugins, plugin);
+          break;
         case INTERMEDIATE_RESPONSE:
           intermediateResponsePlugins =
                removePlugin(intermediateResponsePlugins, plugin);
@@ -5289,6 +5301,84 @@
 
 
   /**
+   * Invokes the set of subordinate delete plugins that have been configured
+   * in the Directory Server.
+   *
+   * @param  deleteOperation  The delete operation with which the
+   *                          subordinate entry is associated.
+   * @param  entry            The subordinate entry being deleted.
+   *
+   * @return The result of processing the subordinate delete plugins.
+   */
+  public PluginResult.SubordinateDelete invokeSubordinateDeletePlugins(
+              DeleteOperation deleteOperation, Entry entry)
+  {
+    PluginResult.SubordinateDelete result = null;
+
+    for (DirectoryServerPlugin p : subordinateDeletePlugins)
+    {
+      if (deleteOperation.isInternalOperation() &&
+          (! p.invokeForInternalOperations()))
+      {
+        continue;
+      }
+
+      try
+      {
+        DirectoryServerPlugin<? extends PluginCfg> gp =
+             (DirectoryServerPlugin<? extends PluginCfg>) p;
+        result = gp.processSubordinateDelete(deleteOperation, entry);
+      }
+      catch (Exception e)
+      {
+        if (debugEnabled())
+        {
+          TRACER.debugCaught(DebugLogLevel.ERROR, e);
+        }
+
+        Message message =
+            ERR_PLUGIN_SUBORDINATE_DELETE_PLUGIN_EXCEPTION.get(
+                String.valueOf(p.getPluginEntryDN()),
+                deleteOperation.getConnectionID(),
+                deleteOperation.getOperationID(),
+                stackTraceToSingleLineString(e));
+        logError(message);
+
+        return PluginResult.SubordinateDelete.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
+      }
+
+      if (result == null)
+      {
+        Message message =
+            ERR_PLUGIN_SUBORDINATE_DELETE_PLUGIN_RETURNED_NULL.get(
+                        String.valueOf(p.getPluginEntryDN()),
+                        deleteOperation.getConnectionID(),
+                        String.valueOf(deleteOperation.getOperationID()));
+        logError(message);
+
+        return PluginResult.SubordinateDelete.stopProcessing(
+            DirectoryServer.getServerErrorResultCode(), message);
+      }
+      else if (! result.continuePluginProcessing())
+      {
+        return result;
+      }
+    }
+
+    if (result == null)
+    {
+      // This should only happen if there were no subordinate modify DN plugins
+      // registered, which is fine.
+      result = PluginResult.SubordinateDelete.continueOperationProcessing();
+    }
+
+    return result;
+  }
+
+
+
+  /**
    * Invokes the set of intermediate response plugins that have been configured
    * in the Directory Server.
    *

--
Gitblit v1.10.0