From bd33c8d0ad24667483866e700965ae983fc80ba7 Mon Sep 17 00:00:00 2001
From: ludovicp <ludovicp@localhost>
Date: Fri, 25 Jun 2010 10:19:52 +0000
Subject: [PATCH] Fix issue 4524, updates to the Group cache are now handled by a post-op through internal API rather than the Change Listener API.

---
 opends/src/server/org/opends/server/core/GroupManager.java |  205 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 175 insertions(+), 30 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/GroupManager.java b/opends/src/server/org/opends/server/core/GroupManager.java
index 1cf06c1..827ce7a 100644
--- a/opends/src/server/org/opends/server/core/GroupManager.java
+++ b/opends/src/server/org/opends/server/core/GroupManager.java
@@ -44,9 +44,12 @@
 import org.opends.server.admin.std.server.RootCfg;
 import org.opends.server.api.Backend;
 import org.opends.server.api.BackendInitializationListener;
-import org.opends.server.api.ChangeNotificationListener;
 import org.opends.server.api.DITCacheMap;
 import org.opends.server.api.Group;
+import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
+import org.opends.server.api.plugin.PluginResult;
+import org.opends.server.api.plugin.PluginResult.PostOperation;
+import org.opends.server.api.plugin.PluginType;
 import org.opends.server.config.ConfigException;
 import org.opends.server.loggers.debug.DebugTracer;
 import org.opends.server.protocols.internal.InternalClientConnection;
@@ -64,10 +67,15 @@
 import org.opends.server.types.SearchResultEntry;
 import org.opends.server.types.SearchScope;
 import org.opends.server.types.SearchFilter;
-import org.opends.server.types.operation.PostResponseAddOperation;
-import org.opends.server.types.operation.PostResponseDeleteOperation;
-import org.opends.server.types.operation.PostResponseModifyOperation;
-import org.opends.server.types.operation.PostResponseModifyDNOperation;
+import org.opends.server.types.operation.PluginOperation;
+import org.opends.server.types.operation.PostOperationAddOperation;
+import org.opends.server.types.operation.PostOperationDeleteOperation;
+import org.opends.server.types.operation.PostOperationModifyDNOperation;
+import org.opends.server.types.operation.PostOperationModifyOperation;
+import org.opends.server.types.operation.PostSynchronizationAddOperation;
+import org.opends.server.types.operation.PostSynchronizationDeleteOperation;
+import org.opends.server.types.operation.PostSynchronizationModifyDNOperation;
+import org.opends.server.types.operation.PostSynchronizationModifyOperation;
 import org.opends.server.workflowelement.localbackend.
             LocalBackendSearchOperation;
 
@@ -91,12 +99,11 @@
  * memory.  If it is determined that this approach is not workable in all cases,
  * then we will need an alternate strategy.
  */
-public class GroupManager
+public class GroupManager extends InternalDirectoryServerPlugin
        implements ConfigurationChangeListener<GroupImplementationCfg>,
                   ConfigurationAddListener<GroupImplementationCfg>,
                   ConfigurationDeleteListener<GroupImplementationCfg>,
