mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
02.35.2007 20c804510a308ad66a141b9d91acdfb90de6b461
Update the code involving change notification listeners to ensure that they are
invoked just before the response is sent to the client rather than just after
the response. This can help avoid race conditions in which the server needs to
use a change notification listener to perform some additional processing for a
given operation, and the client sends a second request that depends on this
processing immediately after receiving a "success" response for the operation
that triggered the change notification.

OpenDS Issue Number: 1200
7 files modified
196 ■■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/api/ChangeNotificationListener.java 36 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java 33 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java 35 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/GroupManager.java 12 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java 33 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java 33 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestChangeNotificationListener.java 14 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/api/ChangeNotificationListener.java
@@ -22,17 +22,18 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.api;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.types.Entry;
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;
@@ -46,11 +47,15 @@
 * be invoked for successful operations.
 * <BR><BR>
 * Each change notification listener will be notified whenever an
 * update is made in the server (just after the response has been sent
 * to the client), so the listener should use a very efficient
 * mechanism for determining whether or not any action is required for
 * the associated operation and quickly return for cases in which the
 * update is not applicable.
 * update is made in the server (just before the response is sent to
 * the client), so the listener should use a very efficient mechanism
 * for determining whether or not any action is required for the
 * associated operation and quickly return for cases in which the
 * update is not applicable.  Also note that even though the listener
 * will be invoked before the response is sent to the client, it may
 * not alter that response in any way and therefore the listener will
 * be given what is essentially a read-only view of the associated
 * operation.
 * <BR><BR>
 * Note that while this interface can be used by clients to be
 * notified of changes to the configuration data just as easily as it
