From b1e950cafac995e6a0c4ad9d2787894e8afeb053 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Mon, 10 Nov 2008 13:41:49 +0000
Subject: [PATCH] This change fixes issue 3567:
---
opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java | 6
opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java | 55 --
opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java | 67 --
opendj-sdk/opends/src/server/org/opends/server/core/PersistentSearch.java | 630 +++++++++++++-----------
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java | 62 +
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java | 84 +-
opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperationBasis.java | 68 --
opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java | 47 +
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java | 9
opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperationBasis.java | 66 --
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java | 79 ++
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java | 64 +
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java | 2
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java | 4
opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperationBasis.java | 9
opendj-sdk/opends/src/server/org/opends/server/types/Operation.java | 10
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java | 25
opendj-sdk/opends/src/server/org/opends/server/core/AddOperationBasis.java | 64 --
opendj-sdk/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java | 8
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java | 15
opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java | 8
opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java | 63 +
opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java | 29
24 files changed, 706 insertions(+), 783 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java b/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java
index c56d565..e2be916 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -32,6 +32,7 @@
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -45,7 +46,6 @@
import org.opends.server.core.SearchOperation;
import org.opends.server.core.networkgroups.NetworkGroup;
import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.types.AbstractOperation;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
@@ -814,8 +814,7 @@
* @return The set of operations in progress for this client
* connection.
*/
- public abstract Collection<AbstractOperation>
- getOperationsInProgress();
+ public abstract Collection<Operation> getOperationsInProgress();
@@ -828,8 +827,7 @@
* @return The operation in progress with the specified message ID,
* or {@code null} if no such operation could be found.
*/
- public abstract AbstractOperation
- getOperationInProgress(int messageID);
+ public abstract Operation getOperationInProgress(int messageID);
@@ -857,8 +855,7 @@
* @return The set of persistent searches registered for this
* client.
*/
- public final CopyOnWriteArrayList<PersistentSearch>
- getPersistentSearches()
+ public final List<PersistentSearch> getPersistentSearches()
{
return persistentSearches;
}
@@ -1660,13 +1657,13 @@
if ((authzDN == null) || authzDN.isNullDN())
{
- return java.util.Collections.<Group>emptySet();
+ return Collections.<Group>emptySet();
}
Entry userEntry = DirectoryServer.getEntry(authzDN);
if (userEntry == null)
{
- return java.util.Collections.<Group>emptySet();
+ return Collections.<Group>emptySet();
}
HashSet<Group> groupSet = new HashSet<Group>();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperationBasis.java
index 649f815..b3e48f0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/AbandonOperationBasis.java
@@ -39,8 +39,6 @@
import org.opends.server.api.ClientConnection;
import org.opends.server.api.plugin.PluginResult;
-import org.opends.server.loggers.debug.DebugLogger;
-import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.*;
import org.opends.server.types.operation.PostOperationAbandonOperation;
import org.opends.server.types.operation.PreParseAbandonOperation;
@@ -57,11 +55,6 @@
PostOperationAbandonOperation
{
- /**
- * The tracer object for the debug logger.
- */
- private static final DebugTracer TRACER = DebugLogger.getTracer();
-
// The message ID of the operation that should be abandoned.
private final int idToAbandon;
@@ -251,7 +244,7 @@
// code to reflect whether the abandon was successful and an error message
// if it was not. Even though there is no response, the result should
// still be logged.
- AbstractOperation operation =
+ Operation operation =
clientConnection.getOperationInProgress(idToAbandon);
if (operation == null)
{
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/AddOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/AddOperationBasis.java
index 4d74a49..7280815 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/AddOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/AddOperationBasis.java
@@ -25,7 +25,6 @@
* Copyright 2007-2008 Sun Microsystems, Inc.
*/
package org.opends.server.core;
-import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
@@ -38,10 +37,8 @@
import static org.opends.server.core.CoreConstants.LOG_ELEMENT_RESULT_CODE;
import static org.opends.server.loggers.AccessLogger.logAddRequest;
import static org.opends.server.loggers.AccessLogger.logAddResponse;
-import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.util.StaticUtils.getExceptionMessage;
import static org.opends.server.util.StaticUtils.toLowerCase;
import java.util.ArrayList;
@@ -797,9 +794,10 @@
// Log the add response message.
logAddResponse(this);
- // Notifies any persistent searches that might be registered with the
- // server.
- notifyPersistentSearches(workflowExecuted);
+ // Invoke the post-response callbacks.
+ if (workflowExecuted) {
+ invokePostResponseCallbacks();
+ }
// Invoke the post-response add plugins.
invokePostResponsePlugins(workflowExecuted);
@@ -855,60 +853,6 @@
}
- /**
- * Notifies any persistent searches that might be registered with the server.
- * If no workflow has been executed then don't notify persistent searches.
- *
- * @param workflowExecuted <code>true</code> if a workflow has been
- * executed
- */
- private void notifyPersistentSearches(boolean workflowExecuted)
- {
- if (! workflowExecuted)
- {
- return;
- }
-
- List<?> localOperations =
- (List<?>)getAttachment(Operation.LOCALBACKENDOPERATIONS);
-
- if (localOperations != null)
- {
- for (Object localOp : localOperations)
- {
- LocalBackendAddOperation localOperation =
- (LocalBackendAddOperation)localOp;
-
- if ((getResultCode() == ResultCode.SUCCESS) &&
- (localOperation.getEntryToAdd() != null))
- {
- for (PersistentSearch persistentSearch :
- DirectoryServer.getPersistentSearches())
- {
- try
- {
- persistentSearch.processAdd(localOperation,
- localOperation.getEntryToAdd());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = ERR_ADD_ERROR_NOTIFYING_PERSISTENT_SEARCH.get(
- String.valueOf(persistentSearch), getExceptionMessage(e));
- logError(message);
-
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
- }
- }
- }
- }
- }
- }
-
/**
* Updates the error message and the result code of the operation.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperationBasis.java
index 3d33ca6..2bbd45b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DeleteOperationBasis.java
@@ -25,7 +25,6 @@
* Copyright 2007-2008 Sun Microsystems, Inc.
*/
package org.opends.server.core;
-import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
@@ -37,11 +36,8 @@
import static org.opends.server.core.CoreConstants.LOG_ELEMENT_RESULT_CODE;
import static org.opends.server.loggers.AccessLogger.logDeleteRequest;
import static org.opends.server.loggers.AccessLogger.logDeleteResponse;
-import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.util.StaticUtils.getExceptionMessage;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -452,9 +448,10 @@
// Log the delete response.
logDeleteResponse(this);
- // Notifies any persistent searches that might be registered with the
- // server.
- notifyPersistentSearches(workflowExecuted);
+ // Invoke the post-response callbacks.
+ if (workflowExecuted) {
+ invokePostResponseCallbacks();
+ }
// Invoke the post-response delete plugins.
invokePostResponsePlugins(workflowExecuted);
@@ -511,61 +508,6 @@
/**
- * Notifies any persistent searches that might be registered with the server.
- * If no workflow has been executed then don't notify persistent searches.
- *
- * @param workflowExecuted <code>true</code> if a workflow has been
- * executed
- */
- private void notifyPersistentSearches(boolean workflowExecuted)
- {
- if (! workflowExecuted)
- {
- return;
- }
-
- List localOperations =
- (List)getAttachment(Operation.LOCALBACKENDOPERATIONS);
-
- if (localOperations != null)
- {
- for (Object localOp : localOperations)
- {
- LocalBackendDeleteOperation localOperation =
- (LocalBackendDeleteOperation)localOp;
- // Notify any persistent searches that might be registered with the
- // server.
- if (getResultCode() == ResultCode.SUCCESS)
- {
- for (PersistentSearch persistentSearch :
- DirectoryServer.getPersistentSearches())
- {
- try
- {
- persistentSearch.processDelete(localOperation,
- localOperation.getEntryToDelete());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = ERR_DELETE_ERROR_NOTIFYING_PERSISTENT_SEARCH.
- get(String.valueOf(persistentSearch), getExceptionMessage(e));
- logError(message);
-
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
- }
- }
- }
- }
- }
- }
-
-
- /**
* Updates the error message and the result code of the operation.
*
* This method is called because no workflows were found to process
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index 6f5b117..ebe41bf 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -497,9 +497,6 @@
// The set of import task listeners registered with the Directory Server.
private CopyOnWriteArrayList<ImportTaskListener> importTaskListeners;
- // The set of persistent searches registered with the Directory Server.
- private CopyOnWriteArrayList<PersistentSearch> persistentSearches;
-
// The set of restore task listeners registered with the Directory Server.
private CopyOnWriteArrayList<RestoreTaskListener> restoreTaskListeners;
@@ -937,8 +934,6 @@
directoryServer.baseDnRegistry = new BaseDnRegistry();
directoryServer.changeNotificationListeners =
new CopyOnWriteArrayList<ChangeNotificationListener>();
- directoryServer.persistentSearches =
- new CopyOnWriteArrayList<PersistentSearch>();
directoryServer.shutdownListeners =
new CopyOnWriteArrayList<ServerShutdownListener>();
directoryServer.synchronizationProviders =
@@ -7730,56 +7725,6 @@
/**
- * Retrieves the set of persistent searches registered with the Directory
- * Server.
- *
- * @return The set of persistent searches registered with the Directory
- * Server.
- */
- public static CopyOnWriteArrayList<PersistentSearch> getPersistentSearches()
- {
- return directoryServer.persistentSearches;
- }
-
-
-
- /**
- * Registers the provided persistent search operation with the Directory
- * Server so that it will be notified of any add, delete, modify, or modify DN
- * operations that are performed.
- *
- * @param persistentSearch The persistent search operation to register with
- * the Directory Server.
- */
- public static void registerPersistentSearch(PersistentSearch persistentSearch)
- {
- directoryServer.persistentSearches.add(persistentSearch);
- persistentSearch.getSearchOperation().getClientConnection().
- registerPersistentSearch(persistentSearch);
- }
-
-
-
- /**
- * Deregisters the provided persistent search operation with the Directory
- * Server so that it will no longer be notified of any add, delete, modify, or
- * modify DN operations that are performed.
- *
- * @param persistentSearch The persistent search operation to deregister
- * with the Directory Server.
- */
- public static void deregisterPersistentSearch(PersistentSearch
- persistentSearch)
- {
- directoryServer.persistentSearches.remove(persistentSearch);
- persistentSearch.getSearchOperation().getClientConnection().
- deregisterPersistentSearch(persistentSearch);
- }
-
-
-
-
- /**
* Retrieves the set of synchronization providers that have been registered
* with the Directory Server.
*
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
index ef02509..3f1643c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
@@ -25,7 +25,6 @@
* Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.core;
-import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import java.util.ArrayList;
@@ -47,9 +46,7 @@
import org.opends.server.loggers.debug.DebugLogger;
import org.opends.server.loggers.debug.DebugTracer;
-import org.opends.server.loggers.ErrorLogger;
import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.util.StaticUtils.*;
/**
@@ -665,9 +662,10 @@
// Log the modify DN response.
logModifyDNResponse(this);
- // Notifies any persistent searches that might be registered with the
- // server.
- notifyPersistentSearches(workflowExecuted);
+ // Invoke the post-response callbacks.
+ if (workflowExecuted) {
+ invokePostResponseCallbacks();
+ }
// Invoke the post-response modify DN plugins.
invokePostResponsePlugins(workflowExecuted);
@@ -724,63 +722,6 @@
/**
- * Notifies any persistent searches that might be registered with the server.
- * If no workflow has been executed then don't notify persistent searches.
- *
- * @param workflowExecuted <code>true</code> if a workflow has been
- * executed
- */
- private void notifyPersistentSearches(boolean workflowExecuted)
- {
- if (! workflowExecuted)
- {
- return;
- }
-
- List localOperations =
- (List)getAttachment(Operation.LOCALBACKENDOPERATIONS);
-
- if (localOperations != null)
- {
- for (Object localOperation : localOperations)
- {
- LocalBackendModifyDNOperation localOp =
- (LocalBackendModifyDNOperation)localOperation;
- // Notify any persistent searches that might be registered with
- // the server.
- if (getResultCode() == ResultCode.SUCCESS)
- {
- for (PersistentSearch persistentSearch :
- DirectoryServer.getPersistentSearches())
- {
- try
- {
- persistentSearch.processModifyDN(
- localOp,
- localOp.getOriginalEntry(),
- localOp.getUpdatedEntry());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = ERR_MODDN_ERROR_NOTIFYING_PERSISTENT_SEARCH.get(
- String.valueOf(persistentSearch), getExceptionMessage(e));
- ErrorLogger.logError(message);
-
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
- }
- }
- }
- }
- }
- }
-
-
- /**
* Updates the error message and the result code of the operation.
*
* This method is called because no workflows were found to process
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperationBasis.java
index 8ab08ce..43474bd 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/ModifyOperationBasis.java
@@ -27,9 +27,6 @@
package org.opends.server.core;
import org.opends.messages.MessageBuilder;
-import org.opends.messages.Message;
-
-
import static org.opends.server.core.CoreConstants.LOG_ELEMENT_ENTRY_DN;
import static org.opends.server.core.CoreConstants.LOG_ELEMENT_ERROR_MESSAGE;
import static org.opends.server.core.CoreConstants.LOG_ELEMENT_MATCHED_DN;
@@ -38,11 +35,8 @@
import static org.opends.server.core.CoreConstants.LOG_ELEMENT_RESULT_CODE;
import static org.opends.server.loggers.AccessLogger.logModifyRequest;
import static org.opends.server.loggers.AccessLogger.logModifyResponse;
-import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.messages.CoreMessages.*;
-import static org.opends.server.util.StaticUtils.getExceptionMessage;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -554,9 +548,10 @@
// Log the modify response.
logModifyResponse(this);
- // Notifies any persistent searches that might be registered with the
- // server.
- notifyPersistentSearches(workflowExecuted);
+ // Invoke the post-response callbacks.
+ if (workflowExecuted) {
+ invokePostResponseCallbacks();
+ }
// Invoke the post-response add plugins.
invokePostResponsePlugins(workflowExecuted);
@@ -612,61 +607,6 @@
}
- /**
- * Notifies any persistent searches that might be registered with the server.
- * If no workflow has been executed then don't notify persistent searches.
- *
- * @param workflowExecuted <code>true</code> if a workflow has been
- * executed
- */
- private void notifyPersistentSearches(boolean workflowExecuted)
- {
- if (! workflowExecuted)
- {
- return;
- }
-
- List localOperations =
- (List)getAttachment(Operation.LOCALBACKENDOPERATIONS);
-
- if (localOperations != null)
- {
- for (Object localOp : localOperations)
- {
- LocalBackendModifyOperation localOperation =
- (LocalBackendModifyOperation)localOp;
- // Notify any persistent searches that might be registered with
- // the server.
- if (localOperation.getResultCode() == ResultCode.SUCCESS)
- {
- for (PersistentSearch persistentSearch :
- DirectoryServer.getPersistentSearches())
- {
- try
- {
- persistentSearch.processModify(localOperation,
- localOperation.getCurrentEntry(),
- localOperation.getModifiedEntry());
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = ERR_MODIFY_ERROR_NOTIFYING_PERSISTENT_SEARCH.
- get(String.valueOf(persistentSearch), getExceptionMessage(e));
- logError(message);
-
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
- }
- }
- }
- }
- }
- }
-
/**
* Updates the error message and the result code of the operation.
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java b/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java
index 5027094..02684d7 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/OperationWrapper.java
@@ -484,5 +484,13 @@
throws CanceledOperationException {
operation.checkIfCanceled(signalTooLate);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void registerPostResponseCallback(Runnable callback)
+ {
+ operation.registerPostResponseCallback(callback);
+ }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/PersistentSearch.java b/opendj-sdk/opends/src/server/org/opends/server/core/PersistentSearch.java
index 5e33329..a40bd0f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/PersistentSearch.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/PersistentSearch.java
@@ -27,206 +27,219 @@
package org.opends.server.core;
+
+import static org.opends.server.loggers.debug.DebugLogger.*;
+
import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.opends.server.controls.EntryChangeNotificationControl;
import org.opends.server.controls.PersistentSearchChangeType;
+import org.opends.server.loggers.debug.DebugTracer;
+import org.opends.server.types.CancelResult;
import org.opends.server.types.Control;
import org.opends.server.types.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
+import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchScope;
-import org.opends.server.workflowelement.localbackend.*;
-
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import org.opends.server.loggers.debug.DebugTracer;
/**
- * This class defines a data structure that will be used to hold the information
- * necessary for processing a persistent search.
+ * This class defines a data structure that will be used to hold the
+ * information necessary for processing a persistent search.
*/
-public class PersistentSearch
+public final class PersistentSearch
{
+
+ /**
+ * A cancellation call-back which can be used by work-flow element
+ * implementations in order to register for resource cleanup when a
+ * persistent search is cancelled.
+ */
+ public static interface CancellationCallback
+ {
+
+ /**
+ * The provided persistent search has been cancelled. Any
+ * resources associated with the persistent search should be
+ * released.
+ *
+ * @param psearch
+ * The persistent search which has just been cancelled.
+ */
+ void persistentSearchCancelled(PersistentSearch psearch);
+ }
+
/**
* The tracer object for the debug logger.
*/
private static final DebugTracer TRACER = getTracer();
- // Indicates whether entries returned should include the entry change
- // notification control.
- private boolean returnECs;
+ // Indicates whether entries returned should include the entry
+ // change notification control.
+ private final boolean returnECs;
// The base DN for the search operation.
- private DN baseDN;
+ private final DN baseDN;
// The set of change types we want to see.
- private Set<PersistentSearchChangeType> changeTypes;
+ private final Set<PersistentSearchChangeType> changeTypes;
// The scope for the search operation.
- private SearchScope scope;
+ private final SearchScope scope;
// The filter for the search operation.
- private SearchFilter filter;
+ private final SearchFilter filter;
// The reference to the associated search operation.
- private SearchOperation searchOperation;
+ private final SearchOperation searchOperation;
+
+ // Indicates whether or not this persistent search has already been
+ // aborted.
+ private boolean isCancelled = false;
+
+ // Cancellation callbacks which should be run when this persistent
+ // search is cancelled.
+ private final List<CancellationCallback> cancellationCallbacks =
+ new CopyOnWriteArrayList<CancellationCallback>();
/**
- * Creates a new persistent search object with the provided information.
+ * Creates a new persistent search object with the provided
+ * information.
*
- * @param searchOperation The search operation for this persistent search.
- * @param changeTypes The change types for which changes should be
- * examined.
- * @param returnECs Indicates whether to include entry change
- * notification controls in search result entries
- * sent to the client.
+ * @param searchOperation
+ * The search operation for this persistent search.
+ * @param changeTypes
+ * The change types for which changes should be examined.
+ * @param returnECs
+ * Indicates whether to include entry change notification
+ * controls in search result entries sent to the client.
*/
public PersistentSearch(SearchOperation searchOperation,
- Set<PersistentSearchChangeType> changeTypes,
- boolean returnECs)
+ Set<PersistentSearchChangeType> changeTypes, boolean returnECs)
{
this.searchOperation = searchOperation;
- this.changeTypes = changeTypes;
- this.returnECs = returnECs;
+ this.changeTypes = changeTypes;
+ this.returnECs = returnECs;
- baseDN = searchOperation.getBaseDN();
- scope = searchOperation.getScope();
- filter = searchOperation.getFilter();
+ this.baseDN = searchOperation.getBaseDN();
+ this.scope = searchOperation.getScope();
+ this.filter = searchOperation.getFilter();
}
/**
- * Retrieves the search operation for this persistent search.
+ * Cancels this persistent search operation. On exit this persistent
+ * search will no longer be valid and any resources associated with
+ * it will have been released.
*
- * @return The search operation for this persistent search.
+ * @return The result of the cancellation.
*/
- public SearchOperation getSearchOperation()
+ public synchronized CancelResult cancel()
{
- return searchOperation;
+ if (!isCancelled)
+ {
+ isCancelled = true;
+
+ // The persistent search can no longer be cancelled.
+ searchOperation.getClientConnection().deregisterPersistentSearch(this);
+
+ // Notify any cancellation callbacks.
+ for (CancellationCallback callback : cancellationCallbacks)
+ {
+ try
+ {
+ callback.persistentSearchCancelled(this);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ }
+ }
+ }
+
+ return new CancelResult(ResultCode.CANCELED, null);
}
/**
- * Retrieves the set of change types for this persistent search.
+ * Gets the message ID associated with this persistent search.
*
- * @return The set of change types for this persistent search.
+ * @return The message ID associated with this persistent search.
*/
- public Set<PersistentSearchChangeType> getChangeTypes()
+ public int getMessageID()
{
- return changeTypes;
+ return searchOperation.getMessageID();
}
/**
- * Retrieves the returnECs flag for this persistent search.
+ * Notifies the persistent searches that an entry has been added.
*
- * @return The return ECs flag for this persistent search.
+ * @param entry
+ * The entry that was added.
+ * @param changeNumber
+ * The change number associated with the operation that
+ * added the entry, or {@code -1} if there is no change
+ * number.
*/
- public boolean getReturnECs()
- {
- return returnECs;
- }
-
-
-
- /**
- * Retrieves the base DN for this persistent search.
- *
- * @return The base DN for this persistent search.
- */
- public DN getBaseDN()
- {
- return baseDN;
- }
-
-
-
- /**
- * Retrieves the scope for this persistent search.
- *
- * @return The scope for this persistent search.
- */
- public SearchScope getScope()
- {
- return scope;
- }
-
-
-
- /**
- * Retrieves the filter for this persistent search.
- *
- * @return The filter for this persistent search.
- */
- public SearchFilter getFilter()
- {
- return filter;
- }
-
-
-
- /**
- * Performs any necessary processing for the provided add operation.
- *
- * @param addOperation The add operation that has been processed.
- * @param entry The entry that was added.
- */
- public void processAdd(LocalBackendAddOperation addOperation, Entry entry)
+ public void processAdd(Entry entry, long changeNumber)
{
// See if we care about add operations.
- if (! changeTypes.contains(PersistentSearchChangeType.ADD))
+ if (!changeTypes.contains(PersistentSearchChangeType.ADD))
{
return;
}
-
// Make sure that the entry is within our target scope.
switch (scope)
{
- case BASE_OBJECT:
- if (! baseDN.equals(entry.getDN()))
- {
- return;
- }
- break;
- case SINGLE_LEVEL:
- if (! baseDN.equals(entry.getDN().getParentDNInSuffix()))
- {
- return;
- }
- break;
- case WHOLE_SUBTREE:
- if (! baseDN.isAncestorOf(entry.getDN()))
- {
- return;
- }
- break;
- case SUBORDINATE_SUBTREE:
- if (baseDN.equals(entry.getDN()) ||
- (! baseDN.isAncestorOf(entry.getDN())))
- {
- return;
- }
- break;
- default:
+ case BASE_OBJECT:
+ if (!baseDN.equals(entry.getDN()))
+ {
return;
+ }
+ break;
+ case SINGLE_LEVEL:
+ if (!baseDN.equals(entry.getDN().getParentDNInSuffix()))
+ {
+ return;
+ }
+ break;
+ case WHOLE_SUBTREE:
+ if (!baseDN.isAncestorOf(entry.getDN()))
+ {
+ return;
+ }
+ break;
+ case SUBORDINATE_SUBTREE:
+ if (baseDN.equals(entry.getDN()) || (!baseDN.isAncestorOf(entry.getDN())))
+ {
+ return;
+ }
+ break;
+ default:
+ return;
}
-
// Make sure that the entry matches the target filter.
try
{
- if (! filter.matchesEntry(entry))
+ if (!filter.matchesEntry(entry))
{
return;
}
@@ -243,25 +256,22 @@
return;
}
-
- // The entry is one that should be sent to the client. See if we also need
- // to construct an entry change notification control.
+ // The entry is one that should be sent to the client. See if we
+ // also need to construct an entry change notification control.
ArrayList<Control> entryControls = new ArrayList<Control>(1);
if (returnECs)
{
entryControls.add(new EntryChangeNotificationControl(
- PersistentSearchChangeType.ADD,
- addOperation.getChangeNumber()));
+ PersistentSearchChangeType.ADD, changeNumber));
}
-
- // Send the entry and see if we should continue processing. If not, then
- // deregister this persistent search.
+ // Send the entry and see if we should continue processing. If
+ // not, then deregister this persistent search.
try
{
- if (! searchOperation.returnEntry(entry, entryControls))
+ if (!searchOperation.returnEntry(entry, entryControls))
{
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
searchOperation.sendSearchResultDone();
}
}
@@ -272,7 +282,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
try
{
@@ -291,58 +301,58 @@
/**
- * Performs any necessary processing for the provided delete operation.
+ * Notifies the persistent searches that an entry has been deleted.
*
- * @param deleteOperation The delete operation that has been processed.
- * @param entry The entry that was removed.
+ * @param entry
+ * The entry that was deleted.
+ * @param changeNumber
+ * The change number associated with the operation that
+ * deleted the entry, or {@code -1} if there is no change
+ * number.
*/
- public void processDelete(LocalBackendDeleteOperation deleteOperation,
- Entry entry)
+ public void processDelete(Entry entry, long changeNumber)
{
// See if we care about delete operations.
- if (! changeTypes.contains(PersistentSearchChangeType.DELETE))
+ if (!changeTypes.contains(PersistentSearchChangeType.DELETE))
{
return;
}
-
// Make sure that the entry is within our target scope.
switch (scope)
{
- case BASE_OBJECT:
- if (! baseDN.equals(entry.getDN()))
- {
- return;
- }
- break;
- case SINGLE_LEVEL:
- if (! baseDN.equals(entry.getDN().getParentDNInSuffix()))
- {
- return;
- }
- break;
- case WHOLE_SUBTREE:
- if (! baseDN.isAncestorOf(entry.getDN()))
- {
- return;
- }
- break;
- case SUBORDINATE_SUBTREE:
- if (baseDN.equals(entry.getDN()) ||
- (! baseDN.isAncestorOf(entry.getDN())))
- {
- return;
- }
- break;
- default:
+ case BASE_OBJECT:
+ if (!baseDN.equals(entry.getDN()))
+ {
return;
+ }
+ break;
+ case SINGLE_LEVEL:
+ if (!baseDN.equals(entry.getDN().getParentDNInSuffix()))
+ {
+ return;
+ }
+ break;
+ case WHOLE_SUBTREE:
+ if (!baseDN.isAncestorOf(entry.getDN()))
+ {
+ return;
+ }
+ break;
+ case SUBORDINATE_SUBTREE:
+ if (baseDN.equals(entry.getDN()) || (!baseDN.isAncestorOf(entry.getDN())))
+ {
+ return;
+ }
+ break;
+ default:
+ return;
}
-
// Make sure that the entry matches the target filter.
try
{
- if (! filter.matchesEntry(entry))
+ if (!filter.matchesEntry(entry))
{
return;
}
@@ -359,25 +369,22 @@
return;
}
-
- // The entry is one that should be sent to the client. See if we also need
- // to construct an entry change notification control.
+ // The entry is one that should be sent to the client. See if we
+ // also need to construct an entry change notification control.
ArrayList<Control> entryControls = new ArrayList<Control>(1);
if (returnECs)
{
entryControls.add(new EntryChangeNotificationControl(
- PersistentSearchChangeType.DELETE,
- deleteOperation.getChangeNumber()));
+ PersistentSearchChangeType.DELETE, changeNumber));
}
-
- // Send the entry and see if we should continue processing. If not, then
- // deregister this persistent search.
+ // Send the entry and see if we should continue processing. If
+ // not, then deregister this persistent search.
try
{
- if (! searchOperation.returnEntry(entry, entryControls))
+ if (!searchOperation.returnEntry(entry, entryControls))
{
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
searchOperation.sendSearchResultDone();
}
}
@@ -388,7 +395,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
try
{
@@ -407,61 +414,78 @@
/**
- * Performs any necessary processing for the provided modify operation.
+ * Notifies the persistent searches that an entry has been modified.
*
- * @param modifyOperation The modify operation that has been processed.
- * @param oldEntry The entry before the modification was applied.
- * @param newEntry The entry after the modification was applied.
+ * @param entry
+ * The entry after it was modified.
+ * @param changeNumber
+ * The change number associated with the operation that
+ * modified the entry, or {@code -1} if there is no change
+ * number.
*/
- public void processModify(LocalBackendModifyOperation modifyOperation,
- Entry oldEntry,
- Entry newEntry)
+ public void processModify(Entry entry, long changeNumber)
+ {
+ processModify(entry, changeNumber, entry);
+ }
+
+
+
+ /**
+ * Notifies persistent searches that an entry has been modified.
+ *
+ * @param entry
+ * The entry after it was modified.
+ * @param changeNumber
+ * The change number associated with the operation that
+ * modified the entry, or {@code -1} if there is no change
+ * number.
+ * @param oldEntry
+ * The entry before it was modified.
+ */
+ public void processModify(Entry entry, long changeNumber, Entry oldEntry)
{
// See if we care about modify operations.
- if (! changeTypes.contains(PersistentSearchChangeType.MODIFY))
+ if (!changeTypes.contains(PersistentSearchChangeType.MODIFY))
{
return;
}
-
// Make sure that the entry is within our target scope.
switch (scope)
{
- case BASE_OBJECT:
- if (! baseDN.equals(oldEntry.getDN()))
- {
- return;
- }
- break;
- case SINGLE_LEVEL:
- if (! baseDN.equals(oldEntry.getDN().getParentDNInSuffix()))
- {
- return;
- }
- break;
- case WHOLE_SUBTREE:
- if (! baseDN.isAncestorOf(oldEntry.getDN()))
- {
- return;
- }
- break;
- case SUBORDINATE_SUBTREE:
- if (baseDN.equals(oldEntry.getDN()) ||
- (! baseDN.isAncestorOf(oldEntry.getDN())))
- {
- return;
- }
- break;
- default:
+ case BASE_OBJECT:
+ if (!baseDN.equals(oldEntry.getDN()))
+ {
return;
+ }
+ break;
+ case SINGLE_LEVEL:
+ if (!baseDN.equals(oldEntry.getDN().getParent()))
+ {
+ return;
+ }
+ break;
+ case WHOLE_SUBTREE:
+ if (!baseDN.isAncestorOf(oldEntry.getDN()))
+ {
+ return;
+ }
+ break;
+ case SUBORDINATE_SUBTREE:
+ if (baseDN.equals(oldEntry.getDN())
+ || (!baseDN.isAncestorOf(oldEntry.getDN())))
+ {
+ return;
+ }
+ break;
+ default:
+ return;
}
-
// Make sure that the entry matches the target filter.
try
{
- if ((! filter.matchesEntry(oldEntry)) &&
- (! filter.matchesEntry(newEntry)))
+ if ((!filter.matchesEntry(oldEntry)) && (!filter.matchesEntry(entry)))
{
return;
}
@@ -478,25 +502,22 @@
return;
}
-
- // The entry is one that should be sent to the client. See if we also need
- // to construct an entry change notification control.
+ // The entry is one that should be sent to the client. See if we
+ // also need to construct an entry change notification control.
ArrayList<Control> entryControls = new ArrayList<Control>(1);
if (returnECs)
{
entryControls.add(new EntryChangeNotificationControl(
- PersistentSearchChangeType.MODIFY,
- modifyOperation.getChangeNumber()));
+ PersistentSearchChangeType.MODIFY, changeNumber));
}
-
- // Send the entry and see if we should continue processing. If not, then
- // deregister this persistent search.
+ // Send the entry and see if we should continue processing. If
+ // not, then deregister this persistent search.
try
{
- if (! searchOperation.returnEntry(newEntry, entryControls))
+ if (!searchOperation.returnEntry(entry, entryControls))
{
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
searchOperation.sendSearchResultDone();
}
}
@@ -507,7 +528,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
try
{
@@ -526,82 +547,83 @@
/**
- * Performs any necessary processing for the provided modify DN operation.
+ * Notifies the persistent searches that an entry has been renamed.
*
- * @param modifyDNOperation The modify DN operation that has been processed.
- * @param oldEntry The entry before the modify DN.
- * @param newEntry The entry after the modify DN.
+ * @param entry
+ * The entry after it was modified.
+ * @param changeNumber
+ * The change number associated with the operation that
+ * modified the entry, or {@code -1} if there is no change
+ * number.
+ * @param oldDN
+ * The DN of the entry before it was renamed.
*/
- public void processModifyDN(LocalBackendModifyDNOperation modifyDNOperation,
- Entry oldEntry, Entry newEntry)
+ public void processModifyDN(Entry entry, long changeNumber, DN oldDN)
{
// See if we care about modify DN operations.
- if (! changeTypes.contains(PersistentSearchChangeType.MODIFY_DN))
+ if (!changeTypes.contains(PersistentSearchChangeType.MODIFY_DN))
{
return;
}
-
- // Make sure that the old or new entry is within our target scope. In this
- // case, we need to check the DNs of both the old and new entry so we know
- // which one(s) should be compared against the filter.
+ // Make sure that the old or new entry is within our target scope.
+ // In this case, we need to check the DNs of both the old and new
+ // entry so we know which one(s) should be compared against the
+ // filter.
boolean oldMatches = false;
boolean newMatches = false;
switch (scope)
{
- case BASE_OBJECT:
- oldMatches = baseDN.equals(oldEntry.getDN());
- newMatches = baseDN.equals(newEntry.getDN());
+ case BASE_OBJECT:
+ oldMatches = baseDN.equals(oldDN);
+ newMatches = baseDN.equals(entry.getDN());
- if (! (oldMatches || newMatches))
- {
- return;
- }
-
- break;
- case SINGLE_LEVEL:
- oldMatches = baseDN.equals(oldEntry.getDN().getParentDNInSuffix());
- newMatches = baseDN.equals(newEntry.getDN().getParentDNInSuffix());
-
- if (! (oldMatches || newMatches))
- {
- return;
- }
-
- break;
- case WHOLE_SUBTREE:
- oldMatches = baseDN.isAncestorOf(oldEntry.getDN());
- newMatches = baseDN.isAncestorOf(newEntry.getDN());
-
- if (! (oldMatches || newMatches))
- {
- return;
- }
-
- break;
- case SUBORDINATE_SUBTREE:
- oldMatches = ((! baseDN.equals(oldEntry.getDN())) &&
- baseDN.isAncestorOf(oldEntry.getDN()));
- newMatches = ((! baseDN.equals(newEntry.getDN())) &&
- baseDN.isAncestorOf(newEntry.getDN()));
-
- if (! (oldMatches || newMatches))
- {
- return;
- }
-
- break;
- default:
+ if (!(oldMatches || newMatches))
+ {
return;
- }
+ }
+ break;
+ case SINGLE_LEVEL:
+ oldMatches = baseDN.equals(oldDN.getParent());
+ newMatches = baseDN.equals(entry.getDN().getParent());
+
+ if (!(oldMatches || newMatches))
+ {
+ return;
+ }
+
+ break;
+ case WHOLE_SUBTREE:
+ oldMatches = baseDN.isAncestorOf(oldDN);
+ newMatches = baseDN.isAncestorOf(entry.getDN());
+
+ if (!(oldMatches || newMatches))
+ {
+ return;
+ }
+
+ break;
+ case SUBORDINATE_SUBTREE:
+ oldMatches = ((!baseDN.equals(oldDN)) && baseDN.isAncestorOf(oldDN));
+ newMatches = ((!baseDN.equals(entry.getDN())) && baseDN
+ .isAncestorOf(entry.getDN()));
+
+ if (!(oldMatches || newMatches))
+ {
+ return;
+ }
+
+ break;
+ default:
+ return;
+ }
// Make sure that the entry matches the target filter.
try
{
- if (((! oldMatches) || (! filter.matchesEntry(oldEntry))) &&
- ((! newMatches) && (! filter.matchesEntry(newEntry))))
+ if (!oldMatches && !newMatches && !filter.matchesEntry(entry))
{
return;
}
@@ -618,26 +640,22 @@
return;
}
-
- // The entry is one that should be sent to the client. See if we also need
- // to construct an entry change notification control.
+ // The entry is one that should be sent to the client. See if we
+ // also need to construct an entry change notification control.
ArrayList<Control> entryControls = new ArrayList<Control>(1);
if (returnECs)
{
entryControls.add(new EntryChangeNotificationControl(
- PersistentSearchChangeType.MODIFY_DN,
- oldEntry.getDN(),
- modifyDNOperation.getChangeNumber()));
+ PersistentSearchChangeType.MODIFY_DN, oldDN, changeNumber));
}
-
- // Send the entry and see if we should continue processing. If not, then
- // deregister this persistent search.
+ // Send the entry and see if we should continue processing. If
+ // not, then deregister this persistent search.
try
{
- if (! searchOperation.returnEntry(newEntry, entryControls))
+ if (!searchOperation.returnEntry(entry, entryControls))
{
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
searchOperation.sendSearchResultDone();
}
}
@@ -648,7 +666,7 @@
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- DirectoryServer.deregisterPersistentSearch(this);
+ cancel();
try
{
@@ -667,10 +685,26 @@
/**
+ * Registers a cancellation callback with this persistent search.
+ * The cancellation callback will be notified when this persistent
+ * search has been cancelled.
+ *
+ * @param callback
+ * The cancellation callback.
+ */
+ public void registerCancellationCallback(CancellationCallback callback)
+ {
+ cancellationCallbacks.add(callback);
+ }
+
+
+
+ /**
* Retrieves a string representation of this persistent search.
*
- * @return A string representation of this persistent search.
+ * @return A string representation of this persistent search.
*/
+ @Override
public String toString()
{
StringBuilder buffer = new StringBuilder();
@@ -681,10 +715,11 @@
/**
- * Appends a string representation of this persistent search to the provided
- * buffer.
+ * Appends a string representation of this persistent search to the
+ * provided buffer.
*
- * @param buffer The buffer to which the information should be appended.
+ * @param buffer
+ * The buffer to which the information should be appended.
*/
public void toString(StringBuilder buffer)
{
@@ -701,4 +736,3 @@
buffer.append("\")");
}
}
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index f296b93..4c2b312 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -1277,7 +1277,7 @@
if (persistentSearch != null)
{
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
+ persistentSearch.cancel();
persistentSearch = null;
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
index 34d09f0..69c1571 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
@@ -141,7 +141,7 @@
private AuthenticationInfo authenticationInfo;
// The empty operation list for this connection.
- private LinkedList<AbstractOperation> operationList;
+ private LinkedList<Operation> operationList;
// The connection ID for this client connection.
private long connectionID;
@@ -258,7 +258,7 @@
}
connectionID = nextConnectionID.getAndDecrement();
- operationList = new LinkedList<AbstractOperation>();
+ operationList = new LinkedList<Operation>();
try
{
@@ -298,7 +298,7 @@
super.setLookthroughLimit(0);
connectionID = nextConnectionID.getAndDecrement();
- operationList = new LinkedList<AbstractOperation>();
+ operationList = new LinkedList<Operation>();
try
{
@@ -2919,7 +2919,7 @@
mayExtend=false,
mayInvoke=false)
@Override()
- public Collection<AbstractOperation> getOperationsInProgress()
+ public Collection<Operation> getOperationsInProgress()
{
return operationList;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
index 5c3387b..62f5abd 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
@@ -100,7 +100,7 @@
private ConnectionSecurityProvider securityProvider;
// The empty operation list for this connection.
- private LinkedList<AbstractOperation> operationList;
+ private LinkedList<Operation> operationList;
// The connection ID for this client connection.
private long connectionID;
@@ -155,7 +155,7 @@
true,
ERR_LDAP_CONNHANDLER_REJECTED_BY_SERVER.get());
}
- operationList = new LinkedList<AbstractOperation>();
+ operationList = new LinkedList<Operation>();
try
{
@@ -1130,7 +1130,7 @@
*
* @return The set of operations in progress for this client connection.
*/
- public Collection<AbstractOperation> getOperationsInProgress()
+ public Collection<Operation> getOperationsInProgress()
{
return operationList;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
index 1586159..d7eee43 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -138,7 +138,7 @@
private byte[] elementValue;
// The set of all operations currently in progress on this connection.
- private ConcurrentHashMap<Integer,AbstractOperation> operationsInProgress;
+ private ConcurrentHashMap<Integer,Operation> operationsInProgress;
// The number of operations performed on this connection.
// Used to compare with the resource limits of the network group.
@@ -264,7 +264,7 @@
nextOperationID = new AtomicLong(0);
connectionValid = true;
disconnectRequested = false;
- operationsInProgress = new ConcurrentHashMap<Integer,AbstractOperation>();
+ operationsInProgress = new ConcurrentHashMap<Integer,Operation>();
operationsPerformed = 0;
operationsPerformedLock = new Object();
keepStats = connectionHandler.keepStats();
@@ -1136,7 +1136,7 @@
*
* @return The set of operations in progress for this client connection.
*/
- public Collection<AbstractOperation> getOperationsInProgress()
+ public Collection<Operation> getOperationsInProgress()
{
return operationsInProgress.values();
}
@@ -1151,7 +1151,7 @@
* @return The operation in progress with the specified message ID, or
* <CODE>null</CODE> if no such operation could be found.
*/
- public AbstractOperation getOperationInProgress(int messageID)
+ public Operation getOperationInProgress(int messageID)
{
return operationsInProgress.get(messageID);
}
@@ -1192,7 +1192,7 @@
// See if there is already an operation in progress with the same
// message ID. If so, then we can't allow it.
- AbstractOperation op = operationsInProgress.get(messageID);
+ Operation op = operationsInProgress.get(messageID);
if (op != null)
{
Message message =
@@ -1252,7 +1252,7 @@
*/
public boolean removeOperationInProgress(int messageID)
{
- AbstractOperation operation = operationsInProgress.remove(messageID);
+ Operation operation = operationsInProgress.remove(messageID);
if (operation == null)
{
return false;
@@ -1279,16 +1279,15 @@
public CancelResult cancelOperation(int messageID,
CancelRequest cancelRequest)
{
- AbstractOperation op = operationsInProgress.get(messageID);
+ Operation op = operationsInProgress.get(messageID);
if (op == null)
{
// See if the operation is in the list of persistent searches.
for (PersistentSearch ps : getPersistentSearches())
{
- if (ps.getSearchOperation().getMessageID() == messageID)
+ if (ps.getMessageID() == messageID)
{
- CancelResult cancelResult =
- ps.getSearchOperation().cancel(cancelRequest);
+ CancelResult cancelResult = ps.cancel();
if (keepStats && (cancelResult.getResultCode() ==
ResultCode.CANCELED))
@@ -1329,11 +1328,11 @@
{
try
{
- for (AbstractOperation o : operationsInProgress.values())
+ for (Operation o : operationsInProgress.values())
{
try
{
- o.abort(cancelRequest);
+ o.abort(cancelRequest);
// TODO: Assume its cancelled?
if (keepStats)
@@ -1361,7 +1360,7 @@
for (PersistentSearch persistentSearch : getPersistentSearches())
{
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
+ persistentSearch.cancel();
}
}
catch (Exception e)
@@ -1400,7 +1399,7 @@
continue;
}
- AbstractOperation o = operationsInProgress.get(msgID);
+ Operation o = operationsInProgress.get(msgID);
if (o != null)
{
try
@@ -1429,7 +1428,7 @@
for (PersistentSearch persistentSearch : getPersistentSearches())
{
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
+ persistentSearch.cancel();
lastCompletionTime.set(TimeThread.getTime());
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java b/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java
index e9a365b..d7dae8c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/AbstractOperation.java
@@ -33,12 +33,14 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.opends.server.api.ClientConnection;
import org.opends.server.types.operation.PostResponseOperation;
import org.opends.server.types.operation.PreParseOperation;
import org.opends.server.core.DirectoryServer;
+
import static org.opends.server.loggers.debug.
DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
@@ -168,6 +170,9 @@
// nanoseconds.
private long processingStopNanoTime;
+ // The callbacks to be invoked once a response has been sent.
+ private List<Runnable> postResponseCallbacks = null;
+
/**
* Creates a new operation with the provided information.
*
@@ -1148,5 +1153,47 @@
* processing.
*/
public abstract void run();
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void registerPostResponseCallback(Runnable callback)
+ {
+ if (postResponseCallbacks == null)
+ {
+ postResponseCallbacks = new LinkedList<Runnable>();
+ }
+ postResponseCallbacks.add(callback);
+ }
+
+
+
+ /**
+ * Invokes the post response callbacks that were registered with
+ * this operation.
+ */
+ protected final void invokePostResponseCallbacks()
+ {
+ if (postResponseCallbacks != null)
+ {
+ for (Runnable callback : postResponseCallbacks)
+ {
+ try
+ {
+ callback.run();
+ }
+ catch (Exception e)
+ {
+ // Should not happen.
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java b/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java
index 2e46443..1d9bf0f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Operation.java
@@ -622,5 +622,15 @@
public void checkIfCanceled(boolean signalTooLate)
throws CanceledOperationException;
+ /**
+ * Registers a callback which should be run once this operation has
+ * completed and the response sent back to the client.
+ *
+ * @param callback
+ * The callback to be run once this operation has completed
+ * and the response sent back to the client.
+ */
+ public void registerPostResponseCallback(Runnable callback);
+
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
index 985e55c..f1fdefe 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -65,6 +65,7 @@
import org.opends.server.core.AddOperationWrapper;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.PasswordPolicy;
+import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.schema.AuthPasswordSyntax;
@@ -173,16 +174,17 @@
/**
* Process this add operation against a local backend.
*
- * @param backend The backend in which the add operation should be
- * processed.
- *
- * @throws CanceledOperationException if this operation should be
- * cancelled
+ * @param wfe
+ * The local backend work-flow element.
+ * @throws CanceledOperationException
+ * if this operation should be cancelled
*/
- void processLocalAdd(Backend backend) throws CanceledOperationException {
+ void processLocalAdd(final LocalBackendWorkflowElement wfe)
+ throws CanceledOperationException
+ {
boolean executePostOpPlugins = false;
- this.backend = backend;
+ this.backend = wfe.getBackend();
ClientConnection clientConnection = getClientConnection();
// Get the plugin config manager that will be used for invoking plugins.
@@ -772,29 +774,41 @@
}
}
-
- // Notify any change notification listeners that might be registered with
- // the server.
- if ((getResultCode() == ResultCode.SUCCESS) && (entry != null))
+ // Register a post-response call-back which will notify persistent
+ // searches and change listeners.
+ if (getResultCode() == ResultCode.SUCCESS)
{
- for (ChangeNotificationListener changeListener :
- DirectoryServer.getChangeNotificationListeners())
+ registerPostResponseCallback(new Runnable()
{
- try
+ public void run()
{
- changeListener.handleAddOperation(this, entry);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ // Notify persistent searches.
+ for (PersistentSearch psearch : wfe.getPersistentSearches()) {
+ psearch.processAdd(entry, getChangeNumber());
}
- logError(ERR_ADD_ERROR_NOTIFYING_CHANGE_LISTENER.get(
- getExceptionMessage(e)));
+ // Notify change listeners.
+ for (ChangeNotificationListener changeListener : DirectoryServer
+ .getChangeNotificationListeners())
+ {
+ try
+ {
+ changeListener.handleAddOperation(LocalBackendAddOperation.this,
+ entry);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ logError(ERR_ADD_ERROR_NOTIFYING_CHANGE_LISTENER
+ .get(getExceptionMessage(e)));
+ }
+ }
}
- }
+ });
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
index 191b614..bccc5df 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -178,12 +178,13 @@
/**
* Process this bind operation in a local backend.
*
- * @param backend The backend in which the bind operation should be
- * processed.
+ * @param wfe
+ * The local backend work-flow element.
+ *
*/
- void processLocalBind(Backend backend)
+ void processLocalBind(LocalBackendWorkflowElement wfe)
{
- this.backend = backend;
+ this.backend = wfe.getBackend();
// Initialize a number of variables for use during the bind processing.
clientConnection = getClientConnection();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
index 950e7f6..83d2279 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendCompareOperation.java
@@ -116,16 +116,17 @@
/**
* Process this compare operation in a local backend.
*
- * @param backend The backend in which the compare operation should be
- * processed.
- *
- * @throws CanceledOperationException if this operation should be
- * cancelled
+ * @param wfe
+ * The local backend work-flow element.
+ * @throws CanceledOperationException
+ * if this operation should be cancelled
*/
- void processLocalCompare(Backend backend) throws CanceledOperationException {
+ void processLocalCompare(LocalBackendWorkflowElement wfe)
+ throws CanceledOperationException
+ {
boolean executePostOpPlugins = false;
- this.backend = backend;
+ this.backend = wfe.getBackend();
clientConnection = getClientConnection();
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
index 3e8571a..ccd4c22 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendDeleteOperation.java
@@ -47,6 +47,7 @@
import org.opends.server.core.DeleteOperationWrapper;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.DirectoryServer;
+import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.AttributeType;
@@ -143,16 +144,16 @@
/**
* Process this delete operation in a local backend.
*
- * @param backend The backend in which the delete operation should be
- * processed.
- *
- * @throws CanceledOperationException if this operation should be
- * cancelled
+ * @param wfe
+ * The local backend work-flow element.
+ * @throws CanceledOperationException
+ * if this operation should be cancelled
*/
- void processLocalDelete(Backend backend) throws CanceledOperationException {
+ void processLocalDelete(final LocalBackendWorkflowElement wfe)
+ throws CanceledOperationException
+ {
boolean executePostOpPlugins = false;
-
- this.backend = backend;
+ this.backend = wfe.getBackend();
clientConnection = getClientConnection();
@@ -444,29 +445,43 @@
}
- // Notify any change notification listeners that might be registered with
- // the server.
+ // Register a post-response call-back which will notify persistent
+ // searches and change listeners.
if (getResultCode() == ResultCode.SUCCESS)
{
- for (ChangeNotificationListener changeListener :
- DirectoryServer.getChangeNotificationListeners())
+ registerPostResponseCallback(new Runnable()
{
- try
+
+ public void run()
{
- changeListener.handleDeleteOperation(this, entry);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ // Notify persistent searches.
+ for (PersistentSearch psearch : wfe.getPersistentSearches()) {
+ psearch.processDelete(entry, getChangeNumber());
}
- Message message = ERR_DELETE_ERROR_NOTIFYING_CHANGE_LISTENER.get(
- getExceptionMessage(e));
- logError(message);
+ // Notify change listeners.
+ for (ChangeNotificationListener changeListener : DirectoryServer
+ .getChangeNotificationListeners())
+ {
+ try
+ {
+ changeListener.handleDeleteOperation(
+ LocalBackendDeleteOperation.this, entry);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message = ERR_DELETE_ERROR_NOTIFYING_CHANGE_LISTENER
+ .get(getExceptionMessage(e));
+ logError(message);
+ }
+ }
}
- }
+ });
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
index d23006f..fcbedd5 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyDNOperation.java
@@ -51,6 +51,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyDNOperationWrapper;
+import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.Attribute;
@@ -180,16 +181,16 @@
/**
* Process this modify DN operation in a local backend.
*
- * @param backend The backend in which the modify DN operation should be
- * processed.
- *
- * @throws CanceledOperationException if this operation should be
- * cancelled
+ * @param wfe
+ * The local backend work-flow element.
+ * @throws CanceledOperationException
+ * if this operation should be cancelled
*/
- void processLocalModifyDN(Backend backend) throws CanceledOperationException {
+ void processLocalModifyDN(final LocalBackendWorkflowElement wfe)
+ throws CanceledOperationException
+ {
boolean executePostOpPlugins = false;
-
- this.backend = backend;
+ this.backend = wfe.getBackend();
clientConnection = getClientConnection();
@@ -632,30 +633,45 @@
}
}
-
- // Notify any change notification listeners that might be registered with
- // the server.
+ // Register a post-response call-back which will notify persistent
+ // searches and change listeners.
if (getResultCode() == ResultCode.SUCCESS)
{
- for (ChangeNotificationListener changeListener :
- DirectoryServer.getChangeNotificationListeners())
+ registerPostResponseCallback(new Runnable()
{
- try
+
+ public void run()
{
- changeListener.handleModifyDNOperation(this, currentEntry, newEntry);
- }
- catch (Exception e)
- {
- if (debugEnabled())
+ // Notify persistent searches.
+ for (PersistentSearch psearch : wfe.getPersistentSearches())
{
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ psearch.processModifyDN(newEntry, getChangeNumber(),
+ currentEntry.getDN());
}
- Message message = ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER.get(
- getExceptionMessage(e));
- logError(message);
+ // Notify change listeners.
+ for (ChangeNotificationListener changeListener : DirectoryServer
+ .getChangeNotificationListeners())
+ {
+ try
+ {
+ changeListener.handleModifyDNOperation(
+ LocalBackendModifyDNOperation.this, currentEntry, newEntry);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message = ERR_MODDN_ERROR_NOTIFYING_CHANGE_LISTENER
+ .get(getExceptionMessage(e));
+ logError(message);
+ }
+ }
}
- }
+ });
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
index 0f903f0..dc83bc6 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -65,6 +65,7 @@
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.ModifyOperationWrapper;
import org.opends.server.core.PasswordPolicyState;
+import org.opends.server.core.PersistentSearch;
import org.opends.server.core.PluginConfigManager;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
@@ -293,16 +294,16 @@
/**
* Process this modify operation against a local backend.
*
- * @param backend The backend in which the modify operation should be
- * performed.
- *
- * @throws CanceledOperationException if this operation should be
- * cancelled
+ * @param wfe
+ * The local backend work-flow element.
+ * @throws CanceledOperationException
+ * if this operation should be cancelled
*/
- void processLocalModify(Backend backend) throws CanceledOperationException {
+ void processLocalModify(final LocalBackendWorkflowElement wfe)
+ throws CanceledOperationException
+ {
boolean executePostOpPlugins = false;
-
- this.backend = backend;
+ this.backend = wfe.getBackend();
clientConnection = getClientConnection();
@@ -690,11 +691,46 @@
}
- // Notify any change notification listeners that might be registered with
- // the server.
+ // Register a post-response call-back which will notify persistent
+ // searches and change listeners.
if (getResultCode() == ResultCode.SUCCESS)
{
- notifyChangeListeners();
+ registerPostResponseCallback(new Runnable()
+ {
+
+ public void run()
+ {
+ // Notify persistent searches.
+ for (PersistentSearch psearch : wfe.getPersistentSearches())
+ {
+ psearch.processModify(modifiedEntry, getChangeNumber(),
+ currentEntry);
+ }
+
+ // Notify change listeners.
+ for (ChangeNotificationListener changeListener : DirectoryServer
+ .getChangeNotificationListeners())
+ {
+ try
+ {
+ changeListener
+ .handleModifyOperation(LocalBackendModifyOperation.this,
+ currentEntry, modifiedEntry);
+ }
+ catch (Exception e)
+ {
+ if (debugEnabled())
+ {
+ TRACER.debugCaught(DebugLogLevel.ERROR, e);
+ }
+
+ Message message = ERR_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER
+ .get(getExceptionMessage(e));
+ logError(message);
+ }
+ }
+ }
+ });
}
}
@@ -2228,32 +2264,6 @@
- /**
- * Notify any registered change listeners about this update.
- */
- private void notifyChangeListeners()
- {
- for (ChangeNotificationListener changeListener :
- DirectoryServer.getChangeNotificationListeners())
- {
- try
- {
- changeListener.handleModifyOperation(this, currentEntry, modifiedEntry);
- }
- catch (Exception e)
- {
- if (debugEnabled())
- {
- TRACER.debugCaught(DebugLogLevel.ERROR, e);
- }
-
- Message message = ERR_MODIFY_ERROR_NOTIFYING_CHANGE_LISTENER.get(
- getExceptionMessage(e));
- logError(message);
- }
- }
- }
-
private boolean handleConflictResolution() {
boolean returnVal = true;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
index 9f966e3..293cb99 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendSearchOperation.java
@@ -121,16 +121,16 @@
/**
* Process this search operation against a local backend.
*
- * @param backend The backend in which the search operation should be
- * performed.
- *
- * @throws CanceledOperationException if this operation should be
- * cancelled
+ * @param wfe
+ * The local backend work-flow element.
+ * @throws CanceledOperationException
+ * if this operation should be cancelled
*/
- void processLocalSearch(Backend backend) throws CanceledOperationException {
+ void processLocalSearch(LocalBackendWorkflowElement wfe)
+ throws CanceledOperationException
+ {
boolean executePostOpPlugins = false;
-
- this.backend = backend;
+ this.backend = wfe.getBackend();
clientConnection = getClientConnection();
@@ -230,7 +230,8 @@
// If there's a persistent search, then register it with the server.
if (persistentSearch != null)
{
- DirectoryServer.registerPersistentSearch(persistentSearch);
+ wfe.registerPersistentSearch(persistentSearch);
+ clientConnection.registerPersistentSearch(persistentSearch);
setSendResponse(false);
}
@@ -254,7 +255,7 @@
if (persistentSearch != null)
{
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
+ persistentSearch.cancel();
setSendResponse(true);
}
@@ -264,7 +265,7 @@
{
if (persistentSearch != null)
{
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
+ persistentSearch.cancel();
setSendResponse(true);
}
@@ -283,7 +284,7 @@
if (persistentSearch != null)
{
- DirectoryServer.deregisterPersistentSearch(persistentSearch);
+ persistentSearch.cancel();
setSendResponse(true);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
index 70b58ba..839ae6e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -31,6 +31,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
@@ -47,6 +48,7 @@
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyOperation;
+import org.opends.server.core.PersistentSearch;
import org.opends.server.core.SearchOperation;
import org.opends.server.types.*;
import org.opends.server.workflowelement.LeafWorkflowElement;
@@ -73,6 +75,10 @@
registeredLocalBackends =
new TreeMap<String, LocalBackendWorkflowElement>();
+ // The set of persistent searches registered with this work flow
+ // element.
+ private final List<PersistentSearch> persistentSearches =
+ new CopyOnWriteArrayList<PersistentSearch>();
// a lock to guarantee safe concurrent access to the registeredLocalBackends
// variable
@@ -154,6 +160,12 @@
// an NPE
super.initialize(null, null);
backend = null;
+
+ // Cancel all persistent searches.
+ for (PersistentSearch psearch : persistentSearches) {
+ psearch.cancel();
+ }
+ persistentSearches.clear();
}
@@ -372,43 +384,43 @@
case BIND:
LocalBackendBindOperation bindOperation =
new LocalBackendBindOperation((BindOperation) operation);
- bindOperation.processLocalBind(backend);
+ bindOperation.processLocalBind(this);
break;
case SEARCH:
LocalBackendSearchOperation searchOperation =
new LocalBackendSearchOperation((SearchOperation) operation);
- searchOperation.processLocalSearch(backend);
+ searchOperation.processLocalSearch(this);
break;
case ADD:
LocalBackendAddOperation addOperation =
new LocalBackendAddOperation((AddOperation) operation);
- addOperation.processLocalAdd(backend);
+ addOperation.processLocalAdd(this);
break;
case DELETE:
LocalBackendDeleteOperation deleteOperation =
new LocalBackendDeleteOperation((DeleteOperation) operation);
- deleteOperation.processLocalDelete(backend);
+ deleteOperation.processLocalDelete(this);
break;
case MODIFY:
LocalBackendModifyOperation modifyOperation =
new LocalBackendModifyOperation((ModifyOperation) operation);
- modifyOperation.processLocalModify(backend);
+ modifyOperation.processLocalModify(this);
break;
case MODIFY_DN:
LocalBackendModifyDNOperation modifyDNOperation =
new LocalBackendModifyDNOperation((ModifyDNOperation) operation);
- modifyDNOperation.processLocalModifyDN(backend);
+ modifyDNOperation.processLocalModifyDN(this);
break;
case COMPARE:
LocalBackendCompareOperation compareOperation =
new LocalBackendCompareOperation((CompareOperation) operation);
- compareOperation.processLocalCompare(backend);
+ compareOperation.processLocalCompare(this);
break;
case ABANDON:
@@ -456,5 +468,58 @@
newAttachment);
}
+
+
+ /**
+ * Gets the backend associated with this local backend workflow
+ * element.
+ *
+ * @return The backend associated with this local backend workflow
+ * element.
+ */
+ Backend getBackend()
+ {
+ return backend;
+ }
+
+
+
+ /**
+ * Registers the provided persistent search operation with this
+ * local backend workflow element so that it will be notified of any
+ * add, delete, modify, or modify DN operations that are performed.
+ *
+ * @param persistentSearch
+ * The persistent search operation to register with this
+ * local backend workflow element.
+ */
+ void registerPersistentSearch(PersistentSearch persistentSearch)
+ {
+ PersistentSearch.CancellationCallback callback =
+ new PersistentSearch.CancellationCallback()
+ {
+ public void persistentSearchCancelled(PersistentSearch psearch)
+ {
+ persistentSearches.remove(psearch);
+ }
+ };
+
+ persistentSearches.add(persistentSearch);
+ persistentSearch.registerCancellationCallback(callback);
+ }
+
+
+
+ /**
+ * Gets the list of persistent searches currently active against
+ * this local backend workflow element.
+ *
+ * @return The list of persistent searches currently active against
+ * this local backend workflow element.
+ */
+ List<PersistentSearch> getPersistentSearches()
+ {
+ return persistentSearches;
+ }
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
index 57d32b5..ac5386e 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/protocols/internal/InternalClientConnectionTestCase.java
@@ -54,7 +54,6 @@
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.protocols.ldap.LDAPModification;
-import org.opends.server.types.AbstractOperation;
import org.opends.server.types.Attributes;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.CancelRequest;
@@ -65,6 +64,7 @@
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
import org.opends.server.types.ModificationType;
+import org.opends.server.types.Operation;
import org.opends.server.types.RawAttribute;
import org.opends.server.types.RawModification;
import org.opends.server.types.RDN;
@@ -1074,7 +1074,7 @@
{
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
- Collection<AbstractOperation> opList = conn.getOperationsInProgress();
+ Collection<Operation> opList = conn.getOperationsInProgress();
assertNotNull(opList);
assertTrue(opList.isEmpty());
}
--
Gitblit v1.10.0