-                  BackendInitializationListener,
-                  ChangeNotificationListener
+                  BackendInitializationListener
 {
   /**
    * The tracer object for the debug logger.
@@ -120,20 +127,38 @@
   // Lock to protect internal data structures.
   private final ReentrantReadWriteLock lock;
 
+  // Dummy configuration DN for Group Manager.
+  private static final String CONFIG_DN = "cn=Group Manager,cn=config";
+
 
 
   /**
    * Creates a new instance of this group manager.
+   *
+   * @throws DirectoryException If a problem occurs while
+   *                            creating an instance of
+   *                            the group manager.
    */
-  public GroupManager()
+  public GroupManager() throws DirectoryException
   {
+    super(DN.decode(CONFIG_DN), EnumSet.of(
+          PluginType.POST_OPERATION_ADD,
+          PluginType.POST_OPERATION_DELETE,
+          PluginType.POST_OPERATION_MODIFY,
+          PluginType.POST_OPERATION_MODIFY_DN,
+          PluginType.POST_SYNCHRONIZATION_ADD,
+          PluginType.POST_SYNCHRONIZATION_DELETE,
+          PluginType.POST_SYNCHRONIZATION_MODIFY,
+          PluginType.POST_SYNCHRONIZATION_MODIFY_DN),
+          true);
+
     groupImplementations = new ConcurrentHashMap<DN,Group>();
     groupInstances       = new DITCacheMap<Group>();
 
     lock = new ReentrantReadWriteLock();
 
+    DirectoryServer.registerInternalPlugin(this);
     DirectoryServer.registerBackendInitializationListener(this);
-    DirectoryServer.registerChangeNotificationListener(this);
   }
 
 
@@ -532,6 +557,9 @@
    */
   public void finalizeGroupManager()
   {
+    DirectoryServer.deregisterInternalPlugin(this);
+    DirectoryServer.deregisterBackendInitializationListener(this);
+
     deregisterAllGroups();
 
     for (Group groupImplementation : groupImplementations.values())
@@ -763,12 +791,12 @@
 
 
   /**
-   * {@inheritDoc}  In this case, each entry is checked to see if it contains
-   * a group definition, and if so it will be instantiated and registered with
-   * this group manager.
+   * In this case, each entry is checked to see if it contains
+   * a group definition, and if so it will be instantiated and
+   * registered with this group manager.
    */
-  public void handleAddOperation(PostResponseAddOperation addOperation,
-                                 Entry entry)
+  private void doPostAdd(PluginOperation addOperation,
+          Entry entry)
   {
     List<Control> requestControls = addOperation.getRequestControls();
     if (requestControls != null)
@@ -796,11 +824,11 @@
 
 
   /**
-   * {@inheritDoc}  In this case, if the entry is associated with a registered
+   * In this case, if the entry is associated with a registered
    * group instance, then that group instance will be deregistered.
    */
-  public void handleDeleteOperation(PostResponseDeleteOperation deleteOperation,
-                                    Entry entry)
+  private void doPostDelete(PluginOperation deleteOperation,
+          Entry entry)
   {
     List<Control> requestControls = deleteOperation.getRequestControls();
     if (requestControls != null)
@@ -828,12 +856,13 @@
 
 
   /**
-   * {@inheritDoc}  In this case, if the entry is associated with a registered
-   * group instance, then that instance will be recreated from the contents of
-   * the provided entry and re-registered with the group manager.
+   * In this case, if the entry is associated with a registered
+   * group instance, then that instance will be recreated from
+   * the contents of the provided entry and re-registered with
+   * the group manager.
    */
-  public void handleModifyOperation(PostResponseModifyOperation modifyOperation,
-                                    Entry oldEntry, Entry newEntry)
+  private void doPostModify(PluginOperation modifyOperation,
+          Entry oldEntry, Entry newEntry)
   {
     List<Control> requestControls = modifyOperation.getRequestControls();
     if (requestControls != null)
@@ -870,14 +899,14 @@
 
 
   /**
-   * {@inheritDoc}  In this case, if the entry is associated with a registered
-   * group instance, then that instance will be recreated from the contents of
-   * the provided entry and re-registered with the group manager under the new
-   * DN, and the old instance will be deregistered.
+   * In this case, if the entry is associated with a registered
+   * group instance, then that instance will be recreated from
+   * the contents of the provided entry and re-registered with
+   * the group manager under the new DN, and the old instance
+   * will be deregistered.
    */
-  public void handleModifyDNOperation(
-                   PostResponseModifyDNOperation modifyDNOperation,
-                   Entry oldEntry, Entry newEntry)
+  private void doPostModifyDN(PluginOperation modifyDNOperation,
+          Entry oldEntry, Entry newEntry)
   {
     List<Control> requestControls = modifyDNOperation.getRequestControls();
     if (requestControls != null)
@@ -935,6 +964,122 @@
 
 
   /**
+   * {@inheritDoc}
+   */
+  @Override
+  public PostOperation doPostOperation(
+          PostOperationAddOperation addOperation)
+  {
+    doPostAdd(addOperation, addOperation.getEntryToAdd());
+
+    // If we've gotten here, then everything is acceptable.
+    return PluginResult.PostOperation.continueOperationProcessing();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public PostOperation doPostOperation(
+          PostOperationDeleteOperation deleteOperation)
+  {
+    doPostDelete(deleteOperation, deleteOperation.getEntryToDelete());
+
+    // If we've gotten here, then everything is acceptable.
+    return PluginResult.PostOperation.continueOperationProcessing();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public PostOperation doPostOperation(
+          PostOperationModifyOperation modifyOperation)
+  {
+    doPostModify(modifyOperation,
+            modifyOperation.getCurrentEntry(),
+            modifyOperation.getModifiedEntry());
+
+    // If we've gotten here, then everything is acceptable.
+    return PluginResult.PostOperation.continueOperationProcessing();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public PostOperation doPostOperation(
+          PostOperationModifyDNOperation modifyDNOperation)
+  {
+    doPostModifyDN(modifyDNOperation,
+            modifyDNOperation.getOriginalEntry(),
+            modifyDNOperation.getUpdatedEntry());
+
+    // If we've gotten here, then everything is acceptable.
+    return PluginResult.PostOperation.continueOperationProcessing();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void doPostSynchronization(
+      PostSynchronizationAddOperation addOperation)
+  {
+    Entry entry = addOperation.getEntryToAdd();
+    if (entry != null)
+    {
+      doPostAdd(addOperation, entry);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void doPostSynchronization(
+      PostSynchronizationDeleteOperation deleteOperation)
+  {
+    Entry entry = deleteOperation.getEntryToDelete();
+    if (entry != null)
+    {
+      doPostDelete(deleteOperation, entry);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void doPostSynchronization(
+      PostSynchronizationModifyOperation modifyOperation)
+  {
+    Entry entry = modifyOperation.getCurrentEntry();
+    Entry modEntry = modifyOperation.getModifiedEntry();
+    if ((entry != null) && (modEntry != null))
+    {
+      doPostModify(modifyOperation, entry, modEntry);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void doPostSynchronization(
+      PostSynchronizationModifyDNOperation modifyDNOperation)
+  {
+    Entry oldEntry = modifyDNOperation.getOriginalEntry();
+    Entry newEntry = modifyDNOperation.getUpdatedEntry();
+    if ((oldEntry != null) && (newEntry != null))
+    {
+      doPostModifyDN(modifyDNOperation, oldEntry, newEntry);
+    }
+  }
+
+
+
+  /**
    * Attempts to create a group instance from the provided entry, and if that is
    * successful then register it with the server, overwriting any existing
    * group instance that may be registered with the same DN.

--
Gitblit v1.10.0