@@ -73,7 +78,8 @@
   *                       server.
   * @param  entry         The entry that was added to the server.
   */
  public void handleAddOperation(AddOperation addOperation,
  public void handleAddOperation(
                   PostResponseAddOperation addOperation,
                                 Entry entry);
@@ -87,7 +93,8 @@
   * @param  entry            The entry that was removed from the
   *                          server.
   */
  public void handleDeleteOperation(DeleteOperation deleteOperation,
  public void handleDeleteOperation(
                   PostResponseDeleteOperation deleteOperation,
                                    Entry entry);
@@ -101,7 +108,8 @@
   * @param  oldEntry         The entry before it was updated.
   * @param  newEntry         The entry after it was updated.
   */
  public void handleModifyOperation(ModifyOperation modifyOperation,
  public void handleModifyOperation(
                   PostResponseModifyOperation modifyOperation,
                                    Entry oldEntry, Entry newEntry);
@@ -116,7 +124,7 @@
   * @param  newEntry           The entry after it was updated.
   */
  public void handleModifyDNOperation(
                   ModifyDNOperation modifyDNOperation,
                   PostResponseModifyDNOperation modifyDNOperation,
                   Entry oldEntry, Entry newEntry);
}
opendj-sdk/opends/src/server/org/opends/server/core/AddOperation.java
@@ -2154,20 +2154,8 @@
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the add response to the client.
    getClientConnection().sendResponse(this);
    // Log the add response.
    logAddResponse(this);
    // Notify any change listeners and/or persistent searches that might be
    // registered with the server.
    // Notify any change notification listeners that might be registered with
    // the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (ChangeNotificationListener changeListener :
@@ -2187,7 +2175,24 @@
                   message, msgID);
        }
      }
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the add response to the client.
    getClientConnection().sendResponse(this);
    // Log the add response.
    logAddResponse(this);
    // Notify any persistent searches that might be registered with the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (PersistentSearch persistentSearch :
           DirectoryServer.getPersistentSearches())
      {
opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperation.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.core;
@@ -1197,20 +1197,8 @@
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the delete response to the client.
    getClientConnection().sendResponse(this);
    // Log the delete response.
    logDeleteResponse(this);
    // Notify any change listeners and/or persistent searches that might be
    // registered with the server.
    // Notify any change notification listeners that might be registered with
    // the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (ChangeNotificationListener changeListener :
@@ -1230,7 +1218,24 @@
                   message, msgID);
        }
      }
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the delete response to the client.
    getClientConnection().sendResponse(this);
    // Log the delete response.
    logDeleteResponse(this);
    // Notify any persistent searches that might be registered with the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (PersistentSearch persistentSearch :
           DirectoryServer.getPersistentSearches())
      {
opendj-sdk/opends/src/server/org/opends/server/core/GroupManager.java
@@ -62,6 +62,10 @@
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 static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.Debug.*;
@@ -1186,7 +1190,7 @@
   * a group definition, and if so it will be instantiated and registered with
   * this group manager.
   */
  public void handleAddOperation(AddOperation addOperation,
  public void handleAddOperation(PostResponseAddOperation addOperation,
                                 Entry entry)
  {
    assert debugEnter(CLASS_NAME, "handleAddOperation",
@@ -1213,7 +1217,7 @@
   * {@inheritDoc}  In this case, if the entry is associated with a registered
   * group instance, then that group instance will be deregistered.
   */
  public void handleDeleteOperation(DeleteOperation deleteOperation,
  public void handleDeleteOperation(PostResponseDeleteOperation deleteOperation,
                                    Entry entry)
  {
    assert debugEnter(CLASS_NAME, "handleDeleteOperation",
@@ -1241,7 +1245,7 @@
   * 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(ModifyOperation modifyOperation,
  public void handleModifyOperation(PostResponseModifyOperation modifyOperation,
                                    Entry oldEntry, Entry newEntry)
  {
    assert debugEnter(CLASS_NAME, "handleModifyOperation",
@@ -1285,7 +1289,7 @@
   * DN, and the old instance will be deregistered.
   */
  public void handleModifyDNOperation(
                   ModifyDNOperation modifyDNOperation,
                   PostResponseModifyDNOperation modifyDNOperation,
                   Entry oldEntry, Entry newEntry)
  {
    assert debugEnter(CLASS_NAME, "handleModifyDNOperation",
opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperation.java
@@ -2003,20 +2003,8 @@
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the modify DN response to the client.
    clientConnection.sendResponse(this);
    // Log the modify DN response.
    logModifyDNResponse(this);
    // Notify any change listeners and/or persistent searches that might be
    // registered with the server.
    // Notify any change notification listeners that might be registered with
    // the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (ChangeNotificationListener changeListener :
@@ -2036,7 +2024,24 @@
                   message, msgID);
        }
      }
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the modify DN response to the client.
    clientConnection.sendResponse(this);
    // Log the modify DN response.
    logModifyDNResponse(this);
    // Notify any persistent searches that might be registered with the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (PersistentSearch persistentSearch :
           DirectoryServer.getPersistentSearches())
      {
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperation.java
@@ -2731,20 +2731,8 @@
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the modify response to the client.
    clientConnection.sendResponse(this);
    // Log the modify response.
    logModifyResponse(this);
    // Notify any change listeners and/or persistent searches that might be
    // registered with the server.
    // Notify any change notification listeners that might be registered with
    // the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (ChangeNotificationListener changeListener :
@@ -2765,7 +2753,24 @@
                   message, msgID);
        }
      }
    }
    // Stop the processing timer.
    processingStopTime = System.currentTimeMillis();
    // Send the modify response to the client.
    clientConnection.sendResponse(this);
    // Log the modify response.
    logModifyResponse(this);
    // Notify any persistent searches that might be registered with the server.
    if (getResultCode() == ResultCode.SUCCESS)
    {
      for (PersistentSearch persistentSearch :
           DirectoryServer.getPersistentSearches())
      {
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/core/TestChangeNotificationListener.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.core;
@@ -32,6 +32,10 @@
import org.opends.server.api.ChangeNotificationListener;
import org.opends.server.types.Entry;
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;
@@ -76,7 +80,7 @@
  /**
   * {@inheritDoc}
   */
  public void handleAddOperation(AddOperation addOperation,
  public void handleAddOperation(PostResponseAddOperation addOperation,
                                 Entry entry)
  {
    addCount.incrementAndGet();
@@ -87,7 +91,7 @@
  /**
   * {@inheritDoc}
   */
  public void handleDeleteOperation(DeleteOperation deleteOperation,
  public void handleDeleteOperation(PostResponseDeleteOperation deleteOperation,
                                    Entry entry)
  {
    deleteCount.incrementAndGet();
@@ -98,7 +102,7 @@
  /**
   * {@inheritDoc}
   */
  public void handleModifyOperation(ModifyOperation modifyOperation,
  public void handleModifyOperation(PostResponseModifyOperation modifyOperation,
                                    Entry oldEntry, Entry newEntry)
  {
    modifyCount.incrementAndGet();
@@ -110,7 +114,7 @@
   * {@inheritDoc}
   */
  public void handleModifyDNOperation(
                   ModifyDNOperation modifyDNOperation,
                   PostResponseModifyDNOperation modifyDNOperation,
                   Entry oldEntry, Entry newEntry)
  {
    modifyDNCount.incrementAndGet();